Question: Should return instead of raising if the inputs are incompatible? I'm trying to implement a duck type of . If you are interested, the project is available . I'm running into trouble trying to coerce my duck type to use the reflected versions of the arithmetic operators if the left operand is not an instance of the duck type and they have equivalent but different units. Consider the following minimal working example of my duck type. If I do an operation like It works as expected. Or I can do and it still works properly. But if the left operand has different units I get the following error: I would argue that should really return in this instance, since it would allow for to be called instead of the error being raised. I feel that the current behavior is also inconsistent with the which specify that should be returned if the requested operation is not implemented. What does everyone think? I am more than happy to open a PR to try and solve this issue if we think it's worth pursuing.

Returns         -------        result : `~astropy.units.Quantity`        result : `~astropy.units.Quantity` or `NotImplemented`             Results of the ufunc, with the unit set properly.         """         # Determine required conversion functions -- to bring the unit of the         # input to that expected (e.g., radian for np.sin), or to get         # consistent units between two inputs (e.g., in np.add) --         # and the unit of the result (or tuple of units for nout > 1).        converters, unit = converters_and_unit(function, method, *inputs)        try:            converters, unit = converters_and_unit(function, method, *inputs)            out = kwargs.get("out", None)            # Avoid loop back by turning any Quantity output into array views.            if out is not None:                # If pre-allocated output is used, check it is suitable.                # This also returns array view, to ensure we don't loop back.                if function.nout == 1:                    out = out[0]                out_array = check_output(out, unit, inputs, function=function)                # Ensure output argument remains a tuple.                kwargs["out"] = (out_array,) if function.nout == 1 else out_array            if method == "reduce" and "initial" in kwargs and unit is not None:                # Special-case for initial argument for reductions like                # np.add.reduce.  This should be converted to the output unit as                # well, which is typically the same as the input unit (but can                # in principle be different: unitless for np.equal, radian                # for np.arctan2, though those are not necessarily useful!)                kwargs["initial"] = self._to_own_unit(                    kwargs["initial"], check_precision=False, unit=unit                )         out = kwargs.get("out", None)        # Avoid loop back by turning any Quantity output into array views.        if out is not None:            # If pre-allocated output is used, check it is suitable.            # This also returns array view, to ensure we don't loop back.            if function.nout == 1:                out = out[0]            out_array = check_output(out, unit, inputs, function=function)            # Ensure output argument remains a tuple.            kwargs["out"] = (out_array,) if function.nout == 1 else out_array        if method == "reduce" and "initial" in kwargs and unit is not None:            # Special-case for initial argument for reductions like            # np.add.reduce.  This should be converted to the output unit as            # well, which is typically the same as the input unit (but can            # in principle be different: unitless for np.equal, radian            # for np.arctan2, though those are not necessarily useful!)            kwargs["initial"] = self._to_own_unit(                kwargs["initial"], check_precision=False, unit=unit            # Same for inputs, but here also convert if necessary.            arrays = []            for input_, converter in zip(inputs, converters):                input_ = getattr(input_, "value", input_)                arrays.append(converter(input_) if converter else input_)            # Call our superclass's __array_ufunc__            result = super().__array_ufunc__(function, method, *arrays, **kwargs)            # If unit is None, a plain array is expected (e.g., comparisons), which            # means we're done.            # We're also done if the result was None (for method 'at') or            # NotImplemented, which can happen if other inputs/outputs override            # __array_ufunc__; hopefully, they can then deal with us.            if unit is None or result is None or result is NotImplemented:                return result            return self._result_as_quantity(result, unit, out)        except (TypeError, ValueError) as e:            out_normalized = kwargs.get("out", tuple())            inputs_and_outputs = inputs + out_normalized            ignored_ufunc = (                None,                np.ndarray.__array_ufunc__,                type(self).__array_ufunc__,             )        # Same for inputs, but here also convert if necessary.        arrays = []        for input_, converter in zip(inputs, converters):            input_ = getattr(input_, "value", input_)            arrays.append(converter(input_) if converter else input_)        # Call our superclass's __array_ufunc__        result = super().__array_ufunc__(function, method, *arrays, **kwargs)        # If unit is None, a plain array is expected (e.g., comparisons), which        # means we're done.        # We're also done if the result was None (for method 'at') or        # NotImplemented, which can happen if other inputs/outputs override        # __array_ufunc__; hopefully, they can then deal with us.        if unit is None or result is None or result is NotImplemented:            return result        return self._result_as_quantity(result, unit, out)            if not all(                getattr(type(io), "__array_ufunc__", None) in ignored_ufunc                for io in inputs_and_outputs            ):                return NotImplemented            else:                raise e      def _result_as_quantity(self, result, unit, out):         """Turn result into a quantity with the given unit.


Question: Degrees Celsius should be supported by FITS units <!-- This comments are hidden when you submit the issue, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted. If a similar issue is closed, have a quick look to see if you are satisfied by the resolution. If not please go ahead and open an issue! --The FITS standards says that units should follow IAU recommendations. These note that: However, astropy does not support for fits: See

def _generate_unit_names():         from astropy import units as u         names = {}        # add some units up-front for which we don't want to use prefixes        # and that have different names from the astropy default.        names = {            "Celsius": u.deg_C,            "deg C": u.deg_C,        }         deprecated_names = set()         bases = [             "m", "g", "s", "rad", "sr", "K", "A", "mol", "cd",diff --git a/astropy/units/si.py b/astropy/units/si.py-- a/astropy/units/si.py++ b/astropy/units/si.py


Question: Degrees Celsius should be supported by FITS units <!-- This comments are hidden when you submit the issue, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted. If a similar issue is closed, have a quick look to see if you are satisfied by the resolution. If not please go ahead and open an issue! --The FITS standards says that units should follow IAU recommendations. These note that: However, astropy does not support for fits: See

["deg_C", "Celsius"],     namespace=_ns,     doc="Degrees Celsius",    format={"latex": r"{}^{\circ}C", "unicode": "°C"},    format={"latex": r"{}^{\circ}C", "unicode": "°C", "fits": "Celsius"}, )


Question: Subclassed SkyCoord gives misleading attribute access message I'm trying to subclass , and add some custom properties. This all seems to be working fine, but when I have a custom property ( below) that tries to access a non-existent attribute () below, the error message is misleading because it says doesn't exist, where it should say doesn't exist. raises

if frame_cls is not None and self.frame.is_transformable_to(frame_cls):                 return self.transform_to(attr)         # Fail        raise AttributeError(            f"'{self.__class__.__name__}' object has no attribute '{attr}'"        )        # Call __getattribute__; this will give correct exception.        return self.__getattribute__(attr)      def __setattr__(self, attr, val):         # This is to make anything available through __getattr__ immutable


