[AstroPy] Bug in units decompose()?

John Quinn john.quinn at ucd.ie
Wed Jul 2 15:28:16 EDT 2014


On 1 Jul 2014, at 21:41, Michael Droettboom <mdroe at stsci.edu> wrote:

> 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.
> 
Thanks for clarifying. I think I had started to figure that out as I used the package more. 

For teaching purposes I will be clear on the different uses of to, compose and decompose.

> 
>> 
>> 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")]
OK, but the following is confusing to the uninitiated since u.erg decomposes into SI by default:

In [4]: u.erg.decompose()
Out[4]: Unit("1e-07 kg m2 / s2")

In [5]: u.erg.decompose(bases=[u.kg, u.m, u.s])
Out[5]: Unit("1e-07 kg m2 / s2")

In [6]: u.erg.decompose(bases=[u.N,u.m])
---------------------------------------------------------------------------
UnitsError                                Traceback (most recent call last)
:
:

From your explanation I see why this is - there is a clear difference between decomposing and converting,
and I was using decompose to convert. 

>> 
>> 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.
> 
No, my mistake! It is always consistent. Sorry about that.

> 
>> 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.
I have evaluated several python packages for handing units and astropy seems to be excellent and most suit our requirements,
once one gets to grips with compose , decompose and to and their intended uses.
After I have used the package a bit more and got experience with students using it in the labs I will send any suggestions for 
clarification of the documentation.

From my experience so far I think it would be great if the error messages gave a little more information about why it failed. 

Thanks for your help,

John


> Mike
> 
> 
> 
>> 
>> Regards,
>> 
>> John
>> 
>> 
>> 
>> 
>> 
>> On 1 Jul 2014, at 18:43, Erik Bray <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
>>>> http://mail.scipy.org/mailman/listinfo/astropy
>>>> 
>>> 
>>> _______________________________________________
>>> AstroPy mailing list
>>> 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
>> 
>> 
>> 
>> 
>> 
>> _______________________________________________
>> 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
> _______________________________________________
> AstroPy mailing list
> 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



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/astropy/attachments/20140702/7ffc8456/attachment.html>


More information about the AstroPy mailing list