Example #1
0
def plot_spectra(plan, date):
    '''take plan[std name] -> (path, ver) and plot'''

    figure(1)
    clf()
    figure(2)
    clf()
    xlim(360, 980)

    for stdname, todo in plan.iteritems():

        print stdname, todo
        path, ver = todo
        sp = path.split("/")
        name, datetime, ver = sp[-3:]

        FF = pf.open(os.path.join(path, "%s.fits" % name))
        dat = FF[0].data
        itime = FF[0].header['exptime']
        airmass = FF[0].header['airmass']
        l, s = dat[0, :], dat[2, :] / itime
        magperairmass = Atm.ext(l * 10)
        mag_ext = magperairmass * airmass
        ext = 10**(-magperairmass / 2.5)
        s /= ext
        sourcefun = interp1d(l, s)
        stdfun = get_std_spec(name)
        figure(1)
        plot(l, s)
        plot(l, stdfun(l))
        figure(2)
        corr = stdfun(l) / s
        semilogy(l, corr)

        try:
            all_corr += stdfun(all_l) / sourcefun(all_l)
        except:
            all_l = l
            all_corr = stdfun(l) / s

    all_corr /= len(plan)
    figure(2)
    legend(plan.keys())

    figure(3)
    ok = np.isfinite(all_corr)
    all_l = all_l[ok]
    all_corr = all_corr[ok]

    ok = (all_l > 370) & (all_l < 920) & (all_corr > 0)
    ff = interp1d(all_l[ok], all_corr[ok], bounds_error=False)
    semilogy(all_l, all_corr, '.')
    semilogy(all_l, ff(all_l))

    np.save('correction_%s' % date, [all_l, all_corr])

    show()
Example #2
0
def plot_spectra(plan, date):
    '''take plan[std name] -> (path, ver) and plot'''

    figure(1) ; clf()
    figure(2) ; clf()
    xlim(360,980)

    for stdname, todo in plan.iteritems():

        print stdname,todo
        path,ver = todo
        sp = path.split("/")
        name, datetime, ver = sp[-3:]

        FF = pf.open(os.path.join(path, "%s.fits" % name))
        dat = FF[0].data
        itime = FF[0].header['exptime']
        airmass = FF[0].header['airmass']
        l,s = dat[0,:], dat[2,:]/itime
        magperairmass = Atm.ext(l*10)
        mag_ext = magperairmass * airmass
        ext = 10**(-magperairmass/2.5)
        s /= ext
        sourcefun = interp1d(l, s)
        stdfun = get_std_spec(name)
        figure(1)
        plot(l,s)
        plot(l, stdfun(l))
        figure(2)
        corr = stdfun(l)/s
        semilogy(l, corr)

        try:
            all_corr += stdfun(all_l)/sourcefun(all_l)
        except:
            all_l = l
            all_corr = stdfun(l)/s

    all_corr /= len(plan)
    figure(2)
    legend(plan.keys())

    figure(3)
    ok = np.isfinite(all_corr)
    all_l = all_l[ok]
    all_corr = all_corr[ok]

    ok = (all_l > 370) & (all_l < 920) & (all_corr > 0)
    ff = interp1d(all_l[ok], all_corr[ok],bounds_error = False)
    semilogy(all_l,all_corr,'.')
    semilogy(all_l, ff(all_l))

    np.save('correction_%s' % date, [all_l, all_corr])


    show()
Example #3
0
    def draw_res(self):
        ''' Draw the resulting spectrum'''
        pl.figure(3)
        pl.clf()
        pl.xlim([350, 950])
        pl.ylim(-1000, 4000)

        allwav = allsky = allobj = None
        headers = []
        for i in xrange(len(self.RESULTS)):
            res = self.RESULTS[i]
            if res is None: continue

            header = self.headers[i]
            header = clean_header(header)
            headers.append(header)
            airmass = header['airmass']

            wave, sky, obj = res.copy()
            skyf = interp1d(wave, sky, fill_value=np.nan, bounds_error=False)
            objf = interp1d(wave, obj, fill_value=np.nan, bounds_error=False)

            if self.qecurve is None: correction = 1.0
            else:
                print "Applying correction"
                ext = 10**(-Atm.ext(wave * 10) * airmass / 2.5)
                correction = 1 / self.qecurve(wave * 10) * ext
                correction = 1.

            pl.step(wave, obj * correction)

            if allwav is None:
                allwav = wave[:]
                allsky = sky[:]
                allobj = obj[:]
            else:
                allsky += skyf(allwav)
                allobj += objf(allwav)

        if self.qecurve is None: correction = 1.0
        else: correction = 1 / self.qecurve(allwav * 10)

        pl.step(allwav, allobj * correction, linewidth=3)
        #pl.step(allwav, allobj, linewidth=3)

        # Raw data
        result = np.array([allwav, allsky, allobj])
        pf = pyfits.PrimaryHDU(result, header=header)
        name = self.plan[self.index]['name']
        pf.header["REDNAME"] = name
        outpath = os.path.join(self.outdir, "%s.fits" % (name))

        try:
            os.remove(outpath)
        except:
            pass

        pf.writeto(outpath)
        # Corrected
        if self.qecurve is not None:
            result = np.array(
                [allwav, allsky * correction, allobj * correction])
            pf = pyfits.PrimaryHDU(result, header=header)
            name = self.plan[self.index]['name']
            pf.header["REDNAME"] = name
            outpath = os.path.join(self.outdir, "%s_corr.fits" % (name))
            try:
                os.remove(outpath)
            except:
                pass
            pf.writeto(outpath)
