[AstroPy] Constructing Angle from a tuple specified as sign string plus numbers for degrees, arcmin, arcsec
Eric Jensen
ejensen1 at swarthmore.edu
Mon Aug 10 23:13:26 EDT 2015
Hi all,
Thanks for the suggestions. These solutions both have the problem that I suspect the original table formatting was designed to avoid, which is the infamous “minus zero” problem, affecting declinations between 0 and -1 degrees. For those decs, the leading part of the coordinate is “-00” which is fine as a string, but doesn’t preserve sign when evaluated as an integer:
In [1]: x = '-00'
In [2]: print int(x)
0
In [3]: print int(x) < 0
False
So I think what I probably need to do instead is construct a separate “sign” variable with a +1 or -1, and then multiply it by the final coordinate. I couldn’t see how to do it before (because of the masked integer vs. string column issue that Erik notes) but having seen these examples, it seems like I should be able to do something like this:
for row in t['DE-', 'DEd', 'DEm', 'DEs']:
dec = Angle(row[1], row[2], row[3]) * int(row[0] + '1')
but when trying to do that I get an error on units, whether or not I specify them explicitly. Ultimately, I was able to make it work with this:
t['Dec'] = Angle((t['DEd'], t['DEm'], t['DEs']), unit=u.deg)
sign = np.array([])
# Construct an integer +1 or -1 sign variable from the string:
for sign_string in t['DE-‘]:
sign = np.append(sign,int(sign_string + '1'))
t['Dec'] *= sign
So my immediate problem is solved (thanks!) but the overall “minus zero” problem is a real issue, I think - I hadn’t thought about it this generally at the outset, but any three-element angle constructor will have this problem if the angles are allowed to be negative. So it still seems to me that a four-element angle constructor would be very useful (and perhaps a warning for the three-element version).
Thanks,
Eric
P.S. Just saw John Gizis’ reply as I was about to send:
"I don't think is unusual for CDS tables. I always thought it was because Fortran77 didn't know -00 is different than +00. “
It’s not just Fortran - Python too! (And pretty much any other language you can name, unless you’re dealing with strings.)
In [1]: +0 == -0
Out[1]: True
On Aug 10, 2015, at 6:00 PM, Erik Bray <embray at stsci.edu> wrote:
>>> You can instantiate an Angle array using a generator, so you could probably just
>>> slurp in the data using a generator expression, allowing you to transform the
>>> values one a time while creating the Angle rather than transforming the table
>>> all at once first (please bear with the LISPiness of this example):
>>>
>>> dec = Angle(((int(row[0] + str(row[1])), row[2], row[3])
>>> for row in table['DE-', 'DEd', 'DEm', 'DEs'))
>>>
>>>
>>> # (Note: originally I used row[2:] above, but there seems to be an unrelated bug
>>> involved in taking slices of rows...I'll report on that.)
>>
>> In case you want to do this without loops, np.char.add can be used to
>> concatenate string arrays element-wise. So for instance you could
>> concatenate the sign column and the degree column of the declination with
>>
>> np.add(t['DE-'], t['DEd'])
>>
>> then you would end up with three arrays instead of four.
>
> This doesn't work because t['DE-'] is a string column, and t['DEd'] is a
> (masked) integer column.
>
> In any case, doing a row-wise transformation allows doing this with one fewer loop.
More information about the AstroPy
mailing list