""" Module for parsing astronomical object names to extract embedded coordinates eg: '2MASS J06495091-0737408' """ import re import numpy as np import astropy.units as u from astropy.coordinates import SkyCoord RA_REGEX = r'()([0-2]\d)([0-5]\d)([0-5]\d)\.?(\d{0,3})' DEC_REGEX = r'([+-])(\d{1,2})([0-5]\d)([0-5]\d)\.?(\d{0,3})' JCOORD_REGEX = '(.*?J)' + RA_REGEX + DEC_REGEX JPARSER = re.compile(JCOORD_REGEX) def _sexagesimal(g): # convert matched regex groups to sexigesimal array sign, h, m, s, frac = g sign = -1 if (sign == '-') else 1 s = '.'.join((s, frac)) return sign * np.array([h, m, s], float) def search(name, raise_=False): """Regex match for coordinates in name""" # extract the coordinate data from name match = JPARSER.search(name) if match is None and raise_: raise ValueError('No coordinate match found!') return match def to_ra_dec_angles(name): """get RA in hourangle and DEC in degrees by parsing name """ groups = search(name, True).groups() prefix, hms, dms = np.split(groups, [1, 6]) ra = (_sexagesimal(hms) / (1, 60, 60 * 60) * u.hourangle).sum() dec = (_sexagesimal(dms) * (u.deg, u.arcmin, u.arcsec)).sum() return ra, dec def to_skycoord(name, frame='icrs'): """Convert to `name` to `SkyCoords` object""" return SkyCoord(*to_ra_dec_angles(name), frame=frame) def shorten(name): """ Produce a shortened version of the full object name using: the prefix (usually the survey name) and RA (hour, minute), DEC (deg, arcmin) parts. e.g.: '2MASS J06495091-0737408' --> '2MASS J0649-0737' Parameters ---------- name : str Full object name with J-coords embedded. Returns ------- shortName: str """ match = search(name) return ''.join(match.group(1, 3, 4, 7, 8, 9))