Example #4
0
def handle_AB(A, B, fine, outname=None, corrfile=None,
    Aoffset=None, Boffset=None, radius=2, flat_corrections=None,
    nosky=False, lmin=650, lmax=700):
    '''Loads 2k x 2k IFU frame "A" and "B" and extracts A-B and A+B spectra
    from the "fine" location. 

    Args:
        A (string): filename of ifu FITS file to extract from.
        B (string): filename of ifu FITS file to extract from.
        fine (string): filename of NumPy file with locations + wavelength
            soln
        outname (string): filename to write results to
        Aoffset (2tuple): X (nm)/Y (pix) shift to apply for flexure correction
        Boffset (2tuple): X (nm)/Y (pix) shift to apply for flexure correction
        radius (float): Extraction radius in arcsecond
        flat_corrections (list): A list of FlatCorrection objects for
            correcting the extraction
	nosky (Boolean): if True don't subtract sky, merely sum in aperture

    Returns:
        The extracted spectrum, a dictionary:
        {'ph_10m_nm': Flux in photon / 10 m / nanometer integrated
        'var'
        'nm': Wavelength solution in nm
        'N_spaxA': Total number of "A" spaxels 
        'N_spaxB': Total number of "B" spaxels
        'skyph': Sky flux in photon / 10 m / nanometer / spaxel
        'radius_as': Extraction radius in arcsec
        'pos': X/Y extraction location of spectrum in arcsec}

    Raises:
        None
    '''

    fine = np.load(fine)
    if outname is None:
        outname = "%sm%s" % (A,B)

    if Aoffset is not None:
        ff = np.load(Aoffset)
        flexure_x_corr_nm = ff[0]['dXnm']
        flexure_y_corr_pix = -ff[0]['dYpix']

        print "Dx %2.1f | Dy %2.1f" % (ff[0]['dXnm'], ff[0]['dYpix'])
    else:
        flexure_x_corr_nm = 0
        flexure_y_corr_pix = 0

    read_var = 5*5
    if os.path.isfile(outname + ".fits.npy"):
        print "USING extractions in %s!" % outname
        E, meta = np.load(outname + ".fits.npy")
        E_var, meta_var = np.load("var_" + outname + ".fits.npy")
    else:
        if not outname.endswith(".fits"): 
            outname = outname + ".fits"
            diff = subtract(A,B, outname)
            add(A,B, "tmpvar_" + outname)

            adcspeed = diff[0].header["ADCSPEED"]
            if adcspeed == 2: read_var = 22*22
            else: read_var = 5*5

        var = add("tmpvar_" + outname, str(read_var), "var_" + outname)
        os.remove("tmpvar_" + outname + ".gz")


        E, meta = Wavelength.wavelength_extract(diff, fine, 
            filename=outname,
            flexure_x_corr_nm = flexure_x_corr_nm, 
            flexure_y_corr_pix = flexure_y_corr_pix,
            flat_corrections=flat_corrections)
        meta['airmass1'] = diff[0].header['airmass1']
        meta['airmass2'] = diff[0].header['airmass2']
        meta['airmass'] = diff[0].header['airmass']
        header = {}
        for k,v in diff[0].header.iteritems():
            try: header[k] = v
            except: pass
        meta['HA'] = diff[0].header['HA']
        meta['Dec'] = diff[0].header['Dec']
        meta['RA'] = diff[0].header['RA']
        meta['PRLLTC'] = diff[0].header['PRLLTC']
        meta['equinox'] = diff[0].header['Equinox']
        meta['utc'] = diff[0].header['utc']

        meta['header'] = header

        meta['exptime'] = diff[0].header['exptime']
        np.save(outname, [E, meta])

        exfile = "extracted_var_%s.npy" % outname
        E_var, meta_var = Wavelength.wavelength_extract(var, fine, 
            filename=outname,
            flexure_x_corr_nm = flexure_x_corr_nm, 
            flexure_y_corr_pix = flexure_y_corr_pix,
            flat_corrections=flat_corrections)

        np.save("var_" + outname, [E_var, meta_var])

    sixA, posA, all_A = identify_spectra_gui(E, radius=radius, 
        PRLLTC=Angle(meta['PRLLTC'], unit='deg'),
        lmin=lmin, lmax=lmax, airmass=meta['airmass'])
    sixB, posB, all_B = identify_spectra_gui(E, radius=radius,
        PRLLTC=Angle(meta['PRLLTC'], unit='deg'),
        lmin=lmin, lmax=lmax, airmass=meta['airmass'])

    to_image(E, meta, outname, posA=posA, posB=posB, adcpos=all_A)

    skyA = identify_bgd_spectra(E, posA)
    skyB = identify_bgd_spectra(E, posB)

    allix = np.concatenate([sixA, sixB])
    resA = interp_spectra(E, sixA, sign=1, outname=outname+"_A.pdf", corrfile=corrfile)
    resB = interp_spectra(E, sixB, sign=-1, outname=outname+"_B.pdf", corrfile=corrfile)
    skyA = interp_spectra(E, skyA, sign=1, outname=outname+"_skyA.pdf", corrfile=corrfile)
    skyB = interp_spectra(E, skyB, sign=-1, outname=outname+"_skYB.pdf", corrfile=corrfile)
    varA = interp_spectra(E_var, sixA, sign=1, outname=outname+"_A_var.pdf", corrfile=corrfile)
    varB = interp_spectra(E_var, sixB, sign=1, outname=outname+"_B_var.pdf", corrfile=corrfile)
    
    
    ## Plot out the X/Y selected spectra
    XSA = []
    YSA = []
    XSB = []
    YSB = []
    for ix in sixA:
        XSA.append(E[ix].X_as)
        YSA.append(E[ix].Y_as)
    for ix in sixB:
        XSB.append(E[ix].X_as)
        YSB.append(E[ix].Y_as)

    pl.figure()
    pl.clf()
    pl.ylim(-30,30)
    pl.xlim(-30,30)
    pl.scatter(XSA,YSA, color='blue', marker='H', linewidth=.1)
    pl.scatter(XSB,YSB, color='red', marker='H', linewidth=.1)
    pl.savefig("XYs_%s.pdf" % outname)
    pl.close()
    # / End Plot

    np.save("sp_A_" + outname, resA)
    np.save("sp_B_" + outname, resB)
    np.save("var_A_" + outname, varA)
    np.save("var_B_" + outname, varB)

    ll = Wavelength.fiducial_spectrum()
    sky_A = interp1d(skyA[0]['nm'], skyA[0]['ph_10m_nm'], bounds_error=False)
    sky_B = interp1d(skyB[0]['nm'], skyB[0]['ph_10m_nm'], bounds_error=False)
    sky = np.nanmean([sky_A(ll), sky_B(ll)], axis=0)

    var_A = interp1d(varA[0]['nm'], varA[0]['ph_10m_nm'], bounds_error=False)
    var_B = interp1d(varB[0]['nm'], varB[0]['ph_10m_nm'], bounds_error=False)
    varspec = np.nanmean([var_A(ll), var_B(ll)], axis=0) * (len(sixA) + len(sixB))

    res = np.copy(resA)
    res = [{"doc": resA[0]["doc"], "ph_10m_nm": np.copy(resA[0]["ph_10m_nm"]),
        "nm": np.copy(resA[0]["ph_10m_nm"])}]
    res[0]['nm'] = np.copy(ll)
    f1 = interp1d(resA[0]['nm'], resA[0]['ph_10m_nm'], bounds_error=False)
    f2 = interp1d(resB[0]['nm'], resB[0]['ph_10m_nm'], bounds_error=False)

    airmassA = meta['airmass1']
    airmassB = meta['airmass2']

    extCorrA = 10**(Atm.ext(ll*10)*airmassA/2.5)
    extCorrB = 10**(Atm.ext(ll*10)*airmassB/2.5)
    print "Median airmass corr: ", np.median(extCorrA), np.median(extCorrB)
    # If requested merely sum in aperture, otherwise subtract sky
    if nosky:
    	res[0]['ph_10m_nm'] = \
        	np.nansum([
            	f1(ll) * extCorrA, 
            	f2(ll) * extCorrB], axis=0) * \
            	(len(sixA) + len(sixB))
    else:
    	res[0]['ph_10m_nm'] = \
        	np.nansum([
            	(f1(ll)-sky_A(ll)) * extCorrA, 
            	(f2(ll)-sky_B(ll)) * extCorrB], axis=0) * \
            	(len(sixA) + len(sixB))

    res[0]['exptime'] = meta['exptime']
    res[0]['Extinction Correction'] = 'Applied using Hayes & Latham'
    res[0]['extinction_corr_A'] = extCorrA
    res[0]['extinction_corr_B'] = extCorrB
    res[0]['skyph'] = sky
    res[0]['var'] = varspec
    res[0]['radius_as'] = radius
    res[0]['positionA'] = posA
    res[0]['positionB'] = posA
    res[0]['N_spaxA'] = len(sixA)
    res[0]['N_spaxB'] = len(sixB)
    res[0]['meta'] = meta
    res[0]['object_spaxel_ids_A'] = sixA
    res[0]['sky_spaxel_ids_A'] = skyA 
    res[0]['object_spaxel_ids_B'] = sixB
    res[0]['sky_spaxel_ids_B'] = skyB

    coef = chebfit(np.arange(len(ll)), ll, 4)
    xs = np.arange(len(ll)+1)
    newll = chebval(xs, coef)

    res[0]['dlam'] = np.diff(newll)

    np.save("sp_" + outname, res)
Example #5
0
def handle_A(A, fine, outname=None, standard=None, corrfile=None,
    Aoffset=None, radius=2, flat_corrections=None, nosky=False):
    '''Loads 2k x 2k IFU frame "A" and extracts spectra from the locations
    in "fine". 

    Args:
        A (string): filename of ifu FITS file to extract from.
        fine (string): filename of NumPy file with locations + wavelength
            soln
        outname (string): filename to write results to
        Aoffset (2tuple): X (nm)/Y (pix) shift to apply for flexure correction
        radius (float): Extraction radius in arcsecond
        flat_corrections (list): A list of FlatCorrection objects for
            correcting the extraction
	nosky (Boolean): if True don't subtract sky, merely sum in aperture

    Returns:
        The extracted spectrum, a dictionary:
        {'ph_10m_nm': Flux in photon / 10 m / nanometer integrated
        'nm': Wavelength solution in nm
        'N_spax': Total number of spaxels that created ph_10m_nm
        'skyph': Sky flux in photon / 10 m / nanometer / spaxel
        'radius_as': Extraction radius in arcsec
        'pos': X/Y extraction location of spectrum in arcsec}

    Raises:
        None
    '''

    fine = np.load(fine)
    if outname is None:
        outname = "%s" % (A)

    spec = pf.open(A)

    if Aoffset is not None:
        ff = np.load(Aoffset)
        flexure_x_corr_nm = ff[0]['dXnm']
        flexure_y_corr_pix = ff[0]['dYpix']

        print "Dx %2.1f | Dy %2.1f" % (ff[0]['dXnm'], ff[0]['dYpix'])
    else:
        flexure_x_corr_nm = 0
        flexure_y_corr_pix = 0

    if os.path.isfile(outname+".npy"):
        print "USING extractions in %s!" % outname
        print "rm %s.npy # if you want to recreate extractions" % outname
        E, meta = np.load(outname+".npy")
    else:
        print "CREATING extractions ..."
        E, meta = Wavelength.wavelength_extract(spec, fine, filename=outname,
            flexure_x_corr_nm=flexure_x_corr_nm, 
            flexure_y_corr_pix=flexure_y_corr_pix,
            flat_corrections = flat_corrections)

        meta['airmass'] = spec[0].header['airmass']
        header = {}
        for k,v in spec[0].header.iteritems():
            try: header[k] = v
            except: pass
        meta['HA'] = spec[0].header['HA']
        meta['Dec'] = spec[0].header['Dec']
        meta['RA'] = spec[0].header['RA']
        meta['PRLLTC'] = spec[0].header['PRLLTC']
        meta['equinox'] = spec[0].header['Equinox']
        meta['utc'] = spec[0].header['utc']

        meta['header'] = header

        np.save(outname, [E, meta])

    '''six, pos, adcpos = identify_spectra_gui(E, radius=radius, 
        PRLLTC=Angle(meta['PRLLTC'], unit='deg'), 
        lmin=650, lmax=700, airmass=meta['airmass'])'''

    six, pos, adcpos = identify_spectra_Gauss_fit(E, outname=outname, radius=radius, 
        PRLLTC=Angle(meta['PRLLTC'], unit='deg'), 
        lmin=650, lmax=700, airmass=meta['airmass'])
        
    skyix = identify_bgd_spectra(E, pos, inner=radius*1.1)
    res = interp_spectra(E, six, outname=outname+".pdf", corrfile=corrfile)
    sky = interp_spectra(E, skyix, onto=res[0]['nm'], outname=outname+"_sky.pdf", corrfile=corrfile)
    
    to_image(E, meta, outname, posA=pos, adcpos=adcpos)
    if standard is not None:
        print "STANDARD"
        wav = standard[:,0]/10.0
        flux = standard[:,1]

        fun = interp1d(wav, flux, bounds_error=False, fill_value = np.nan)
        correction = fun(res[0]['nm'])/res[0]['ph_10m_nm']

        res[0]['std-correction'] = correction


    airmass = meta['airmass']
    extCorr = 10**(Atm.ext(res[0]['nm']*10) * airmass/2.5)
    print "Median airmass corr: ", np.nanmedian(extCorr)

    ff = interp1d(sky[0]['nm'], sky[0]['ph_10m_nm'], bounds_error=False)
    skybgd = ff(res[0]['nm'])

    res[0]['exptime'] = spec[0].header['exptime']
    res[0]['Extinction Correction'] = 'Applied using Hayes & Latham'
    res[0]['extinction_corr'] = extCorr
    res[0]['skynm'] = sky[0]['nm']
    res[0]['skyph'] = sky[0]['ph_10m_nm']

    if not nosky:
    	res[0]['ph_10m_nm'] -= skybgd 
    res[0]['ph_10m_nm'] *= extCorr * len(six)

    res[0]['radius_as'] = radius
    res[0]['position'] = pos
    res[0]['N_spax'] = len(six)
    res[0]['meta'] = meta
    res[0]['object_spaxel_ids'] = six
    res[0]['sky_spaxel_ids'] = skyix
    res[0]['sky_spectra'] = sky[0]['spectra']

    np.save("sp_" + outname, res)
Example #6
0
    def draw_res(self):
        """ Draw the resulting spectrum"""
        pl.figure(3)
        pl.clf()
        pl.xlim([350, 950])
        pl.ylim(-1000, 4000)

        allwav = allsky = allobj = None
        headers = []
        for i in xrange(len(self.RESULTS)):
            res = self.RESULTS[i]
            if res is None:
                continue

            header = self.headers[i]
            header = clean_header(header)
            headers.append(header)
            airmass = header["airmass"]

            wave, sky, obj = res.copy()
            skyf = interp1d(wave, sky, fill_value=np.nan, bounds_error=False)
            objf = interp1d(wave, obj, fill_value=np.nan, bounds_error=False)

            if self.qecurve is None:
                correction = 1.0
            else:
                print "Applying correction"
                ext = 10 ** (-Atm.ext(wave * 10) * airmass / 2.5)
                correction = 1 / self.qecurve(wave * 10) * ext
                correction = 1.0

            pl.step(wave, obj * correction)

            if allwav is None:
                allwav = wave[:]
                allsky = sky[:]
                allobj = obj[:]
            else:
                allsky += skyf(allwav)
                allobj += objf(allwav)

        if self.qecurve is None:
            correction = 1.0
        else:
            correction = 1 / self.qecurve(allwav * 10)

        pl.step(allwav, allobj * correction, linewidth=3)
        # pl.step(allwav, allobj, linewidth=3)

        # Raw data
        result = np.array([allwav, allsky, allobj])
        pf = pyfits.PrimaryHDU(result, header=header)
        name = self.plan[self.index]["name"]
        pf.header["REDNAME"] = name
        outpath = os.path.join(self.outdir, "%s.fits" % (name))

        try:
            os.remove(outpath)
        except:
            pass

        pf.writeto(outpath)
        # Corrected
        if self.qecurve is not None:
            result = np.array([allwav, allsky * correction, allobj * correction])
            pf = pyfits.PrimaryHDU(result, header=header)
            name = self.plan[self.index]["name"]
            pf.header["REDNAME"] = name
            outpath = os.path.join(self.outdir, "%s_corr.fits" % (name))
            try:
                os.remove(outpath)
            except:
                pass
            pf.writeto(outpath)
Example #7
0
def handle_AB(A,
              B,
              fine,
              outname=None,
              corrfile=None,
              Aoffset=None,
              Boffset=None,
              radius=2,
              flat_corrections=None,
              lmin=650,
              lmax=700):
    '''Loads 2k x 2k IFU frame "A" and "B" and extracts A-B and A+B spectra
    from the "fine" location. 

    Args:
        A (string): filename of ifu FITS file to extract from.
        B (string): filename of ifu FITS file to extract from.
        fine (string): filename of NumPy file with locations + wavelength
            soln
        outname (string): filename to write results to
        Aoffset (2tuple): X (nm)/Y (pix) shift to apply for flexure correction
        Boffset (2tuple): X (nm)/Y (pix) shift to apply for flexure correction
        radius (float): Extraction radius in arcsecond
        flat_corrections (list): A list of FlatCorrection objects for
            correcting the extraction

    Returns:
        The extracted spectrum, a dictionary:
        {'ph_10m_nm': Flux in photon / 10 m / nanometer integrated
        'var'
        'nm': Wavelength solution in nm
        'N_spaxA': Total number of "A" spaxels 
        'N_spaxB': Total number of "B" spaxels
        'skyph': Sky flux in photon / 10 m / nanometer / spaxel
        'radius_as': Extraction radius in arcsec
        'pos': X/Y extraction location of spectrum in arcsec}

    Raises:
        None
    '''

    fine = np.load(fine)
    if outname is None:
        outname = "%sm%s" % (A, B)

    if Aoffset is not None:
        ff = np.load(Aoffset)
        f2 = np.load(Aoffset)
        flexure_x_corr_nm = ff[0]['dXnm']
        flexure_y_corr_pix = -ff[0]['dYpix']

        print "Dx %2.1f, %2.1f | Dy %2.1f %2.1f" % (
            ff[0]['dXnm'], f2[0]['dXnm'], ff[0]['dYpix'], f2[0]['dYpix'])
    else:
        flexure_x_corr_nm = 0
        flexure_y_corr_pix = 0

    read_var = 5 * 5
    if os.path.isfile(outname + ".fits.npy"):
        print "USING extractions in %s!" % outname
        E, meta = np.load(outname + ".fits.npy")
        E_var, meta_var = np.load("var_" + outname + ".fits.npy")
    else:
        if not outname.endswith(".fits"):
            outname = outname + ".fits"
            diff = subtract(A, B, outname)
            add(A, B, "tmpvar_" + outname)

            adcspeed = diff[0].header["ADCSPEED"]
            if adcspeed == 2: read_var = 22 * 22
            else: read_var = 5 * 5

        var = add("tmpvar_" + outname, str(read_var), "var_" + outname)
        os.remove("tmpvar_" + outname + ".gz")

        E, meta = Wavelength.wavelength_extract(
            diff,
            fine,
            filename=outname,
            flexure_x_corr_nm=flexure_x_corr_nm,
            flexure_y_corr_pix=flexure_y_corr_pix,
            flat_corrections=flat_corrections)
        meta['airmass1'] = diff[0].header['airmass1']
        meta['airmass2'] = diff[0].header['airmass2']
        meta['airmass'] = diff[0].header['airmass']
        header = {}
        for k, v in diff[0].header.iteritems():
            try:
                header[k] = v
            except:
                pass
        meta['HA'] = diff[0].header['HA']
        meta['Dec'] = diff[0].header['Dec']
        meta['RA'] = diff[0].header['RA']
        meta['PRLLTC'] = diff[0].header['PRLLTC']
        meta['equinox'] = diff[0].header['Equinox']
        meta['utc'] = diff[0].header['utc']

        meta['header'] = header

        meta['exptime'] = diff[0].header['exptime']
        np.save(outname, [E, meta])

        exfile = "extracted_var_%s.npy" % outname
        E_var, meta_var = Wavelength.wavelength_extract(
            var,
            fine,
            filename=outname,
            flexure_x_corr_nm=flexure_x_corr_nm,
            flexure_y_corr_pix=flexure_y_corr_pix,
            flat_corrections=flat_corrections)

        np.save("var_" + outname, [E_var, meta_var])

    sixA, posA, all_A = identify_spectra_gui(E,
                                             radius=radius,
                                             PRLLTC=Angle(meta['PRLLTC'],
                                                          unit='deg'),
                                             lmin=lmin,
                                             lmax=lmax,
                                             airmass=meta['airmass'])
    sixB, posB, all_B = identify_spectra_gui(E,
                                             radius=radius,
                                             PRLLTC=Angle(meta['PRLLTC'],
                                                          unit='deg'),
                                             lmin=lmin,
                                             lmax=lmax,
                                             airmass=meta['airmass'])

    to_image(E, meta, outname, posA=posA, posB=posB, adcpos=all_A)

    skyA = identify_bgd_spectra(E, posA)
    skyB = identify_bgd_spectra(E, posB)

    allix = np.concatenate([sixA, sixB])
    resA = interp_spectra(E,
                          sixA,
                          sign=1,
                          outname=outname + "_A.pdf",
                          corrfile=corrfile)
    resB = interp_spectra(E,
                          sixB,
                          sign=-1,
                          outname=outname + "_B.pdf",
                          corrfile=corrfile)
    skyA = interp_spectra(E,
                          skyA,
                          sign=1,
                          outname=outname + "_skyA.pdf",
                          corrfile=corrfile)
    skyB = interp_spectra(E,
                          skyB,
                          sign=-1,
                          outname=outname + "_skYB.pdf",
                          corrfile=corrfile)
    varA = interp_spectra(E_var,
                          sixA,
                          sign=1,
                          outname=outname + "_A_var.pdf",
                          corrfile=corrfile)
    varB = interp_spectra(E_var,
                          sixB,
                          sign=1,
                          outname=outname + "_B_var.pdf",
                          corrfile=corrfile)

    ## Plot out the X/Y selected spectra
    XSA = []
    YSA = []
    XSB = []
    YSB = []
    for ix in sixA:
        XSA.append(E[ix].X_as)
        YSA.append(E[ix].Y_as)
    for ix in sixB:
        XSB.append(E[ix].X_as)
        YSB.append(E[ix].Y_as)

    pl.figure()
    pl.clf()
    pl.ylim(-30, 30)
    pl.xlim(-30, 30)
    pl.scatter(XSA, YSA, color='blue', marker='H', linewidth=.1)
    pl.scatter(XSB, YSB, color='red', marker='H', linewidth=.1)
    pl.savefig("XYs_%s.pdf" % outname)
    pl.close()
    # / End Plot

    np.save("sp_A_" + outname, resA)
    np.save("sp_B_" + outname, resB)
    np.save("var_A_" + outname, varA)
    np.save("var_B_" + outname, varB)

    ll = Wavelength.fiducial_spectrum()
    sky_A = interp1d(skyA[0]['nm'], skyA[0]['ph_10m_nm'], bounds_error=False)
    sky_B = interp1d(skyB[0]['nm'], skyB[0]['ph_10m_nm'], bounds_error=False)
    sky = np.nanmean([sky_A(ll), sky_B(ll)], axis=0)

    var_A = interp1d(varA[0]['nm'], varA[0]['ph_10m_nm'], bounds_error=False)
    var_B = interp1d(varB[0]['nm'], varB[0]['ph_10m_nm'], bounds_error=False)
    varspec = np.nanmean([var_A(ll), var_B(ll)],
                         axis=0) * (len(sixA) + len(sixB))

    res = np.copy(resA)
    res = [{
        "doc": resA[0]["doc"],
        "ph_10m_nm": np.copy(resA[0]["ph_10m_nm"]),
        "nm": np.copy(resA[0]["ph_10m_nm"])
    }]
    res[0]['nm'] = np.copy(ll)
    f1 = interp1d(resA[0]['nm'], resA[0]['ph_10m_nm'], bounds_error=False)
    f2 = interp1d(resB[0]['nm'], resB[0]['ph_10m_nm'], bounds_error=False)

    airmassA = meta['airmass1']
    airmassB = meta['airmass2']

    extCorrA = 10**(Atm.ext(ll * 10) * airmassA / 2.5)
    extCorrB = 10**(Atm.ext(ll * 10) * airmassB / 2.5)
    print "Median airmass corr: ", np.median(extCorrA), np.median(extCorrB)
    res[0]['ph_10m_nm'] = \
        np.nansum([
            (f1(ll)-sky_A(ll)) * extCorrA,
            (f2(ll)-sky_B(ll)) * extCorrB], axis=0) * \
            (len(sixA) + len(sixB))

    res[0]['exptime'] = meta['exptime']
    res[0]['Extinction Correction'] = 'Applied using Hayes & Latham'
    res[0]['extinction_corr_A'] = extCorrA
    res[0]['extinction_corr_B'] = extCorrB
    res[0]['skyph'] = sky
    res[0]['var'] = varspec
    res[0]['radius_as'] = radius
    res[0]['positionA'] = posA
    res[0]['positionB'] = posA
    res[0]['N_spaxA'] = len(sixA)
    res[0]['N_spaxB'] = len(sixB)
    res[0]['meta'] = meta
    res[0]['object_spaxel_ids_A'] = sixA
    res[0]['sky_spaxel_ids_A'] = skyA
    res[0]['object_spaxel_ids_B'] = sixB
    res[0]['sky_spaxel_ids_B'] = skyB

    coef = chebfit(np.arange(len(ll)), ll, 4)
    xs = np.arange(len(ll) + 1)
    newll = chebval(xs, coef)

    res[0]['dlam'] = np.diff(newll)

    np.save("sp_" + outname, res)
Example #8
0
def handle_A(A,
             fine,
             outname=None,
             standard=None,
             corrfile=None,
             Aoffset=None,
             radius=2,
             flat_corrections=None):
    '''Loads 2k x 2k IFU frame "A" and extracts spectra from the locations
    in "fine". 

    Args:
        A (string): filename of ifu FITS file to extract from.
        fine (string): filename of NumPy file with locations + wavelength
            soln
        outname (string): filename to write results to
        Aoffset (2tuple): X (nm)/Y (pix) shift to apply for flexure correction
        radius (float): Extraction radius in arcsecond
        flat_corrections (list): A list of FlatCorrection objects for
            correcting the extraction

    Returns:
        The extracted spectrum, a dictionary:
        {'ph_10m_nm': Flux in photon / 10 m / nanometer integrated
        'nm': Wavelength solution in nm
        'N_spax': Total number of spaxels that created ph_10m_nm
        'skyph': Sky flux in photon / 10 m / nanometer / spaxel
        'radius_as': Extraction radius in arcsec
        'pos': X/Y extraction location of spectrum in arcsec}

    Raises:
        None
    '''

    fine = np.load(fine)
    if outname is None:
        outname = "%s" % (A)

    spec = pf.open(A)

    if Aoffset is not None:
        ff = np.load(Aoffset)
        flexure_x_corr_nm = ff[0]['dXnm']
        flexure_y_corr_pix = ff[0]['dYpix']
    else:
        flexure_x_corr_nm = 0
        flexure_y_corr_pix = 0

    if os.path.isfile(outname + ".npy"):
        print "USING extractions in %s!" % outname
        print "rm %s.npy # if you want to recreate extractions" % outname
        E, meta = np.load(outname + ".npy")
    else:
        print "CREATING extractions ..."
        E, meta = Wavelength.wavelength_extract(
            spec,
            fine,
            filename=outname,
            flexure_x_corr_nm=flexure_x_corr_nm,
            flexure_y_corr_pix=flexure_y_corr_pix,
            flat_corrections=flat_corrections)

        meta['airmass'] = spec[0].header['airmass']
        header = {}
        for k, v in spec[0].header.iteritems():
            try:
                header[k] = v
            except:
                pass
        meta['HA'] = spec[0].header['HA']
        meta['Dec'] = spec[0].header['Dec']
        meta['RA'] = spec[0].header['RA']
        meta['PRLLTC'] = spec[0].header['PRLLTC']
        meta['equinox'] = spec[0].header['Equinox']
        meta['utc'] = spec[0].header['utc']

        meta['header'] = header

        np.save(outname, [E, meta])

    six, pos, adcpos = identify_spectra_gui(E,
                                            radius=radius,
                                            PRLLTC=Angle(meta['PRLLTC'],
                                                         unit='deg'),
                                            lmin=650,
                                            lmax=700,
                                            airmass=meta['airmass'])

    skyix = identify_bgd_spectra(E, pos, inner=radius * 1.1)
    res = interp_spectra(E, six, outname=outname + ".pdf", corrfile=corrfile)
    sky = interp_spectra(E,
                         skyix,
                         onto=res[0]['nm'],
                         outname=outname + "_sky.pdf",
                         corrfile=corrfile)

    to_image(E, meta, outname, posA=pos, adcpos=adcpos)
    if standard is not None:
        print "STANDARD"
        wav = standard[:, 0] / 10.0
        flux = standard[:, 1]

        fun = interp1d(wav, flux, bounds_error=False, fill_value=np.nan)
        correction = fun(res[0]['nm']) / res[0]['ph_10m_nm']

        res[0]['std-correction'] = correction

    airmass = meta['airmass']
    extCorr = 10**(Atm.ext(res[0]['nm'] * 10) * airmass / 2.5)
    print "Median airmass corr: ", np.median(extCorr)

    ff = interp1d(sky[0]['nm'], sky[0]['ph_10m_nm'], bounds_error=False)
    skybgd = ff(res[0]['nm'])

    res[0]['exptime'] = spec[0].header['exptime']
    res[0]['Extinction Correction'] = 'Applied using Hayes & Latham'
    res[0]['extinction_corr'] = extCorr
    res[0]['skynm'] = sky[0]['nm']
    res[0]['skyph'] = sky[0]['ph_10m_nm']

    res[0]['ph_10m_nm'] -= skybgd
    res[0]['ph_10m_nm'] *= extCorr * len(six)

    res[0]['radius_as'] = radius
    res[0]['position'] = pos
    res[0]['N_spax'] = len(six)
    res[0]['meta'] = meta
    res[0]['object_spaxel_ids'] = six
    res[0]['sky_spaxel_ids'] = skyix
    res[0]['sky_spectra'] = sky[0]['spectra']

    np.save("sp_" + outname, res)
