[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