Source code for sofia_redux.instruments.forcast.getpar

# Licensed under a 3-clause BSD style license - see LICENSE.rst

from astropy import log
from astropy.io import fits

import sofia_redux.instruments.forcast.configuration as dripconfig

configuration = None

__all__ = ['getpar']


[docs] def getpar(header, parname, writename=None, dtype=None, comment=None, update_header=True, default=None, dripconf=True, warn=False): """ Get a header or configuration parameter Looks up a parameter from the DRIP configuration or the provided header. Values in the configuration file take precedence over values in the header. This function converts all parameters to string values before returning them. If a parameter cannot be found in either the configuration file or the header, then None will be returned. Any string values enclosed within single quotes will have those outer quotes removed. Parameters ---------- header : astropy.io.fits.header.Header Input header parname : str Parameter name writename : str If set, the parameter to be returned will be added or modified in the header update_header : bool Will update the header if True comment : str Comment to write to the header along with the parameter dtype : type Attempt to convert the value to a float or int type. Failure will return zero of either type. default Value to return if not found. Note that an attempt will be made to convert default to type `dtype` if `dtype` is supplied. dripconf : bool, optional Indicates whether configuration values can overwrite header keyword values. warn : bool, optional Sends a message to logger at warning level if the default value is used. Returns ------- String or None if from the configuration. Otherwise it could be anything, or set it yourself via dtype. """ def bad_exit(): dout = default if dtype is not None: try: dout = dtype(default) except (ValueError, TypeError): dout = default if warn: log.warning("%s not found - default is %s" % (parname, dout)) return dout if not isinstance(parname, str): log.error('invalid parname: %s (%s)' % (parname, type(parname))) return bad_exit() if header is None: header = fits.header.Header() if not isinstance(header, fits.header.Header): log.error('invalid header type (%s)' % type(header)) return bad_exit() if not dripconf: config_val = {} else: if dripconfig.configuration is None: dripconfig.load() global configuration configuration = dripconfig.configuration config_val = configuration key = parname.strip().upper() for ckey in config_val.keys(): if ckey.strip().upper() == key: value = config_val[ckey] from_header = False break else: value = header.get(key[:8]) from_header = True # DETCHAN weirdness fixed here if key == 'DETCHAN': if str(value).strip().upper() in ['1', 'LW']: new_value = 'LW' else: new_value = 'SW' if new_value != value: value = new_value from_header = False if value is None: return bad_exit() elif isinstance(value, list): value = '[%s]' % ','.join([str(v) for v in value]) # convert to dtype before updating header if dtype is not None: try: value = dtype(value) except (ValueError, TypeError): log.warning('Could not convert value to %s' % dtype) value = None header_update = update_header header_update &= (comment is not None) | (not from_header) if header_update and value is not None: setname = writename if isinstance(writename, str) else key setname = setname.strip().upper()[:8] if setname not in header: if 'HISTORY' in header: header.insert('HISTORY', (setname, value, comment)) else: header[setname] = value, comment else: if comment is None: update_comment = header.comments[setname] else: update_comment = comment header[setname] = value, update_comment return value