예제 #1
0
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
예제 #2
0
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
예제 #3
0
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