[AstroPy] Type changing (float to int) of header fields in astropy.wcs.to_header ?
Michael Droettboom
mdroe at stsci.edu
Wed Jan 22 17:12:11 EST 2014
On 01/22/2014 02:42 PM, Eric L. N. Jensen wrote:
> Hi Mike,
>
> Thanks for your quick and helpful response - I really appreciate it.
>
> First, let me say that I completely agree with this:
>
>> Honestly, and I don't mean to sound unhelpful, this sounds like a bug
>> in CASA. It should cast to a float before performing floating-point
>> operations.
>
> I wasn't sure if that was the case before because I hadn't found the
> part of the FITS standard you reference (thanks!) about the decimal
> point being optional for floats in FITS. And for what it's worth,
> I'm not sure if it's an issue with floating-point operations, or just
> with interpreting the field as an int and trying to store it as such.
> (In fact the value in my particular case, ~3.45E9, is too long to
> store even as a long int in C. So I guess the key issue is whether
> the FITS reader knows which fields to interpret as floats even if they
> have no non-integer part.)
It isn't the responsibility of the FITS reader to interpret the values
-- it's the responsibility of the code that needs to use the value. In
effect, CASA should be saying "give me CRVAL3 as a float, because I know
that's what a CRVAL should be." It's not ideal, but that's the best one
can do with the FITS standard such as it is.
The issue with the maximum size of C ints is one of the reasons CFITSIO
has the caller say what type they want the value returned in. My
sidestep this a little in PyFITS by using Python's arbitrary-precision
integers, so it doesn't matter if the value is read first as an int (by
astropy.fits) and later recast as a float (by the tool using astropy.fits).
I'm sorry if I seemed abrupt -- others at my office have wondered why we
can't just add a decimal place to these values in wcslib and be done
with it. We certainly can, but it doesn't change the fact that any tool
*reading* a WCS structure still needs to be fixed in order to read
anything that may be thrown at it (which may well include a floating
point value that looks like an integer). And I'd just rather fix the
problem at its source than accrue even more workarounds (there's way too
many of those in the FITS/WCS world already).
>
> Still, there's something unsatisfying to me about this happening
> within astropy:
>
>>> From WCS object:
>>>
>>> CRVAL3 is type <type 'numpy.float64'> with value:
>>> 345797143190.0
>>>
>>> After to_header conversion:
>>>
>>> CRVAL3 is type <type 'int'> with value:
>>> 345797143190
>
> All that is within Python, i.e. the stated datatype *in Python*
> changes after the call to 'to_header'. Could this be a problem if,
> e.g., a user decides to divide by that value (reasoning that it should
> be a float, since the input was float) and gets the result of integer
> division rather than floating-point division? (I admit that this is a
> contrived example, since it would require that the numerator be an
> integer as well, but I'm still a little puzzled by the type change.)
Even in this contrived example, if the user wants to do floating point
division, they should cast the value to a floating point value first.
>
> I guess I still don't see how this conversion happens. I see in the
> code where you pointed out that wcslib will drop the decimal in
> making the number into a string, but to_header doesn't return a
> string-representation FITS header; it returns a FITS header object
> (which seems dictionary-like) that definitely doesn't have only string
> values.
wcslib converts its internal data structures back into a string
representation of a FITS header, which we parse back into an
`astropy.fits.Header` object. This is because wcslib does not provide
an API to get a list of key/value pairs, only to get a parsed and
cleaned up header back as a string. The mapping from the internal data
structure to key/value pairs is non-trivial.
> Do these fields get converted to strings and then back to numbers
> during the to_header call?
Yes. It's all just a peculiarity from the decision to use wcslib, which
has many years of effort in implementing the WCS standard and not
wanting to reimplement it.
>
> At some level this won't matter for my particular problem if the final
> output file is written with that wcsutil_double2str
> function, but I am curious on your thoughts about the above, i.e. what
> is happening within Python itself.
>
Hope it's clearer.
The flow is basically:
astropy.io.fits.Header ->
FITS Header string ->
[all kinds of normalization and fixups for different changing and
obsolete conventions] ->
WCS data structure (normalized and optimized for performing the
transformations) ->
FITS header string ->
astropy.io.fits.Header
Mike
--
_
|\/|o _|_ _. _ | | \.__ __|__|_|_ _ _ ._ _
| ||(_| |(_|(/_| |_/|(_)(/_|_ |_|_)(_)(_)| | |
http://www.droettboom.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/astropy/attachments/20140122/50fe12e2/attachment.html>
More information about the AstroPy
mailing list