Repository navigation
FITS, Units and numeric multiplier #3991
Copy link
Copy link
Closed
Description
Hi,
For the MUSE Fits files, we use units of 10**(-20)*erg/s/cm**2/Angstrom for the BUNIT keyword, and I was wondering how to handle these units with astropy.unit. Parsing this BUNIT string with Unit fails:
In [49]: u.Unit('10**(-20)*erg/s/cm**2/Angstrom', format='fits')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-49-85fbe5e89603> in <module>()
----> 1 u.Unit('10**(-20)*erg/s/cm**2/Angstrom', format='fits')
/home/simon/lib/astropy/astropy/units/core.pyc in __call__(self, s, represents, format, namespace, doc, parse_strict)
1808 .format(s, format_clause, six.text_type(e)))
1809 if parse_strict == 'raise':
-> 1810 raise ValueError(msg)
1811 elif parse_strict == 'warn':
1812 warnings.warn(msg, UnitsWarning)
ValueError: '10**(-20)*erg/s/cm**2/Angstrom' did not parse as fits unit: Syntax error parsing unit '10**(-20)*erg/s/cm**2/Angstrom'If I change the separator for the multiplier to a space, then it works:
In [50]: u.Unit('10**(-20) erg/s/cm**2/Angstrom', format='fits')
Out[50]: Unit("1e-20 erg / (Angstrom cm2 s)")Looking at the FITS standard 3.0, both seems valid. It is not clear that using a star for the separator of the multiplier is forbidden. I think the star/space equivalence should work also here.
Then, another issue happens if I want to convert back these units to strings:
In [52]: u.Unit('erg/s/cm**2/Angstrom', format='fits').to_string('fits')
Out[52]: u'Angstrom-1 cm-2 erg s-1'
In [53]: u.Unit('10**(-20) erg/s/cm**2/Angstrom', format='fits').to_string('fits')
---------------------------------------------------------------------------
UnitScaleError Traceback (most recent call last)
<ipython-input-53-87d586bdb87d> in <module>()
----> 1 u.Unit('10**(-20) erg/s/cm**2/Angstrom', format='fits').to_string('fits')
/home/simon/lib/astropy/astropy/units/core.pyc in to_string(self, format)
593 """
594 f = unit_format.get_format(format)
--> 595 return f.to_string(self)
596
597 def __format__(self, format_spec):
/home/simon/lib/astropy/astropy/units/format/fits.pyc in to_string(cls, unit)
119 raise core.UnitScaleError(
120 "The FITS unit format is not able to represent scale. "
--> 121 "Multiply your data by {0:e}.".format(unit.scale))
122
123 pairs = list(zip(unit.bases, unit.powers))
UnitScaleError: The FITS unit format is not able to represent scale. Multiply your data by 1.000000e-20Why should I multiply my data by 1e-20 (we don't want this ;)) while astropy was able to parse this unit ? (and putting the 10**-20 in the unit string is valid).
Reactions are currently unavailable
Activity
Fix astropy#3991: FITS unit format fixes
mdboom commentedon Jul 22, 2015
I think that could be read either way from the standard. The scale at the front is a special case -- it's always at the beginning, is not a unit, so in general numeric operators can not be applied to it. However, I don't think it's ambiguous to also accept a
*here, so I've modified the parser to accept it -- but it will always write out a space.Yes -- the FITS format writer was rejecting any scale, when in fact it should only reject scales that aren't powers of 10.
mdboom commentedon Jul 22, 2015
See #3993 for fixes.
saimn commentedon Jul 22, 2015
Great, thanks Michael !
Fix astropy#3991: FITS unit format fixes