Source code for sofia_redux.spectroscopy.readspec

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

from astropy import log
import numpy as np
from sofia_redux.toolkit.utilities.fits import gethdul
from sofia_redux.toolkit.utilities.func import setnumber, valid_num

__all__ = ['readspec']


[docs] def readspec(filename): """ Reads a SpeX spectral FITS image Parameters ---------- filename : str File path to FITS file Returns ------- dict """ hdul = gethdul(filename, verbose=True) if hdul is None: return data = hdul[0].data header = hdul[0].header if data is None: log.error('Unexpected data format: first HDU has no data.') return result = {'orders': np.array(str(header.get('ORDERS')).split(','))} if all([x.isdigit() for x in result['orders']]): result['orders'] = result['orders'].astype(int) result['norders'] = setnumber(header.get('NORDERS'), default=1, minval=1) result['naps'] = setnumber(header.get('NAPS'), default=1, minval=1) result['instr'] = header.get('INSTR') result['obsmode'] = ''.join(str(header.get('MODENAME')).split()) result['rp'] = setnumber(header.get('RP'), default=2000, dtype=float) result['start'] = setnumber(header.get('START'), default=0) result['stop'] = setnumber(header.get('STOP'), default=0) result['slith_pix'] = header.get('SLTH_PIX') result['slith_arc'] = header.get('SLTH_ARC') result['slitw_pix'] = header.get('SLTW_PIX') result['slitw_arc'] = header.get('SLTW_ARC') result['airmass'] = header.get('AIRMASS') result['xunits'] = str(header.get('XUNITS')).strip() result['yunits'] = str(header.get('YUNITS')).strip() result['runits'] = str(header.get('RAWUNITS')).strip() result['xtitle'] = str(header.get('XTITLE', '!7k!5 (%s)' % result['xunits'])).strip() result['ytitle'] = str(header.get('YTITLE', '!5f (%s)' % result['yunits'])).strip() bgr = str(header.get('BGR')).split(';') obg = [] for bg in bgr: ob = [] for b in bg.split(','): ob.append([float(x) if valid_num(x) else np.nan for x in b.split('-')]) obg.append(ob) result['bgr'] = np.array(obg) appos = np.full((result['norders'], result['naps']), np.nan) aprad = np.full((result['norders'], result['naps']), np.nan) psfrad = np.full((result['norders'], result['naps']), np.nan) shape = list(data.shape) if len(shape) == 3: shape = shape[1:] spectra = np.full( (result['norders'], result['naps'], *shape), np.nan) for j in range(result['norders']): onum = str(result['orders'][j]).zfill(2) p = ''.join(str(header.get('APPOSO' + onum)).split()).split(',') r = ''.join(str(header.get('APRADO' + onum)).split()).split(',') f = ''.join(str(header.get('PSFRAD' + onum)).split()).split(',') msg = "Mismatch: data size, number of apertures, " \ "and number of orders" try: appos[j] = np.array([float(x) if valid_num(x) else np.nan for x in p]) aprad[j] = np.array([float(x) if valid_num(x) else np.nan for x in r]) psfrad[j] = np.array([float(x) if valid_num(x) else np.nan for x in f]) except (KeyError, ValueError): log.error(msg) raise ValueError(msg) from None for k in range(result['naps']): ns = (j * result['naps']) + k if data.ndim == 3 and ns < data.shape[0]: spectra[j, k] = data[ns] elif j != 0 or k != 0: log.error(msg) raise ValueError(msg) elif data.ndim == 2: spectra[j, k] = data else: msg = "Invalid data shape." log.error(msg) raise ValueError(msg) result['appos'] = appos result['aprad'] = aprad result['psfrad'] = psfrad result['spectra'] = spectra result['header'] = header return result