def do_fitprof(datafile): """Run IRAF fitprof routine to measure line centers and widths. For each line specified in the module header generate the necessary inputs to fitprof and execture the routine. The fitting regions are also specified in the module header. Parameters ---------- datafile : str Name of a multispec fits file to pass as input to fitprof. Must have a WCS solution in the header. Returns ------- None Nothing is returned. Instead, IRAF writes the results to a file. """ for l, cl, r in zip(llist,centlist,rlist): with open('{}.lines'.format(l),'w') as f: print l for c in cl: f.write('{} INDEF g\n'.format(c)) iraf.fitprofs(datafile, region=r, positio='{}.lines'.format(l), logfile='{}.fitp'.format(l)) return
def do_fitprof(datafile, pointing): """Run IRAF fitprof routine to measure line centers and widths. For each line specified in the module header generate the necessary inputs to fitprof and execture the routine. The fitting regions are also specified in the module header. Parameters ---------- datafile : str Name of a multispec fits file to pass as input to fitprof. Must have a WCS solution in the header. Returns ------- None Nothing is returned. Instead, IRAF writes the results to a file. """ dirn = os.path.dirname(datafile) if len(dirn) > 0: dirn += '/' for l, cl, r in zip(llist, centlist, rlist): with open('{}P{}_{}.lines'.format(dirn,pointing,l),'w') as f: for c in cl: f.write('{:4.2f} INDEF g 15\n'.format(c)) proffile = '{}P{}_{}.fitp'.format(dirn,pointing,l) if os.path.exists(proffile): print 'Removing ' + proffile os.system('rm '+proffile) os.system('rm {}P{}_{}_fits.fits'.format(dirn,pointing,l)) os.system('rm {}P{}_{}_fits.pt'.format(dirn,pointing,l)) try: iraf.fitprofs(datafile, region='{:4.0f} {:4.0f}'.format(*r), positio='{}P{}_{}.lines'.format(dirn,pointing,l), logfile='{}P{}_{}.fitp'.format(dirn,pointing,l), fitpositions='single', fitgfwhm='single', plotfile='{}P{}_{}_fits.pt'.format(dirn,pointing,l), output='{}P{}_{}_fits.fits'.format(dirn,pointing,l), option='fit', nerrsam=100, sigma0=0.41, invgain=0.0) except Exception as e: print 'IRAF died:' print e pass return
def dofitprofs(spectrum,specband,varband,redshift,outprefix,alreadyvar=0,startfwhm=4.5,fwhmlim=10,theconstant=10000): """ Use IRAF's fitprofs to do spectral line fitting theconstant is added to the spectrum to prevent negative values that would confuse fitprofs (it should be larger than the most negative value in the spectrum) """ outdic={} ##add a constant to the spectrum so that fitprofs won't be confused by negative values shiftspec='fitprofstempfile.fits';os.system('rm -f '+shiftspec) iraf.imarith(spectrum,'+',theconstant,shiftspec) for j in glines.keys(): ##redshift the line centers and fitting regions zbgreg=array(gbgrs[j])*(1+redshift) zcenters=array(glines[j])*(1+redshift) ##create positions file os.system('rm -f fitprofs_positions.temp') for val in zcenters: os.system('echo '+str(val)+' INDEF INDEF '+str(startfwhm)+' >> fitprofs_positions.temp') ##load spectrum [waves,spec]=pygetspec(spectrum,specband-1) [waves,var]=pygetspec(spectrum,varband-1) if alreadyvar==0: var=var**2 #find index numbers associated with the bg and fit region and center wavelengths bg1=0;bg2=0;bg3=0;bg4=0 for i in range(len(waves)): if (waves[i]>=zbgreg[0]) and (bg1==0): bg1=i if (waves[i]>=zbgreg[1]) and (bg2==0): bg2=i if (waves[i]>=zbgreg[2]) and (bg3==0): bg3=i if (waves[i]>=zbgreg[3]) and (bg4==0): bg4=i ##get estimate of noise parameters x=append(spec[bg1:bg2],spec[bg3:bg4])+theconstant;y=append(var[bg1:bg2],var[bg3:bg4])+theconstant slope, intercept, r_value, p_value, std_err=linregress(x,y) #plt.plot(x,y,'o');plt.plot(x,x*slope+intercept);plt.show();pdb.set_trace() if intercept<0: intercept=0 noisefloor=intercept+median(x)*slope ##get estimate of background level bglevel=median(x-theconstant);bgsigma=bglevel/std(x-theconstant) ##run fitprofs bgstring="med("+str(int(zbgreg[0]))+"-"+str(int(zbgreg[1]))+") med("+str(int(zbgreg[2]))+"-"+str(int(zbgreg[3]))+")" rgstring=str(int(zbgreg[1]))+' '+str(int(zbgreg[2])) flog=outprefix+'_fitprofs_log.temp';fplot=outprefix+'_fitprofs'+str(j)+'.gki';os.system('rm -f '+fplot) try: iraf.fitprofs(shiftspec,lines=specband,region=rgstring,positions='fitprofs_positions.temp',background=bgstring,profile='gaussian',gfwhm=4,fitbackground='yes',fitpositions='single',fitgfwhm='all',nerrsample=100,sigma0=intercept**.5,invgain=slope,logfile=flog,plotfile=fplot,verbose=0) except: print "Fitting failed for "+spectrum+", "+str(glines[j]) os.system("echo '#fitprofs fitting failed' >> "+flog) for k in range(len(glines[j])): os.system("echo 'nan nan nan nan nan nan nan' >> "+flog) ##load results f=open(flog,'r');lst=f.readlines() for k in range(len(glines[j])): ##did the error calculation work? if '(' in lst[-1]: goback=2*(len(glines[j])-k-1);backstep=2 ##errors scenter=float(lst[-1-goback].replace('(','').replace(')','').split()[0]) sflux=float(lst[-1-goback].replace('(','').replace(')','').split()[2]) sew=float(lst[-1-goback].replace('(','').replace(')','').replace('INDEF','nan').split()[3])*(1+theconstant/bglevel) ##correct for theconstant sfwhm=float(lst[-1-goback].replace('(','').replace(')','').split()[5]) else: goback=1*(len(glines[j])-k-1);backstep=1 ##take the variance floor as the error scenter=nan sflux=noisefloor**.5*startfwhm sfwhm=nan sew=nan ##values center=float(lst[-backstep-goback].replace('(','').replace(')','').split()[0]) flux=float(lst[-backstep-goback].replace('(','').replace(')','').split()[2]) ew=float(lst[-backstep-goback].replace('(','').replace(')','').replace('INDEF','nan').split()[3])*(1+theconstant/bglevel) fwhm=float(lst[-backstep-goback].replace('(','').replace(')','').split()[5]) ##reject negative fluxes ##reject objects with too-large FWHM if flux<0 or fwhm>fwhmlim: center=nan;flux=nan;fwhm=nan;sflux=nan;scenter=nan;sfwhm=nan ##If continuum was negligable (<2sigma), read out huge equivalent width if bgsigma<2: ew=-inf;sEW=-inf ##don't accept a flux error below the noise floor if sflux<noisefloor**.5*startfwhm: sflux=noisefloor**.5*startfwhm ##save to dictionary outdic[glines[j][k]]={'cent':center,'scent':scenter,'flux':flux,'sflux':sflux,'fwhm':fwhm,'sfwhm':sfwhm,'EW':ew,'sEW':sew} ###rename lines outdic2={} for i in range(len(elines)): outdic2[linenames[i]]=outdic[elines[i]] return outdic2