Example #9
0
def handle_A(A, fine, outname=None, standard=None, corrfile=None,
    Aoffset=None, radius=2, flat_corrections=None, nosky=False,
    lmin=650, lmax=700):
    '''Loads 2k x 2k IFU frame "A" and extracts spectra from the locations
    in "fine".

    Args:
        A (string): filename of ifu FITS file to extract from.
        fine (string): filename of NumPy file with locations + wavelength
            soln
        outname (string): filename to write results to
        Aoffset (2tuple): X (nm)/Y (pix) shift to apply for flexure correction
        radius (float): Extraction radius in arcsecond
        flat_corrections (list): A list of FlatCorrection objects for
            correcting the extraction
        nosky (Boolean): if True don't subtract sky, merely sum in aperture

    Returns:
        The extracted spectrum, a dictionary:
        {'ph_10m_nm': Flux in photon / 10 m / nanometer integrated
        'nm': Wavelength solution in nm
        'N_spax': Total number of spaxels that created ph_10m_nm
        'skyph': Sky flux in photon / 10 m / nanometer / spaxel
        'radius_as': Extraction radius in arcsec
        'pos': X/Y extraction location of spectrum in arcsec}

    Raises:
        None
    '''

    fine = np.load(fine)
    if outname is None:
        outname = "%s" % (A)

    if Aoffset is not None:
        ff = np.load(Aoffset)
        flexure_x_corr_nm = ff[0]['dXnm']
        flexure_y_corr_pix = ff[0]['dYpix']

        print "Dx %2.1f nm | Dy %2.1f px" % (ff[0]['dXnm'], ff[0]['dYpix'])
    else:
        flexure_x_corr_nm = 0
        flexure_y_corr_pix = 0

    if os.path.isfile(outname+".npy"):
        print "USING extractions in %s.npy!" % outname
        print "rm %s.npy # if you want to recreate extractions" % outname
        E, meta = np.load(outname+".npy")
        E_var, meta_var = np.load("var_" + outname + ".npy")
    else:
        print "\nCREATING extractions ..."
        spec = pf.open(A)

        adcspeed = spec[0].header["ADCSPEED"]
        if adcspeed == 2: read_var = 22*22
        else: read_var = 5*5

        var = addcon(A, str(read_var), "var_" + outname + ".fits")

        print "\nExtracting object spectra"
        E, meta = Wavelength.wavelength_extract(spec, fine, filename=outname,
            flexure_x_corr_nm=flexure_x_corr_nm,
            flexure_y_corr_pix=flexure_y_corr_pix,
            flat_corrections = flat_corrections)
        meta['airmass'] = spec[0].header['airmass']
        header = {}
        for k,v in spec[0].header.iteritems():
            try: header[k] = v
            except: pass
        meta['HA'] = spec[0].header['HA']
        meta['Dec'] = spec[0].header['Dec']
        meta['RA'] = spec[0].header['RA']
        meta['PRLLTC'] = spec[0].header['PRLLTC']
        meta['equinox'] = spec[0].header['Equinox']
        meta['utc'] = spec[0].header['utc']

        meta['header'] = header

        meta['exptime'] = spec[0].header['exptime']
        np.save(outname, [E, meta])

        print "\nExtracting variance spectra"
        E_var, meta_var = Wavelength.wavelength_extract(var, fine,
            filename=outname,
            flexure_x_corr_nm = flexure_x_corr_nm,
            flexure_y_corr_pix = flexure_y_corr_pix,
            flat_corrections=flat_corrections)

        np.save("var_" + outname, [E_var, meta_var])

    object = meta['header']['OBJECT'].split()[0]

    sixA, posA, adcpos, radius_used = identify_spectra_gui(E, radius=radius,
        PRLLTC=Angle(meta['PRLLTC'], unit='deg'),
        lmin=lmin, lmax=lmax, object=object, airmass=meta['airmass'])

    to_image(E, meta, outname, posA=posA, adcpos=adcpos)

    if standard is None:
        kixA = identify_bgd_spectra(E, posA, inner=radius_used*1.1)
    else:
        kixA = identify_sky_spectra(E, posA, inner=radius_used*1.1)

    # get the mean spectrum over the selected spaxels
    resA = interp_spectra(E, sixA, outname=outname+".pdf", corrfile=corrfile)
    skyA = interp_spectra(E, kixA, outname=outname+"_sky.pdf", corrfile=corrfile)
    varA = interp_spectra(E_var, sixA, outname=outname+"_var.pdf", corrfile=corrfile)

    ## Plot out the X/Y positions of the selected spaxels
    XSA = []
    YSA = []
    XSK = []
    YSK = []
    for ix in sixA:
        XSA.append(E[ix].X_as)
        YSA.append(E[ix].Y_as)
    for ix in kixA:
        XSK.append(E[ix].X_as)
        YSK.append(E[ix].Y_as)

    pl.figure()
    pl.clf()
    pl.ylim(-30,30)
    pl.xlim(-30,30)
    pl.scatter(XSA,YSA, color='red', marker='H', linewidth=.1)
    pl.scatter(XSK,YSK, color='green', marker='H', linewidth=.1)
    pl.savefig("XYs_%s.pdf" % outname)
    pl.close()
    # / End Plot

    # Define our standard wavelength grid
    ll = Wavelength.fiducial_spectrum()

    # Resample sky onto standard wavelength grid
    sky_A = interp1d(skyA[0]['nm'], skyA[0]['ph_10m_nm'], bounds_error=False)
    sky = sky_A(ll)

    # Resample variance onto standard wavelength grid
    var_A = interp1d(varA[0]['nm'], varA[0]['ph_10m_nm'], bounds_error=False)
    varspec = var_A(ll)

    # Copy and resample object spectrum onto standard wavelength grid
    res = np.copy(resA)
    res = [{"doc": resA[0]["doc"], "ph_10m_nm": np.copy(resA[0]["ph_10m_nm"]),
        "spectra": np.copy(resA[0]["spectra"]),
        "coefficients": np.copy(resA[0]["coefficients"]),
        "nm": np.copy(resA[0]["ph_10m_nm"])}]
    res[0]['nm'] = np.copy(ll)
    f1 = interp1d(resA[0]['nm'], resA[0]['ph_10m_nm'], bounds_error=False)

    # Calculate airmass correction
    airmass = meta['airmass']

    extCorr = 10**(Atm.ext(ll*10) * airmass/2.5)
    print "Median airmass corr: %.4f" % np.median(extCorr)

    # Calculate output corrected spectrum
    if nosky:
        # Account for airmass and aperture
        res[0]['ph_10m_nm'] = f1(ll) * extCorr * len(sixA)
    else:
        # Account for sky, airmass and aperture
        res[0]['ph_10m_nm'] = (f1(ll)-sky_A(ll)) * extCorr * len(sixA)

    # Process standard star objects
    if standard is not None:
        print "STANDARD"

        # Extract reference data
        wav = standard[:,0]/10.0
        flux = standard[:,1]

        # Calculate/Interpolate correction onto object wavelengths
        fun = interp1d(wav, flux, bounds_error=False, fill_value = np.nan)
        correction0 = fun(res[0]['nm'])/res[0]['ph_10m_nm']

        # Filter for resolution
        flxf = filters.gaussian_filter(flux,19.)

        # Calculate/Interpolate filtered correction
        fun = interp1d(wav, flxf, bounds_error=False, fill_value = np.nan)
        correction = fun(res[0]['nm'])/res[0]['ph_10m_nm']

        # Use unfiltered for H-beta region
        ROI = (res[0]['nm'] > 470.) & (res[0]['nm'] < 600.)
        correction[ROI] = correction0[ROI]

        res[0]['std-correction'] = correction
        res[0]['std-maxnm'] = np.max(wav)


    res[0]['exptime'] = meta['exptime']
    res[0]['Extinction Correction'] = 'Applied using Hayes & Latham'
    res[0]['extinction_corr'] = extCorr
    res[0]['skyph'] = sky * len(sixA)
    res[0]['skynm'] = ll
    res[0]['var'] = varspec
    res[0]['radius_as'] = radius_used
    res[0]['position'] = posA
    res[0]['N_spax'] = len(sixA)
    res[0]['meta'] = meta
    res[0]['object_spaxel_ids'] = sixA
    res[0]['sky_spaxel_ids'] = kixA
    res[0]['sky_spectra'] = skyA[0]['spectra']

    coef = chebfit(np.arange(len(ll)), ll, 4)
    xs = np.arange(len(ll)+1)
    newll = chebval(xs, coef)

    res[0]['dlam'] = np.diff(newll)

    np.save("sp_" + outname, res)
    print "Wrote sp_"+outname+".npy"