Repository navigation
Closed
Description
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
Activity
mhvk commentedon Aug 23, 2024
This is a little tricky: in general, once units are involved, we treat numbers/arrays as dimensionless, and here the function needs angular units. So, in that sense, the error is logical. Note that you don't normally notice this for something like
np.sin, since if the argument has no unit, it never reaches the units machinery and hence the number is interpreted as being in radians bynp.sinitself. But if you donp.sin(0.5, out=u.Quantity()), you get exactly the same confusing error message.I think, though, that this issue is mostly about the confusing error message - which should be fixable! - is that the case?
maxnoe commentedon Aug 24, 2024
Yes, sure, if this is not easy to fix, something like "either all or none of the arguments must be provided as quantities" would be fine I guess
mhvk commentedon Aug 25, 2024
See #16878 for a fix.