Question: Should calling on instances with incompatible units return ? <!-- This comments are hidden when you submit the issue, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted. If a similar issue is closed, have a quick look to see if you are satisfied by the resolution. If not please go ahead and open an issue! --<!-- Please check that the development version still produces the same bug. You can install development version with pip install command. --Using on instances with incompatible units raises a . I would've expected this function just to return in this case. Do we think it's really necessary to halt if the units are incompatible? <!-- What actually happened. --An exception was raised. <!-- Ideally a code example could be provided so we can run it ourselves. --<!-- If you are pasting code, use triple backticks (python np.arrayequal([1, 2, 3] u.mm, [1, 2, 3] u.s) Traceback (most recent call last): File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 980, in tovalue scale = (unit) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1129, in to raise UnitConversionError(f"'{self!r}' is not a scaled version of '{other!r}'") 'Unit("s")' is not a scaled version of 'Unit("mm")' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\royts\AppData\Local\Programs\Python\Python310\lib\site-packages\IPython\core\", line 3378, in runcode exec(codeobj, self.userglobalns, ) File "<ipython-input-13-", line 1, in <modulenp.arrayequal([1, 2, 3] u.mm, [1, 2, 3] u.s) File "<arrayfunction internals", line 180, in arrayequal File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1844, in arrayfunction args, kwargs, unit, out = functionhelper(args, *kwargs) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\quantityhelper\", line 566, in arrayequal args, unit = quantities2arrays(a1, a2) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\quantityhelper\", line 351, in quantities2arrays arrays = tuple((q.toownunit(arg)) for arg in args) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\quantityhelper\", line 351, in <genexprarrays = tuple((q.toownunit(arg)) for arg in args) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1652, in toownunit value = value.tovalue(unit) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 983, in tovalue value = self.tovalue(unit, equivalencies) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 889, in tovalue return ( File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1165, in to return self.getconverter(Unit(other), equivalencies)(value) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1094, in getconverter raise exc File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1077, in getconverter return self.applyequivalencies( File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1054, in applyequivalencies raise UnitConversionError(f"{unitstr} and {other_str} are not convertible") 's' (time) and 'mm' (length) are not convertible Windows-10-10.0.-SP0 Python 3.10.8 (tags/v3.10.8:, Oct 11 2022, 16:50:30) [MSC v.1933 64 bit (AMD64)] Numpy 1.23.5 pyerfa 2.0.0.1 astropy 5.3.dev89+g4989e530b Scipy 1.9.1 Matplotlib 3.6.0

import numpy as np from numpy.lib import recfunctions as rfn from astropy.units.core import UnitsError, UnitTypeError, dimensionless_unscaledfrom astropy.units.core import (    UnitConversionError,    UnitsError,    UnitTypeError,    dimensionless_unscaled,) from astropy.utils import isiterable from astropy.utils.compat import NUMPY_LT_1_23


Question: Should calling on instances with incompatible units return ? <!-- This comments are hidden when you submit the issue, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted. If a similar issue is closed, have a quick look to see if you are satisfied by the resolution. If not please go ahead and open an issue! --<!-- Please check that the development version still produces the same bug. You can install development version with pip install command. --Using on instances with incompatible units raises a . I would've expected this function just to return in this case. Do we think it's really necessary to halt if the units are incompatible? <!-- What actually happened. --An exception was raised. <!-- Ideally a code example could be provided so we can run it ourselves. --<!-- If you are pasting code, use triple backticks (python np.arrayequal([1, 2, 3] u.mm, [1, 2, 3] u.s) Traceback (most recent call last): File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 980, in tovalue scale = (unit) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1129, in to raise UnitConversionError(f"'{self!r}' is not a scaled version of '{other!r}'") 'Unit("s")' is not a scaled version of 'Unit("mm")' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\royts\AppData\Local\Programs\Python\Python310\lib\site-packages\IPython\core\", line 3378, in runcode exec(codeobj, self.userglobalns, ) File "<ipython-input-13-", line 1, in <modulenp.arrayequal([1, 2, 3] u.mm, [1, 2, 3] u.s) File "<arrayfunction internals", line 180, in arrayequal File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1844, in arrayfunction args, kwargs, unit, out = functionhelper(args, *kwargs) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\quantityhelper\", line 566, in arrayequal args, unit = quantities2arrays(a1, a2) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\quantityhelper\", line 351, in quantities2arrays arrays = tuple((q.toownunit(arg)) for arg in args) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\quantityhelper\", line 351, in <genexprarrays = tuple((q.toownunit(arg)) for arg in args) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1652, in toownunit value = value.tovalue(unit) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 983, in tovalue value = self.tovalue(unit, equivalencies) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 889, in tovalue return ( File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1165, in to return self.getconverter(Unit(other), equivalencies)(value) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1094, in getconverter raise exc File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1077, in getconverter return self.applyequivalencies( File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1054, in applyequivalencies raise UnitConversionError(f"{unitstr} and {other_str} are not convertible") 's' (time) and 'mm' (length) are not convertible Windows-10-10.0.-SP0 Python 3.10.8 (tags/v3.10.8:, Oct 11 2022, 16:50:30) [MSC v.1933 64 bit (AMD64)] Numpy 1.23.5 pyerfa 2.0.0.1 astropy 5.3.dev89+g4989e530b Scipy 1.9.1 Matplotlib 3.6.0

return (a, b, rtol, atol) + args, kwargs, None, None  @function_helper@dispatched_function def array_equal(a1, a2, equal_nan=False):    args, unit = _quantities2arrays(a1, a2)    return args, dict(equal_nan=equal_nan), None, None    try:        args, unit = _quantities2arrays(a1, a2)    except UnitConversionError:        return False, None, None    return np.array_equal(*args, equal_nan=equal_nan), None, None  @function_helper@dispatched_function def array_equiv(a1, a2):    args, unit = _quantities2arrays(a1, a2)    return args, {}, None, None    try:        args, unit = _quantities2arrays(a1, a2)    except UnitConversionError:        return False, None, None    return np.array_equiv(*args), None, None   @function_helper(helps={np.dot, np.outer})


Question: Please support header rows in RestructuredText output It would be great if the following would work: RestructuredText output is a great way to fill autogenerated documentation with content, so having this flexible makes the life easier

class SimpleRSTData(FixedWidthData):<del>    start_line = 3</del>     end_line = -1     splitter_class = FixedWidthTwoLineDataSplitter


Question: Please support header rows in RestructuredText output It would be great if the following would work: RestructuredText output is a great way to fill autogenerated documentation with content, so having this flexible makes the life easier

Example::         ==== ===== ======        Col1  Col2  Col3        ==== ===== ======          1    2.3  Hello          2    4.5  Worlds        ==== ===== ======      >>> from astropy.table import QTable      >>> import astropy.units as u      >>> import sys      >>> tbl = QTable({"wave": [350, 950] * u.nm, "response": [0.7, 1.2] * u.count})      >>> tbl.write(sys.stdout,  format="ascii.rst")      ===== ========       wave response      ===== ========      350.0      0.7      950.0      1.2      ===== ========    Like other fixed-width formats, when writing a table you can provide ``header_rows``    to specify a list of table rows to output as the header.  For example::      >>> tbl.write(sys.stdout,  format="ascii.rst", header_rows=['name', 'unit'])      ===== ========       wave response         nm       ct      ===== ========      350.0      0.7      950.0      1.2      ===== ========      Currently there is no support for reading tables which utilize continuation lines,     or for ones which define column spans through the use of an additional


Question: Please support header rows in RestructuredText output It would be great if the following would work: RestructuredText output is a great way to fill autogenerated documentation with content, so having this flexible makes the life easier

data_class = SimpleRSTData     header_class = SimpleRSTHeader     def __init__(self):        super().__init__(delimiter_pad=None, bookend=False)    def __init__(self, header_rows=None):        super().__init__(delimiter_pad=None, bookend=False, header_rows=header_rows)      def write(self, lines):         lines = super().write(lines)        lines = [lines[1]] + lines + [lines[1]]        idx = len(self.header.header_rows)        lines = [lines[idx]] + lines + [lines[idx]]         return lines    def read(self, table):        self.data.start_line = 2 + len(self.header.header_rows)        return super().read(table)


Question: The argument to -like functions does not accept instances of <!-- This comments are hidden when you submit the issue, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted. If a similar issue is closed, have a quick look to see if you are satisfied by the resolution. If not please go ahead and open an issue! --<!-- Please check that the development version still produces the same bug. You can install development version with pip install command. --When using , , etc. family of functions, with instances of , the argument only accepts instances of . I would have expected that the argument needs to be an instance of with compatible units. An is raised if is an instance of . <!-- Ideally a code example could be provided so we can run it ourselves. --<!-- If you are pasting code, use triple backticks (python import numpy as np import as u a = (21) u.m np.histogram(a, range=[.25, .75] u.m) Traceback (most recent call last): File "C:\Users\royts\AppData\Local\Programs\Python\Python310\lib\site-packages\IPython\core\", line 3378, in runcode exec(codeobj, self.userglobalns, ) File "<ipython-input-8-", line 1, in <modulenp.histogram(a, range=[.2, .7] u.m) File "<arrayfunction internals", line 200, in histogram File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1844, in arrayfunction result = super().arrayfunction(function, types, args, kwargs) File "C:\Users\royts\AppData\Local\Programs\Python\Python310\lib\site-packages\numpy\lib\", line 824, in histogram keep = (tmpa = firstedge) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 699, in arrayufunc raise e File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 644, in arrayufunc converters, unit = convertersandunit(function, method, inputs) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\quantityhelper\", line 200, in convertersandunit raise UnitConversionError( Can only apply 'lessequal' function to dimensionless quantities when other argument is not a quantity (unless the latter is all zero/infinity/nan). Windows-10-10.0.-SP0 Python 3.10.8 (tags/v3.10.8:, Oct 11 2022, 16:50:30) [MSC v.1933 64 bit (AMD64)] Numpy 1.24.0 pyerfa 2.0.0.1 astropy 5.3.dev128+ge512a6799 Scipy 1.9.1 Matplotlib 3.6.0

return bins  <ins>def _check_range(range, unit):    range = _as_quantity(range)    range = range.to_value(unit)    return range</ins> @function_helper def histogram(a, bins=10, range=None, weights=None, density=None):     if weights is not None:


Question: The argument to -like functions does not accept instances of <!-- This comments are hidden when you submit the issue, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted. If a similar issue is closed, have a quick look to see if you are satisfied by the resolution. If not please go ahead and open an issue! --<!-- Please check that the development version still produces the same bug. You can install development version with pip install command. --When using , , etc. family of functions, with instances of , the argument only accepts instances of . I would have expected that the argument needs to be an instance of with compatible units. An is raised if is an instance of . <!-- Ideally a code example could be provided so we can run it ourselves. --<!-- If you are pasting code, use triple backticks (python import numpy as np import as u a = (21) u.m np.histogram(a, range=[.25, .75] u.m) Traceback (most recent call last): File "C:\Users\royts\AppData\Local\Programs\Python\Python310\lib\site-packages\IPython\core\", line 3378, in runcode exec(codeobj, self.userglobalns, ) File "<ipython-input-8-", line 1, in <modulenp.histogram(a, range=[.2, .7] u.m) File "<arrayfunction internals", line 200, in histogram File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1844, in arrayfunction result = super().arrayfunction(function, types, args, kwargs) File "C:\Users\royts\AppData\Local\Programs\Python\Python310\lib\site-packages\numpy\lib\", line 824, in histogram keep = (tmpa = firstedge) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 699, in arrayufunc raise e File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 644, in arrayufunc converters, unit = convertersandunit(function, method, inputs) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\quantityhelper\", line 200, in convertersandunit raise UnitConversionError( Can only apply 'lessequal' function to dimensionless quantities when other argument is not a quantity (unless the latter is all zero/infinity/nan). Windows-10-10.0.-SP0 Python 3.10.8 (tags/v3.10.8:, Oct 11 2022, 16:50:30) [MSC v.1933 64 bit (AMD64)] Numpy 1.24.0 pyerfa 2.0.0.1 astropy 5.3.dev128+ge512a6799 Scipy 1.9.1 Matplotlib 3.6.0

if not isinstance(bins, str):         bins = _check_bins(bins, a.unit) <ins>    if range is not None:        range = _check_range(range, a.unit)</ins>     if density:         unit = (unit or 1) / a.unit


Question: The argument to -like functions does not accept instances of <!-- This comments are hidden when you submit the issue, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted. If a similar issue is closed, have a quick look to see if you are satisfied by the resolution. If not please go ahead and open an issue! --<!-- Please check that the development version still produces the same bug. You can install development version with pip install command. --When using , , etc. family of functions, with instances of , the argument only accepts instances of . I would have expected that the argument needs to be an instance of with compatible units. An is raised if is an instance of . <!-- Ideally a code example could be provided so we can run it ourselves. --<!-- If you are pasting code, use triple backticks (python import numpy as np import as u a = (21) u.m np.histogram(a, range=[.25, .75] u.m) Traceback (most recent call last): File "C:\Users\royts\AppData\Local\Programs\Python\Python310\lib\site-packages\IPython\core\", line 3378, in runcode exec(codeobj, self.userglobalns, ) File "<ipython-input-8-", line 1, in <modulenp.histogram(a, range=[.2, .7] u.m) File "<arrayfunction internals", line 200, in histogram File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1844, in arrayfunction result = super().arrayfunction(function, types, args, kwargs) File "C:\Users\royts\AppData\Local\Programs\Python\Python310\lib\site-packages\numpy\lib\", line 824, in histogram keep = (tmpa = firstedge) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 699, in arrayufunc raise e File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 644, in arrayufunc converters, unit = convertersandunit(function, method, inputs) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\quantityhelper\", line 200, in convertersandunit raise UnitConversionError( Can only apply 'lessequal' function to dimensionless quantities when other argument is not a quantity (unless the latter is all zero/infinity/nan). Windows-10-10.0.-SP0 Python 3.10.8 (tags/v3.10.8:, Oct 11 2022, 16:50:30) [MSC v.1933 64 bit (AMD64)] Numpy 1.24.0 pyerfa 2.0.0.1 astropy 5.3.dev128+ge512a6799 Scipy 1.9.1 Matplotlib 3.6.0

if not isinstance(bins, str):         bins = _check_bins(bins, a.unit) <ins>    if range is not None:        range = _check_range(range, a.unit)</ins>     return (a.value, bins, range, weights), {}, a.unit, None


Question: The argument to -like functions does not accept instances of <!-- This comments are hidden when you submit the issue, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted. If a similar issue is closed, have a quick look to see if you are satisfied by the resolution. If not please go ahead and open an issue! --<!-- Please check that the development version still produces the same bug. You can install development version with pip install command. --When using , , etc. family of functions, with instances of , the argument only accepts instances of . I would have expected that the argument needs to be an instance of with compatible units. An is raised if is an instance of . <!-- Ideally a code example could be provided so we can run it ourselves. --<!-- If you are pasting code, use triple backticks (python import numpy as np import as u a = (21) u.m np.histogram(a, range=[.25, .75] u.m) Traceback (most recent call last): File "C:\Users\royts\AppData\Local\Programs\Python\Python310\lib\site-packages\IPython\core\", line 3378, in runcode exec(codeobj, self.userglobalns, ) File "<ipython-input-8-", line 1, in <modulenp.histogram(a, range=[.2, .7] u.m) File "<arrayfunction internals", line 200, in histogram File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1844, in arrayfunction result = super().arrayfunction(function, types, args, kwargs) File "C:\Users\royts\AppData\Local\Programs\Python\Python310\lib\site-packages\numpy\lib\", line 824, in histogram keep = (tmpa = firstedge) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 699, in arrayufunc raise e File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 644, in arrayufunc converters, unit = convertersandunit(function, method, inputs) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\quantityhelper\", line 200, in convertersandunit raise UnitConversionError( Can only apply 'lessequal' function to dimensionless quantities when other argument is not a quantity (unless the latter is all zero/infinity/nan). Windows-10-10.0.-SP0 Python 3.10.8 (tags/v3.10.8:, Oct 11 2022, 16:50:30) [MSC v.1933 64 bit (AMD64)] Numpy 1.24.0 pyerfa 2.0.0.1 astropy 5.3.dev128+ge512a6799 Scipy 1.9.1 Matplotlib 3.6.0

bins = _check_bins(bins, x.unit)             y = y.to(x.unit) <ins>    if range is not None:        range = tuple(            _check_range(r, unit) for (r, unit) in zip(range, (x.unit, y.unit))        )</ins>     if density:         unit = (unit or 1) / x.unit / y.unit


Question: The argument to -like functions does not accept instances of <!-- This comments are hidden when you submit the issue, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted. If a similar issue is closed, have a quick look to see if you are satisfied by the resolution. If not please go ahead and open an issue! --<!-- Please check that the development version still produces the same bug. You can install development version with pip install command. --When using , , etc. family of functions, with instances of , the argument only accepts instances of . I would have expected that the argument needs to be an instance of with compatible units. An is raised if is an instance of . <!-- Ideally a code example could be provided so we can run it ourselves. --<!-- If you are pasting code, use triple backticks (python import numpy as np import as u a = (21) u.m np.histogram(a, range=[.25, .75] u.m) Traceback (most recent call last): File "C:\Users\royts\AppData\Local\Programs\Python\Python310\lib\site-packages\IPython\core\", line 3378, in runcode exec(codeobj, self.userglobalns, ) File "<ipython-input-8-", line 1, in <modulenp.histogram(a, range=[.2, .7] u.m) File "<arrayfunction internals", line 200, in histogram File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 1844, in arrayfunction result = super().arrayfunction(function, types, args, kwargs) File "C:\Users\royts\AppData\Local\Programs\Python\Python310\lib\site-packages\numpy\lib\", line 824, in histogram keep = (tmpa = firstedge) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 699, in arrayufunc raise e File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\", line 644, in arrayufunc converters, unit = convertersandunit(function, method, inputs) File "C:\Users\royts\Kankelborg-Group\astropy\astropy\units\quantityhelper\", line 200, in convertersandunit raise UnitConversionError( Can only apply 'lessequal' function to dimensionless quantities when other argument is not a quantity (unless the latter is all zero/infinity/nan). Windows-10-10.0.-SP0 Python 3.10.8 (tags/v3.10.8:, Oct 11 2022, 16:50:30) [MSC v.1933 64 bit (AMD64)] Numpy 1.24.0 pyerfa 2.0.0.1 astropy 5.3.dev128+ge512a6799 Scipy 1.9.1 Matplotlib 3.6.0

)         bins = [_check_bins(b, unit) for (b, unit) in zip(bins, sample_units)] <ins>    if range is not None:        range = tuple(_check_range(r, unit) for (r, unit) in zip(range, sample_units))</ins>     if density:         unit = functools.reduce(operator.truediv, sample_units, (unit or 1))


Question: When should be linked to a new object? Mostly for - I noticed that in the way we have set up , is passed on not just for views (where it should be), but also for copies (implicitly in arithmetic operations, etc.). Which ones are reasonable? Just thinking about whether, e.g., should be propagated, I'd think: Surely for views & reshapes: , , etc. insertions: Probably for selection of scalars: or in (for columns this returns a scalar without ) copies: and equivalents equivalent unit changes: , , , etc. Probably not for operations real unit changes (including in-place??; ) What do you think? p.s. Currently, all of the above happen, in part because I use in , something which I don't think we had really considered when we made the change in . But that also means that in principle it may not too hard to fairly finely define the behaviour.

if out is None:             # View the result array as a Quantity with the proper unit.            return result if unit is None else self._new_view(result, unit)            return (                result if unit is None else self._new_view(result, unit, finalize=False)            )          elif isinstance(out, Quantity):             # For given Quantity output, just set the unit. We know the unit


Question: When should be linked to a new object? Mostly for - I noticed that in the way we have set up , is passed on not just for views (where it should be), but also for copies (implicitly in arithmetic operations, etc.). Which ones are reasonable? Just thinking about whether, e.g., should be propagated, I'd think: Surely for views & reshapes: , , etc. insertions: Probably for selection of scalars: or in (for columns this returns a scalar without ) copies: and equivalents equivalent unit changes: , , , etc. Probably not for operations real unit changes (including in-place??; ) What do you think? p.s. Currently, all of the above happen, in part because I use in , something which I don't think we had really considered when we made the change in . But that also means that in principle it may not too hard to fairly finely define the behaviour.

"""         return Quantity, True     def _new_view(self, obj=None, unit=None):        """        Create a Quantity view of some array-like input, and set the unit    def _new_view(self, obj=None, unit=None, finalize=True):        """Create a Quantity view of some array-like input, and set the unit          By default, return a view of ``obj`` of the same class as ``self`` and         with the same unit.  Subclasses can override the type of class for a


Question: When should be linked to a new object? Mostly for - I noticed that in the way we have set up , is passed on not just for views (where it should be), but also for copies (implicitly in arithmetic operations, etc.). Which ones are reasonable? Just thinking about whether, e.g., should be propagated, I'd think: Surely for views & reshapes: , , etc. insertions: Probably for selection of scalars: or in (for columns this returns a scalar without ) copies: and equivalents equivalent unit changes: , , , etc. Probably not for operations real unit changes (including in-place??; ) What do you think? p.s. Currently, all of the above happen, in part because I use in , something which I don't think we had really considered when we made the change in . But that also means that in principle it may not too hard to fairly finely define the behaviour.

subclass, and explicitly assigned to the view if given.             If not given, the subclass and unit will be that of ``self``.         finalize : bool, optional            Whether to call ``__array_finalize__`` to transfer properties from            ``self`` to the new view of ``obj`` (e.g., ``info`` for all            subclasses, or ``_wrap_angle`` for `~astropy.coordinates.Latitude`).            Default: `True`, as appropriate for, e.g., unit conversions or slicing,            where the nature of the object does not change.         Returns         -------         view : `~astropy.units.Quantity` subclass         """         # Determine the unit and quantity subclass that we need for the view.         if unit is None:


Question: When should be linked to a new object? Mostly for - I noticed that in the way we have set up , is passed on not just for views (where it should be), but also for copies (implicitly in arithmetic operations, etc.). Which ones are reasonable? Just thinking about whether, e.g., should be propagated, I'd think: Surely for views & reshapes: , , etc. insertions: Probably for selection of scalars: or in (for columns this returns a scalar without ) copies: and equivalents equivalent unit changes: , , , etc. Probably not for operations real unit changes (including in-place??; ) What do you think? p.s. Currently, all of the above happen, in part because I use in , something which I don't think we had really considered when we made the change in . But that also means that in principle it may not too hard to fairly finely define the behaviour.

# such as ``info``, ``wrap_angle`` in `Longitude`, etc.         view = obj.view(quantity_subclass)         view._set_unit(unit)        view.__array_finalize__(self)        if finalize:            view.__array_finalize__(self)         return view      def _set_unit(self, unit):


Question: When should be linked to a new object? Mostly for - I noticed that in the way we have set up , is passed on not just for views (where it should be), but also for copies (implicitly in arithmetic operations, etc.). Which ones are reasonable? Just thinking about whether, e.g., should be propagated, I'd think: Surely for views & reshapes: , , etc. insertions: Probably for selection of scalars: or in (for columns this returns a scalar without ) copies: and equivalents equivalent unit changes: , , , etc. Probably not for operations real unit changes (including in-place??; ) What do you think? p.s. Currently, all of the above happen, in part because I use in , something which I don't think we had really considered when we made the change in . But that also means that in principle it may not too hard to fairly finely define the behaviour.

if isinstance(other, (UnitBase, str)):             try:                return self._new_view(self.copy(), other * self.unit)                return self._new_view(                    self.value.copy(), other * self.unit, finalize=False                )             except UnitsError:  # let other try to deal with it                 return NotImplemented


Question: When should be linked to a new object? Mostly for - I noticed that in the way we have set up , is passed on not just for views (where it should be), but also for copies (implicitly in arithmetic operations, etc.). Which ones are reasonable? Just thinking about whether, e.g., should be propagated, I'd think: Surely for views & reshapes: , , etc. insertions: Probably for selection of scalars: or in (for columns this returns a scalar without ) copies: and equivalents equivalent unit changes: , , , etc. Probably not for operations real unit changes (including in-place??; ) What do you think? p.s. Currently, all of the above happen, in part because I use in , something which I don't think we had really considered when we made the change in . But that also means that in principle it may not too hard to fairly finely define the behaviour.

if isinstance(other, (UnitBase, str)):             try:                return self._new_view(self.copy(), self.unit / other)                return self._new_view(                    self.value.copy(), self.unit / other, finalize=False                )             except UnitsError:  # let other try to deal with it                 return NotImplemented


Question: When should be linked to a new object? Mostly for - I noticed that in the way we have set up , is passed on not just for views (where it should be), but also for copies (implicitly in arithmetic operations, etc.). Which ones are reasonable? Just thinking about whether, e.g., should be propagated, I'd think: Surely for views & reshapes: , , etc. insertions: Probably for selection of scalars: or in (for columns this returns a scalar without ) copies: and equivalents equivalent unit changes: , , , etc. Probably not for operations real unit changes (including in-place??; ) What do you think? p.s. Currently, all of the above happen, in part because I use in , something which I don't think we had really considered when we made the change in . But that also means that in principle it may not too hard to fairly finely define the behaviour.

"""Right Division between `Quantity` objects and other objects."""          if isinstance(other, (UnitBase, str)):            return self._new_view(1.0 / self.value, other / self.unit)            return self._new_view(1.0 / self.value, other / self.unit, finalize=False)          return super().__rtruediv__(other)      def __pow__(self, other):         if isinstance(other, Fraction):             # Avoid getting object arrays by raising the value to a Fraction.            return self._new_view(self.value ** float(other), self.unit**other)            return self._new_view(                self.value ** float(other), self.unit**other, finalize=False            )          return super().__pow__(other)


Question: When should be linked to a new object? Mostly for - I noticed that in the way we have set up , is passed on not just for views (where it should be), but also for copies (implicitly in arithmetic operations, etc.). Which ones are reasonable? Just thinking about whether, e.g., should be propagated, I'd think: Surely for views & reshapes: , , etc. insertions: Probably for selection of scalars: or in (for columns this returns a scalar without ) copies: and equivalents equivalent unit changes: , , , etc. Probably not for operations real unit changes (including in-place??; ) What do you think? p.s. Currently, all of the above happen, in part because I use in , something which I don't think we had really considered when we made the change in . But that also means that in principle it may not too hard to fairly finely define the behaviour.

def __getitem__(self, key):         if isinstance(key, str) and isinstance(self.unit, StructuredUnit):            return self._new_view(self.view(np.ndarray)[key], self.unit[key])            return self._new_view(                self.view(np.ndarray)[key], self.unit[key], finalize=False            )          try:             out = super().__getitem__(key)


Question: Presence of SIP keywords leads to ignored PV keywords. <!-- This comments are hidden when you submit the issue, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted. If a similar issue is closed, have a quick look to see if you are satisfied by the resolution. If not please go ahead and open an issue! --<!-- Please check that the development version still produces the same bug. You can install development version with pip install command. --I am working on updating the fits header for one of our telescopes. We wanted to represent the distortions in SIP convention and the projection to be 'CAR'. While working on this, I noticed if SIP coefficients are present in the header and/or '-SIP' is to CTYPEia keywords, astropy treats the PV keywords (PV10, PV11 and PV12) as "redundant SCAMP distortions". Earlier I could not figure out why the projection weren't going as I expected, and I suspected a bug in astropy wcs. After talking to Mark Calabretta about the difficulties I'm facing, that suspicion only grew stronger. The header was working as expected with WCSLIB but was giving unexpected behavior in astropy wcs. The following would be one example header - When you parse the wcs information from this header, the image should be centered at ra=120 and dec=29 with lines of constant ra and dec looking like the following image generated using wcslib - ! If I parse the wcs information using astropy wcs, it throws the following warning - And the resulting grid is different. Code - Grid - ! The astropy wcs grid/solution does not change whethere we keep or remove the PV keywords. Furthermore, the astropy grid can be recreated in wcslib, by removing the PV keywords. ! <!-- Ideally a code example could be provided so we can run it ourselves. --<!-- If you are pasting code, use triple backticks () around your code snippet. --<!-- If necessary, sanitize your screen output to be pasted so you do not reveal secrets like tokens and passwords. --the header the header using the graticule the PV keywords and run again will find the same graticule indicating that PV keywords are completely ignored. Additionally, the graticules can be compared with the wcsgrid utility of wcslib. <!-- Even if you do not think this is necessary, it is useful information for the maintainers. Please run the following snippet and paste the output below: import platform; print(platform.platform()) import sys; print("Python", sys.version) import numpy; print("Numpy", numpy.version) import erfa; print("pyerfa", erfa.version) import astropy; print("astropy", astropy.version) import scipy; print("Scipy", scipy.version) import matplotlib; print("Matplotlib", matplotlib.version) --Linux-6.0.11-200.fc36.x8664-x8664-with-glibc2.35 Python 3.9.12 (main, Apr 5 2022, 06:56:58) [GCC 7.5.0] Numpy 1.21.5 pyerfa 2.0.0 astropy 5.1 Scipy 1.7.3 Matplotlib 3.5.1 Remove heuristic code to handle PTF files which is causing a bug <!-- This comments are hidden when you submit the pull request, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- If you are new or need to be re-acquainted with Astropy contributing workflow, please see . There is even a practical example at . --<!-- Astropy coding style guidelines can be found here: Our testing infrastructure enforces to follow a subset of the PEP8 to be followed. You can check locally whether your changes have followed these by running the following command: tox -e codestyle --<!-- Please just have a quick search on GitHub to see if a similar pull request has already been posted. We have old closed pull requests that might provide useful code or ideas that directly tie in with your pull request. --<!-- We have several automatic features that run when a pull request is open. They can appear daunting but do not worry because maintainers will help you navigate them, if necessary. --<!-- Provide a general description of what your pull request does. Complete the following sentence and add relevant details as you see fit. --<!-- In addition please ensure that the pull request title is descriptive and allows maintainers to infer the applicable subpackage(s). --<!-- READ THIS FOR MANUAL BACKPORT FROM A MAINTAINER: Apply "skip-basebranch-check" label before you open the PR! --Currently the function remove any PV keywords when SIP distortions are present and no radial terms are present which should not be the case. This function was put in place for solving but it causes the bug . We can either keep adding heuristic code to fix the edge cases as they come up with or remove and let the user deal with non-standard files. I'm opening a pull request for the latter following the discusison in . <!-- If the pull request closes any open issues you can add this. If you replace <Issue Numberwith a number, GitHub will automatically link it. If this pull request is unrelated to any issues, please remove the following line. -- <!-- This section is to be filled by package maintainer(s) who will review this pull request. --This checklist is meant to remind the package maintainer(s) who will review this pull request of some common things to look for. This list is not exhaustive. [ ] Do the proposed changes actually accomplish desired goals? ? ? ? . . [ ] Is a change log needed? If yes, did the change log check pass? If no, add the label. If this is a manual backport, use the label unless special changelog handling is necessary. [ ] Is this a big PR that makes a "What's new?" entry worthwhile and if so, is (1) a "what's new" entry included in this PR and (2) the "whatsnew-needed" label applied? [ ] Is a milestone set? Milestone must be set but check might be missing; do not let the green checkmark fool you. [ ] At the time of adding the milestone, if the milestone set requires a backport to release branch(es), apply the appropriate label(s) before merge.

det2im = self._read_det2im_kw(header, fobj, err=minerr)             cpdis = self._read_distortion_kw(header, fobj, dist="CPDIS", err=minerr)<ins>            self._fix_pre2012_scamp_tpv(header)</ins>             sip = self._read_sip_kw(header, wcskey=key)             self._remove_sip_kw(header)


Question: Presence of SIP keywords leads to ignored PV keywords. <!-- This comments are hidden when you submit the issue, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted. If a similar issue is closed, have a quick look to see if you are satisfied by the resolution. If not please go ahead and open an issue! --<!-- Please check that the development version still produces the same bug. You can install development version with pip install command. --I am working on updating the fits header for one of our telescopes. We wanted to represent the distortions in SIP convention and the projection to be 'CAR'. While working on this, I noticed if SIP coefficients are present in the header and/or '-SIP' is to CTYPEia keywords, astropy treats the PV keywords (PV10, PV11 and PV12) as "redundant SCAMP distortions". Earlier I could not figure out why the projection weren't going as I expected, and I suspected a bug in astropy wcs. After talking to Mark Calabretta about the difficulties I'm facing, that suspicion only grew stronger. The header was working as expected with WCSLIB but was giving unexpected behavior in astropy wcs. The following would be one example header - When you parse the wcs information from this header, the image should be centered at ra=120 and dec=29 with lines of constant ra and dec looking like the following image generated using wcslib - ! If I parse the wcs information using astropy wcs, it throws the following warning - And the resulting grid is different. Code - Grid - ! The astropy wcs grid/solution does not change whethere we keep or remove the PV keywords. Furthermore, the astropy grid can be recreated in wcslib, by removing the PV keywords. ! <!-- Ideally a code example could be provided so we can run it ourselves. --<!-- If you are pasting code, use triple backticks () around your code snippet. --<!-- If necessary, sanitize your screen output to be pasted so you do not reveal secrets like tokens and passwords. --the header the header using the graticule the PV keywords and run again will find the same graticule indicating that PV keywords are completely ignored. Additionally, the graticules can be compared with the wcsgrid utility of wcslib. <!-- Even if you do not think this is necessary, it is useful information for the maintainers. Please run the following snippet and paste the output below: import platform; print(platform.platform()) import sys; print("Python", sys.version) import numpy; print("Numpy", numpy.version) import erfa; print("pyerfa", erfa.version) import astropy; print("astropy", astropy.version) import scipy; print("Scipy", scipy.version) import matplotlib; print("Matplotlib", matplotlib.version) --Linux-6.0.11-200.fc36.x8664-x8664-with-glibc2.35 Python 3.9.12 (main, Apr 5 2022, 06:56:58) [GCC 7.5.0] Numpy 1.21.5 pyerfa 2.0.0 astropy 5.1 Scipy 1.7.3 Matplotlib 3.5.1 Remove heuristic code to handle PTF files which is causing a bug <!-- This comments are hidden when you submit the pull request, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- If you are new or need to be re-acquainted with Astropy contributing workflow, please see . There is even a practical example at . --<!-- Astropy coding style guidelines can be found here: Our testing infrastructure enforces to follow a subset of the PEP8 to be followed. You can check locally whether your changes have followed these by running the following command: tox -e codestyle --<!-- Please just have a quick search on GitHub to see if a similar pull request has already been posted. We have old closed pull requests that might provide useful code or ideas that directly tie in with your pull request. --<!-- We have several automatic features that run when a pull request is open. They can appear daunting but do not worry because maintainers will help you navigate them, if necessary. --<!-- Provide a general description of what your pull request does. Complete the following sentence and add relevant details as you see fit. --<!-- In addition please ensure that the pull request title is descriptive and allows maintainers to infer the applicable subpackage(s). --<!-- READ THIS FOR MANUAL BACKPORT FROM A MAINTAINER: Apply "skip-basebranch-check" label before you open the PR! --Currently the function remove any PV keywords when SIP distortions are present and no radial terms are present which should not be the case. This function was put in place for solving but it causes the bug . We can either keep adding heuristic code to fix the edge cases as they come up with or remove and let the user deal with non-standard files. I'm opening a pull request for the latter following the discusison in . <!-- If the pull request closes any open issues you can add this. If you replace <Issue Numberwith a number, GitHub will automatically link it. If this pull request is unrelated to any issues, please remove the following line. -- <!-- This section is to be filled by package maintainer(s) who will review this pull request. --This checklist is meant to remind the package maintainer(s) who will review this pull request of some common things to look for. This list is not exhaustive. [ ] Do the proposed changes actually accomplish desired goals? ? ? ? . . [ ] Is a change log needed? If yes, did the change log check pass? If no, add the label. If this is a manual backport, use the label unless special changelog handling is necessary. [ ] Is this a big PR that makes a "What's new?" entry worthwhile and if so, is (1) a "what's new" entry included in this PR and (2) the "whatsnew-needed" label applied? [ ] Is a milestone set? Milestone must be set but check might be missing; do not let the green checkmark fool you. [ ] At the time of adding the milestone, if the milestone set requires a backport to release branch(es), apply the appropriate label(s) before merge.

SIP distortion parameters.          See https://github.com/astropy/astropy/issues/299.        SCAMP uses TAN projection exclusively. The case of CTYPE ending        in -TAN should have been handled by ``_fix_pre2012_scamp_tpv()`` before        calling this function.         """        # Nothing to be done if no WCS attached         if self.wcs is None:             return         # Nothing to be done if no PV parameters attached        # Delete SIP if CTYPE explicitly has '-TPV' code:        ctype = [ct.strip().upper() for ct in self.wcs.ctype]        if sum(ct.endswith("-TPV") for ct in ctype) == 2:            if self.sip is not None:                self.sip = None                warnings.warn(                    "Removed redundant SIP distortion parameters "                    + "because CTYPE explicitly specifies TPV distortions",                    FITSFixedWarning,                )            return        # Nothing to be done if no PV parameters attached since SCAMP        # encodes distortion coefficients using PV keywords         pv = self.wcs.get_pv()         if not pv:             return


Question: Presence of SIP keywords leads to ignored PV keywords. <!-- This comments are hidden when you submit the issue, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted. If a similar issue is closed, have a quick look to see if you are satisfied by the resolution. If not please go ahead and open an issue! --<!-- Please check that the development version still produces the same bug. You can install development version with pip install command. --I am working on updating the fits header for one of our telescopes. We wanted to represent the distortions in SIP convention and the projection to be 'CAR'. While working on this, I noticed if SIP coefficients are present in the header and/or '-SIP' is to CTYPEia keywords, astropy treats the PV keywords (PV10, PV11 and PV12) as "redundant SCAMP distortions". Earlier I could not figure out why the projection weren't going as I expected, and I suspected a bug in astropy wcs. After talking to Mark Calabretta about the difficulties I'm facing, that suspicion only grew stronger. The header was working as expected with WCSLIB but was giving unexpected behavior in astropy wcs. The following would be one example header - When you parse the wcs information from this header, the image should be centered at ra=120 and dec=29 with lines of constant ra and dec looking like the following image generated using wcslib - ! If I parse the wcs information using astropy wcs, it throws the following warning - And the resulting grid is different. Code - Grid - ! The astropy wcs grid/solution does not change whethere we keep or remove the PV keywords. Furthermore, the astropy grid can be recreated in wcslib, by removing the PV keywords. ! <!-- Ideally a code example could be provided so we can run it ourselves. --<!-- If you are pasting code, use triple backticks () around your code snippet. --<!-- If necessary, sanitize your screen output to be pasted so you do not reveal secrets like tokens and passwords. --the header the header using the graticule the PV keywords and run again will find the same graticule indicating that PV keywords are completely ignored. Additionally, the graticules can be compared with the wcsgrid utility of wcslib. <!-- Even if you do not think this is necessary, it is useful information for the maintainers. Please run the following snippet and paste the output below: import platform; print(platform.platform()) import sys; print("Python", sys.version) import numpy; print("Numpy", numpy.version) import erfa; print("pyerfa", erfa.version) import astropy; print("astropy", astropy.version) import scipy; print("Scipy", scipy.version) import matplotlib; print("Matplotlib", matplotlib.version) --Linux-6.0.11-200.fc36.x8664-x8664-with-glibc2.35 Python 3.9.12 (main, Apr 5 2022, 06:56:58) [GCC 7.5.0] Numpy 1.21.5 pyerfa 2.0.0 astropy 5.1 Scipy 1.7.3 Matplotlib 3.5.1 Remove heuristic code to handle PTF files which is causing a bug <!-- This comments are hidden when you submit the pull request, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- If you are new or need to be re-acquainted with Astropy contributing workflow, please see . There is even a practical example at . --<!-- Astropy coding style guidelines can be found here: Our testing infrastructure enforces to follow a subset of the PEP8 to be followed. You can check locally whether your changes have followed these by running the following command: tox -e codestyle --<!-- Please just have a quick search on GitHub to see if a similar pull request has already been posted. We have old closed pull requests that might provide useful code or ideas that directly tie in with your pull request. --<!-- We have several automatic features that run when a pull request is open. They can appear daunting but do not worry because maintainers will help you navigate them, if necessary. --<!-- Provide a general description of what your pull request does. Complete the following sentence and add relevant details as you see fit. --<!-- In addition please ensure that the pull request title is descriptive and allows maintainers to infer the applicable subpackage(s). --<!-- READ THIS FOR MANUAL BACKPORT FROM A MAINTAINER: Apply "skip-basebranch-check" label before you open the PR! --Currently the function remove any PV keywords when SIP distortions are present and no radial terms are present which should not be the case. This function was put in place for solving but it causes the bug . We can either keep adding heuristic code to fix the edge cases as they come up with or remove and let the user deal with non-standard files. I'm opening a pull request for the latter following the discusison in . <!-- If the pull request closes any open issues you can add this. If you replace <Issue Numberwith a number, GitHub will automatically link it. If this pull request is unrelated to any issues, please remove the following line. -- <!-- This section is to be filled by package maintainer(s) who will review this pull request. --This checklist is meant to remind the package maintainer(s) who will review this pull request of some common things to look for. This list is not exhaustive. [ ] Do the proposed changes actually accomplish desired goals? ? ? ? . . [ ] Is a change log needed? If yes, did the change log check pass? If no, add the label. If this is a manual backport, use the label unless special changelog handling is necessary. [ ] Is this a big PR that makes a "What's new?" entry worthwhile and if so, is (1) a "what's new" entry included in this PR and (2) the "whatsnew-needed" label applied? [ ] Is a milestone set? Milestone must be set but check might be missing; do not let the green checkmark fool you. [ ] At the time of adding the milestone, if the milestone set requires a backport to release branch(es), apply the appropriate label(s) before merge.

if self.sip is None:             return         # Nothing to be done if any radial terms are present...        # Loop over list to find any radial terms.        # Certain values of the `j' index are used for storing        # radial terms; refer to Equation (1) in        # <http://web.ipac.caltech.edu/staff/shupe/reprints/SIP_to_PV_SPIE2012.pdf>.        pv = np.asarray(pv)         # Loop over distinct values of `i' index<del>        for i in set(pv[:, 0]):</del><ins>        has_scamp = False        for i in {v[0] for v in pv}:</ins>             # Get all values of `j' index for this value of `i' index<del>            js = set(pv[:, 1][pv[:, 0] == i])            # Find max value of `j' index            max_j = max(js)            for j in (3, 11, 23, 39):                if j < max_j and j in js:                    return        self.wcs.set_pv([])        warnings.warn(            "Removed redundant SCAMP distortion parameters "            + "because SIP parameters are also present",            FITSFixedWarning,        )            js = tuple(v[1] for v in pv if v[0] == i)            if "-TAN" in self.wcs.ctype[i - 1].upper() and js and max(js) >= 5:                # TAN projection *may* use PVi_j with j up to 4 - see                # Sections 2.5, 2.6, and Table 13                # in https://doi.org/10.1051/0004-6361:20021327                has_scamp = True                break        if has_scamp and all(ct.endswith("-SIP") for ct in ctype):            # Prefer SIP - see recommendations in Section 7 in            # http://web.ipac.caltech.edu/staff/shupe/reprints/SIP_to_PV_SPIE2012.pdf            self.wcs.set_pv([])            warnings.warn(                "Removed redundant SCAMP distortion parameters "                + "because SIP parameters are also present",                FITSFixedWarning,            )            return      def fix(self, translate_units="", naxis=None):         """


Question: Presence of SIP keywords leads to ignored PV keywords. <!-- This comments are hidden when you submit the issue, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted. If a similar issue is closed, have a quick look to see if you are satisfied by the resolution. If not please go ahead and open an issue! --<!-- Please check that the development version still produces the same bug. You can install development version with pip install command. --I am working on updating the fits header for one of our telescopes. We wanted to represent the distortions in SIP convention and the projection to be 'CAR'. While working on this, I noticed if SIP coefficients are present in the header and/or '-SIP' is to CTYPEia keywords, astropy treats the PV keywords (PV10, PV11 and PV12) as "redundant SCAMP distortions". Earlier I could not figure out why the projection weren't going as I expected, and I suspected a bug in astropy wcs. After talking to Mark Calabretta about the difficulties I'm facing, that suspicion only grew stronger. The header was working as expected with WCSLIB but was giving unexpected behavior in astropy wcs. The following would be one example header - When you parse the wcs information from this header, the image should be centered at ra=120 and dec=29 with lines of constant ra and dec looking like the following image generated using wcslib - ! If I parse the wcs information using astropy wcs, it throws the following warning - And the resulting grid is different. Code - Grid - ! The astropy wcs grid/solution does not change whethere we keep or remove the PV keywords. Furthermore, the astropy grid can be recreated in wcslib, by removing the PV keywords. ! <!-- Ideally a code example could be provided so we can run it ourselves. --<!-- If you are pasting code, use triple backticks () around your code snippet. --<!-- If necessary, sanitize your screen output to be pasted so you do not reveal secrets like tokens and passwords. --the header the header using the graticule the PV keywords and run again will find the same graticule indicating that PV keywords are completely ignored. Additionally, the graticules can be compared with the wcsgrid utility of wcslib. <!-- Even if you do not think this is necessary, it is useful information for the maintainers. Please run the following snippet and paste the output below: import platform; print(platform.platform()) import sys; print("Python", sys.version) import numpy; print("Numpy", numpy.version) import erfa; print("pyerfa", erfa.version) import astropy; print("astropy", astropy.version) import scipy; print("Scipy", scipy.version) import matplotlib; print("Matplotlib", matplotlib.version) --Linux-6.0.11-200.fc36.x8664-x8664-with-glibc2.35 Python 3.9.12 (main, Apr 5 2022, 06:56:58) [GCC 7.5.0] Numpy 1.21.5 pyerfa 2.0.0 astropy 5.1 Scipy 1.7.3 Matplotlib 3.5.1 Remove heuristic code to handle PTF files which is causing a bug <!-- This comments are hidden when you submit the pull request, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- If you are new or need to be re-acquainted with Astropy contributing workflow, please see . There is even a practical example at . --<!-- Astropy coding style guidelines can be found here: Our testing infrastructure enforces to follow a subset of the PEP8 to be followed. You can check locally whether your changes have followed these by running the following command: tox -e codestyle --<!-- Please just have a quick search on GitHub to see if a similar pull request has already been posted. We have old closed pull requests that might provide useful code or ideas that directly tie in with your pull request. --<!-- We have several automatic features that run when a pull request is open. They can appear daunting but do not worry because maintainers will help you navigate them, if necessary. --<!-- Provide a general description of what your pull request does. Complete the following sentence and add relevant details as you see fit. --<!-- In addition please ensure that the pull request title is descriptive and allows maintainers to infer the applicable subpackage(s). --<!-- READ THIS FOR MANUAL BACKPORT FROM A MAINTAINER: Apply "skip-basebranch-check" label before you open the PR! --Currently the function remove any PV keywords when SIP distortions are present and no radial terms are present which should not be the case. This function was put in place for solving but it causes the bug . We can either keep adding heuristic code to fix the edge cases as they come up with or remove and let the user deal with non-standard files. I'm opening a pull request for the latter following the discusison in . <!-- If the pull request closes any open issues you can add this. If you replace <Issue Numberwith a number, GitHub will automatically link it. If this pull request is unrelated to any issues, please remove the following line. -- <!-- This section is to be filled by package maintainer(s) who will review this pull request. --This checklist is meant to remind the package maintainer(s) who will review this pull request of some common things to look for. This list is not exhaustive. [ ] Do the proposed changes actually accomplish desired goals? ? ? ? . . [ ] Is a change log needed? If yes, did the change log check pass? If no, add the label. If this is a manual backport, use the label unless special changelog handling is necessary. [ ] Is this a big PR that makes a "What's new?" entry worthwhile and if so, is (1) a "what's new" entry included in this PR and (2) the "whatsnew-needed" label applied? [ ] Is a milestone set? Milestone must be set but check might be missing; do not let the green checkmark fool you. [ ] At the time of adding the milestone, if the milestone set requires a backport to release branch(es), apply the appropriate label(s) before merge.

write_dist(1, self.cpdis1)         write_dist(2, self.cpdis2)     def _remove_sip_kw(self, header):    def _fix_pre2012_scamp_tpv(self, header, wcskey=""):        """        Replace -TAN with TPV (for pre-2012 SCAMP headers that use -TAN        in CTYPE). Ignore SIP if present. This follows recommendations in        Section 7 in        http://web.ipac.caltech.edu/staff/shupe/reprints/SIP_to_PV_SPIE2012.pdf.        This is to deal with pre-2012 headers that may contain TPV with a        CTYPE that ends in '-TAN' (post-2012 they should end in '-TPV' when        SCAMP has adopted the new TPV convention).        """        if isinstance(header, (str, bytes)):            return        wcskey = wcskey.strip().upper()        cntype = [            (nax, header.get(f"CTYPE{nax}{wcskey}", "").strip())            for nax in range(1, self.naxis + 1)        ]        tan_axes = [ct[0] for ct in cntype if ct[1].endswith("-TAN")]        if len(tan_axes) == 2:            # check if PVi_j with j >= 5 is present and if so, do not load SIP            tan_to_tpv = False            for nax in tan_axes:                js = []                for p in header[f"PV{nax}_*{wcskey}"].keys():                    prefix = f"PV{nax}_"                    if p.startswith(prefix):                        p = p[len(prefix) :]                        p = p.rstrip(wcskey)                        try:                            p = int(p)                        except ValueError:                            continue                        js.append(p)                if js and max(js) >= 5:                    tan_to_tpv = True                    break            if tan_to_tpv:                warnings.warn(                    "Removed redundant SIP distortion parameters "                    + "because SCAMP' PV distortions are also present",                    FITSFixedWarning,                )                self._remove_sip_kw(header, del_order=True)                for i in tan_axes:                    kwd = f"CTYPE{i:d}{wcskey}"                    if kwd in header:                        header[kwd] = (                            header[kwd].strip().upper().replace("-TAN", "-TPV")                        )    @staticmethod    def _remove_sip_kw(header, del_order=False):         """         Remove SIP information from a header.         """


Question: Presence of SIP keywords leads to ignored PV keywords. <!-- This comments are hidden when you submit the issue, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted. If a similar issue is closed, have a quick look to see if you are satisfied by the resolution. If not please go ahead and open an issue! --<!-- Please check that the development version still produces the same bug. You can install development version with pip install command. --I am working on updating the fits header for one of our telescopes. We wanted to represent the distortions in SIP convention and the projection to be 'CAR'. While working on this, I noticed if SIP coefficients are present in the header and/or '-SIP' is to CTYPEia keywords, astropy treats the PV keywords (PV10, PV11 and PV12) as "redundant SCAMP distortions". Earlier I could not figure out why the projection weren't going as I expected, and I suspected a bug in astropy wcs. After talking to Mark Calabretta about the difficulties I'm facing, that suspicion only grew stronger. The header was working as expected with WCSLIB but was giving unexpected behavior in astropy wcs. The following would be one example header - When you parse the wcs information from this header, the image should be centered at ra=120 and dec=29 with lines of constant ra and dec looking like the following image generated using wcslib - ! If I parse the wcs information using astropy wcs, it throws the following warning - And the resulting grid is different. Code - Grid - ! The astropy wcs grid/solution does not change whethere we keep or remove the PV keywords. Furthermore, the astropy grid can be recreated in wcslib, by removing the PV keywords. ! <!-- Ideally a code example could be provided so we can run it ourselves. --<!-- If you are pasting code, use triple backticks () around your code snippet. --<!-- If necessary, sanitize your screen output to be pasted so you do not reveal secrets like tokens and passwords. --the header the header using the graticule the PV keywords and run again will find the same graticule indicating that PV keywords are completely ignored. Additionally, the graticules can be compared with the wcsgrid utility of wcslib. <!-- Even if you do not think this is necessary, it is useful information for the maintainers. Please run the following snippet and paste the output below: import platform; print(platform.platform()) import sys; print("Python", sys.version) import numpy; print("Numpy", numpy.version) import erfa; print("pyerfa", erfa.version) import astropy; print("astropy", astropy.version) import scipy; print("Scipy", scipy.version) import matplotlib; print("Matplotlib", matplotlib.version) --Linux-6.0.11-200.fc36.x8664-x8664-with-glibc2.35 Python 3.9.12 (main, Apr 5 2022, 06:56:58) [GCC 7.5.0] Numpy 1.21.5 pyerfa 2.0.0 astropy 5.1 Scipy 1.7.3 Matplotlib 3.5.1 Remove heuristic code to handle PTF files which is causing a bug <!-- This comments are hidden when you submit the pull request, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- If you are new or need to be re-acquainted with Astropy contributing workflow, please see . There is even a practical example at . --<!-- Astropy coding style guidelines can be found here: Our testing infrastructure enforces to follow a subset of the PEP8 to be followed. You can check locally whether your changes have followed these by running the following command: tox -e codestyle --<!-- Please just have a quick search on GitHub to see if a similar pull request has already been posted. We have old closed pull requests that might provide useful code or ideas that directly tie in with your pull request. --<!-- We have several automatic features that run when a pull request is open. They can appear daunting but do not worry because maintainers will help you navigate them, if necessary. --<!-- Provide a general description of what your pull request does. Complete the following sentence and add relevant details as you see fit. --<!-- In addition please ensure that the pull request title is descriptive and allows maintainers to infer the applicable subpackage(s). --<!-- READ THIS FOR MANUAL BACKPORT FROM A MAINTAINER: Apply "skip-basebranch-check" label before you open the PR! --Currently the function remove any PV keywords when SIP distortions are present and no radial terms are present which should not be the case. This function was put in place for solving but it causes the bug . We can either keep adding heuristic code to fix the edge cases as they come up with or remove and let the user deal with non-standard files. I'm opening a pull request for the latter following the discusison in . <!-- If the pull request closes any open issues you can add this. If you replace <Issue Numberwith a number, GitHub will automatically link it. If this pull request is unrelated to any issues, please remove the following line. -- <!-- This section is to be filled by package maintainer(s) who will review this pull request. --This checklist is meant to remind the package maintainer(s) who will review this pull request of some common things to look for. This list is not exhaustive. [ ] Do the proposed changes actually accomplish desired goals? ? ? ? . . [ ] Is a change log needed? If yes, did the change log check pass? If no, add the label. If this is a manual backport, use the label unless special changelog handling is necessary. [ ] Is this a big PR that makes a "What's new?" entry worthwhile and if so, is (1) a "what's new" entry included in this PR and (2) the "whatsnew-needed" label applied? [ ] Is a milestone set? Milestone must be set but check might be missing; do not let the green checkmark fool you. [ ] At the time of adding the milestone, if the milestone set requires a backport to release branch(es), apply the appropriate label(s) before merge.

}:             del header[key] <ins>        if del_order:            for kwd in ["A_ORDER", "B_ORDER", "AP_ORDER", "BP_ORDER"]:                if kwd in header:                    del header[kwd]</ins>     def _read_sip_kw(self, header, wcskey=""):         """         Reads `SIP`_ header keywords and returns a `~astropy.wcs.Sip`


Question: IndexError: tuple index out of range in identifyformat (io.registry) <!-- This comments are hidden when you submit the issue, so you do not need to remove them! --<!-- Please be sure to check out our contributing guidelines, . Please be sure to check out our code of conduct, . --<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted. If a similar issue is closed, have a quick look to see if you are satisfied by the resolution. If not please go ahead and open an issue! --<!-- Please check that the development version still produces the same bug. You can install development version with pip install command. --Cron tests in HENDRICS using identifyformat have started failing in (e.g. ) with this error: As per a Slack conversation with and this should be related to Citing When is a string without a FITS extension, the function was returning None, now it executes <!-- Ideally a code example could be provided so we can run it ourselves. --<!-- If you are pasting code, use triple backticks ( In [1]: from import identifyformat In [3]: from import Table In [4]: identifyformat("write", Table, "", None, [], {}) IndexError Traceback (most recent call last) Cell In [4], line 1 ----1 identifyformat("write", Table, "", None, [], {}) File ~/opt/anaconda3/envs/py310/lib/python3.10/site-, in makeiofunc.<locals.wrapper(registry, args, kwargs) 50 registry = defaultregistry 51 # get and call bound method from registry instance ---52 return getattr(registry, methodname)(args, kwargs) File ~/opt/anaconda3/envs/py310/lib/python3.10/site-, in UnifiedIORegistryBase.identifyformat(self, origin, dataclassrequired, path, fileobj, args, kwargs) 311 for dataformat, dataclass in self.identifiers: 312 if self.isbestmatch(dataclassrequired, dataclass, self.identifiers): --313 if self.identifiers(dataformat, dataclass): 316 (dataformat) 318 return validformats File ~/opt/anaconda3/envs/py310/lib/python3.10/site-, in is_fits(origin, filepath, fileobj, args, kwargs) 68 if ().endswith( 69 (".fits", "", ".fit", "", ".fts", "") 70 ): 71 return True ---72 return isinstance(args[0], (HDUList, TableHDU, BinTableHDU, GroupsHDU)) IndexError: tuple index out of range <!-- Even if you do not think this is necessary, it is useful information for the maintainers. Please run the following snippet and paste the output below: import platform; print(platform.platform()) import sys; print("Python", sys.version) import numpy; print("Numpy", numpy.version) import erfa; print("pyerfa", erfa.version) import astropy; print("astropy", astropy.version) import scipy; print("Scipy", scipy.version) import matplotlib; print("Matplotlib", matplotlib.version) --

fileobj.seek(pos)         return sig == FITS_SIGNATURE     elif filepath is not None:        if filepath.lower().endswith(        return filepath.lower().endswith(             (".fits", ".fits.gz", ".fit", ".fit.gz", ".fts", ".fts.gz")        ):            return True        )     return isinstance(args[0], (HDUList, TableHDU, BinTableHDU, GroupsHDU))


Question: Table format assumes QDP commands are upper case assumes that commands in a QDP file are upper case, for example, for errors they must be "READ SERR 1 2" whereas QDP itself is not case sensitive and case use "read serr 1 2". As many QDP files are created by hand, the expectation that all commands be all-caps should be removed. The following qdp file should read into a with errors, rather than crashing. Create a QDP file: Running "qdp " works just fine. Python 3.10.9 (main, Dec 7 2022, 02:03:23) [Clang 13.0.0 (clang-1300.0.29.30)] astropy 5.1 Numpy 1.24.1 pyerfa 2.0.0.1 Scipy 1.10.0 Matplotlib 3.6.3

_new_re = rf"NO({sep}NO)+"     _data_re = rf"({_decimal_re}|NO|[-+]?nan)({sep}({_decimal_re}|NO|[-+]?nan))*)"     _type_re = rf"^\s*((?P<command>{_command_re})|(?P<new>{_new_re})|(?P<data>{_data_re})?\s*(\!(?P<comment>.*))?\s*$"    _line_type_re = re.compile(_type_re)    _line_type_re = re.compile(_type_re, re.IGNORECASE)     line = line.strip()     if not line:         return "comment"


Question: Table format assumes QDP commands are upper case assumes that commands in a QDP file are upper case, for example, for errors they must be "READ SERR 1 2" whereas QDP itself is not case sensitive and case use "read serr 1 2". As many QDP files are created by hand, the expectation that all commands be all-caps should be removed. The following qdp file should read into a with errors, rather than crashing. Create a QDP file: Running "qdp " works just fine. Python 3.10.9 (main, Dec 7 2022, 02:03:23) [Clang 13.0.0 (clang-1300.0.29.30)] astropy 5.1 Numpy 1.24.1 pyerfa 2.0.0.1 Scipy 1.10.0 Matplotlib 3.6.3

values = []             for v in line.split(delimiter):                if v == "NO":                if v.upper() == "NO":                     values.append(np.ma.masked)                 else:                     # Understand if number is int or float


Question: Incorrect units read from MRT (CDS format) files with When reading MRT files (formatted according to the CDS standard which is also the format recommended by AAS/ApJ) with , incorrectly parses composite units. According to CDS standard the units should be SI without spaces (http://vizier.u-). Thus a unit of (surface brightness for a continuum measurement) should be written as . When I use these types of composite units with the reader the units do not come out correct. Specifically the order of the division seems to be jumbled. The units in the resulting Table should be the same as in the input MRT file. Get astropy package from pip Using the following MRT as input: And then reading the table I get: For the SBCONT column the second is in the wrong place, and for SBLINE kpc2 is in the wrong place.

for Astronomical Catalogues 2.0         <http://vizier.u-strasbg.fr/vizier/doc/catstd-3.2.htx>`_, which is not         terribly precise.  The exact grammar is here is based on the<del>        YACC grammar in the `unity library        <https://bitbucket.org/nxg/unity/>`_.</del><ins>        YACC grammar in the `unity library <https://purl.org/nxg/dist/unity/>`_.</ins>         """         tokens = cls._tokens


Question: Incorrect units read from MRT (CDS format) files with When reading MRT files (formatted according to the CDS standard which is also the format recommended by AAS/ApJ) with , incorrectly parses composite units. According to CDS standard the units should be SI without spaces (http://vizier.u-). Thus a unit of (surface brightness for a continuum measurement) should be written as . When I use these types of composite units with the reader the units do not come out correct. Specifically the order of the division seems to be jumbled. The units in the resulting Table should be the same as in the input MRT file. Get astropy package from pip Using the following MRT as input: And then reading the table I get: For the SBCONT column the second is in the wrong place, and for SBLINE kpc2 is in the wrong place.

def p_division_of_units(p):             """             division_of_units : DIVISION unit_expression                              | unit_expression DIVISION combined_units                              | combined_units DIVISION unit_expression             """             if len(p) == 3:                 p[0] = p[2] ** -1diff --git a/astropy/units/format/cds_parsetab.py b/astropy/units/format/cds_parsetab.py-- a/astropy/units/format/cds_parsetab.py++ b/astropy/units/format/cds_parsetab.py


Question: Incorrect units read from MRT (CDS format) files with When reading MRT files (formatted according to the CDS standard which is also the format recommended by AAS/ApJ) with , incorrectly parses composite units. According to CDS standard the units should be SI without spaces (http://vizier.u-). Thus a unit of (surface brightness for a continuum measurement) should be written as . When I use these types of composite units with the reader the units do not come out correct. Specifically the order of the division seems to be jumbled. The units in the resulting Table should be the same as in the input MRT file. Get astropy package from pip Using the following MRT as input: And then reading the table I get: For the SBCONT column the second is in the wrong place, and for SBLINE kpc2 is in the wrong place.

_lr_method = 'LALR' _lr_signature = 'CLOSE_BRACKET CLOSE_PAREN DIMENSIONLESS DIVISION OPEN_BRACKET OPEN_PAREN PRODUCT SIGN UFLOAT UINT UNIT X\n            main : factor combined_units\n                 | combined_units\n                 | DIMENSIONLESS\n                 | OPEN_BRACKET combined_units CLOSE_BRACKET\n                 | OPEN_BRACKET DIMENSIONLESS CLOSE_BRACKET\n                 | factor\n            \n            combined_units : product_of_units\n                           | division_of_units\n            \n            product_of_units : unit_expression PRODUCT combined_units\n                             | unit_expression\n            \n            division_of_units : DIVISION unit_expression\n                              | unit_expression DIVISION combined_units\n            \n            unit_expression : unit_with_power\n                            | OPEN_PAREN combined_units CLOSE_PAREN\n            \n            factor : signed_float X UINT signed_int\n                   | UINT X UINT signed_int\n                   | UINT signed_int\n                   | UINT\n                   | signed_float\n            \n            unit_with_power : UNIT numeric_power\n                            | UNIT\n            \n            numeric_power : sign UINT\n            \n            sign : SIGN\n                 |\n            \n            signed_int : SIGN UINT\n            \n            signed_float : sign UINT\n                         | sign UFLOAT\n            '_lr_signature = 'CLOSE_BRACKET CLOSE_PAREN DIMENSIONLESS DIVISION OPEN_BRACKET OPEN_PAREN PRODUCT SIGN UFLOAT UINT UNIT X\n            main : factor combined_units\n                 | combined_units\n                 | DIMENSIONLESS\n                 | OPEN_BRACKET combined_units CLOSE_BRACKET\n                 | OPEN_BRACKET DIMENSIONLESS CLOSE_BRACKET\n                 | factor\n            \n            combined_units : product_of_units\n                           | division_of_units\n            \n            product_of_units : unit_expression PRODUCT combined_units\n                             | unit_expression\n            \n            division_of_units : DIVISION unit_expression\n                              | combined_units DIVISION unit_expression\n            \n            unit_expression : unit_with_power\n                            | OPEN_PAREN combined_units CLOSE_PAREN\n            \n            factor : signed_float X UINT signed_int\n                   | UINT X UINT signed_int\n                   | UINT signed_int\n                   | UINT\n                   | signed_float\n            \n            unit_with_power : UNIT numeric_power\n                            | UNIT\n            \n            numeric_power : sign UINT\n            \n            sign : SIGN\n                 |\n            \n            signed_int : SIGN UINT\n            \n            signed_float : sign UINT\n                         | sign UFLOAT\n            '     _lr_action_items = {'DIMENSIONLESS':([0,5,],[4,19,]),'OPEN_BRACKET':([0,],[5,]),'UINT':([0,10,13,16,20,21,23,31,],[7,24,-23,-24,34,35,36,40,]),'DIVISION':([0,2,5,6,7,11,14,15,16,22,24,25,26,27,30,36,39,40,41,42,],[12,12,12,-19,-18,27,-13,12,-21,-17,-26,-27,12,12,-20,-25,-14,-22,-15,-16,]),'SIGN':([0,7,16,34,35,],[13,23,13,23,23,]),'UFLOAT':([0,10,13,],[-24,25,-23,]),'OPEN_PAREN':([0,2,5,6,7,12,15,22,24,25,26,27,36,41,42,],[15,15,15,-19,-18,15,15,-17,-26,-27,15,15,-25,-15,-16,]),'UNIT':([0,2,5,6,7,12,15,22,24,25,26,27,36,41,42,],[16,16,16,-19,-18,16,16,-17,-26,-27,16,16,-25,-15,-16,]),'$end':([1,2,3,4,6,7,8,9,11,14,16,17,22,24,25,28,30,32,33,36,37,38,39,40,41,42,],[0,-6,-2,-3,-19,-18,-7,-8,-10,-13,-21,-1,-17,-26,-27,-11,-20,-4,-5,-25,-9,-12,-14,-22,-15,-16,]),'X':([6,7,24,25,],[20,21,-26,-27,]),'CLOSE_BRACKET':([8,9,11,14,16,18,19,28,30,37,38,39,40,],[-7,-8,-10,-13,-21,32,33,-11,-20,-9,-12,-14,-22,]),'CLOSE_PAREN':([8,9,11,14,16,28,29,30,37,38,39,40,],[-7,-8,-10,-13,-21,-11,39,-20,-9,-12,-14,-22,]),'PRODUCT':([11,14,16,30,39,40,],[26,-13,-21,-20,-14,-22,]),}_lr_action_items = {'DIMENSIONLESS':([0,5,],[4,20,]),'OPEN_BRACKET':([0,],[5,]),'UINT':([0,10,13,16,21,22,24,31,],[7,25,-23,-24,35,36,37,40,]),'DIVISION':([0,2,3,5,6,7,8,9,11,14,15,16,17,19,23,25,26,27,28,29,30,32,37,38,39,40,41,42,],[12,12,18,12,-19,-18,-7,-8,-10,-13,12,-21,18,18,-17,-26,-27,12,-11,18,-20,-12,-25,18,-14,-22,-15,-16,]),'SIGN':([0,7,16,35,36,],[13,24,13,24,24,]),'UFLOAT':([0,10,13,],[-24,26,-23,]),'OPEN_PAREN':([0,2,5,6,7,12,15,18,23,25,26,27,37,41,42,],[15,15,15,-19,-18,15,15,15,-17,-26,-27,15,-25,-15,-16,]),'UNIT':([0,2,5,6,7,12,15,18,23,25,26,27,37,41,42,],[16,16,16,-19,-18,16,16,16,-17,-26,-27,16,-25,-15,-16,]),'$end':([1,2,3,4,6,7,8,9,11,14,16,17,23,25,26,28,30,32,33,34,37,38,39,40,41,42,],[0,-6,-2,-3,-19,-18,-7,-8,-10,-13,-21,-1,-17,-26,-27,-11,-20,-12,-4,-5,-25,-9,-14,-22,-15,-16,]),'X':([6,7,25,26,],[21,22,-26,-27,]),'CLOSE_BRACKET':([8,9,11,14,16,19,20,28,30,32,38,39,40,],[-7,-8,-10,-13,-21,33,34,-11,-20,-12,-9,-14,-22,]),'CLOSE_PAREN':([8,9,11,14,16,28,29,30,32,38,39,40,],[-7,-8,-10,-13,-21,-11,39,-20,-12,-9,-14,-22,]),'PRODUCT':([11,14,16,30,39,40,],[27,-13,-21,-20,-14,-22,]),}  _lr_action = {} for _k, _v in _lr_action_items.items():


Question: Incorrect units read from MRT (CDS format) files with When reading MRT files (formatted according to the CDS standard which is also the format recommended by AAS/ApJ) with , incorrectly parses composite units. According to CDS standard the units should be SI without spaces (http://vizier.u-). Thus a unit of (surface brightness for a continuum measurement) should be written as . When I use these types of composite units with the reader the units do not come out correct. Specifically the order of the division seems to be jumbled. The units in the resulting Table should be the same as in the input MRT file. Get astropy package from pip Using the following MRT as input: And then reading the table I get: For the SBCONT column the second is in the wrong place, and for SBLINE kpc2 is in the wrong place.

_lr_action[_x][_k] = _y del _lr_action_items _lr_goto_items = {'main':([0,],[1,]),'factor':([0,],[2,]),'combined_units':([0,2,5,15,26,27,],[3,17,18,29,37,38,]),'signed_float':([0,],[6,]),'product_of_units':([0,2,5,15,26,27,],[8,8,8,8,8,8,]),'division_of_units':([0,2,5,15,26,27,],[9,9,9,9,9,9,]),'sign':([0,16,],[10,31,]),'unit_expression':([0,2,5,12,15,26,27,],[11,11,11,28,11,11,11,]),'unit_with_power':([0,2,5,12,15,26,27,],[14,14,14,14,14,14,14,]),'signed_int':([7,34,35,],[22,41,42,]),'numeric_power':([16,],[30,]),}_lr_goto_items = {'main':([0,],[1,]),'factor':([0,],[2,]),'combined_units':([0,2,5,15,27,],[3,17,19,29,38,]),'signed_float':([0,],[6,]),'product_of_units':([0,2,5,15,27,],[8,8,8,8,8,]),'division_of_units':([0,2,5,15,27,],[9,9,9,9,9,]),'sign':([0,16,],[10,31,]),'unit_expression':([0,2,5,12,15,18,27,],[11,11,11,28,11,32,11,]),'unit_with_power':([0,2,5,12,15,18,27,],[14,14,14,14,14,14,14,]),'signed_int':([7,35,36,],[23,41,42,]),'numeric_power':([16,],[30,]),}  _lr_goto = {} for _k, _v in _lr_goto_items.items():