class SOURCE(KeyCollection): """`KeyCollection` for the `Source` class. Attributes ---------- NAME : STRING BIBCODE : STRING URL : STRING ACKNOWLEDGMENT : STRING REFERENCE : STRING ALIAS : NUMERIC Numerical alias (shorthand) for this entry. Saved as a string (or list of strings), despite being stored as an integer. SECONDARY : BOOL Whether the given source is one which collected data from another, 'Primary'-source, from which it actually originated """ # Strings NAME = Key('name', KEY_TYPES.STRING) BIBCODE = Key('bibcode', KEY_TYPES.STRING) ARXIVID = Key('arxivid', KEY_TYPES.STRING) DOI = Key('doi', KEY_TYPES.STRING) URL = Key('url', KEY_TYPES.STRING, compare=False) ACKNOWLEDGMENT = Key('acknowledgment', KEY_TYPES.STRING, compare=False) REFERENCE = Key('reference', KEY_TYPES.STRING, compare=False) # Numbers ALIAS = Key('alias', KEY_TYPES.NUMERIC, compare=False) # Booleans SECONDARY = Key('secondary', KEY_TYPES.BOOL, compare=False) PRIVATE = Key('private', KEY_TYPES.BOOL, compare=False)
class MODEL(KeyCollection): # Strings SOURCE = Key('source', KEY_TYPES.STRING, compare=False) CODE = Key('code', KEY_TYPES.STRING) NAME = Key('name', KEY_TYPES.STRING) VERSION = Key('version', KEY_TYPES.STRING) DATE = Key('date', KEY_TYPES.STRING) DESC = Key('description', KEY_TYPES.STRING, compare=False) # Numbers ALIAS = Key('alias', KEY_TYPES.NUMERIC, compare=False) # Arrays REALIZATIONS = Key('realizations', compare=False) SETUP = Key('setup', compare=False)
class CORRELATION(KeyCollection): """`KeyCollection` subclass for the the `Correlation` class. Attributes ---------- VALUE : ANY The actual value being stored. KIND : STRING """ # Any VALUE = Key('value', priority=10) # Numeric # Booleans DERIVED = Key('derived', KEY_TYPES.BOOL) # Strings KIND = Key('kind', KEY_TYPES.STRING, listable=True) QUANTITY = Key('quantity', KEY_TYPES.STRING)
class CATACLYSMIC(ENTRY): """Cataclysmic `Key` child class.""" CLAIMED_TYPE = Key('claimedtype', KEY_TYPES.STRING, kind_preference=['spectroscopic', 'photometric'], replace_better=True) DISCOVERY_DATE = Key('discoverdate', KEY_TYPES.STRING) EXPLOSION_DATE = Key('explosiondate', KEY_TYPES.STRING) MAX_VISUAL_ABS_MAG = Key('maxvisualabsmag', KEY_TYPES.NUMERIC) MAX_VISUAL_APP_MAG = Key('maxappmag', KEY_TYPES.NUMERIC) MAX_VISUAL_BAND = Key('maxvisualband', KEY_TYPES.STRING) MAX_VISUAL_DATE = Key('maxvisualdate', KEY_TYPES.STRING, replace_better=True) VISUAL_MAG = Key('visualmag', KEY_TYPES.NUMERIC) ERRORS = Key('errors')
class ERROR(KeyCollection): # Any VALUE = Key('value') EXTRA = Key('extra') # Numeric ERROR = Key('error', KEY_TYPES.NUMERIC) # Booleans UPPER_LIMIT = Key('upperlimit', KEY_TYPES.BOOL) # Strings UNIT = Key('unit', KEY_TYPES.STRING) KIND = Key('kind', KEY_TYPES.STRING) SOURCE = Key('source', KEY_TYPES.STRING) SOURCE_KIND = Key('sourcekind', KEY_TYPES.STRING)
class SUPERNOVA(ENTRY): CLAIMED_TYPE = Key('claimedtype', KEY_TYPES.STRING, kind_preference=['spectroscopic', 'photometric'], replace_better=True) DISCOVERY_DATE = Key('discoverdate', KEY_TYPES.STRING) EXPLOSION_DATE = Key('explosiondate', KEY_TYPES.STRING) MAX_VISUAL_ABS_MAG = Key('maxvisualabsmag', KEY_TYPES.NUMERIC) MAX_VISUAL_APP_MAG = Key('maxvisualappmag', KEY_TYPES.NUMERIC) MAX_VISUAL_BAND = Key('maxvisualband', KEY_TYPES.STRING) MAX_VISUAL_DATE = Key('maxvisualdate', KEY_TYPES.STRING, replace_better=True) ERRORS = Key('errors')
class PHOTOMETRY(KeyCollection): """Keys for the `Photometry` class.""" TIME = Key('time', KEY_TYPES.TIME, listable=True, priority=10) MAGNITUDE = Key('magnitude', KEY_TYPES.NUMERIC, priority=9) FLUX = Key('flux', KEY_TYPES.NUMERIC) FLUX_DENSITY = Key('fluxdensity', KEY_TYPES.NUMERIC) COUNT_RATE = Key('countrate', KEY_TYPES.NUMERIC) LUMINOSITY = Key('luminosity', KEY_TYPES.NUMERIC) ZERO_POINT = Key('zeropoint', KEY_TYPES.NUMERIC) UPPER_LIMIT_SIGMA = Key('upperlimitsigma', KEY_TYPES.NUMERIC) ENERGY = Key('energy', KEY_TYPES.NUMERIC, listable=True) FREQUENCY = Key('frequency', KEY_TYPES.NUMERIC, listable=True) WAVELENGTH = Key('wavelength', KEY_TYPES.NUMERIC, listable=True) NHMW = Key('nhmw', KEY_TYPES.NUMERIC) PHOTON_INDEX = Key('photonindex', KEY_TYPES.NUMERIC) UNABSORBED_FLUX = Key('unabsorbedflux', KEY_TYPES.NUMERIC) EXPOSURE_TIME = Key('exposuretime', KEY_TYPES.NUMERIC) OFF_AXIS_ANGLE = Key('offaxisangle', KEY_TYPES.NUMERIC) EXTRACTION_RADIUS = Key('extractionradius', KEY_TYPES.NUMERIC) E_COUNT_RATE = Key('e_countrate', KEY_TYPES.NUMERIC) E_FLUX = Key('e_flux', KEY_TYPES.NUMERIC) E_FLUX_DENSITY = Key('e_fluxdensity', KEY_TYPES.NUMERIC) E_LUMINOSITY = Key('e_luminosity', KEY_TYPES.NUMERIC) E_MAGNITUDE = Key('e_magnitude', KEY_TYPES.NUMERIC, priority=7) E_TIME = Key('e_time', KEY_TYPES.NUMERIC) E_UNABSORBED_FLUX = Key('e_unabsorbedflux', KEY_TYPES.NUMERIC) E_LOWER_UNABSORBED_FLUX = Key('e_lower_unabsorbedflux', KEY_TYPES.NUMERIC) E_UPPER_UNABSORBED_FLUX = Key('e_upper_unabsorbedflux', KEY_TYPES.NUMERIC) E_LOWER_COUNT_RATE = Key('e_lower_countrate', KEY_TYPES.NUMERIC) E_UPPER_COUNT_RATE = Key('e_upper_countrate', KEY_TYPES.NUMERIC) E_LOWER_MAGNITUDE = Key('e_lower_magnitude', KEY_TYPES.NUMERIC) E_UPPER_MAGNITUDE = Key('e_upper_magnitude', KEY_TYPES.NUMERIC) E_LOWER_FLUX = Key('e_lower_flux', KEY_TYPES.NUMERIC) E_UPPER_FLUX_DENSITY = Key('e_upper_fluxdensity', KEY_TYPES.NUMERIC) E_LOWER_FLUX_DENSITY = Key('e_lower_fluxdensity', KEY_TYPES.NUMERIC) E_UPPER_FLUX = Key('e_upper_flux', KEY_TYPES.NUMERIC) E_LOWER_LUMINOSITY = Key('e_lower_luminosity', KEY_TYPES.NUMERIC) E_UPPER_LUMINOSITY = Key('e_upper_luminosity', KEY_TYPES.NUMERIC) E_LOWER_TIME = Key('e_lower_time', KEY_TYPES.NUMERIC) E_UPPER_TIME = Key('e_upper_time', KEY_TYPES.NUMERIC) MODEL = Key('model', KEY_TYPES.STRING, compare=False) REALIZATION = Key('realization', KEY_TYPES.STRING, priority=15) SOURCE = Key('source', KEY_TYPES.STRING, compare=False) TELESCOPE = Key('telescope', KEY_TYPES.STRING, compare=False) INSTRUMENT = Key('instrument', KEY_TYPES.STRING, compare=False) MODE = Key('mode', KEY_TYPES.STRING, compare=False) BAND = Key('band', KEY_TYPES.STRING, priority=8) OBSERVATORY = Key('observatory', KEY_TYPES.STRING, compare=False) OBSERVER = Key('observer', KEY_TYPES.STRING, compare=False) SURVEY = Key('survey', KEY_TYPES.STRING, compare=False) BAND_SET = Key('bandset', KEY_TYPES.STRING) SYSTEM = Key('system', KEY_TYPES.STRING) DESCRIPTION = Key('description', KEY_TYPES.STRING, compare=False) U_COUNT_RATE = Key('u_countrate', KEY_TYPES.STRING) U_TIME = Key('u_time', KEY_TYPES.STRING) U_FLUX = Key('u_flux', KEY_TYPES.STRING) U_FLUX_DENSITY = Key('u_fluxdensity', KEY_TYPES.STRING) U_FREQUENCY = Key('u_frequency', KEY_TYPES.STRING) U_WAVELENGTH = Key('u_wavelength', KEY_TYPES.STRING) U_ENERGY = Key('u_energy', KEY_TYPES.STRING) U_LUMINOSITY = Key('u_luminosity', KEY_TYPES.STRING) U_EXPOSURE_TIME = Key('u_exposuretime', KEY_TYPES.STRING) U_OFF_AXIS_ANGLE = Key('u_offaxisangle', KEY_TYPES.STRING) U_EXTRACTION_RADIUS = Key('u_extractionradius', KEY_TYPES.STRING) SCORRECTED = Key('scorrected', KEY_TYPES.BOOL) KCORRECTED = Key('kcorrected', KEY_TYPES.BOOL) MCORRECTED = Key('mcorrected', KEY_TYPES.BOOL) SYNTHETIC = Key('synthetic', KEY_TYPES.BOOL) SIMULATED = Key('simulated', KEY_TYPES.BOOL) UPPER_LIMIT = Key('upperlimit', KEY_TYPES.BOOL, priority=6) LOWER_LIMIT = Key('lowerlimit', KEY_TYPES.BOOL) HOST = Key('host', KEY_TYPES.BOOL) INCLUDES_HOST = Key('includeshost', KEY_TYPES.BOOL) REST_FRAME = Key('restframe', KEY_TYPES.BOOL) HOST_NH_CORR = Key('hostnhcorr', KEY_TYPES.BOOL)
class SPECTRUM(KeyCollection): """Collection of attributes for the `Spectrum` class.""" # Arrays DATA = Key('data', compare=False) ERRORS = Key('errors', compare=False) EXCLUDE = Key('exclude', compare=False) WAVELENGTHS = Key('wavelengths', compare=False) FLUXES = Key('fluxes', compare=False) # Numbers E_LOWER_TIME = Key('e_lower_time', KEY_TYPES.NUMERIC, compare=False) E_TIME = Key('e_time', KEY_TYPES.NUMERIC, compare=False) E_UPPER_TIME = Key('e_upper_time', KEY_TYPES.NUMERIC, compare=False) SNR = Key('snr', KEY_TYPES.NUMERIC, compare=False) TIME = Key('time', KEY_TYPES.NUMERIC, compare=False, listable=True) REDSHIFT = Key('redshift', KEY_TYPES.NUMERIC, compare=False) AIRMASS = Key('airmass', KEY_TYPES.NUMERIC, compare=False) FILENAME = Key('filename', KEY_TYPES.STRING) U_FLUXES = Key('u_fluxes', KEY_TYPES.STRING, compare=False) U_ERRORS = Key('u_errors', KEY_TYPES.STRING, compare=False) INSTRUMENT = Key('instrument', KEY_TYPES.STRING, compare=False) OBSERVATORY = Key('observatory', KEY_TYPES.STRING, compare=False) OBSERVER = Key('observer', KEY_TYPES.STRING, compare=False) MODEL = Key('model', KEY_TYPES.STRING, compare=False) REALIZATION = Key('realization', KEY_TYPES.STRING, priority=15) SOURCE = Key('source', KEY_TYPES.STRING, compare=False) REDUCER = Key('reducer', KEY_TYPES.STRING, compare=False) REDUCTION = Key('reduction', KEY_TYPES.STRING, compare=False) SURVEY = Key('survey', KEY_TYPES.STRING, compare=False) TELESCOPE = Key('telescope', KEY_TYPES.STRING, compare=False) U_TIME = Key('u_time', KEY_TYPES.STRING, compare=False) U_WAVELENGTHS = Key('u_wavelengths', KEY_TYPES.STRING, compare=False) # Booleans DEREDDENED = Key('dereddened', KEY_TYPES.BOOL, compare=False) DEREDSHIFTED = Key('deredshifted', KEY_TYPES.BOOL, compare=False) HOST = Key('host', KEY_TYPES.BOOL, compare=False) INCLUDES_HOST = Key('includeshost', KEY_TYPES.BOOL, compare=False) VACUUM_WAVELENGTHS = Key('vacuumwavelengths', KEY_TYPES.BOOL, compare=False)
class ENTRY(KeyCollection): """General `CatDict` keys which should be relevant for all catalogs.""" # Constants for use in key definitions _DIST_PREF_KINDS = [ 'heliocentric', 'cmb', 'spectroscopic', 'photometric', 'host', 'cluster' ] _HOST_DIST_PREF_KINDS = [ 'heliocentric', 'cmb', 'spectroscopic', 'photometric', 'host', 'cluster' ] # List of keys ALIAS = Key('alias', KEY_TYPES.STRING) COMOVING_DIST = Key('comovingdist', KEY_TYPES.NUMERIC, kind_preference=_DIST_PREF_KINDS, replace_better=True) DEC = Key('dec', KEY_TYPES.STRING) DISCOVER_DATE = Key('discoverdate', KEY_TYPES.STRING, replace_better=True) DISCOVERER = Key('discoverer', KEY_TYPES.STRING) DISTINCT_FROM = Key('distinctfrom', KEY_TYPES.STRING) EBV = Key('ebv', KEY_TYPES.NUMERIC, replace_better=True) AV_CIRCUM = Key('avcircum', KEY_TYPES.NUMERIC, replace_better=True) ERRORS = Key('errors', no_source=True) HOST = Key('host', KEY_TYPES.STRING) HOST_DEC = Key('hostdec', KEY_TYPES.STRING) HOST_OFFSET_ANG = Key('hostoffsetang', KEY_TYPES.NUMERIC) HOST_OFFSET_DIST = Key('hostoffsetdist', KEY_TYPES.NUMERIC) HOST_RA = Key('hostra', KEY_TYPES.STRING) HOST_REDSHIFT = Key('hostredshift', KEY_TYPES.NUMERIC, kind_preference=_HOST_DIST_PREF_KINDS, replace_better=True) HOST_VELOCITY = Key('hostvelocity', KEY_TYPES.NUMERIC, kind_preference=_HOST_DIST_PREF_KINDS, replace_better=True) HOST_LUM_DIST = Key('hostlumdist', KEY_TYPES.NUMERIC, kind_preference=_HOST_DIST_PREF_KINDS, replace_better=True) HOST_COMOVING_DIST = Key('hostcomovingdist', KEY_TYPES.NUMERIC, kind_preference=_HOST_DIST_PREF_KINDS, replace_better=True) LUM_DIST = Key('lumdist', KEY_TYPES.NUMERIC, kind_preference=_DIST_PREF_KINDS, replace_better=True) MAX_ABS_MAG = Key('maxabsmag', KEY_TYPES.NUMERIC) MAX_APP_MAG = Key('maxappmag', KEY_TYPES.NUMERIC) MAX_BAND = Key('maxband', KEY_TYPES.STRING) MAX_DATE = Key('maxdate', KEY_TYPES.STRING, replace_better=True) MODELS = Key('models') NAME = Key('name', KEY_TYPES.STRING, no_source=True) PHOTOMETRY = Key('photometry') RA = Key('ra', KEY_TYPES.STRING) REDSHIFT = Key('redshift', KEY_TYPES.NUMERIC, kind_preference=_DIST_PREF_KINDS, replace_better=True) SCHEMA = Key('schema', no_source=True) SOURCES = Key('sources', no_source=True) SPECTRA = Key('spectra') VELOCITY = Key('velocity', KEY_TYPES.NUMERIC, kind_preference=_DIST_PREF_KINDS, replace_better=True)
def __init__(self, parent, key=None, **kwargs): """Initialize `CatDict`.""" super(CatDict, self).__init__() # Store the parent object (an `Entry` subclass) to which this instance # will belong. e.g. a `Supernova` entry. self._parent = parent self._key = key self._log = parent.catalog.log # Store any individual keys which are required self._req_keys = [] for rks in self._REQ_KEY_SETS: # If this set is only 1 long, that key is individually required if len(rks) == 1: self._req_keys.append(rks[0]) # Iterate over all `_KEYS` parameters, load each if given note that the # stored 'values' are the `Key` objects, referred to here with the name # 'key'. vals = self._KEYS.vals() for key in kwargs.copy(): # If we allow unknown keys, or key is in list of known keys, # process and store it. kiv = key in vals if self._ALLOW_UNKNOWN_KEYS or kiv: # Load associated Key object if it exists, otherwise construct # a default Key object. if kiv: key_obj = vals[vals.index(key)] else: self._log.info('[{}] `{}` not in list of keys for `{}`, ' 'adding anyway as allow unknown keys is ' '`{}`.'.format(parent[parent._KEYS.NAME], key, type(self).__name__, self._ALLOW_UNKNOWN_KEYS)) key_obj = Key(key) # Handle Special Cases # -------------------- # Only keep booleans and strings if they evaluate true. if ((key_obj.type == KEY_TYPES.BOOL or key_obj.type == KEY_TYPES.STRING) and not kwargs[key]): del kwargs[key] continue # Make sure value is compatible with the 'Key' specification. check_fail = False if not key_obj.check(kwargs[key]): check_fail = True self._log.info("Value for '{}' is invalid " "'{}':'{}'".format(key_obj.pretty(), key, kwargs[key])) # Have the parent log a warning if this is a required key if key in self._req_keys: raise CatDictError( "Value for required key '{}' is invalid " "'{}:{}'".format(key_obj.pretty(), key, kwargs[key]), warn=True) # Check and store values # ---------------------- # Remove key-value pair from `kwargs` dictionary. value = kwargs.pop(key) value = self._clean_value_for_key(key_obj, value) # only store values that are not empty if value and not check_fail: self[key] = value # If we require all parameters to be a key in `PHOTOMETRY`, then all # elements should have been removed from `kwargs`. if not self._ALLOW_UNKNOWN_KEYS and len(kwargs): raise CatDictError( "All permitted keys stored, remaining: '{}'".format(kwargs)) # Make sure that currently stored values are valid self._check() return
class MODEL(KeyCollection): """Collection of keys for models.""" # Strings SOURCE = Key('source', KEY_TYPES.STRING, compare=False) CODE = Key('code', KEY_TYPES.STRING) NAME = Key('name', KEY_TYPES.STRING) VERSION = Key('version', KEY_TYPES.STRING) DATE = Key('date', KEY_TYPES.STRING) DESCRIPTION = Key('description', KEY_TYPES.STRING, compare=False) # Numbers ALIAS = Key('alias', KEY_TYPES.NUMERIC, compare=False) STEPS = Key('steps', KEY_TYPES.NUMERIC, compare=False) # Arrays/dictionaries CONVERGENCE = Key('convergence', compare=False) REALIZATIONS = Key('realizations', compare=False) SCORE = Key('score', compare=False) SETUP = Key('setup', compare=False)
class FASTSTARS(ENTRY): """FastStars `Key` child class.""" DISCOVER_DATE = Key('discoverdate', KEY_TYPES.STRING) DISCOVERER = Key('discoverer', KEY_TYPES.STRING) PROPER_MOTION_RA = Key('propermotionra', KEY_TYPES.NUMERIC) PROPER_MOTION_DEC = Key('propermotiondec', KEY_TYPES.NUMERIC) PARALLAX = Key('parallax', KEY_TYPES.NUMERIC) MASS = Key('mass', KEY_TYPES.NUMERIC) LOGG = Key('logg', KEY_TYPES.NUMERIC) TEFF = Key('teff', KEY_TYPES.NUMERIC) SPECTRAL_TYPE = Key('spectraltype',KEY_TYPES.STRING) STELLAR_CLASS = Key('stellarclass',KEY_TYPES.STRING) BOUND_PROBABILITY = Key('boundprobability',KEY_TYPES.NUMERIC) VELOCITY = Key('velocity',KEY_TYPES.NUMERIC) ERRORS = Key('errors') LUM_DIST = Key('lumdist',KEY_TYPES.NUMERIC,replace_better=True) DISTANCE_PRIOR_LENGTH_SCALE = Key('distancepriorlengthscale',KEY_TYPES.NUMERIC)
class QUANTITY(KeyCollection): """`KeyCollection` subclass for the the `Quantity` class. Attributes ---------- VALUE : ANY The actual value being stored. E_VALUE : NUMERIC The 'error' (uncertainty) associate with the measured value. E_LOWER_VALUE : NUMERIC The 'error' (uncertainty) in the lower (more negative) direction. E_UPPER_VALUE : NUMERIC The 'error' (uncertainty) in the upper (more positive) direction. PROB : NUMERIC UPPER_LIMIT : BOOL If this value corresponds to a measured upper-limit. DESCRIPTION : STRING Verbal description or notes on a quantity. U_VALUE : STRING Unit of measurement associated with this value. U_E_VALUE : STRING Unit of measurement associated with the error in the value (if different from value). KIND : STRING SOURCE : STRING The alias number(s) of the 'source(s)' (reference) for this value. NOTE: while source-aliases are integers referring to the actual source-entries, this entry is stored as a *single* string, where numerous souces are stored as a single, comma-separated string. e.g. ``Entry[QUANTITY.SOURCE] = '1, 4, 5'``. """ # Any VALUE = Key('value', priority=10) CORRELATIONS = Key('correlations') # Numeric E_VALUE = Key('e_value', KEY_TYPES.NUMERIC) E_LOWER_VALUE = Key('e_lower_value', KEY_TYPES.NUMERIC) E_UPPER_VALUE = Key('e_upper_value', KEY_TYPES.NUMERIC) PROB = Key('probability', KEY_TYPES.NUMERIC) # Booleans UPPER_LIMIT = Key('upperlimit', KEY_TYPES.BOOL) LOWER_LIMIT = Key('lowerlimit', KEY_TYPES.BOOL) DERIVED = Key('derived', KEY_TYPES.BOOL) # Strings DESCRIPTION = Key('description', KEY_TYPES.STRING, compare=False) U_VALUE = Key('u_value', KEY_TYPES.STRING) U_E_VALUE = Key('u_e_value', KEY_TYPES.STRING) KIND = Key('kind', KEY_TYPES.STRING, listable=True) SOURCE = Key('source', KEY_TYPES.STRING, compare=False) MODEL = Key('model', KEY_TYPES.STRING, compare=False) REALIZATION = Key('realization', KEY_TYPES.STRING)
class REALIZATION(KeyCollection): SCORE = Key('score', KEY_TYPES.NUMERIC) PARAMETERS = Key('parameters', KEY_TYPES.DICT)
class REALIZATION(KeyCollection): SCORE = Key('score', KEY_TYPES.NUMERIC) WEIGHT = Key('weight', KEY_TYPES.NUMERIC) PARAMETERS = Key('parameters', KEY_TYPES.DICT) ALIAS = Key('alias', KEY_TYPES.STRING)