[AstroPy] Bug in units decompose()?
Michael Droettboom
mdroe at stsci.edu
Tue Jul 1 16:41:01 EDT 2014
On 07/01/2014 04:14 PM, John Quinn wrote:
> Thanks for the responses.
>
> I think I can use to() to convert to other units and that will do
> what I want.
If you just want to convert a value to another unit, |to| is what you
want. |decompose| and |compose| are really more about introspecting the
structure of units and finding alternate representations.
>
> I was confused after reading the documentation at:
> http://docs.astropy.org/en/stable/units/decomposing_and_composing.html#reducing-a-unit-to-its-irreducible-parts
> and found that:
> > u.J.compose()
> [Unit("J"), Unit("1e+07 erg"), Unit("4.58743e+17 Ry"),
> Unit("6.24151e+18 eV")]
>
> > u.Ry.decompose(bases=[u.m, u.N])
> 2.17987e-18 m N
>
> > u.eV.decompose(bases=[u.m, u.N])
> 1.60218e-19 m N
>
> but:
>
> > u.erg.decompose(bases=[u.m, u.N])
> gives an error.
erg is not defined in terms of N since it comes from the cgs system. It
is |cm2 g / s2|. If you want to recompose that back into N, you should
use |compose|:
|u.erg.compose(units=[u.m, u.N])
[Unit("1e-07 m N")]
|
>
> Similarly, converting to J sometimes works and sometimes doesn't,
Can you elaborate on this? If something is nondeterministic I'd consider
that a bug.
> and I was very surprised that decomposing
> something in J to J gave an error.
We could probably special case this for decompose just to avoid confusion.
I know this |decompose| vs. |compose| difference is confusing for others
as well, and your suggestions about how to improve the docs and/or
naming of things to make it more obvious are welcome. I think we still
want to have both available, and I don't see an argument for changing
the behavior (excepting the |X.decompose(bases=[X])| case). |decompose|
is asking "how is this unit defined from its lower-level parts?",
whereas |compose| is asking "given all of the units you know about, how
can this unit be refactored into them?" So |decompose| is useful for
introspecting the definition of a unit and |compose| is useful for
searching for alternative representations. And it should be obvious that
|compose| is a lot more computationally expensive. Neither are really
necessary for pure unit conversion, where `to` is your friend.
Mike
>
> Regards,
>
> John
>
>
>
>
>
> On 1 Jul 2014, at 18:43, Erik Bray <embray at stsci.edu
> <mailto:embray at stsci.edu>> wrote:
>
>> If I understand correctly this is because u.J is already defined in
>> terms of
>> kilograms, meters, and seconds (actually Newtons and meters). You could
>> redefine J as a new unit, and then redefine those other units
>> relative to the new J.
>>
>> But I'm not entirely clear exactly what the intent is here. I do
>> agree the
>> error is a little confusing. But not as much if you know that Joule
>> is already a
>> compound unit, and it's trying to recursively decompose the units
>> that comprise
>> it in terms of Joules, hence the confusion.
>>
>> Erik
>>
>> On 07/01/2014 11:18 AM, John Quinn wrote:
>>> Hello,
>>>
>>> I am currently evaluating iPython Notebook as a replacement for
>>> MATHCAD in our
>>> teaching laboratories
>>> and am particularly interested in using the units and constants
>>> packages of
>>> astropy.
>>>
>>> I have encountered an apparent bug using the units decompose
>>> function and have
>>> reduced it to the
>>> following example:
>>>
>>>> from astropy import units as u
>>>> u.J.decompose(bases=[u.J])
>>>
>>> which produces the errors given below.
>>>
>>> Similarly, I cannot decompose a unit consisting of 1 u.N * u.m into
>>> u.J, but
>>> strangely u.Ry.decompose(bases=[u.J]) works fine.
>>>
>>> Am I missing something obvious or is this a bug?
>>>
>>> I am using astropy 0.3.2 with python 3.4.1 on Mac OS X (anaconda).
>>> I see the
>>> same on the Linux and Windows
>>> versions and with Python 2.7.7.
>>>
>>> Thanks,
>>>
>>> John
>>>
>>> ---------------------------------------------------------------------------
>>> UnitsError Traceback (most recent
>>> call last)
>>> <ipython-input-54-3aa084c7cc08> in<module>()
>>> ----> 1 u.J.decompose(bases=[u.J])
>>>
>>> /Users/quinn/anaconda/envs/py34/lib/python3.4/site-packages/astropy/units/core.py
>>> indecompose(self, bases)
>>> 1837
>>> 1838 def decompose(self, bases=set()):
>>> -> 1839 return self._represents.decompose(bases=bases)
>>> 1840 decompose.__doc__= UnitBase.decompose.__doc__
>>> 1841
>>>
>>> /Users/quinn/anaconda/envs/py34/lib/python3.4/site-packages/astropy/units/core.py
>>> indecompose(self, bases)
>>> 1999
>>> 2000 x = CompositeUnit(self.scale, self.bases,
>>> self.powers, decompose=True,
>>> -> 2001 decompose_bases=bases)
>>> 2002 if len(bases) == 0:
>>> 2003 self._decomposed_cache= x
>>>
>>> /Users/quinn/anaconda/envs/py34/lib/python3.4/site-packages/astropy/units/core.py
>>> in__init__(self, scale, bases, powers, decompose, decompose_bases,
>>> _error_check)
>>> 1897 self._powers= powers
>>> 1898 self._decomposed_cache= None
>>> -> 1899 self._expand_and_gather(decompose=decompose,
>>> bases=decompose_bases)
>>> 1900
>>> 1901 def __repr__(self):
>>>
>>> /Users/quinn/anaconda/envs/py34/lib/python3.4/site-packages/astropy/units/core.py
>>> in_expand_and_gather(self, decompose, bases)
>>> 1959 for b, pin zip(self.bases, self.powers):
>>> 1960 if decomposeand bnot in bases:
>>> -> 1961 b = b.decompose(bases=bases)
>>> 1962
>>> 1963 if isinstance(b, CompositeUnit):
>>>
>>> /Users/quinn/anaconda/envs/py34/lib/python3.4/site-packages/astropy/units/core.py
>>> indecompose(self, bases)
>>> 1837
>>> 1838 def decompose(self, bases=set()):
>>> -> 1839 return self._represents.decompose(bases=bases)
>>> 1840 decompose.__doc__= UnitBase.decompose.__doc__
>>> 1841
>>>
>>> /Users/quinn/anaconda/envs/py34/lib/python3.4/site-packages/astropy/units/core.py
>>> indecompose(self, bases)
>>> 1999
>>> 2000 x = CompositeUnit(self.scale, self.bases,
>>> self.powers, decompose=True,
>>> -> 2001 decompose_bases=bases)
>>> 2002 if len(bases) == 0:
>>> 2003 self._decomposed_cache= x
>>>
>>> /Users/quinn/anaconda/envs/py34/lib/python3.4/site-packages/astropy/units/core.py
>>> in__init__(self, scale, bases, powers, decompose, decompose_bases,
>>> _error_check)
>>> 1897 self._powers= powers
>>> 1898 self._decomposed_cache= None
>>> -> 1899 self._expand_and_gather(decompose=decompose,
>>> bases=decompose_bases)
>>> 1900
>>> 1901 def __repr__(self):
>>>
>>> /Users/quinn/anaconda/envs/py34/lib/python3.4/site-packages/astropy/units/core.py
>>> in_expand_and_gather(self, decompose, bases)
>>> 1959 for b, pin zip(self.bases, self.powers):
>>> 1960 if decomposeand bnot in bases:
>>> -> 1961 b = b.decompose(bases=bases)
>>> 1962
>>> 1963 if isinstance(b, CompositeUnit):
>>>
>>> /Users/quinn/anaconda/envs/py34/lib/python3.4/site-packages/astropy/units/core.py
>>> indecompose(self, bases)
>>> 1573 raise UnitsError(
>>> 1574 "Unit {0} can not be decomposed into the
>>> requested"
>>> -> 1575 "bases".format(self))
>>> 1576
>>> 1577 return self
>>>
>>> UnitsError: Unit kg can not be decomposed into the requested bases
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> AstroPy mailing list
>>> AstroPy at scipy.org <mailto:AstroPy at scipy.org>
>>> http://mail.scipy.org/mailman/listinfo/astropy
>>>
>>
>> _______________________________________________
>> AstroPy mailing list
>> AstroPy at scipy.org <mailto:AstroPy at scipy.org>
>> http://mail.scipy.org/mailman/listinfo/astropy
>
> Dr. John Quinn
> School of Physics
> Science Center North
> University College Dublin
> Belfield, Dublin 4
> Ireland
>
> T: +353-1-7162278
> F: +353-1-2837275
> john.quinn at ucd.ie <mailto:john.quinn at ucd.ie>
>
>
>
>
>
> _______________________________________________
> AstroPy mailing list
> AstroPy at scipy.org
> http://mail.scipy.org/mailman/listinfo/astropy
--
Michael Droettboom
Science Software Branch
Space Telescope Science Institute
http://www.droettboom.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/astropy/attachments/20140701/228c31e4/attachment.html>
More information about the AstroPy
mailing list