def extinctfit(ss): #ss1,ss2): ss1 = ss[0] ss2 = ss[1] trans1 = ss1['name'][4] trans2 = ss2['name'][4] if trans1 == 'S': jupper1 = int(ss1['name'][6])+2 jupper2 = int(ss2['name'][6]) vupper1 = int(ss1['name'][0]) vupper2 = int(ss2['name'][0]) s = 0 q = 1 elif trans1 == 'Q': jupper1 = int(ss2['name'][6])+2 jupper2 = int(ss1['name'][6]) vupper1 = int(ss1['name'][0]) vupper2 = int(ss2['name'][0]) s = 1 q = 0 else: print "Error: wrong transition type" return if jupper1 != jupper2 or vupper1!=vupper2: print "Error: upper levels not matched" return ASdivAQ = aval(vupper1,jupper1,jupper1-2) / aval(vupper1,jupper1,jupper1) # S / Q WSdivWQ = restwl(vupper1,vupper1-1,jupper1,jupper1-2) / restwl(vupper1,vupper1-1,jupper1,jupper1) midwl = [median(ss1['wavelength']),median(ss2['wavelength'])] pguess1 = [0,ss1['data'].max()*1e17,midwl[0],5] pguess2 = [0,ss2['data'].max()*1e17,midwl[1],5] p1,fit1,perr1,gof1 = gaussfitter.onedgaussfit(ss1['wavelength'],ss1['data']*1e17,ss1['err']*1e17,params=pguess1,minpars=[-1,0,19000,0],limitedmin=[True,True,True,True]) p2,fit2,perr2,gof2 = gaussfitter.onedgaussfit(ss2['wavelength'],ss2['data']*1e17,ss2['err']*1e17,params=pguess2,minpars=[-1,0,19000,0],limitedmin=[True,True,True,True]) ss[0]['model'] = fit1*1e-17 ss[1]['model'] = fit2*1e-17 if s == 0: # want S / Q SdivQ = fit1.sum()/fit2.sum() else: SdivQ = fit2.sum()/fit1.sum() dtau12 = -log(SdivQ/ASdivAQ*WSdivWQ) # see Moore, Lumsden, Ridge, Puxley 2005 # alpha = 1.8 comes from Martin & Whittet 1990 tau1 = dtau12 / ( (midwl[s]/midwl[q])**-1.8 - 1 ) AL = 100**(.2) * log10(exp(1)) * tau1 # conversion from optical depth to magnitude # AK = AL * lambda^-alpha AK = AL * (midwl[q]/22000.0)**-1.8 # again alpha=1.8 comes from Martin & Whittet 1990. alpha=1.75 from Rieke and Lebofsky 1985 return AK,AL,SdivQ,ASdivAQ
def onedfit(self, usemoments=True, annotate=True, vheight=True, height=0, negamp=None,**kwargs): self.ngauss = 1 self.auto = True self.setfitspec() if usemoments: # this can be done within gaussfit but I want to save them self.guesses = gaussfitter.onedmoments( self.specplotter.vind[self.gx1:self.gx2], self.spectofit[self.gx1:self.gx2], vheight=vheight,negamp=negamp,**kwargs) if vheight is False: self.guesses = [height]+self.guesses else: if negamp: self.guesses = [height,-1,0,1] else: self.guesses = [height,1,0,1] mpp,model,mpperr,chi2 = gaussfitter.onedgaussfit( self.specplotter.vind[self.gx1:self.gx2], self.spectofit[self.gx1:self.gx2], err=self.errspec[self.gx1:self.gx2], vheight=vheight, params=self.guesses, **self.fitkwargs) self.chi2 = chi2 self.dof = self.gx2-self.gx1-self.ngauss*3-vheight if vheight: self.specplotter.baseline.baselinepars = mpp[:1] # first item in list form self.model = model - mpp[0] else: self.model = model self.residuals = self.spectofit[self.gx1:self.gx2] - self.model self.modelpars = mpp[1:].tolist() self.modelerrs = mpperr[1:].tolist() self.modelplot = self.specplotter.axis.plot( self.specplotter.vind[self.gx1:self.gx2], self.model+self.specplotter.offset, color=self.fitcolor, linewidth=0.5) if annotate: self.annotate() if vheight: self.specplotter.baseline.annotate()
def linefit(ss): pguess = [0,ss['data'].max()*1e17,0,20] wl = (ss['wavelength']-ss['linewl'])/ss['linewl']*3e5 pa,fit,perr,gof = gaussfitter.onedgaussfit(wl,ss['data']*1e17,ss['err']*1e17,params=pguess, minpars=[-1,0,-200,0],limitedmin=[True,True,True,True]) # import pdb; pdb.set_trace() ss['model'] = fit*1e-17 return pa,perr,gof
def linefit(ss): pguess = [0, ss['data'].max() * 1e17, 0, 20] wl = (ss['wavelength'] - ss['linewl']) / ss['linewl'] * 3e5 pa, fit, perr, gof = gaussfitter.onedgaussfit( wl, ss['data'] * 1e17, ss['err'] * 1e17, params=pguess, minpars=[-1, 0, -200, 0], limitedmin=[True, True, True, True]) # import pdb; pdb.set_trace() ss['model'] = fit * 1e-17 return pa, perr, gof
def atomicFit(atomWave, cutWave, cutFlux, cutFluxerr, fitMargin): if np.all(cutFluxerr == 0.): theerr = None else: theerr = cutFluxerr spectral_resolution_hi = atomWave / 60 spectral_resolution_lo = atomWave / 120 spectral_resolution_med = np.nanmean( (spectral_resolution_lo, spectral_resolution_hi)) fwhm_guess = spectral_resolution_med fwhm_min = spectral_resolution_lo fwhm_max = spectral_resolution_hi sigma_guess = to_sigma(fwhm_guess) sigma_min = to_sigma(fwhm_min) sigma_max = to_sigma(fwhm_max) sigma_min = sigma_guess * 0.9 sigma_max = sigma_guess * 1.1 yfit = onedgaussfit( cutWave, cutFlux, err=theerr, params=[0, np.nanmax(cutFlux), atomWave, sigma_guess], fixed=[True, False, False, False], limitedmin=[True, True, True, True], limitedmax=[True, False, True, True], minpars=[0, 0, atomWave - fitMargin, sigma_min], maxpars=[ 0, np.nanmax(cutFlux) * 1.5, atomWave + fitMargin, sigma_max ], quiet=True, shh=True) g1 = onedgaussian(cutWave, *yfit[0]) flux_g1 = sp.integrate.simps(g1, cutWave) return flux_g1, yfit
def gaussfit1d(self,xax,data,modelx=None,return_models=True,return_all=False,**kwargs): """ 1d gaussian params: (height, amplitude, shift, width) """ width = xax.max()-xax.min() lower_bound = np.sort(data)[:3].mean() params=[0,(data.max()-data.min())*0.5,0,width*0.2] fixed=[False,False,False,False] limitedmin=[False,True,True,True] limitedmax=[True,True,True,True] minpars=[0,(data.max()-data.min())*0.5,xax.min()-width,width*0.05] maxpars=[lower_bound*1.5,data.max()-data.min(),xax.max(),width*3.0] params,_model,errs,chi2 = onedgaussfit(xax,data,params=params,fixed=fixed,\ limitedmin=limitedmin,limitedmax=limitedmax,\ minpars=minpars,maxpars=maxpars,**kwargs) if modelx == None: modelx = xax model_xdata = onedgaussian(xax,*params) model_fitting = onedgaussian(modelx,*params) if return_all: return params,model_xdata,model_fitting,errs,chi2 elif return_models: return (model_xdata, model_fitting)
else: nel = 1000 else: ntests = 10000 a=zeros(ntests) for i in range(ntests): X=plfit.plexp_inv(rand(nel),xmin,2.5) p=plfit.plfit(X,xmin=xmin,quiet=True,silent=True) a[i]=p._alpha h,b = hist(a,bins=30)[:2] bx = (b[1:]+b[:-1])/2.0 import gaussfitter p,m,pe,chi2 = gaussfitter.onedgaussfit(bx,h,params=[0,ntests/10.0,2.5,0.05],fixed=[1,0,0,0]) plot(bx,m) print "XMIN fixed: Alpha = 2.5 (real), %0.3f +/- %0.3f (measured)" % (p[2],p[3]) a=zeros(ntests) xm=zeros(ntests) for i in range(ntests): X=plfit.plexp_inv(rand(nel),xmin,2.5) p=plfit.plfit(X,quiet=True,silent=True) a[i]=p._alpha xm[i]=p._xmin figure()
def fit_127(wave, csubSI, csuberrSI): def make_127_profile(home_dir, valmin=12.22, valmax=13.2): spectrum_file = \ 'Dropbox/code/Python/fitting_127/average_pah_spectrum.dat' data = np.loadtxt(str(home_dir + spectrum_file)) data = data.T n = np.where((data[0] > valmin) & (data[0] < valmax))[0] wave = data[0][n] flux = data[1][n] fluxerr = data[2][n] band = data[3][n] flux = flux - 0.05 # offset to zero it for i in range(len(wave)): if i != len(wave) - 1: if wave[i + 1] - wave[i] <= 0: # print i, wave[i] cut_it = i w1 = wave[:cut_it + 1] f1 = flux[:cut_it + 1] fe1 = fluxerr[:cut_it + 1] b1 = band[:cut_it + 1] w2 = wave[cut_it + 1:] f2 = flux[cut_it + 1:] fe2 = fluxerr[cut_it + 1:] b2 = band[cut_it + 1:] c1 = np.where(w1 < w2[0])[0] w1 = w1[c1] f1 = f1[c1] fe1 = fe1[c1] b1 = b1[c1] # tie together wave = np.concatenate((w1, w2), axis=0) flux = np.concatenate((f1, f2), axis=0) fluxerr = np.concatenate((fe1, fe2), axis=0) band = np.concatenate((b1, b2), axis=0) # flux -= np.amin(flux) wave1 = np.reshape(wave, (len(wave), 1)) flux1 = np.reshape(flux, (len(flux), 1)) fluxerr1 = np.reshape(fluxerr, (len(fluxerr), 1)) band1 = np.reshape(band, (len(band), 1)) all_cols = np.concatenate((wave1, flux1, fluxerr1, band1), axis=1) np.savetxt("profile_127.dat", all_cols, header="Wave (um), Flux (Jy), Fluxerr (Jy), Band") return wave, flux, fluxerr, band def scale_127(scale_factor): # return flux_127 * scale_factor global hony_downsample_flux_trim return hony_downsample_flux_trim * scale_factor def scale_profile(xax, data, err=(), params=[1], fixed=[False], limitedmin=[False], limitedmax=[False], minpars=[0], maxpars=[10], quiet=True, shh=True): def myfunc(x, y, err): if len(err) == 0: print("OOOOOOOOOO") def f(p, fjac=None): return [0, (y - scale_127(*p))] else: print("KKKKKKKKK") def f(p, fjac=None): return [0, (y - scale_127(*p)) / err] return f parinfo = [{ 'n': 0, 'value': params[0], 'limits': [minpars[0], maxpars[0]], 'limited': [limitedmin[0], limitedmax[0]], 'fixed': fixed[0], 'parname': "scale_factor", 'error': 0 }] mp = mpfit.mpfit(myfunc(xax, data, err), parinfo=parinfo, quiet=quiet) mpp = mp.params mpperr = mp.perror chi2 = mp.fnorm if mp.status == 0: raise Exception(mp.errmsg) if not shh: for i, p in enumerate(mpp): parinfo[i]['value'] = p print((parinfo[i]['parname'], p, " +/- ", mpperr[i])) print(("Chi2: ", mp.fnorm, " Reduced Chi2: ", mp.fnorm / len(data), " DOF:", len(data) - len(mpp))) return mpp, scale_127(*mpp), mpperr, chi2 # Choose range for fitting. rx = np.where((wave >= 11.8) & (wave <= 13.5)) # Isolate region. wavein = wave[rx] fluxin = csubSI[rx] # fluxerrin = csuberrSI[rx] rms = measure_112_RMS(wave, csubSI) # Read in Hony's spectrum. wave_127, flux_127, _, _ = make_127_profile(home_dir, 11.5, 14) wave127 = wave_127 flux127 = si(flux_127, wave_127) # Regrid hony's to the data. spl = interp.splrep(wave127, flux127) honyWave = wavein honyFlux = norm(interp.splev(honyWave, spl)) ########################################################## # Hony # Isolate the 12.4 - 12.6 region for fitting the scale factor, both my # data and Hony's template spectrum. global lower_fitting_boundary global upper_fitting_boundary lower_fitting_boundary = 12.4 upper_fitting_boundary = 12.6 global hony_downsample_flux_trim index = np.where((wavein > lower_fitting_boundary) & (wavein < upper_fitting_boundary))[0] # check for poorly sampled data # (i.e. no indices meet the above condition) if len(index) == 0: # return flux127, fluxerr127, flux128, fluxerr128, amp, position, # sigma, integration_wave, integration_flux return 0, 0, 0, 0, 0, 0, 0, 0, 0 # hony_downsample_wave_trim = honyWave[index] hony_downsample_flux_trim = honyFlux[index] SL_flux_trim = fluxin[index] SL_wave_trim = wavein[index] # Compute scale factor for Hony template spectrum yfit = scale_profile(SL_wave_trim, SL_flux_trim, params=[np.nanmax(fluxin) ]) # False], maxpars=maxpars[10]) my_scale_factor = yfit[0][0] # Subtract scaled Hony spectrum scaled_hony_downsample_flux = honyFlux * my_scale_factor final_flux = fluxin - scaled_hony_downsample_flux final_wave = wavein ########################################################## # 12.8 # Fit remainder with gaussian (Neon line at 12.8) # params - Fit parameters: Height of background, Amplitude, Shift, # Width fwhm_min = 0.08 fwhm_max = 0.12 fwhm_start = 0.1 params_in = [0, np.amax(final_flux), 12.813, to_sigma(fwhm_start)] limitedmin = [True, True, True, True] limitedmax = [True, True, True, True] fixed = [True, False, False, False] minpars = [0, 0, 12.763, to_sigma(fwhm_min)] maxpars = [0.01, np.amax(final_flux) * 1.1, 12.881, to_sigma(fwhm_max)] yfit = onedgaussfit(final_wave, final_flux, params=params_in, limitedmin=limitedmin, minpars=minpars, limitedmax=limitedmax, fixed=fixed, maxpars=maxpars) # plt.plot(x,onedgaussian(x,0,5,42,3),'-g',linewidth=3,label='input') # print yfit[0] amp = yfit[0][1] position = yfit[0][2] sigma = yfit[0][3] # fwhm = 2 * np.sqrt(2 * np.log(2)) * sigma amp_err = yfit[2][1] # position_err = yfit[2][2] sigma_err = yfit[2][3] myrange = [position - 3. * sigma, position + 3. * sigma] N = np.where((final_wave >= myrange[0]) & (final_wave <= myrange[1])) dl = final_wave[1] - final_wave[0] fluxNeII = onedgaussian(final_wave, 0, amp, position, sigma) gauss_128_rms = (rms * np.sqrt(len(N)) * dl * 2) gauss_128_flux = amp * np.abs(np.sqrt(2) * sigma) * np.sqrt(np.pi) if np.sqrt((amp_err / amp)**2 + (sigma_err / sigma)**2) >= 10: gauss_128_flux_err = gauss_128_rms else: frac_err = np.sqrt((amp_err / amp)**2 + (sigma_err / sigma)**2) gauss_128_flux_err = frac_err * gauss_128_flux + gauss_128_rms ########################################################### # 12.7 # Quantities of interest pah_127 = fluxin - fluxNeII pah_wave = wavein pah_127_watts = pah_127 # Using the measured 12.7. cont_low = 12.2 # find_nearest(cont_wave,12.2) cont_hi = 13.0 # find_nearest(cont_wave,13.0) idx = np.where((pah_wave >= cont_low) & (pah_wave <= cont_hi))[0] integration_wave = pah_wave[idx] integration_flux = pah_127_watts[idx] trap_flux = sp.integrate.simps(integration_flux, integration_wave) # Using Hony's 12.7. cont_low = 12.2 # find_nearest(cont_wave,12.2) cont_hi = 13.0 # find_nearest(cont_wave,13.0) idx = np.where((pah_wave >= cont_low) & (pah_wave <= cont_hi))[0] integrationHony_wave = wavein[idx] integrationHony_flux = scaled_hony_downsample_flux[idx] trap_fluxHony = sp.integrate.simps(integrationHony_flux, integrationHony_wave) # ONLY IF USING 12.4 - 12.6 !!!!!!!!!!!! corrected_pah_trap_flux = trap_flux dl3 = integration_wave[1] - integration_wave[0] corrected_pah_trap_flux_err = (rms * np.sqrt(len(integration_wave)) * dl3 * 2) ################################################################ # Plot to check print((gauss_128_flux, gauss_128_flux_err, gauss_128_rms)) print() print(("12.7 flux (using infer. curve): ", trap_flux)) print(("12.7 flux (using hony's curve): ", trap_fluxHony)) # STUFF TO RETURN.... flux127 = corrected_pah_trap_flux fluxerr127 = corrected_pah_trap_flux_err flux128 = gauss_128_flux fluxerr128 = gauss_128_flux_err if (trap_flux - trap_fluxHony) / trap_flux * 100 >= 30: flux127 = trap_fluxHony fluxerr127 = flux127 * 1e10 return flux127, fluxerr127, flux128, fluxerr128, amp, position, \ sigma, integration_wave, integration_flux
def extinctfit(ss): #ss1,ss2): ss1 = ss[0] ss2 = ss[1] trans1 = ss1['name'][4] trans2 = ss2['name'][4] if trans1 == 'S': jupper1 = int(ss1['name'][6]) + 2 jupper2 = int(ss2['name'][6]) vupper1 = int(ss1['name'][0]) vupper2 = int(ss2['name'][0]) s = 0 q = 1 elif trans1 == 'Q': jupper1 = int(ss2['name'][6]) + 2 jupper2 = int(ss1['name'][6]) vupper1 = int(ss1['name'][0]) vupper2 = int(ss2['name'][0]) s = 1 q = 0 else: print "Error: wrong transition type" return if jupper1 != jupper2 or vupper1 != vupper2: print "Error: upper levels not matched" return ASdivAQ = aval(vupper1, jupper1, jupper1 - 2) / aval( vupper1, jupper1, jupper1) # S / Q WSdivWQ = restwl(vupper1, vupper1 - 1, jupper1, jupper1 - 2) / restwl( vupper1, vupper1 - 1, jupper1, jupper1) midwl = [median(ss1['wavelength']), median(ss2['wavelength'])] pguess1 = [0, ss1['data'].max() * 1e17, midwl[0], 5] pguess2 = [0, ss2['data'].max() * 1e17, midwl[1], 5] p1, fit1, perr1, gof1 = gaussfitter.onedgaussfit( ss1['wavelength'], ss1['data'] * 1e17, ss1['err'] * 1e17, params=pguess1, minpars=[-1, 0, 19000, 0], limitedmin=[True, True, True, True]) p2, fit2, perr2, gof2 = gaussfitter.onedgaussfit( ss2['wavelength'], ss2['data'] * 1e17, ss2['err'] * 1e17, params=pguess2, minpars=[-1, 0, 19000, 0], limitedmin=[True, True, True, True]) ss[0]['model'] = fit1 * 1e-17 ss[1]['model'] = fit2 * 1e-17 if s == 0: # want S / Q SdivQ = fit1.sum() / fit2.sum() else: SdivQ = fit2.sum() / fit1.sum() dtau12 = -log( SdivQ / ASdivAQ * WSdivWQ) # see Moore, Lumsden, Ridge, Puxley 2005 # alpha = 1.8 comes from Martin & Whittet 1990 tau1 = dtau12 / ((midwl[s] / midwl[q])**-1.8 - 1) AL = 100**(.2) * log10( exp(1)) * tau1 # conversion from optical depth to magnitude # AK = AL * lambda^-alpha AK = AL * ( midwl[q] / 22000.0 )**-1.8 # again alpha=1.8 comes from Martin & Whittet 1990. alpha=1.75 from Rieke and Lebofsky 1985 return AK, AL, SdivQ, ASdivAQ