def initialpars(self,parfilename): ### Deal with initial parameters from line input file self.fitpars,self.fiterrors,self.parinfo,self.linecmts = joebvpfit.readpars(parfilename) cfg.fitidx=joebvpfit.fitpix(self.wave, self.fitpars) #Set pixels for fit cfg.wavegroups=[] self.datamodel = LineParTableModel(self.fitpars,self.fiterrors,self.parinfo,linecmts=self.linecmts) self.tableView.setModel(self.datamodel) self.datamodel.updatedata(self.fitpars,self.fitpars,self.parinfo,self.linecmts)
def compose_model(spec,filelist,outfile): ''' Generates full-model spectrum (XSpectrum1D) from a set of joebvp output files and writes out a file with the spectrum. Parameters ---------- spec : string or XSpectrum1D The spectrum to be fitted with the input lines filelist : list of strings or str This should be a list containing the names of VP input files or a string referring to a file simply listing the input files. See joebvpfit.readpars for details of file format outfile : str Name of model spectrum output file ''' from joebvp import joebvpfit ### Deal with alternate input types if isinstance(spec,str): specobj = readspec(spec) else: specobj = spec ### Load essentials from spectrum wave = specobj.wavelength.value normsig=specobj.sig.value/specobj.co.value cfg.wave = wave ### Concatenate all the parameter tables concatenate_line_tables(filelist,outtablefile='compiledVPinputs.dat') ### Make the model! fitpars, fiterrors, parinfo, linecmts = joebvpfit.readpars('compiledVPinputs.dat') # read this back in to load params cfg.fitidx = joebvpfit.fitpix(wave, fitpars) # set the pixels in the line regions model = joebvpfit.voigtfunc(wave,fitpars) # generate the Voigt profiles of all lines ### Instantiate XSpectrum1D object and write it out outspec=XSpectrum1D.from_tuple((wave,model,normsig)) outspec.write_to_fits(outfile)
def batch_fit(spec, filelist, outparfile='.VP', outmodelfile='_VPmodel.fits', inspect=True, **kwargs): """ Takes a number of input files and fits the lines in them. The fitting algorithm will be run until convergence for each input file. The program will then ask whether to run the failed runs in GUI mode. Parameters ---------- spec : string or XSpectrum1D The spectrum to be fitted with the input lines filelist : list of strings or str This should be a list containing the names of VP input files or a string referring to a file simply listing the input files. See joebvpfit.readpars for details of file format outparfile : str, optional Suffix for output file for fitted line parameters. outmodelfile: str, optional Suffix for output fits file for fitted model as the 'flux'. inspect : bool, optional Whether to produce plots and model for inspection of individual parameter input files. Default is True. **kwargs : maxiter, itertol These are fed on to the joebvp.fit_to_convergence() function """ if isinstance(spec,str): spectofit = readspec(spec) specfile = spectofit.filename else: spectofit = spec specfile = cfg.filename if isinstance(filelist, str): lstarr=np.genfromtxt(filelist,dtype=None) listofiles=lstarr.tolist() if isinstance(listofiles,str): # In case 'listofiles' is only 1 file listofiles=[listofiles] else: listofiles=filelist wave=spectofit.wavelength.value normflux=spectofit.flux.value/spectofit.co.value normsig=spectofit.sig.value/spectofit.co.value cfg.wave=wave cfg.spectrum = spectofit # need this for defining bad pixels later q_pass = 0 q_fail = 0 fails = [] # store failures filenames for i,ff in enumerate(listofiles): i += 1 fitpars, fiterrors, parinfo, linecmts = joebvpfit.readpars(ff) cfg.wavegroups = [] try: fitpars,fiterrors=joebvpfit.fit_to_convergence(wave,normflux,normsig,fitpars,parinfo, **kwargs) print('VPmeasure: Fit converged:', ff) paroutfilename = ff.split('.')[0] + outparfile modeloutfilename = ff.split('.')[0] + outmodelfile joebvpfit.writelinepars(fitpars, fiterrors, parinfo, specfile, paroutfilename, linecmts) joebvpfit.writeVPmodel(modeloutfilename, wave, fitpars, normflux, normsig) if inspect: jbu.inspect_fits(paroutfilename, output=paroutfilename.split('.')[0]+"_inspect.pdf") q_pass += 1 except: print('VPmeasure: Fitting failed:', ff) fails += [ff] q_fail += 1 print("") print("VPmeasure: {}/{} fits converged, {}/{} failed (see log for details).\n".format(q_pass, i, q_fail, i)) # ask whether run GUI mode on failures if q_fail > 0: print("VPmeasure: Failed runs are: {}\n".format(fails)) while True: answer = raw_input("VPmeasure: Would you like to run the failed fits in GUI mode? (y/n): ") if answer in ['y','n', 'yes','no']: break if answer in ['y', 'yes']: for ff in fails: go(spec, ff) # Concatenate and create fits inspection files concatenate_all(spectofit) print("VPmeasure: Done.")
def inspect_fits(parfile,output='FitInspection.pdf',vlim=[-300,300]*u.km/u.s, **kwargs): ''' Produce pdf of fitting results for quality check. Parameters ---------- parfile : str Name of the parameter file in the joebvp format output : str,optional Name of file to write stackplots output vlim : Quantity array, optional Velocity range of stackplots e.g.: [-400, Returns ------- ''' from joebvp import joebvpfit from matplotlib.backends.backend_pdf import PdfPages llist = LineList('ISM') pp=PdfPages(output) #import pdb; #pdb.set_trace() all=abslines_from_VPfile(parfile,linelist=llist,**kwargs) # Instantiate AbsLine objects and make list acl=abscomponents_from_abslines(all,vtoler=15.) # Instantiate AbsComponent objects from this list fitpars,fiterrors,parinfo,linecmts = joebvpfit.readpars(parfile) fullmodel=makevoigt.cosvoigt(all[0].analy['spec'].wavelength.value,fitpars) ### Make a stackplot for each component for comp in acl: fig=comp.stack_plot(ymnx=(-0.1,1.3),show=False,return_fig=True,vlim=vlim, tight_layout=True) if (len(comp._abslines)<6): numrow = len(comp._abslines)%6 else: numrow = 6 height = numrow*1.0+0.5 fig.set_figheight(height) if len(comp._abslines)<6: fig.set_figwidth(5.) else: fig.set_figwidth(10.) stackaxes = fig.axes for i,ax in enumerate(stackaxes): line = comp._abslines[i] thesepars=[[line.wrest.value],[line.attrib['logN']],[line.attrib['b'].value], [line.z],[line.attrib['vel'].value],[line.limits.vlim[0].value],[line.limits.vlim[1].value]] try: thismodel=makevoigt.cosvoigt(line.analy['spec'].wavelength.value,thesepars) except: ax.text(-100,0.05,'These pixels not used to fit this line') continue axlin=ax.get_lines() veldat=axlin[0].get_data()[0] ax.plot(veldat,fullmodel,color='red',alpha=0.8) ax.plot(veldat,thismodel,color='purple',linestyle='dashed') botbuf = 0.5/height fig.subplots_adjust(bottom=botbuf,left=0.1,right=0.95,hspace=0.,wspace=0.35) title=comp.name fig.suptitle(title) fig.savefig(pp,format='pdf') plt.close(fig) ### Write out full model fits file normflux = line.analy['spec'].flux/line.analy['spec'].co normsig = line.analy['spec'].sig / line.analy['spec'].co modeltab = Table([line.analy['spec'].wavelength.value, fullmodel, normflux, normsig], names=['wavelength', 'model', 'normflux', 'normsig']) # modeltab.write(outfile, format='fits', overwrite=True) dummycont = np.ones(len(normflux)) spec = XSpectrum1D.from_tuple((modeltab['wavelength'], modeltab['model'], modeltab['normsig'], dummycont)) spec.write_to_fits(output[:-4]+'.fits') pp.close()
def batch_fit(spec, filelist, outparfile='.VP', outmodelfile='_VPmodel.fits', inspect=True, **kwargs): """ Takes a number of input files and fits the lines in them. The fitting algorithm will be run until convergence for each input file. The program will then ask whether to run the failed runs in GUI mode. Parameters ---------- spec : string or XSpectrum1D The spectrum to be fitted with the input lines filelist : list of strings or str This should be a list containing the names of VP input files or a string referring to a file simply listing the input files. See joebvpfit.readpars for details of file format outparfile : str, optional Suffix for output file for fitted line parameters. outmodelfile: str, optional Suffix for output fits file for fitted model as the 'flux'. inspect : bool, optional Whether to produce plots and model for inspection of individual parameter input files. Default is True. **kwargs : maxiter, itertol These are fed on to the joebvp.fit_to_convergence() function """ if isinstance(spec,str): spectofit = readspec(spec) specfile = spectofit.filename else: spectofit = spec specfile = cfg.filename if isinstance(filelist, str): lstarr=np.genfromtxt(filelist,dtype=None) listofiles=lstarr.tolist() if sum(1 for line in open(filelist)) == 1: listofiles = [listofiles] else: listofiles=filelist wave=spectofit.wavelength.value normflux=spectofit.flux.value/spectofit.co.value normsig=spectofit.sig.value/spectofit.co.value cfg.wave=wave cfg.spectrum = spectofit # need this for defining bad pixels later q_pass = 0 q_fail = 0 fails = [] # store failures filenames for i,ff in enumerate(listofiles): if isinstance(ff,bytes): ff = ff.decode() i += 1 fitpars, fiterrors, parinfo, linecmts = joebvpfit.readpars(ff) cfg.lsfs = [] cfg.fgs = [] cfg.wavegroups = [] cfg.wgidxs = [] cfg.uqwgidxs = [] try: fitpars,fiterrors=joebvpfit.fit_to_convergence(wave,normflux,normsig,fitpars,parinfo, **kwargs) print('VPmeasure: Fit converged:', ff) paroutfilename = ff.split('.')[0] + outparfile modeloutfilename = ff.split('.')[0] + outmodelfile joebvpfit.writelinepars(fitpars, fiterrors, parinfo, specfile, paroutfilename, linecmts) joebvpfit.writeVPmodel(modeloutfilename, wave, fitpars, normflux, normsig) if inspect: jbu.inspect_fits(paroutfilename, output=paroutfilename.split('.')[0]+"_inspect.pdf") q_pass += 1 except: print('VPmeasure: Fitting failed:', ff) #import pdb; pdb.set_trace() fails += [ff] q_fail += 1 print("") print("VPmeasure: {}/{} fits converged, {}/{} failed (see log for details).\n".format(q_pass, i, q_fail, i)) # ask whether run GUI mode on failures if q_fail > 0: print("VPmeasure: Failed runs are: {}\n".format(fails)) while True: answer = input("VPmeasure: Would you like to run the failed fits in GUI mode? (y/n): ") if answer in ['y','n', 'yes','no']: break if answer in ['y', 'yes']: for ff in fails: try: go(spec, ff) except: raise ValueError('Spectrum/VP input failed to load in interactive mode.') # Concatenate and create fits inspection files concatenate_all(spectofit) print("VPmeasure: Done.")