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()
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()
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)
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)
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)
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)
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)
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)
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"