[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)

In [3]: print int(x) < 0

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).  


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