Skip to content

[1.1] Unit conversion error with astropy 4.2 #737

@olebole

Description

@olebole

With the new Astropy 4.2, Specutils (1.1 from PyPI) starts to show a number of failures in test_smoothing.py that look strange to me:

__________________________ test_smooth_custom_kernel ___________________________

self = <Quantity [1131.01333332, 1366.39097043, 1380.73344458, 1315.70807832,
           1218.18529306, 1225.68833337, 1264.9...557.36062977, 1565.6571005 , 1519.2402814 ,
           1489.30273208, 1434.86908964, 1202.1970936 ,  874.83988599] mJy>
unit = Unit(dimensionless), equivalencies = []

    def to_value(self, unit=None, equivalencies=[]):
        """…"""
        if unit is None or unit is self.unit:
            value = self.view(np.ndarray)
        else:
            unit = Unit(unit)
            # We want a view if the unit does not change.  One could check
            # with "==", but that calculates the scale that we need anyway.
            # TODO: would be better for `unit.to` to have an in-place flag.
            try:
>               scale = self.unit._to(unit)

/usr/lib/python3/dist-packages/astropy/units/quantity.py:738: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = Unit("mJy"), other = Unit(dimensionless)

    def _to(self, other):
        """…"""
        # … 
        if self is other:
            return 1.0
    
        # …
        if isinstance(other, UnitBase):
            self_decomposed = self.decompose()
            other_decomposed = other.decompose()
    
            # …
            if(self_decomposed.powers == other_decomposed.powers and
               all(self_base is other_base for (self_base, other_base)
                   in zip(self_decomposed.bases, other_decomposed.bases))):
                return self_decomposed.scale / other_decomposed.scale
    
>       raise UnitConversionError(
            f"'{self!r}' is not a scaled version of '{other!r}'")
E       astropy.units.core.UnitConversionError: 'Unit("mJy")' is not a scaled version of 'Unit(dimensionless)'

/usr/lib/python3/dist-packages/astropy/units/core.py:950: UnitConversionError

During handling of the above exception, another exception occurred:

simulated_spectra = <specutils.tests.spectral_examples.SpectraExamples object at 0x7f151d2c5c40>

    def test_smooth_custom_kernel(simulated_spectra):
        """
        Test CustomKernel smoothing with correct parmaeters.
        """
    
        # Create the original spectrum
        spec1 = simulated_spectra.s1_um_mJy_e1
        flux_original = spec1.flux
    
        # Create a custom kernel (some weird asymmetric-ness)
        numpy_kernel = np.array([0.5, 1, 2, 0.5, 0.2])
        numpy_kernel = numpy_kernel / np.sum(numpy_kernel)
    
        custom_kernel = convolution.CustomKernel(numpy_kernel)
        flux_smoothed_astropy = convolution.convolve(flux_original, custom_kernel)
    
        # Calculate the custom smoothed
        spec1_smoothed = convolution_smooth(spec1, custom_kernel)
>       compare_flux(spec1_smoothed.flux.value, flux_smoothed_astropy, flux_original.value)

/usr/lib/python3/dist-packages/specutils/tests/test_smoothing.py:58: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/lib/python3/dist-packages/specutils/tests/test_smoothing.py:34: in compare_flux
    assert np.allclose(flux_smooth1, flux_smooth2)
<__array_function__ internals>:5: in allclose
    ???
/usr/lib/python3/dist-packages/astropy/units/quantity.py:1509: in __array_function__
    args, kwargs, unit, out = function_helper(*args, **kwargs)
/usr/lib/python3/dist-packages/astropy/units/quantity_helper/function_helpers.py:545: in close
    (a, b), unit = _quantities2arrays(a, b, unit_from_first=True)
/usr/lib/python3/dist-packages/astropy/units/quantity_helper/function_helpers.py:345: in _quantities2arrays
    arrays = tuple((q._to_own_unit(arg)) for arg in args)
/usr/lib/python3/dist-packages/astropy/units/quantity_helper/function_helpers.py:345: in <genexpr>
    arrays = tuple((q._to_own_unit(arg)) for arg in args)
/usr/lib/python3/dist-packages/astropy/units/quantity.py:1339: in _to_own_unit
    _value = value.to_value(self.unit)
/usr/lib/python3/dist-packages/astropy/units/quantity.py:741: in to_value
    value = self._to_value(unit, equivalencies)
/usr/lib/python3/dist-packages/astropy/units/quantity.py:660: in _to_value
    return self.unit.to(unit, self.view(np.ndarray),
/usr/lib/python3/dist-packages/astropy/units/core.py:987: in to
    return self._get_converter(other, equivalencies=equivalencies)(value)
/usr/lib/python3/dist-packages/astropy/units/core.py:918: in _get_converter
    raise exc
/usr/lib/python3/dist-packages/astropy/units/core.py:903: in _get_converter
    return self._apply_equivalencies(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = Unit("mJy"), unit = Unit("mJy"), other = Unit(dimensionless)
equivalencies = []

    def _apply_equivalencies(self, unit, other, equivalencies):
        """
        Internal function (used from `_get_converter`) to apply
        equivalence pairs.
        """
        def make_converter(scale1, func, scale2):
            def convert(v):
                return func(_condition_arg(v) / scale1) * scale2
            return convert
    
        for funit, tunit, a, b in equivalencies:
            if tunit is None:
                try:
                    ratio_in_funit = (other.decompose() /
                                      unit.decompose()).decompose([funit])
                    return make_converter(ratio_in_funit.scale, a, 1.)
                except UnitsError:
                    pass
            else:
                try:
                    scale1 = funit._to(unit)
                    scale2 = tunit._to(other)
                    return make_converter(scale1, a, scale2)
                except UnitsError:
                    pass
                try:
                    scale1 = tunit._to(unit)
                    scale2 = funit._to(other)
                    return make_converter(scale1, b, scale2)
                except UnitsError:
                    pass
    
        def get_err_str(unit):
            unit_str = unit.to_string('unscaled')
            physical_type = unit.physical_type
            if physical_type != 'unknown':
                unit_str = "'{}' ({})".format(
                    unit_str, physical_type)
            else:
                unit_str = f"'{unit_str}'"
            return unit_str
    
        unit_str = get_err_str(unit)
        other_str = get_err_str(other)
    
>       raise UnitConversionError(
            "{} and {} are not convertible".format(
                unit_str, other_str))
E       astropy.units.core.UnitConversionError: 'mJy' (spectral flux density) and '' (dimensionless) are not convertible

/usr/lib/python3/dist-packages/astropy/units/core.py:886: UnitConversionError

Full test log is here. This happens in a number of test_smooth_* functions (test_smooth_box_good, test_smooth_box_good, test_smooth_gaussian_good, test_smooth_trapezoid_good).

I am not sure whether this is fixed in the current "master" branch; however I couldn't find a commit with an obvious name that fixes it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions