def makemasterflat(flatfiles, rawpath, plot=True): # normalize the flat fields for f in flatfiles: binning = get_binning(f, rawpath) # Use IRAF to get put the data in the right format and subtract the # bias # This will currently break if multiple flats are used for a single setting iraf.unlearn(iraf.gsreduce) if dobias: biasfile = "bias{binning}".format(binning=binning) else: biasfile = '' iraf.gsreduce('@' + f, outimages = f[:-4]+'.mef.fits',rawpath=rawpath, fl_bias=dobias, bias=biasfile, fl_over=dooverscan, fl_flat=False, fl_gmosaic=False, fl_fixpix=False, fl_gsappwave=False, fl_cut=False, fl_title=False, fl_oversize=False, fl_vardq=dodq) if do_qecorr: # Renormalize the chips to remove the discrete jump in the # sensitivity due to differences in the QE for different chips iraf.unlearn(iraf.gqecorr) iraf.gqecorr(f[:-4]+'.mef', outimages=f[:-4]+'.qe.fits', fl_keep=True, fl_correct=True, refimages=f[:-4].replace('flat', 'arc.arc.fits'), corrimages=f[:-9] +'.qe.fits', verbose=True, fl_vardq=dodq) iraf.unlearn(iraf.gmosaic) iraf.gmosaic(f[:-4]+'.qe.fits', outimages=f[:-4]+'.mos.fits', fl_vardq=dodq, fl_clean=False) else: iraf.unlearn(iraf.gmosaic) iraf.gmosaic(f[:-4]+'.mef.fits', outimages=f[:-4]+'.mos.fits', fl_vardq=dodq, fl_clean=False) flat_hdu = fits.open(f[:-4] + '.mos.fits') data = np.median(flat_hdu['SCI'].data, axis=0) chip_edges = get_chipedges(data) x = np.arange(len(data), dtype=np.float) x /= x.max() y = data / np.median(data) fitme_x = x[chip_edges[0][0]:chip_edges[0][1]] fitme_x = np.append(fitme_x, x[chip_edges[1][0]:chip_edges[1][1]]) fitme_x = np.append(fitme_x, x[chip_edges[2][0]:chip_edges[2][1]]) fitme_y = y[chip_edges[0][0]:chip_edges[0][1]] fitme_y = np.append(fitme_y, y[chip_edges[1][0]:chip_edges[1][1]]) fitme_y = np.append(fitme_y, y[chip_edges[2][0]:chip_edges[2][1]]) fit = pfm.pffit(fitme_x, fitme_y, 21, 7, robust=True, M=sm.robust.norms.AndrewWave()) if plot: pyplot.ion() pyplot.clf() pyplot.plot(x, y) pyplot.plot(x, pfm.pfcalc(fit, x)) _junk = raw_input('Press enter to continue') flat_hdu['SCI'].data /= pfm.pfcalc(fit, x) * np.median(data) flat_hdu.writeto(f[:-4] + '.fits')
def makemasterflat(flatfiles, rawpath, plot=True): # normalize the flat fields for f in flatfiles: # Use IRAF to get put the data in the right format and subtract the # bias # This will currently break if multiple flats are used for a single setting iraf.unlearn(iraf.gsreduce) iraf.gsreduce('@' + f, outimages = f[:-4]+'.mef.fits',rawpath=rawpath, bias="bias", fl_over=dooverscan, fl_flat=False, fl_gmosaic=False, fl_fixpix=False, fl_gsappwave=False, fl_cut=False, fl_title=False, fl_oversize=False) if is_GS: # Renormalize the chips to remove the discrete jump in the # sensitivity due to differences in the QE for different chips iraf.unlearn(iraf.gqecorr) iraf.gqecorr(f[:-4]+'.mef', outimages=f[:-4]+'.qe.fits', fl_keep=True, fl_correct=True, refimages=f[:-4].replace('flat', 'arc.arc.fits'), corrimages=f[:-9] +'.qe.fits', verbose=True) iraf.unlearn(iraf.gmosaic) iraf.gmosaic(f[:-4]+'.qe.fits', outimages=f[:-4]+'.mos.fits') else: iraf.unlearn(iraf.gmosaic) iraf.gmosaic(f[:-4]+'.mef.fits', outimages=f[:-4]+'.mos.fits') flat_hdu = pyfits.open(f[:-4] + '.mos.fits') data = np.median(flat_hdu['SCI'].data, axis=0) chip_edges = get_chipedges(data) x = np.arange(len(data), dtype=np.float) x /= x.max() y = data / np.median(data) fitme_x = x[chip_edges[0][0]:chip_edges[0][1]] fitme_x = np.append(fitme_x, x[chip_edges[1][0]:chip_edges[1][1]]) fitme_x = np.append(fitme_x, x[chip_edges[2][0]:chip_edges[2][1]]) fitme_y = y[chip_edges[0][0]:chip_edges[0][1]] fitme_y = np.append(fitme_y, y[chip_edges[1][0]:chip_edges[1][1]]) fitme_y = np.append(fitme_y, y[chip_edges[2][0]:chip_edges[2][1]]) fit = pfm.pffit(fitme_x, fitme_y, 15, 7, robust=True, M=sm.robust.norms.AndrewWave()) if plot: from matplotlib import pyplot pyplot.ion() pyplot.clf() pyplot.plot(x, y) pyplot.plot(x, pfm.pfcalc(fit, x)) _junk = raw_input('Press enter to continue') flat_hdu['SCI'].data /= pfm.pfcalc(fit, x) * np.median(data) flat_hdu.writeto(f[:-4] + '.fits')
def specsens(specfile, outfile, stdfile, extfile, airmass=None, exptime=None, stdzp=3.68e-20, thresh=8, clobber=True): # read in the specfile and create a spectrum object obs_hdu = pyfits.open(specfile) try: obs_flux = obs_hdu[2].data.copy()[0] obs_hdr = obs_hdu[2].header.copy() except: obs_flux = obs_hdu[0].data.copy() obs_hdr = obs_hdu[0].header.copy() obs_hdu.close() obs_wave = fitshdr_to_wave(obs_hdr) # Mask out everything below 3450 where there is no signal obs_flux = obs_flux[obs_wave >= bluecut] obs_wave = obs_wave[obs_wave >= bluecut] # Figure out where the chip gaps are chip_edges = get_chipedges(obs_flux) try: chip_gaps = np.ones(obs_flux.size, dtype=np.bool) for edge in chip_edges: chip_gaps[edge[0]: edge[1]] = False except: chip_gaps = np.zeros(obs_flux.size, dtype=np.bool) template_spectrum = signal.savgol_filter(obs_flux, 21, 3) noise = np.abs(obs_flux - template_spectrum) noise = ndimage.filters.gaussian_filter1d(noise, 100.0) if chip_gaps.sum() != len(chip_gaps): # Smooth the chip gaps intpr = interpolate.splrep(obs_wave[np.logical_not(chip_gaps)], obs_flux[np.logical_not(chip_gaps)], w=1 / noise[np.logical_not(chip_gaps)], k=2, s=20 * np.logical_not(chip_gaps).sum()) obs_flux[chip_gaps] = interpolate.splev(obs_wave[chip_gaps], intpr) # smooth the observed spectrum # read in the std file and convert from magnitudes to fnu # then convert it to fwave (ergs/s/cm2/A) std_wave, std_mag, _stdbnd = np.genfromtxt(stdfile).transpose() std_flux = magtoflux(std_wave, std_mag, stdzp) # Get the typical bandpass of the standard star, std_bandpass = np.diff(std_wave).mean() # Smooth the observed spectrum to that bandpass obs_flux = boxcar_smooth(obs_wave, obs_flux, std_bandpass) # read in the extinction file (leave in magnitudes) ext_wave, ext_mag = np.genfromtxt(extfile).transpose() # calculate the calibrated spectra cal_flux = cal_std(obs_wave, obs_flux, std_wave, std_flux, ext_wave, ext_mag, airmass, exptime) # Normalize the fit variables so the fit is well behaved fitme_x = (obs_wave - obs_wave.min()) / (obs_wave.max() - obs_wave.min()) fitme_y = cal_flux / np.median(cal_flux) coeffs = pfm.pffit(fitme_x, fitme_y, 5 , 7, robust=True, M=sm.robust.norms.AndrewWave()) fitted_flux = pfm.pfcalc(coeffs, fitme_x) * np.median(cal_flux) cal_mag = -1.0 * fluxtomag(fitted_flux) # write the spectra out cal_hdr = sanitizeheader(obs_hdr.copy()) cal_hdr['OBJECT'] = 'Sensitivity function for all apertures' cal_hdr['CRVAL1'] = obs_wave.min() cal_hdr['CRPIX1'] = 1 if is_GS: cal_hdr['QESTATE'] = True else: cal_hdr['QESTATE'] = False tofits(outfile, cal_mag, hdr=cal_hdr, clobber=True)
def specsens(specfile, outfile, stdfile, extfile, airmass=None, exptime=None, stdzp=3.68e-20, thresh=8, clobber=True): # read in the specfile and create a spectrum object obs_hdu = fits.open(specfile) try: obs_flux = obs_hdu[2].data.copy()[0] obs_hdr = obs_hdu[2].header.copy() except: obs_flux = obs_hdu[0].data.copy() obs_hdr = obs_hdu[0].header.copy() obs_hdu.close() obs_wave = fitshdr_to_wave(obs_hdr) # Mask out everything below 3450 where there is no signal obs_flux = obs_flux[obs_wave >= bluecut] obs_wave = obs_wave[obs_wave >= bluecut] # Figure out where the chip gaps are chip_edges = get_chipedges(obs_flux) try: chip_gaps = np.ones(obs_flux.size, dtype=np.bool) for edge in chip_edges: chip_gaps[edge[0]: edge[1]] = False except: chip_gaps = np.zeros(obs_flux.size, dtype=np.bool) template_spectrum = signal.savgol_filter(obs_flux, 21, 3) noise = np.abs(obs_flux - template_spectrum) noise = ndimage.filters.gaussian_filter1d(noise, 100.0) if chip_gaps.sum() != len(chip_gaps): # Smooth the chip gaps intpr = interpolate.splrep(obs_wave[np.logical_not(chip_gaps)], obs_flux[np.logical_not(chip_gaps)], w=1 / noise[np.logical_not(chip_gaps)], k=2, s=20 * np.logical_not(chip_gaps).sum()) obs_flux[chip_gaps] = interpolate.splev(obs_wave[chip_gaps], intpr) # smooth the observed spectrum # read in the std file and convert from magnitudes to fnu # then convert it to fwave (ergs/s/cm2/A) std_wave, std_mag, _stdbnd = np.genfromtxt(stdfile).transpose() std_flux = magtoflux(std_wave, std_mag, stdzp) # Get the typical bandpass of the standard star, std_bandpass = np.max([50.0, np.diff(std_wave).mean()]) # Smooth the observed spectrum to that bandpass obs_flux = boxcar_smooth(obs_wave, obs_flux, std_bandpass) # read in the extinction file (leave in magnitudes) ext_wave, ext_mag = np.genfromtxt(extfile).transpose() # calculate the calibrated spectra cal_flux = cal_std(obs_wave, obs_flux, std_wave, std_flux, ext_wave, ext_mag, airmass, exptime) # Normalize the fit variables so the fit is well behaved fitme_x = (obs_wave - obs_wave.min()) / (obs_wave.max() - obs_wave.min()) fitme_y = cal_flux / np.median(cal_flux) coeffs = pfm.pffit(fitme_x, fitme_y, 5 , 7, robust=True, M=sm.robust.norms.AndrewWave()) fitted_flux = pfm.pfcalc(coeffs, fitme_x) * np.median(cal_flux) cal_mag = -1.0 * fluxtomag(fitted_flux) # write the spectra out cal_hdr = sanitizeheader(obs_hdr.copy()) cal_hdr['OBJECT'] = 'Sensitivity function for all apertures' cal_hdr['CRVAL1'] = obs_wave.min() cal_hdr['CRPIX1'] = 1 if do_qecorr: cal_hdr['QESTATE'] = True else: cal_hdr['QESTATE'] = False tofits(outfile, cal_mag, hdr=cal_hdr, clobber=True)