def loadStd(objectName,wvlBinEdges): #import the known spectrum of the calibrator and rebin to the histogram parameters given #must be imported into array with dtype float so division later does not have error std = MKIDStd.MKIDStd() a = std.load(objectName) a = std.normalizeFlux(a) x = a[:,0] y = a[:,1] realSpectra = y realSpectraWvl = x newa = rebin(x,y,wvlBinEdges) binnedSpectra = newa[:,1] return binnedSpectra
def cleanSpectrum(x,y,objectName, wvlBinEdges): #locations and widths of absorption features in Angstroms #features = [3890,3970,4099,4340,4860,6564,6883,7619] #widths = [50,50,50,50,50,50,50,50] #for i in xrange(len(features)): # #check for absorption feature in std spectrum # ind = np.where((x<(features[i]+15)) & (x>(features[i]-15)))[0] # if len(ind)!=0: # ind = ind[len(ind)/2] # #if feature is found (flux is higher on both sides of the specified wavelength where the feature should be) # if y[ind]<y[ind+1] and y[ind]<y[ind-1]: # #cut out width[i] around feature[i] # inds = np.where((x >= features[i]+widths[i]) | (x <= features[i]-widths[i])) # x = x[inds] # y = y[inds] #fit a tail to the end of the spectrum to interpolate out to desired wavelength in angstroms fraction = 2.1/3 newx = np.arange(int(x[fraction*len(x)]),20000) slopeguess = (np.log(y[-1])-np.log(y[fraction*len(x)]))/(x[-1]-x[fraction*len(x)]) print "Guess at exponential slope is %f"%(slopeguess) guess_a, guess_b, guess_c = float(y[fraction*len(x)]), x[fraction*len(x)], slopeguess guess = [guess_a, guess_b, guess_c] fitx = x[fraction*len(x):] fity = y[fraction*len(x):] exp_decay = lambda fx, A, x0, t: A * np.exp((fx-x0) * t) params, cov = curve_fit(exp_decay, fitx, fity, p0=guess, maxfev=2000) A, x0, t= params print "A = %s\nx0 = %s\nt = %s\n"%(A, x0, t) best_fit = lambda fx: A * np.exp((fx-x0)*t) calcx = np.array(newx,dtype=float) newy = best_fit(calcx) #func = interpolate.splrep(x[fration*len(x):],y[fraction*len(x):],s=smooth) #newx = np.arange(int(x[fraction*len(x)]),self.wvlBinEdges[-1]) #newy = interpolate.splev(newx,func) wl = np.concatenate((x,newx[newx>max(x)])) flux = np.concatenate((y,newy[newx>max(x)])) #new method, rebin data to grid of wavelengths generated from a grid of evenly spaced energy bins #R=7.0 at 4500 #R=E/dE -> dE = R/E dE = 0.3936 #eV start = 1000 #Angs stop = 25000 #Angs enBins = ObsFile.makeWvlBins(dE,start,stop) rebinned = rebin(wl,flux,enBins) re_wl = rebinned[:,0] re_flux = rebinned[:,1] #plt.plot(re_wl,re_flux,color='r') re_wl = re_wl[np.isnan(re_flux)==False] re_flux = re_flux[np.isnan(re_flux)==False] start1 = wvlBinEdges[0] stop1 = wvlBinEdges[-1] #regrid downsampled data new_wl = np.arange(start1,stop1) #print re_wl #print re_flux #print new_wl #weight=1.0/(re_flux)**(2/1.00) print len(re_flux) weight = np.ones(len(re_flux)) #decrease weights near peak ind = np.where(re_flux == max(re_flux))[0] weight[ind] = 0.3 for p in [1,2,3]: if p==1: wt = 0.3 elif p==2: wt = 0.6 elif p==3: wt = 0.7 try: weight[ind+p] = wt except IndexError: pass try: if ind-p >= 0: weight[ind-p] = wt except IndexError: pass #change weights to set how tightly fit must match data points #weight[-4:] = 1.0 weight = [0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7] #print len(weight) #weight = re_flux/min(re_flux) #weight = 1.0/weight #weight = weight/max(weight) print weight f = interpolate.splrep(re_wl,re_flux,w=weight,k=3,s=max(re_flux)**200) new_flux = interpolate.splev(new_wl,f,der=0) return new_wl, new_flux
def cleanSpectrum(x,y,objectName, wvlBinEdges): #locations and widths of absorption features in Angstroms #features = [3890,3970,4099,4340,4860,6564,6883,7619] #widths = [50,50,50,50,50,50,50,50] #for i in xrange(len(features)): # #check for absorption feature in std spectrum # ind = np.where((x<(features[i]+15)) & (x>(features[i]-15)))[0] # if len(ind)!=0: # ind = ind[len(ind)/2] # #if feature is found (flux is higher on both sides of the specified wavelength where the feature should be) # if y[ind]<y[ind+1] and y[ind]<y[ind-1]: # #cut out width[i] around feature[i] # inds = np.where((x >= features[i]+widths[i]) | (x <= features[i]-widths[i])) # x = x[inds] # y = y[inds] #fit a tail to the end of the spectrum to interpolate out to desired wavelength in angstroms fraction = 0 #4.0/5.0 newx = np.arange(int(x[fraction*len(x)]),20000) #slopeguess = (np.log(y[-1])-np.log(y[fraction*len(x)]))/(x[-1]-x[fraction*len(x)]) #print "Guess at exponential slope is %f"%(slopeguess) #guess_a, guess_b, guess_c = float(y[fraction*len(x)]), x[fraction*len(x)], slopeguess #guess = [guess_a, guess_b, guess_c] fitx = x[fraction*len(x)::] fity = y[fraction*len(x)::] #exp_decay = lambda fx, A, x0, t: A * np.exp((fx-x0) * t) #params, cov = curve_fit(exp_decay, fitx, fity, p0=guess, maxfev=2000) #A, x0, t= params #print "A = %s\nx0 = %s\nt = %s\n"%(A, x0, t) #best_fit = lambda fx: A * np.exp((fx-x0)*t) #calcx = np.array(newx,dtype=float) #newy = best_fit(calcx) #normalizing norm = fity.max() fity/=norm guess_a, guess_b = 1/(2*h*c**2/1e-9), 5600 #Constant, Temp guess = [guess_a, guess_b] blackbody = lambda fx, N, T: N * 2*h*c**2 / (fx)**5 * (exp(h*c/(k*T*(fx))) - 1)**-1 # Planck Law #blackbody = lambda fx, N, T: N*2*c*k*T/(fx)**4 #Rayleigh Jeans tail #blackbody = lambda fx, N, T: N*2*h*c**2/(fx**5) * exp(-h*c/(k*T*fx)) #Wein Approx params, cov = curve_fit(blackbody, fitx*1.0e-8, fity, p0=guess, maxfev=2000) N, T= params print "N = %s\nT = %s\n"%(N, T) best_fit = lambda fx: N * 2*h*c**2 / (fx)**5 * (exp(h*c/(k*T*(fx))) - 1)**-1 #Planck Law #best_fit = lambda fx: N*2*c*k*T/(fx)**4 # Rayleigh Jeans Tail #best_fit = lambda fx: N*2*h*c**2/(fx**5) * exp(-h*c/(k*T*fx)) #Wein Approx calcx = np.array(newx,dtype=float) bbfit = best_fit(calcx*1.0E-8) calcx = np.array(newx,dtype=float) newy = best_fit(calcx*1.0E-8) fity*=norm newy*=norm plt.plot(calcx[3.0*len(fitx)/4.0::],newy[3.0*len(fitx)/4.0::]*1E15,linestyle='--',linewidth=2, color="black",alpha=0.5) #plot fit #func = interpolate.splrep(x[fration*len(x):],y[fraction*len(x):],s=smooth) #newx = np.arange(int(x[fraction*len(x)]),self.wvlBinEdges[-1]) #newy = interpolate.splev(newx,func) wl = np.concatenate((x,newx[newx>max(x)])) flux = np.concatenate((y,newy[newx>max(x)])) #new method, rebin data to grid of wavelengths generated from a grid of evenly spaced energy bins #R=7.0 at 4500 #R=E/dE -> dE = R/E dE = 0.3936 #eV start = 1000 #Angs stop = 25000 #Angs enBins = ObsFile.makeWvlBins(dE,start,stop) rebinned = rebin(wl,flux,enBins) re_wl = rebinned[:,0] re_flux = rebinned[:,1] plt.plot(re_wl,re_flux*1E15,linestyle="o", marker="o",markersize=6) #plot rebinned spectrum with exp tail re_wl = re_wl[np.isnan(re_flux)==False] re_flux = re_flux[np.isnan(re_flux)==False] start1 = wvlBinEdges[0] stop1 = wvlBinEdges[-1] #regrid downsampled data new_wl = np.arange(start1,stop1) #print re_wl #print re_flux #print new_wl #weight=1.0/(re_flux)**(2/1.00) print len(re_flux) weight = np.ones(len(re_flux)) #decrease weights near peak ind = np.where(re_flux == max(re_flux))[0] weight[ind] = 0.3 for p in [1,2,3]: if p==1: wt = 0.3 elif p==2: wt = 0.6 elif p==3: wt = 0.7 try: weight[ind+p] = wt except IndexError: pass try: if ind-p >= 0: weight[ind-p] = wt except IndexError: pass #change weights to set how tightly fit must match data points #weight[-4:] = 1.0 weight = 0.7*np.ones((len(re_wl)),dtype=float) #weight = [0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7] #print len(weight) #weight = re_flux/min(re_flux) #weight = 1.0/weight #weight = weight/max(weight) print weight f = interpolate.splrep(re_wl,re_flux,w=weight,k=2,s=0)#max(re_flux)**300) new_flux = interpolate.splev(new_wl,f,der=0) return new_wl, new_flux
y = np.array(fdata[:,1])/scale #flux in ergs/s/cm^2/Angs print y y = y/(h*c/x) #flux in counts/s/cm^2/Angs print y print "Loaded standard spectrum of %s"%(objectName) newwl, newflux = cleanSpectrum(x,y,objectName,wvlBinEdges) print newwl print newflux #plot these to debug std spectrum fitting #plt.plot(newwl,newflux) #plt.plot(x,y) #plt.show() newa = rebin(newwl,newflux,wvlBinEdges) x = newa[:,0] y = newa[:,1] #print x #print y ax.plot(wvls,curve) ax.plot(x,y) ax.set_title('Absolute Spectrum of '+FileName.split('/')[-1].split('_')[0]) ax.set_yscale('log') plt.show() fig = plt.figure() ax = fig.add_subplot(111)
ax.set_xlim(3800,12500) ''' #Plot SDSSJ0926 spectrum for comparison scale = (1.0E17) #for .txt files strange unit scaling fname = 'sdssj0926.txt' fdata = np.loadtxt(fname,dtype=float) x = np.array(fdata[:,0]) y = np.array(fdata[:,1])/scale #flux in ergs/s/cm^2/Angs print y y = y/(h*c/x) #flux in counts/s/cm^2/Angs energyBinWidth = 0.3936 wvlStart = 3000 wvlStop = 13000 wvlBinEdges = ObsFile.makeWvlBins(energyBinWidth,wvlStart,wvlStop) rebinned = rebin(x,y,wvlBinEdges) plt.plot(rebinned[:,0],rebinned[:,1],color="black") plt.plot(x,y,color='red') plt.show() ''' #put crab photometry points on plot plt.errorbar(centers,counts,yerr=counterrors,fmt='ro') #ax.set_yscale("log") plt.show() #output spectrum outspec = synthSpectrum*corotScale