def readtxt(specfile): """ Reads data from text files into standardized astropy table output. """ if 'youn' in specfile.lower(): data = np.loadtxt(specfile) if data.shape[1] == 3: wmid, f, _ = data.T elif data.shape[1] == 2: wmid, f = data.T else: raise ValueError('crap.') e = 0.0 if 'euv' in specfile: we = np.array([100., 200., 300., 400., 500., 600., 700., 800., 912., 1170.]) else: we = mids2edges(wmid) w0, w1 = we[:-1], we[1:] f = np.interp((w0 + w1) / 2.0, wmid, f) inst = db.getinsti(specfile) spectbl = utils.vecs2spectbl(w0, w1, f, e, instrument=inst, filename=specfile) if 'euv' in specfile: spectbl = utils.evenbin(spectbl, 1.0) return [spectbl] else: raise Exception('A parser for {} files has not been implemented.'.format(specfile[2:9]))
def readsav(specfile): """ Reads data from IDL sav files into standardized astropy table output. """ sav = spreadsav(specfile) if 'mod_lya' in specfile: wmid = sav['w140'] flux = sav['lya_mod'] elif 'sun' in specfile: wmid = sav['wave'].squeeze() * 10 # nm to AA flux = sav['flux'].squeeze() * 100 # W m-2 nm-2 we = mids2edges(wmid, 'left', 'linear-x') w0, w1 = we[:-1], we[1:] N = len(flux) err = np.zeros(N) expt, flags = np.zeros(N), np.zeros(N, 'i1') source = db.getinsti(specfile) * np.ones(N) normfac = np.ones(N) start, end = [np.zeros(N)] * 2 data = [w0, w1, flux, err, expt, flags, source, normfac, start, end] return [__maketbl(data, specfile)]
def readfits(specfile, observatory=None, spectrograph=None): """Read a fits file into standardized table.""" if observatory is None: observatory = db.parse_observatory(specfile) spec = fits.open(specfile) if any([ s in specfile for s in ['coadd', 'custom', 'mod', 'panspec', 'other', 'hlsp'] ]): return [readstdfits(specfile)] elif observatory == 'hst': if spectrograph is None: spectrograph = db.parse_spectrograph(specfile) if spectrograph in ['sts', 'cos']: sd, sh = spec[1].data, spec[1].header flux, err = sd['flux'], sd['error'] wmid, flags = sd['wavelength'], sd['dq'] exptarr, start, end = [ np.ones(flux.shape) * sh[s] for s in ['exptime', 'expstart', 'expend'] ] elif spectrograph == 'fos': template = specfile[:-8] + '{}' + '.fits' hdus = [ fits.open(template.format(ext)) for ext in ['c0f', 'c1f', 'c2f', 'cqf'] ] wmid, flux, err, flags = [h[0].data[:, ::-1] for h in hdus] start, end = [ np.ones(flux.shape) * hdus[0][0].header[s] for s in ['expstart', 'expend'] ] exptarr = np.ones( flux.shape) * hdus[0][1].data['exposure'][:, np.newaxis] else: raise NotImplementedError() shape = flux.shape insti = db.getinsti(specfile) iarr = np.ones(shape) * insti wedges = np.array([mids2edges(wm, 'left', 'linear-x') for wm in wmid]) w0, w1 = wedges[:, :-1], wedges[:, 1:] normfac = np.ones(shape) datas = np.array( [w0, w1, flux, err, exptarr, flags, iarr, normfac, start, end]) datas = datas.swapaxes(0, 1) spectbls = [__maketbl(d, specfile) for d in datas] #cull off-detector data spectbls = [__trimHSTtbl(spectbl) for spectbl in spectbls] elif observatory == 'fuse': spectbls = [] star = spec[0].header['targname'] expt = spec[0].header['obstime'] for sub in spec[1:]: w, f, e = [sub.data[s] for s in ['wave', 'flux', 'error']] wedges = midpts(w) wedges = np.insert(wedges, [0, len(wedges)], [2 * w[0] - wedges[0], 2 * w[-1] - wedges[-1]]) w0, w1 = wedges[:-1], wedges[1:] spectbl = utils.vecs2spectbl(w0, w1, f, e, exptime=expt, star=star, filename=specfile) spectbls.append(spectbl) elif observatory in ['xmm', 'cxo']: sh = spec[0].header star = db.parse_star(specfile) def groomwave(ext): wmid = spec[ext].data['Wave'] halfwidth = spec[ext].data['bin_width'] w0, w1 = wmid - halfwidth, wmid + halfwidth assert np.allclose(w0[1:], w1[:-1]) # there may still be slight mismatches, so fix it up betweens = (w0[1:] + w1[:-1]) / 2.0 w0[1:], w1[:-1] = betweens, betweens return w0, w1 # first the observed spectrum optel = db.parse_grating(specfile) if 'gj551' in specfile: expt = sh['pn_duration'] start = np.nan end = np.nan elif optel == 'pn---': expt = sh['spec_exptime_pn'] * 1000.0 start = Time(sh['pn_date-obs']).mjd end = Time(sh['pn_date-end']).mjd elif optel == 'multi': expt = (sh['spec_exptime_mos1'] + sh['spec_exptime_mos2'] + sh['spec_exptime_pn']) / 3.0 * 1000.0 start1 = Time(sh['mos1_date-obs']).mjd start2 = Time(sh['mos2_date-obs']).mjd start3 = Time(sh['pn_date-obs']).mjd end1 = Time(sh['mos1_date-end']).mjd end2 = Time(sh['mos2_date-end']).mjd end3 = Time(sh['pn_date-end']).mjd start = min([start1, start2, start3]) end = max([end1, end2, end3]) elif sh['instrume'] == 'ACIS': starts, ends, expts = [ _parse_keys_sequential(sh, root) for root in ['DATE_OBS', 'DATE_END', 'EXPTIME'] ] expt = sum(expts) * 1000.0 starts, ends = list(map(Time, [starts, ends])) start = min(starts.mjd) end = max(ends.mjd) else: start = 0.0 end = 0.0 expt = 0.0 if '1214' not in sh['target']: flux, err = [ spec['Obs Spectrum'].data[s] for s in ['CFlux', 'CFlux_err'] ] w0, w1 = groomwave('Obs Spectrum') insti = db.getinsti(specfile) obsspec = utils.vecs2spectbl(w0, w1, flux, err, expt, instrument=insti, start=start, end=end, star=star, filename=specfile) good = np.isfinite(obsspec['flux']) obsspec = obsspec[good] spectbls = [obsspec] else: spectbls = [] # next the model flux = spec['Model Spectrum'].data['Flux'] expt, err = 0.0, 0.0 w0, w1 = groomwave('Model Spectrum') name_pieces = db.parse_name(specfile).split('_') configuration = 'mod_apc_-----' name = '_'.join(name_pieces[:1] + [configuration] + name_pieces[4:]) insti = rc.getinsti(configuration) modspec = utils.vecs2spectbl(w0, w1, flux, err, expt, instrument=insti, name=name, filename=specfile) spectbls.append(modspec) else: raise Exception( 'fits2tbl cannot parse data from the {} observatory.'.format( observatory)) spec.close() for tbl in spectbls: tbl['w'] = (tbl['w0'] + tbl['w1']) / 2. return spectbls