Skip to content

Commit 2c09cc1

Browse files
authored
Make get_source_azel compatible with fixed source (#1537)
* Make get_source_azel compatible with fixed source * fix docstring
1 parent c99ce67 commit 2c09cc1

File tree

2 files changed

+45
-15
lines changed

2 files changed

+45
-15
lines changed

sotodlib/coords/planets.py

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,28 @@ def get_source_list_fromstr(target_source):
5151
return isource
5252
raise ValueError(f'Source "{target_source}" not found in {SOURCE_LIST}.')
5353

54+
def match_fixed_source(source_name):
55+
"""Match source_name against a regular expression and if it has the
56+
format 'Jxxx[+-pmn]yyy', where xxx and yyy are decimal numbers,
57+
then RA, Dec = xxx, yyy in degrees will be returned.
58+
If it doesn't match, nans are returned as RA and Dec.
59+
60+
Args:
61+
source_name (str): Name of fixed-position source
62+
Return:
63+
RA (float): Right Ascension of source in degrees
64+
Dec (float): Declination of source in degrees
65+
match (bool): Whether the source_name match with regular expression
66+
"""
67+
m = re.match(
68+
r'[jJ](?P<ra_deg>\d+(\.\d*)?)(?P<dec_sign>[+-pmn])(?P<dec_deg>\d+(\.\d*)?)', source_name)
69+
if m:
70+
sign = (-1)**(m['dec_sign'] in ['-', 'm', 'n'])
71+
ra, dec = float(m['ra_deg']), sign * float(m['dec_deg'])
72+
return ra, dec, m
73+
else:
74+
return np.nan, np.nan, m
75+
5476
class SlowSource:
5577
"""Class to track the time-dependent position of a slow-moving source,
5678
such as a Solar System planet in equatorial coordinates.
@@ -335,7 +357,8 @@ def _get_astrometric(source_name, timestamp, site="_default", planets=None):
335357
336358
Args:
337359
source_name: Planet name; in capitalized format, e.g. "Jupiter",
338-
or fixed source specification.
360+
or fixed source specification with a format 'Jxxx[+-pmn]yyy',
361+
where xxx and yyy are decimal numbers of RA, Dec in degrees.
339362
timestamp: unix timestamp.
340363
site (str or so3g.proj.EarthlySite): if this is a string, the
341364
site will be looked up in so3g.proj.SITES dict.
@@ -380,10 +403,15 @@ def _get_astrometric(source_name, timestamp, site="_default", planets=None):
380403
except (ValueError, KeyError):
381404
pass
382405
else:
383-
options = list(planets.names().values())
384-
raise ValueError(
385-
f'Failed to find a match for "{source_name}" in ephemeris: {options}'
386-
)
406+
ra, dec, m = match_fixed_source(source_name)
407+
if m:
408+
# convert from degrees to hours
409+
target = skyfield_api.Star(ra_hours=ra/15., dec_degrees=dec)
410+
else:
411+
options = list(planets.names().values())
412+
raise ValueError(
413+
f'Failed to find a match for "{source_name}" in ephemeris: {options}'
414+
)
387415

388416
if isinstance(site, str):
389417
site = so3g.proj.SITES[site]
@@ -426,14 +454,10 @@ def get_source_pos(source_name, timestamp, site='_default'):
426454
427455
"""
428456
# Check against fixed-position template...
429-
m = re.match(
430-
r'[jJ](?P<ra_deg>\d+(\.\d*)?)(?P<dec_sign>[+-pmn])(?P<dec_deg>\d+(\.\d*)?)', source_name)
457+
ra, dec, m = match_fixed_source(source_name)
431458
if m:
432-
sign = (-1)**(m['dec_sign'] in ['-', 'm', 'n'])
433-
ra, dec = float(m['ra_deg']) * \
434-
coords.DEG, sign * float(m['dec_deg']) * coords.DEG
435-
return ra, dec, float('inf')
436-
459+
return ra * coords.DEG, dec * coords.DEG, float('inf')
460+
437461
# Derive from skyfield astrometric object
438462
planets, amet0 = _get_astrometric(source_name, timestamp, site)
439463
ra, dec, distance = amet0.radec()

tests/test_coords.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,15 @@ def test_source_pos_fixed(self):
236236
self.assertEqual(pos1[0], pos2[0])
237237
self.assertEqual(pos1[1], pos2[1])
238238

239-
# This doesn't work but it probably should...
240-
#coords.planets.get_source_azel("J1000-1000", t)
241-
239+
pos1 = coords.planets.get_source_azel("J1000+1000", t)
240+
pos2 = coords.planets.get_source_azel("j1000p1000", t)
241+
self.assertEqual(pos1[0], pos2[0])
242+
self.assertEqual(pos1[1], pos2[1])
243+
244+
pos1 = coords.planets.get_source_azel("J1000-1000", t)
245+
pos2 = coords.planets.get_source_azel("j1000m1000", t)
246+
self.assertEqual(pos1[0], pos2[0])
247+
self.assertEqual(pos1[1], pos2[1])
242248

243249
class OpticsTest(unittest.TestCase):
244250
def test_sat_fp(self):

0 commit comments

Comments
 (0)