Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 27 additions & 21 deletions astropy/coordinates/angle_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,21 +149,21 @@ def p_ufloat(p):

def p_colon(p):
'''
colon : sign UINT COLON UINT
colon : sign UINT COLON ufloat
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make it consistent, UINT is all uppercase

| sign UINT COLON UINT COLON ufloat
'''
if len(p) == 5:
p[0] = (p[1] * p[2], p[4], 0.0)
p[0] = (p[1] * p[2], p[4])
elif len(p) == 7:
p[0] = (p[1] * p[2], p[4], p[6])

def p_spaced(p):
'''
spaced : sign UINT UINT
spaced : sign UINT ufloat
| sign UINT UINT ufloat
'''
if len(p) == 4:
p[0] = (p[1] * p[2], p[3], 0.0)
p[0] = (p[1] * p[2], p[3])
elif len(p) == 5:
p[0] = (p[1] * p[2], p[3], p[4])

Expand All @@ -182,8 +182,9 @@ def p_generic(p):
def p_hms(p):
'''
hms : sign UINT HOUR
| sign UINT HOUR UINT
| sign UINT HOUR ufloat
| sign UINT HOUR UINT MINUTE
| sign UINT HOUR UFLOAT MINUTE
| sign UINT HOUR UINT MINUTE ufloat
| sign UINT HOUR UINT MINUTE ufloat SECOND
| generic HOUR
Expand All @@ -193,15 +194,16 @@ def p_hms(p):
elif len(p) == 4:
p[0] = (p[1] * p[2], u.hourangle)
elif len(p) in (5, 6):
p[0] = ((p[1] * p[2], p[4], 0.0), u.hourangle)
p[0] = ((p[1] * p[2], p[4]), u.hourangle)
elif len(p) in (7, 8):
p[0] = ((p[1] * p[2], p[4], p[6]), u.hourangle)

def p_dms(p):
'''
dms : sign UINT DEGREE
| sign UINT DEGREE UINT
| sign UINT DEGREE ufloat
| sign UINT DEGREE UINT MINUTE
| sign UINT DEGREE UFLOAT MINUTE
| sign UINT DEGREE UINT MINUTE ufloat
| sign UINT DEGREE UINT MINUTE ufloat SECOND
| generic DEGREE
Expand All @@ -211,7 +213,7 @@ def p_dms(p):
elif len(p) == 4:
p[0] = (p[1] * p[2], u.degree)
elif len(p) in (5, 6):
p[0] = ((p[1] * p[2], p[4], 0.0), u.degree)
p[0] = ((p[1] * p[2], p[4]), u.degree)
elif len(p) in (7, 8):
p[0] = ((p[1] * p[2], p[4], p[6]), u.degree)

