Beispiel #1
0
def clooge_edges(mids):
    """Just uses the midpoints of the midpoints to guess at the edges for
    a grid. Taking the midpoints of the returned bin edges will _not_ reproduce
    the input."""
    edges = mnp.midpts(mids)
    beg = mids[0] - (edges[0] - mids[0])
    end = mids[-1] + (mids[-1] - edges[-1])
    return np.concatenate([[beg], edges, [end]])
Beispiel #2
0
def readcsv(specfile):
    if db.parse_observatory(specfile) in ['tmd', 'src']:
        data = np.loadtxt(specfile, skiprows=1, delimiter=',')
        wmid, f = data[:,1], data[:,2]
        f *= 100.0 # convert W/m2/nm to erg/s/cm2/AA
        wmid *= 10.0 # convert nm to AA
        we = np.zeros(len(wmid) + 1)
        we[1:-1] = midpts(wmid)
        dw0, dw1 = wmid[1] - wmid[0], wmid[-1] - wmid[-2]
        we[0], we[-1] = wmid[0] - dw0 / 2.0, wmid[-1] + dw1 / 2.0
        w0, w1 = we[:-1], we[1:]
        good = ~np.isnan(f)
        w0, w1, f = w0[good], w1[good], f[good]
        spectbl = utils.vecs2spectbl(w0, w1, f, filename=specfile)
        return [spectbl]
    else:
        raise Exception('A parser for {} files has not been implemented.'.format(specfile[2:9]))
Beispiel #3
0
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
Beispiel #4
0
ir = [7000, np.inf]
broadband_edges = [xray[1], euv[1], fuv[1], nuv[1], vis[1]]
broadbands = [xray, euv, fuv, nuv, vis, [ir[0], 55000]]
broadband_names = ['X-ray', 'EUV', 'FUV', 'NUV', 'Visible', 'IR']

# -----------------------------------------------------------------------------
# PHOENIX DATABASE
phoenixbaseurl = 'ftp://phoenix.astro.physik.uni-goettingen.de/HiResFITS/PHOENIX-ACES-AGSS-COND-2011/'
phxrepo = os.path.join(datapath, 'phoenix')
phxTgrid = np.hstack([np.arange(2300, 7000, 100), np.arange(7000, 12001, 200)])
phxggrid = np.arange(0.0, 6.1, 0.5)
phxZgrid = np.hstack([np.arange(-4.0, -2.0, 1.0), np.arange(-2.0, 1.1, 0.5)])
phxagrid = np.arange(-0.2, 1.3, 0.2)
phxgrids = [phxTgrid, phxggrid, phxZgrid, phxagrid]
phxwave = fits.getdata(os.path.join(phxrepo, 'wavegrid_hires.fits'))
phxwave = np.hstack([[499.95], midpts(phxwave), [54999.875]])


def phxurl(Teff, logg=4.5, FeH=0.0, aM=0.0, repo='ftp'):
    """
    Constructs the URL for the phoenix spectrum file for a star with effective
    temperature Teff, log surface gravity logg, metalicity FeH, and alpha
    elemnt abundance aM.

    Does not check that the URL is actually valid, and digits beyond the
    precision of the numbers used in the path will be truncated.
    """
    zstr = '{:+4.1f}'.format(FeH)
    if FeH == 0.0: zstr = '-' + zstr[1:]
    astr = '.Alpha={:+5.2f}'.format(aM) if aM != 0.0 else ''
    name = (