def makeartificial(sw, sf, fmax, res, dw, pad=10, nkern=200, wrange=None): """For a given line list with fluxes, create an artifical spectrum""" if wrange is None: wrange = [sw.min() - pad, sw.max() + pad] spec = Spectrum.Spectrum( sw, sf, wrange=wrange, dw=dw, stype='line', sigma=res) spec.flux = spec.flux * fmax / spec.flux.max() return spec.wavelength, spec.flux
def getfitsspec(dw=0.1, res=0.1): wrange = None #[y.min(), y.max()] shdu = fits.open('thar.fits') ctype1=shdu[0].header['CTYPE1'] crval1=shdu[0].header['CRVAL1'] cdelt1=shdu[0].header['CDELT1'] sf=shdu[0].data sw=crval1+cdelt1*np.arange(len(shdu[0].data)) spec=Spectrum.Spectrum(sw, sf, wrange=wrange, dw=dw, stype='continuum', sigma=res) return spec
def readspectrum(specfile, stype='continuum', error=True, cols=None, ftype=None): """Given a specfile, read in the spectra and return a spectrum object specfile--file containing the input spectra error--include an error column in the creation of the spectrum object cols--columns or column names for the wavelength, flux, and/or flux error ftype--type of file (ascii or fits) """ # set the ftype for a fits file if ftype is None: if specfile[-5] == '.fits': ftype = 'fits' else: ftype = 'ascii' if ftype == 'ascii': if error: if cols is None: cols = (0, 1, 2) warr, farr, farr_err = np.loadtxt( specfile, usecols=cols, unpack=True) spectra = Spectrum.Spectrum(warr, farr, farr_err, stype=stype) else: if cols is None: cols = (0, 1) warr, farr = np.loadtxt(specfile, usecols=cols, unpack=True) spectra = Spectrum.Spectrum(warr, farr, stype=stype) elif ftype == 'fits': message = 'Support for FITS files not provided yet' raise SaltError(message) else: message = 'Support for %s files is not provided' raise SaltError(message) return spectra
def calfunc(obs_spectra, std_spectra, ext_spectra, airmass, exptime, error=False): """Given an observe spectra, calculate the calibration curve for the spectra. All data is interpolated to the binning of the obs_spectra. The calibrated spectra is then calculated from: C = F_obs/ F_std / 10**(-0.4*A*E)/T/dW where F_obs is the observed flux from the source, F_std is the standard spectra, A is the airmass, E is the extinction in mags, T is the exposure time and dW is the bandpass Parameters ----------- obs_spectra--spectrum of the observed star (counts/A) std_spectra--know spectrum of the standard star (ergs/s/cm2/A) ext_spectra--spectrum of the extinction curve (in mags) airmass--airmass of the observations exptime--exposure time of the observations function """ # re-interpt the std_spectra over the same wavelength std_spectra.interp(obs_spectra.wavelength) # re-interp the ext_spetra over the sam ewavelength ext_spectra.interp(obs_spectra.wavelength) # create the calibration spectra cal_spectra = Spectrum.Spectrum( obs_spectra.wavelength, obs_spectra.flux.copy(), stype='continuum') # set up the bandpass bandpass = np.diff(obs_spectra.wavelength).mean() # correct for extinction cal_spectra.flux = obs_spectra.flux / \ 10 ** (-0.4 * airmass * ext_spectra.flux) # correct for the exposure time and calculation the calitivity curve cal_spectra.flux = cal_spectra.flux / exptime / bandpass / std_spectra.flux # correct the error calc if error: cal_spectra.var = obs_spectra.var * cal_spectra.flux / obs_spectra.flux return cal_spectra
def test_Linefit(): hdu = pyfits.open(inimage) # create the data arra data = hdu[1].data # create the header information instrume = hdu[1].header['INSTRUME'].strip() grating = hdu[1].header['GRATING'].strip() grang = hdu[1].header['GR-ANGLE'] arang = hdu[1].header['AR-ANGLE'] filter = hdu[1].header['FILTER'].strip() slit = float(hdu[1].header['MASKID']) xbin, ybin = hdu[1].header['CCDSUM'].strip().split() # print instrume, grating, grang, arang, filter # print xbin, ybin # print len(data), len(data[0]) # create the RSS Model rssmodel = RSSModel.RSSModel(grating_name=grating, gratang=grang, camang=arang, slit=slit, xbin=int(xbin), ybin=int(ybin)) alpha = rssmodel.rss.gratang beta = rssmodel.rss.gratang - rssmodel.rss.camang sigma = 1e7 * rssmodel.rss.calc_resolelement(alpha, beta) # create artificial spectrum # create the spectrum stype = 'line' w, s = np.loadtxt(inspectra, usecols=(0, 1), unpack=True) spec = Spectrum(w, s, wrange=[4000, 5000], dw=0.1, stype='line', sigma=sigma) spec.flux = spec.set_dispersion(sigma=sigma) sw_arr, sf_arr = spec.wavelength, spec.flux
def test_CreateImage(): # read in the data hdu = fits.open(inimg) im_arr = hdu[1].data hdu.close() # set up the spectrum stype = 'line' w, s = np.loadtxt('Xe.dat', usecols=(0, 1), unpack=True) spec = Spectrum(w, s, wrange=[4000, 5000], dw=0.1, stype=stype) # set up the spectrograph dx = 2 * 0.015 * 8.169 dy = 2 * 0.015 * 0.101 # set up the spectrograph # rssmodel=RSSModel.RSSModel(grating_name='PG0900', gratang=13.625, camang=27.25, slit=1.0, xbin=2, ybin=2, xpos=dx, ypos=dy) rssmodel = RSSModel.RSSModel( grating_name='PG3000', gratang=43.625, camang=87.25, slit=2.0, xbin=2, ybin=2, xpos=dx, ypos=dy) rssmodel.set_camera(name='RSS', focallength=330.0) rss = rssmodel.rss # set up the outfile if os.path.isfile(outfile): os.remove(outfile) arr = im_arr.copy() arr = CreateImage(spec, rss) arr = arr * im_arr.max() / spec.flux.max() writeout(arr, outfile)
def plotarcspectra(arclist='Ne.txt', grating='PG0900', gratang=15.0, camang=30.0, slit=1.5, xbin=2, ybin=2): """Plot an Arc Line list for a given RSS set up arclist--an arc line list in the format of 'wavelength flux' for arc lines grating--name of the grating gratang--angle of the grating camang--angle of the camera (articulation angle) slit--slit width in arcseconds xbin--xbinning ybin--ybinning """ rss = RSSModel.RSSModel(grating_name=grating, gratang=gratang, camang=camang, slit=slit, xbin=xbin, ybin=ybin) #print out some basic statistics print 1e7 * rss.calc_bluewavelength(), 1e7 * rss.calc_centralwavelength( ), 1e7 * rss.calc_redwavelength() R = rss.calc_resolution(rss.calc_centralwavelength(), rss.alpha(), -rss.beta()) res = 1e7 * rss.calc_resolelement(rss.alpha(), -rss.beta()) print R, res #set up the detector ycen = rss.detector.get_ypixcenter() d_arr = rss.detector.make_detector()[ycen, :] #creates 1-D detector map xarr = np.arange(len(d_arr)) w = 1e7 * rss.get_wavelength(xarr) #set up the artificial spectrum sw, sf = pl.loadtxt(arclist, usecols=(0, 1), unpack=True) wrange = [1e7 * rss.calc_bluewavelength(), 1e7 * rss.calc_redwavelength()] spec = Spectrum.Spectrum(sw, sf, wrange=wrange, dw=res / 10, stype='line', sigma=res) #interpolate it over the same range as the detector spec.interp(w) #plot it pl.figure() pl.plot(spec.wavelength, d_arr * ((spec.flux) / spec.flux.max())) print pl.gca().get_ylim() for i, f in zip(sw, sf): if i > spec.wavelength.min() and i < spec.wavelength.max(): print i, f, sf.max(), spec.flux.max() #pl.text(i, f/sf.max(), i, fontsize='large', rotation=90) y = max(0.1, f / sf.max()) pl.text(i, y, i, rotation=90) pl.show()
def test_Linefit(): hdu = fits.open(inimage) # create the data arra data = hdu[1].data # create the header information grating = hdu[1].header['GRATING'].strip() grang = hdu[1].header['GR-ANGLE'] arang = hdu[1].header['AR-ANGLE'] slit = float(hdu[1].header['MASKID']) xbin, ybin = hdu[1].header['CCDSUM'].strip().split() # print instrume, grating, grang, arang, filter # print xbin, ybin # print len(data), len(data[0]) # create the RSS Model rssmodel = RSSModel.RSSModel(grating_name=grating, gratang=grang, camang=arang, slit=slit, xbin=int(xbin), ybin=int(ybin)) alpha = rssmodel.rss.gratang beta = rssmodel.rss.gratang - rssmodel.rss.camang sigma = 1e7 * rssmodel.rss.calc_resolelement(alpha, beta) # create the observed spectrum midpoint = int(0.5 * len(data)) xarr = np.arange(len(data[0]), dtype='float') farr = data[midpoint, :] obs_spec = Spectrum(xarr, farr, stype='continuum') # create artificial spectrum stype = 'line' w, s = np.loadtxt(inspectra, usecols=(0, 1), unpack=True) cal_spec = Spectrum(w, s, wrange=[4000, 5000], dw=0.1, stype=stype, sigma=sigma) cal_spec.flux = cal_spec.set_dispersion(sigma=sigma) cal_spec.flux = cal_spec.flux * obs_spec.flux.max() / cal_spec.flux.max( ) + 1 lf = LF.LineFit(obs_spec, cal_spec, function='legendre', order=3) lf.set_coef( [4.23180070e+03, 2.45517852e-01, -4.46931562e-06, -2.22067766e-10]) print(lf(2000)) print(lf.obs_spec.get_flux(2000), lf.flux(2000)) print('chisq ', (lf.errfit(lf.coef, xarr, farr)**2).sum() / 1e7) lf.set_coef( [4.23280070e+03, 2.45517852e-01, -4.46931562e-06, -2.22067766e-10]) print(lf(2000)) print(lf.obs_spec.get_flux(2000), lf.flux(2000)) print('chisq ', (lf.errfit(lf.coef, xarr, farr)**2).sum() / 1e7) # print lf.lfit(xarr) # print lf.coef # print lf(2000) # print lf.results pl.figure() pl.plot(lf(lf.obs_spec.wavelength), lf.obs_spec.get_flux(xarr)) pl.plot(lf.cal_spec.wavelength, lf.cal_spec.flux) pl.show()
R = rss.calc_resolution(rss.calc_centralwavelength(), rss.alpha(), -rss.beta()) res = 1e7 * rss.calc_resolelement(rss.alpha(), -rss.beta()) print R, res #set up the detector ycen = rss.detector.get_ypixcenter() d_arr = rss.detector.make_detector()[ycen, :] xarr = np.arange(len(d_arr)) w = 1e7 * rss.get_wavelength(xarr) #set up the artificial spectrum sw, sf = pl.loadtxt('Ar.txt', usecols=(0, 1), unpack=True) wrange = [1e7 * rss.calc_bluewavelength(), 1e7 * rss.calc_redwavelength()] spec = Spectrum.Spectrum(sw, sf, wrange=wrange, dw=res / 10, stype='line', sigma=res) #interpolate it over the same range as the detector spec.interp(w) #plot it pl.figure() pl.plot(spec.wavelength, d_arr * ((spec.flux) / spec.flux.max())) pl.plot(spec.wavelength, d_arr * 0.1) yy = np.median(data[1000:1050, 3:3173], 0) pl.plot(spec.wavelength, yy / yy.max()) ymod = d_arr * ((spec.flux) / spec.flux.max()) ydata = yy / yy.max()
def extract_spectra(hdu, yc, dy, outfile, minsize=5, thresh=3, grow=0, smooth=False, maskzeros=False, convert=True, cleanspectra=True, calfile=None, clobber=True, specformat='ascii'): """From an image, extract a spectra. """ data=hdu[1].data #replace the zeros with the average from the frame if maskzeros: mean,std=iterstat(data[data>0]) #rdata=mean np.random.normal(mean, std, size=data.shape) data[data<=0]=mean #rdata[data<=0] y1=yc-dy y2=yc+dy #sy1=y2-2*dy #sy2=y2+2*dy #sdata = 1.0 * data #y,x = np.indices(sdata.shape) #for i in range(sdata.shape[1]): # mask=(hdu[3].data[:,i]==0) # mask[sy1:sy2] = 0 # if mask.sum()>0: # sdata[y1:y2,i] = np.interp(y[y1:y2,i], y[:,i][mask], data[:,i][mask]) #hdu[1].data = sdata #sk_list=extract(hdu, method='normal', section=[(y1,y2)], minsize=minsize, thresh=thresh, convert=True) #ap_list[0].ldata=ap_list[0].ldata-sk_list[0].ldata #ap_list[0].ldata=ap_list[0].ldata-float(y2-y1)/(sy2-sy1)*sk_list[0].ldata ap_list=extract(hdu, method='normal', section=[(y1,y2)], minsize=minsize, thresh=thresh, convert=convert) sy1a=y2 sy2a=sy1a+2.0*dy ska_list=extract(hdu, method='normal', section=[(sy1a,sy2a)], minsize=minsize, thresh=thresh, convert=convert) sy2b=y1-dy sy1b=sy2b-2.0*dy skb_list=extract(hdu, method='normal', section=[(sy1b,sy2b)], minsize=minsize, thresh=thresh, convert=convert) print sy1b, sy2b sdata = 0.5*(ska_list[0].ldata/(sy2a-sy1a) + skb_list[0].ldata/(sy2b-sy1b)) #sdata = ska_list[0].ldata/(sy2a-sy1a) #sdata = skb_list[0].ldata/(sy2b-sy1b) raw = 1.0 * ap_list[0].ldata ap_list[0].ldata=ap_list[0].ldata-float(y2-y1) * sdata print ap_list[0].wave[10], ap_list[0].ldata[10], ap_list[0].lvar[10] flux_spec=Spectrum.Spectrum(ap_list[0].wave, ap_list[0].ldata, abs(ap_list[0].lvar)**0.5, stype='continuum') print flux_spec.wavelength[10], flux_spec.flux[10], flux_spec.var[10] if cleanspectra: clean_spectra(ap_list[0], grow=grow) if calfile: cal_spectra=st.readspectrum(calfile, error=False, ftype='ascii') airmass=hdu[0].header['AIRMASS'] exptime=hdu[0].header['EXPTIME'] extfile=iraf.osfn("pysalt$data/site/suth_extinct.dat") ext_spectra=st.readspectrum(extfile, error=False, ftype='ascii') flux_spec=Spectrum.Spectrum(ap_list[0].wave, ap_list[0].ldata, abs(ap_list[0].lvar)**0.5, stype='continuum') print flux_spec.flux[10], flux_spec.var[10] flux_spec=calfunc(flux_spec, cal_spectra, ext_spectra, airmass, exptime, True) print flux_spec.flux[10], flux_spec.var[10] else: flux_spec = Spectrum.Spectrum(ap_list[0].wave, ap_list[0].ldata, abs(ap_list[0].lvar)**0.5, stype='continuum') if specformat == 'ascii': write_ascii(outfile, flux_spec, clobber=clobber) elif specformat == 'lcogt': write_lcogt(outfile, flux_spec, hdu, sky=float(y2-y1) * sdata, raw = raw, clobber=clobber)
def arclisfromhdr(hdr, slitwidth=1.50, xbin=2, ybin=2, lamp='Ar.txt'): # ** some numbers below hardwired for 2x2 binning (~3170 pix) ** grname = hdr['grating'] camang = hdr['camang'] gratang = hdr['gr-angle'] rss = RSSModel.RSSModel(grating_name=grname, gratang=gratang, camang=camang, slit=slitwidth, xbin=xbin, ybin=ybin) # set up the detector ycen = rss.detector.get_ypixcenter() d_arr = rss.detector.make_detector()[ycen, :] xarr = np.arange(len(d_arr)) w = 1e7 * rss.get_wavelength(xarr) #set up the artificial spectrum res = 1e7 * rss.calc_resolelement(rss.alpha(), -rss.beta()) sw, sf = pl.loadtxt(lamp, usecols=(0, 1), unpack=True) wrange = [1e7 * rss.calc_bluewavelength(), 1e7 * rss.calc_redwavelength()] spec = Spectrum.Spectrum(sw, sf, wrange=wrange, dw=res / 10, stype='line', sigma=res) #interpolate it over the same range as the detector spec.interp(w) if (0): #plot it pl.figure() pl.plot(spec.wavelength, d_arr * ((spec.flux) / spec.flux.max())) pl.plot(spec.wavelength, d_arr * 0.1) #yy=np.median(data[1000:1050,3:3173],0) #pl.plot(spec.wavelength,yy/yy.max()) ymod = d_arr * ((spec.flux) / spec.flux.max()) ydata = yy / yy.max() off, rval = xcor2(ydata, ymod, 100.) yyy = np.roll(yy, -int(off)) / yy.max() pl.plot(spec.wavelength, yyy) pl.show() stop() # We need to return # - a matched list of wavelength(of each pixel),flux for the arc # - a list of the arc lines modarclam = spec.wavelength modarcspec = d_arr * ((spec.flux) / spec.flux.max()) # extract pixel positions for lines of wavelength sw: xpix = np.arange(np.size(modarclam)) ixp = np.interp(sw, modarclam, xpix, left=0, right=0) ok = np.reshape(((ixp > 0.) & (ixp < 3170)).nonzero(), -1) np.savetxt('_tmparc.lis', np.transpose((ixp[ok], sw[ok], sw[ok]))) return modarclam, modarcspec