Expand Down Expand Up @@ -297,6 +299,8 @@ def _check_second_range(sec):
"""
if np.any(sec == 60.):
warn(IllegalSecondWarning(sec, 'Treating as 0 sec, +1 min'))
elif sec is None:
pass
elif np.any(sec < -60.) or np.any(sec > 60.):
# "Error: seconds not in range [-60,60) ({0}).".format(sec))
raise IllegalSecondError(sec)
Expand Down Expand Up @@ -361,7 +365,7 @@ def degrees_to_dms(d):
return np.floor(sign * d), sign * np.floor(m), sign * s


def dms_to_degrees(d, m, s):
def dms_to_degrees(d, m, s=None):
"""
Convert degrees, arcminute, arcsecond to a float degrees value.
"""
Expand All @@ -372,13 +376,14 @@ def dms_to_degrees(d, m, s):
# determine sign
sign = np.copysign(1.0, d)

# TODO: This will fail if d or m have values after the decimal
# place

try:
d = np.floor(np.abs(np.asarray(d)))
m = np.floor(np.abs(np.asarray(m)))
s = np.abs(s)
d = np.floor(np.abs(d))
if s is None:
m = np.abs(m)
s = 0
else:
m = np.floor(np.abs(m))
s = np.abs(s)
except ValueError:
raise ValueError(format_exception(
"{func}: dms values ({1[0]},{2[1]},{3[2]}) could not be "
Expand All @@ -387,7 +392,7 @@ def dms_to_degrees(d, m, s):
return sign * (d + m / 60. + s / 3600.)


def hms_to_hours(h, m, s):
def hms_to_hours(h, m, s=None):
"""
Convert hour, minute, second to a float hour value.
"""
Expand All @@ -397,13 +402,14 @@ def hms_to_hours(h, m, s):
# determine sign
sign = np.copysign(1.0, h)

# TODO: This will fail if d or m have values after the decimal
# place

try:
h = np.floor(np.abs(h))
m = np.floor(np.abs(m))
s = np.abs(s)
if s is None:
m = np.abs(m)
s = 0
else:
m = np.floor(np.abs(m))
s = np.abs(s)
except ValueError:
raise ValueError(format_exception(
"{func}: HMS values ({1[0]},{2[1]},{3[2]}) could not be "
Expand Down
3 changes: 1 addition & 2 deletions astropy/coordinates/angles.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,12 @@ def __new__(cls, angle, unit=None, dtype=None, copy=True):
@staticmethod
def _tuple_to_float(angle, unit):
"""
Converts an angle represented as a 3-tuple into a floating
Converts an angle represented as a 3-tuple or 2-tuple into a floating
point number in the given unit.
"""
if isinstance(angle, tuple):
# TODO: Numpy array of tuples?
if unit is u.hourangle:
util.check_hms_ranges(*angle)
angle = util.hms_to_hours(*angle)
elif unit is u.degree:
angle = util.dms_to_degrees(*angle)
Expand Down
21 changes: 19 additions & 2 deletions astropy/coordinates/sky_coordinate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import collections

import numpy as np
import re

from ..utils.compat.misc import override__dir__
from ..extern import six
Expand All @@ -18,6 +19,9 @@

__all__ = ['SkyCoord']

PMRE = re.compile(r'(\+|\-)')
JPMRE = re.compile(r'J([0-9]{6}\.?[0-9]{0,2})([\+\-][0-9]{6}\.?[0-9]{0,2})\s*$')


# Define a convenience mapping. This is used like a module constants
# but is actually dynamically evaluated.
Expand Down Expand Up @@ -915,8 +919,21 @@ def _parse_coordinate_arg(coords, frame, units):
if isinstance(coord, six.string_types):
coord1 = coord.split()
if len(coord1) == 6:
coord1 = (' '.join(coord1[:3]), ' '.join(coord1[3:]))
coord = coord1
coord = (' '.join(coord1[:3]), ' '.join(coord1[3:]))
elif len(coord1) > 2:
coord = PMRE.split(coord)
coord = (coord[0], ' '.join(coord[1:]))
elif len(coord1) == 1:
try:
coord = JPMRE.match(coord).groups()
coord = ('{0} {1} {2}'.
format(coord[0][0:2], coord[0][2:4], coord[0][4:]),
'{0} {1} {2}'.
format(coord[1][0:3], coord[1][3:5], coord[1][5:]))
except:
coord = coord1
else:
coord = coord1

vals.append(coord) # This assumes coord is a sequence at this point

Expand Down
22 changes: 19 additions & 3 deletions astropy/coordinates/tests/test_sky_coord.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,25 @@ def test_coord_init_string():
assert allclose(sc1.ra, Angle(120 * u.deg))
assert allclose(sc1.dec, Angle(5 * u.deg))

with pytest.raises(ValueError) as err:
SkyCoord('8 00 -5 00 00.0', unit=(u.hour, u.deg), frame='icrs')
assert 'coordinates have 5 values but spherical representation only accepts 3' in str(err)
sc2 = SkyCoord('8 00 -5 00 00.0', unit=(u.hour, u.deg), frame='icrs')
assert isinstance(sc2, SkyCoord)
assert allclose(sc2.ra, Angle(120 * u.deg))
assert allclose(sc2.dec, Angle(-5 * u.deg))

sc3 = SkyCoord('8 00 -5 00.6', unit=(u.hour, u.deg), frame='icrs')
assert isinstance(sc3, SkyCoord)
assert allclose(sc3.ra, Angle(120 * u.deg))
assert allclose(sc3.dec, Angle(-5.01 * u.deg))

sc4 = SkyCoord('J080000.0-050036.0', unit=(u.hour, u.deg), frame='icrs')
assert isinstance(sc4, SkyCoord)
assert allclose(sc4.ra, Angle(120 * u.deg))
assert allclose(sc4.dec, Angle(-5.01 * u.deg))

sc5 = SkyCoord('8h 00.6m -5d 00.6m', unit=(u.hour, u.deg), frame='icrs')
assert isinstance(sc5, SkyCoord)
assert allclose(sc5.ra, Angle(120.15 * u.deg))
assert allclose(sc5.dec, Angle(-5.01 * u.deg))


def test_coord_init_unit():
Expand Down