Skip to content

erfa.p2s does not accept units except for distance #16873

@mhvk

Description

@mhvk

Description

In liberfa/pyerfa#149, @maxnoe reported the following error, which had him puzzled (transferred here since astropy.units.quantity_helpers.erfa is responsible for making pyerfa work with units).

from erfa.ufunc import s2p as spherical_to_cartesian
import astropy.units as u
import numpy  as np
 
lon = np.pi / 2
lat = np.pi / 4
 
spherical_to_cartesian(lon, lat, 5 * u.km)

results in this relatively unhelpful error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[3], line 8
      5 lon = np.pi / 2
      6 lat = np.pi / 4
----> 8 spherical_to_cartesian(lon, lat, 5 * u.km)

File ~/.local/conda/envs/cta-dev/lib/python3.11/site-packages/astropy/units/quantity.py:691, in Quantity.__array_ufunc__(self, function, method, *inputs, **kwargs)
    689     return NotImplemented
    690 else:
--> 691     raise e

File ~/.local/conda/envs/cta-dev/lib/python3.11/site-packages/astropy/units/quantity.py:636, in Quantity.__array_ufunc__(self, function, method, *inputs, **kwargs)
    631 # Determine required conversion functions -- to bring the unit of the
    632 # input to that expected (e.g., radian for np.sin), or to get
    633 # consistent units between two inputs (e.g., in np.add) --
    634 # and the unit of the result (or tuple of units for nout > 1).
    635 try:
--> 636     converters, unit = converters_and_unit(function, method, *inputs)
    638     out = kwargs.get("out", None)
    639     # Avoid loop back by turning any Quantity output into array views.

File ~/.local/conda/envs/cta-dev/lib/python3.11/site-packages/astropy/units/quantity_helper/converters.py:181, in converters_and_unit(function, method, *args)
    178 units = [getattr(arg, "unit", None) for arg in args]
    180 # Determine possible conversion functions, and the result unit.
--> 181 converters, result_unit = ufunc_helper(function, *units)
    183 if any(converter is False for converter in converters):
    184     # for multi-argument ufuncs with a quantity and a non-quantity,
    185     # the quantity normally needs to be dimensionless, *except*
   (...)
    188     # can just have the unit of the quantity
    189     # (this allows, e.g., `q > 0.` independent of unit)
    190     try:
    191         # Don't fold this loop in the test above: this rare case
    192         # should not make the common case slower.

File ~/.local/conda/envs/cta-dev/lib/python3.11/site-packages/astropy/units/quantity_helper/erfa.py:70, in helper_s2p(f, unit1, unit2, unit3)
     67 from astropy.units.si import radian
     69 try:
---> 70     return [get_converter(unit1, radian), get_converter(unit2, radian), None], unit3
     71 except UnitsError:
     72     raise UnitTypeError(
     73         f"Can only apply '{f.__name__}' function to quantities with angle units"
     74     )

File ~/.local/conda/envs/cta-dev/lib/python3.11/site-packages/astropy/units/quantity_helper/helpers.py:42, in get_converter(from_unit, to_unit)
     38 def get_converter(from_unit, to_unit):
     39     """Like Unit._get_converter, except returns None if no scaling is needed,
     40     i.e., if the inferred scale is unity.
     41     """
---> 42     converter = from_unit._get_converter(to_unit)
     43     return None if converter is unit_scale_converter else converter

AttributeError: 'NoneType' object has no attribute '_get_converter'

Expected behavior

No response

How to Reproduce

No response

Versions

import astropy
try:
    astropy.system_info()
except AttributeError:
    import platform; print(platform.platform())
    import sys; print("Python", sys.version)
    import astropy; print("astropy", astropy.__version__)
    import numpy; print("Numpy", numpy.__version__)
    import erfa; print("pyerfa", erfa.__version__)
    try:
        import scipy
        print("Scipy", scipy.__version__)
    except ImportError:
        print("Scipy not installed")
    try:
        import matplotlib
        print("Matplotlib", matplotlib.__version__)
    except ImportError:
        print("Matplotlib not installed")
# Paste the result here

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions