You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
decompose does not accept PrefixUnits as bases #5615
Is this behaviour intended? And if yes, is there another way to achieve what is outlined in the code snipped above, namely decomposing a given unit using TeV (or any composite unit) as base unit?
Note that compose() always returns a list since there may be multiple possibilities; you'd just take the first element. Also note that one still has to add include_prefix_units=True (which perhaps is a bit odd, and could be solved; see #4104).
Stepping back from the specific issue, why do you need this? I ask because over time I found that I care less and less about what specific unit something is in: I just do calculations and at the very end, if I really care, I convert my quantities to a specific unit using quantity.to(desired_unit).
Stepping back from the specific issue, why do you need this?
I need to write all quantities I have to disk in a given units system (cm, s, keV) to use them with Sherpa. Of course I could use quantity.to(desired_unit) but then I'd need to check first of what type my quantity is (energy, flux, length). Therefore I'd like to be able to express any quantity I have in given set of (non-irreducible) units. What you propose works your the use case I've described, for composite units, however, it fails.
In [9]: myunit = u.TeV / u.m ** 2
In [10]: myunit
Out[10]: Unit("TeV / m2")
In [11]: myunit.compose(units=[u.cm, u.keV], include_prefix_units=True)
---------------------------------------------------------------------------
UnitsError Traceback (most recent call last)
<ipython-input-11-cd39fd74ef52> in <module>()
----> 1 myunit.compose(units=[u.cm, u.keV], include_prefix_units=True)
/home/kingj/Software/astropy/astropy/units/core.pyc in compose(self, equivalencies, units, max_depth, include_prefix_units)
1280 return sort_results(self._compose(
1281 equivalencies=equivalencies, namespace=units,
-> 1282 max_depth=max_depth, depth=0, cached_results={}))
1283
1284 def to_system(self, system):
/home/kingj/Software/astropy/astropy/units/core.pyc in _compose(self, equivalencies, namespace, max_depth, depth, cached_results)
1153 "units".format(self))
1154 cached_results[key] = result
-> 1155 raise result
1156
1157 cached_results[key] = [self]
UnitsError: Cannot represent unit TeV / m2 in terms of the given units
The failure you find puzzled me at first, but on further inspection, I see at least what happens: for any of the units provided, the compose() checks whether there are any bases in common with the unit you want to recompose. And TeV/m2 is a bit annoying, in that its decomposition is 1.60218e-07 kg / s2. Since this does not include a length, the length unit gets ignored even though you explicitly passed it in.
Back to the more general goal: it certainly makes sense to want a specific output unit system. In principle, ideally one would define an actual system (i.e., something like cgs), and use unit.to_system(...). However, trying this, it seems that it is pretty much baked in that the system should include a mass, length, and weight.
Looking back, I see there was some discussion of this in #703. There is also a link there to a package (http://gala.adrian.pw/en/latest/units.html) that defines a unit system. Essentially, it is simply a wrapper that allows preferred units for certain physical types. This may be helpful to get moving. In the meantime, I will mark this as a feature request.
Activity
mhvk commentedon Dec 20, 2016
@joleroi -
decomposeis specifically meant to decompose to irreducible units. In your example, I think what you want isNote that
compose()always returns a list since there may be multiple possibilities; you'd just take the first element. Also note that one still has to addinclude_prefix_units=True(which perhaps is a bit odd, and could be solved; see #4104).Stepping back from the specific issue, why do you need this? I ask because over time I found that I care less and less about what specific unit something is in: I just do calculations and at the very end, if I really care, I convert my quantities to a specific unit using
quantity.to(desired_unit).joleroi commentedon Dec 20, 2016
Thanks for your reply
I need to write all quantities I have to disk in a given units system (cm, s, keV) to use them with Sherpa. Of course I could use
quantity.to(desired_unit)but then I'd need to check first of what type my quantity is (energy, flux, length). Therefore I'd like to be able to express any quantity I have in given set of (non-irreducible) units. What you propose works your the use case I've described, for composite units, however, it fails.mhvk commentedon Dec 20, 2016
The failure you find puzzled me at first, but on further inspection, I see at least what happens: for any of the units provided, the
compose()checks whether there are any bases in common with the unit you want to recompose. AndTeV/m2is a bit annoying, in that its decomposition is1.60218e-07 kg / s2. Since this does not include a length, the length unit gets ignored even though you explicitly passed it in.Back to the more general goal: it certainly makes sense to want a specific output unit system. In principle, ideally one would define an actual system (i.e., something like
cgs), and useunit.to_system(...). However, trying this, it seems that it is pretty much baked in that the system should include a mass, length, and weight.Looking back, I see there was some discussion of this in #703. There is also a link there to a package (http://gala.adrian.pw/en/latest/units.html) that defines a unit system. Essentially, it is simply a wrapper that allows preferred units for certain physical types. This may be helpful to get moving. In the meantime, I will mark this as a feature request.
mhvk commentedon Apr 12, 2021
closing in favour of #11525