Source code for potpyri.utils.utilities

"""General utilities for catalogs, coordinates, and numeric parsing.

Used by absolute photometry and other steps that need Vizier catalog IDs
or coordinate handling.
"""
from astropy import units as u
from astropy.coordinates import SkyCoord
import warnings
import csv
import sys
csv.field_size_limit(sys.maxsize)

warnings.filterwarnings('ignore')

viziercat = {
    'sdssdr12': {'name':'V/147',
        'columns': ['RA_ICRS', 'DE_ICRS','class','umag', 'e_umag',
            'gmag','e_gmag', 'rmag','e_rmag', 'imag','i_mag', 'zmag',
            'e_zmag', 'zph']
    },
    '2mass': {'name':'II/246',
        'columns':['RAJ2000', 'DEJ2000', 'Jmag','e_Jmag','Hmag','e_Hmag',
            'Kmag', 'e_Kmag']
    },
    'unwise': {'name':'II/363',
        'columns': ['RAJ2000', 'DEJ2000', 'FW1','e_FW1', 'FW2','e_FW2']
    },
    'glade': {'name':'VII/281',
        'columns': ['RAJ2000', 'DEJ2000', 'Dist', 'e_Dist', 'Bmag', 'Jmag',
            'Hmag', 'Kmag', 'z']
    },
    'des': {'name':'II/357',
        'columns': ['RAJ2000', 'DEJ2000', 'S/Gg', 'S/Gr', 'S/Gi', 'S/Gz',
            'gmag','e_gmag', 'rmag','e_rmag', 'imag','e_imag', 'zmag','e_zmag']
    },
    'skymapper': {'name': 'II/379/smssdr4',
        'columns': ['RAICRS', 'DEICRS', 'uPSF', 'e_uPSF', 'gPSF', 'e_gPSF',
            'rPSF', 'e_rPSF','iPSF', 'e_iPSF','zPSF', 'e_zPSF']
    },
}

[docs] def find_catalog(catalog, fil, coord_ra, coord_dec): """Return Vizier catalog ID and column names for the given catalog and filter. Supports SDSS, 2MASS, UKIRT, PS1, SKYMAPPER. For southern u-band, uses SkyMapper automatically. Parameters ---------- catalog : str Catalog name (e.g. 'PS1', 'SDSS', '2MASS'). fil : str Filter band (e.g. 'r', 'g', 'J'). coord_ra : float Right ascension (used for catalog selection). coord_dec : float Declination (used for catalog selection; <0 can trigger SkyMapper for u-band). Returns ------- tuple (catalog, catalog_ID, ra_col, dec_col, mag_col, err_col) for use in Vizier queries. catalog_ID/ra/dec/mag/err may be None if filter not supported. """ catalog_ID, ra, dec, mag, err = None, None, None, None, None # If declination is less than 0 and filter is u-band, use SkyMapper if coord_dec < 0 and fil.lower()=='u': catalog = 'skymapper' # If these catalogs are to be updated in the future, select mag columns that correspond to the # PSF mags. if catalog.upper() == 'SDSS': if fil.lower() not in ['u','g','r','i','z']: return(catalog, catalog_ID, ra, dec, mag, err) catalog_ID, ra, dec, mag, err = 'V/154', 'RA_ICRS', 'DE_ICRS', fil.lower()+'mag', 'e_'+fil.lower()+'mag' elif catalog.upper() == '2MASS': # K, Ks, Kspec all use 2MASS K-band columns (Kmag, e_Kmag) fil_2mass = fil.upper() if fil_2mass in ('KS', 'KSPEC'): fil_2mass = 'K' if fil_2mass not in ['J', 'H', 'K']: return(catalog, catalog_ID, ra, dec, mag, err) catalog_ID, ra, dec, mag, err = 'II/246', 'RAJ2000', 'DEJ2000', fil_2mass+'mag', 'e_'+fil_2mass+'mag' elif catalog.upper() == 'UKIRT': if fil.upper() not in ['Y','J','H','K']: return(catalog, catalog_ID, ra, dec, mag, err) catalog_ID, ra, dec, mag, err = 'II/319', 'ra', 'dec', fil.upper() + 'mag', 'e_'+fil.upper()+'mag' elif catalog.upper() == 'PS1': if fil.lower() not in ['g','r','i','z','y']: return(catalog, catalog_ID, ra, dec, mag, err) catalog_ID, ra, dec, mag, err = 'II/349', 'RAJ2000', 'DEJ2000', fil.lower()+'mag', 'e_'+fil.lower()+'mag' elif catalog.upper() == 'SKYMAPPER': if fil.lower() not in ['u','v','g','r','i','z']: return(catalog, catalog_ID, ra, dec, mag, err) catalog_ID, ra, dec, mag, err = 'II/379/smssdr4', 'RAICRS', 'DEICRS', fil.lower()+'PSF', 'e_'+fil.lower()+'PSF' return(catalog, catalog_ID, ra, dec, mag, err)
[docs] def is_number(num): """Return True if the value can be interpreted as a number. Parameters ---------- num : str or number Value to test. Returns ------- bool True if float(num) succeeds, False otherwise. """ try: num = float(num) except ValueError: return(False) return(True)
[docs] def parse_coord(ra, dec): """Parse RA and Dec strings into an astropy SkyCoord. Accepts decimal degrees or sexagesimal (e.g. '12:30:00' or '12.5'). Parameters ---------- ra : str or float Right ascension. dec : str or float Declination. Returns ------- SkyCoord or None ICRS coordinate, or None if parsing fails. """ if (not (is_number(ra) and is_number(dec)) and (':' not in ra and ':' not in dec)): error = 'ERROR: cannot interpret: {ra} {dec}' print(error.format(ra=ra, dec=dec)) return(None) if (':' in str(ra) and ':' in str(dec)): # Input RA/DEC are sexagesimal unit = (u.hourangle, u.deg) else: unit = (u.deg, u.deg) try: coord = SkyCoord(ra, dec, frame='icrs', unit=unit) return(coord) except ValueError: error = 'ERROR: Cannot parse coordinates: {ra} {dec}' print(error.format(ra=ra,dec=dec)) return(None)