def Roughfit(obsname, Sourcename, obs_suffix='xwtw2po_cl_seporb.pha', NH=1.0, PL=2, kT=0.5, outfile='Roughfit.spec', PLOT=True): '''Given the observation number file of an observation, the Sourcename, and the name of an output file, this will preform a rough spectral fit to get a handle on the sources flux.''' spec = obsname + '/sw' + obsname + obs_suffix fits = pyfits.open(spec) xspec.AllData(spec) xspec.AllData.ignore("bad") xspec.AllData.ignore("**-0.5 10.0-**") model = xspec.Model("tbabs(po+bb)") errorstr = '1.6 2 3 4 5' model.TBabs.nH = NH model.TBabs.nH.frozen = True model.powerlaw.PhoIndex.values = [PL, 0.01, -3.0, -2.0, 9.0, 10.0] model.bbody.kT.values = [kT, 0.01, 0.0001, 0.01, 100.0, 200.0] xspec.Fit.query = 'yes' xspec.Fit.perform() xspec.Fit.perform() xspec.Plot.xAxis = "keV" xspec.Plot.device = "/xw" xspec.Plot("data", "resid") xspec.Plot() xspec.Fit.error(errorstr) try: xspec.AllModels.calcFlux("0.5 10. err 1000 90") except (RuntimeError, TypeError, NameError, 'Flux Command Error'): pass outf = open(outfile + '.spec', 'w') nH = xspec.AllModels(1)(1) outf.write('# nH: %f (%f - %f)\tChisq: %f\tDOF: %f\n' % (nH.values[0], nH.error[0], nH.error[1], xspec.Fit.statistic, xspec.Fit.dof)) outf.write( '# obsid\tflux\tflux_low\tflux_high\tgamma\tgamma_low\tgamma_high\tkT\tkT_low\tkT_high\tPLnorm/kTnorm\n' ) flux = xspec.AllData(1).flux output = '%s\t%E\t%E\t%E\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n' %\ ( spec, flux[0], flux[1], flux[2],xspec.AllModels(1)(2).values[0], xspec.AllModels(1)(2).error[0], xspec.AllModels(1)(2).error[1], xspec.AllModels(1)(4).values[0], xspec.AllModels(1)(4).error[0], xspec.AllModels(1)(4).error[1], xspec.AllModels(1)(3).values[0]/xspec.AllModels(1)(5).values[0] ) outf.write(output) outf.close() xspec.AllData.clear() xspec.AllModels.clear()
def bkg_only_fit(output, steppar=False, error=False): """ Fit bkg region alone to XRB model """ out = g309.load_data_and_models(["bkg"], snr_model=None) set_energy_range(out['bkg']) xs.AllData.ignore("bad") # Reset XRB to "typical" values # As usual, fit is pretty sensitive to initial values # (initial kT values that are too small drive fit to a bad local minimum) xrb = xs.AllModels(1, 'xrb') xrb.setPars({xrb.apec.kT.index : "0.2, , 0, 0, 0.5, 1"}, # Unabsorped apec (local bubble) {xrb.tbnew_gas.nH.index : "1.5, , 0.01, 0.1, 5, 10"}, # Galactic absorption {xrb.apec_6.kT.index : "0.7, , 0, 0, 2, 4"}, # Absorbed apec (galactic halo) {xrb.apec.norm.index : 1e-3}, {xrb.apec_6.norm.index : 1e-3} ) xrb.apec.kT.frozen = False xrb.tbnew_gas.nH.frozen = False xrb.apec_6.kT.frozen = False xrb.apec.norm.frozen = False xrb.apec_6.norm.frozen = False xs.Fit.perform() if xs.Plot.device == "/xs": xs.Plot("ldata delchi") if steppar: xs.Fit.steppar("xrb:{:d} 0.1 0.5 20".format(xs_utils.par_num(xrb, xrb.apec.kT))) xs.Fit.steppar("xrb:{:d} 0.4 0.8 20".format(xs_utils.par_num(xrb, xrb.apec_6.kT))) if xs.Plot.device == "/xs": xs.Plot("ldata delchi") if error: xs.Xset.openLog(output + "_error.log") print "Error run started:", datetime.now() xs.Fit.error("xrb:{:d}".format(xs_utils.par_num(xrb, xrb.apec.kT)) + " xrb:{:d}".format(xs_utils.par_num(xrb, xrb.apec.norm)) + " xrb:{:d}".format(xs_utils.par_num(xrb, xrb.tbnew_gas.nH)) + " xrb:{:d}".format(xs_utils.par_num(xrb, xrb.apec_6.kT)) + " xrb:{:d}".format(xs_utils.par_num(xrb, xrb.apec_6.norm))) print "Error run complete:", datetime.now() xs.Xset.closeLog() # Dump useful things here... products(output) print_model(xrb, output + "_xrb.txt")
def plot(self): """Plot the fit. """ xspec.Fit.show() xspec.Plot.device = '/xs' xspec.Plot.xAxis = 'keV' xspec.Plot('ldata', 'resid')
def pdf(fname, cmd="ldata delchi"): """Dump a plot w/ given cmd to fname WARNING: this will NOT WORK IN SCRIPTS IF THE PLOT DEVICE WAS SET TO /xw ALREADY (and something was displayed?...)! XSPEC will hang at a prompt "Type <RETURN> for next page:" Partial fix: use "/xs" instead... No plot settings are applied; tweak PyXSPEC parameters as you need first. Arguments f_stem: filename stem cmd: XSPEC plot (sub)commands (default: ldata delchi) Output None. File written to {fname} On occasion XSPEC dumps have not displayed properly """ old_device = xs.Plot.device # Kludgy, but guarantees that no other application will overwrite the temp # file until method concludes fh_ps = tempfile.NamedTemporaryFile(delete=False) fh_ps.close() temp_ps = fh_ps.name xs.Plot.device = temp_ps + "/cps" xs.Plot(cmd) call(["ps2pdf", temp_ps, fname]) call(["rm", temp_ps]) xs.Plot.device = old_device
def fake_data(**kwargs): bkg = kwargs['bkg'] + "{1}" rsp = kwargs['rsp'] xs.AllData.clear() xs.AllModels.clear() m = xs.Model('ALP') for i in range(len(N)): m.ALP.norm.values = N[i] m.ALP.norm.frozen = True xs.AllData.clear() fs = xs.FakeitSettings(background=bkg, response=rsp, fileName='fake_spec_%s.fak' % i) sl = 2000 * [fs] # making 2000 simulations xs.AllData.fakeit(2000, sl) if kwargs['show']: import matplotlib.pyplot as plt xs.AllData.clear() for i in range(1, 2001): xs.AllData += "fake_spec_20.fak{%i}" % i xs.AllModels.clear() m = xs.Model("ALP") xs.Fit.statMethod = "pgstat" xs.Plot.device = "/xs" xs.Plot.xAxis = "MeV" xs.Plot.add = True xs.Plot.background = True xs.Plot.xLog = True xs.Plot.yLog = True xs.Plot.show() xs.Plot("ufspec") xerr_uf = np.zeros((2001, len(E_LLE))) yerr_uf = np.zeros((2001, len(E_LLE))) spec_uf = np.zeros((2001, len(E_LLE))) for i in range(1, 2001): xerr_uf[i, :] = np.asarray(xs.Plot.xErr(i)) yerr_uf[i, :] = np.asarray(xs.Plot.yErr(i)) spec_uf[i, :] = np.asarray(xs.Plot.y(i)) for i in range(1, 2001): plt.errorbar(E_LLE, spec_uf[i, :], xerr=xerr_uf[i, :], yerr=yerr_uf[i, :]) plt.plot(E_LLE, SED * N[20], 'r', zorder=2001, label='Theoretical spectrum') plt.xlabel('Energy, [MeV]') plt.ylabel('[photons cm$^{-2}$ s$^{-1}$ MeV$^{-1}$] ') plt.xscale('log') plt.grid() plt.legend() plt.show()
def set_xspec(obsid, model = None, rmffile='/Users/corcoran/Dropbox/nicer_cal/nicer_v0.06.rmf', arffile='/Users/corcoran/Dropbox/nicer_cal/ni_xrcall_onaxis_v0.06.arf', workdir='/Users/corcoran/research/WR140/NICER/work/', ignore='0.0-0.45, 5.-**', showplot=False, showmodel=False ): """ sets the pha and model instances for a given obsid :param obsid: NICER observation id (integer) :param rmffile: NICER response file :param arffile: NICER effective area file :param workdir: NICER dataset working directory :param ignore: energy range in keV to ignore when fitting :param showplot: if True plot the model and spectrum vs. energy :param showmodel: if True print the model parameters :return: """ import xspec import matplotlib as plt obs = str(obsid) xspec.AllData.clear() xspec.AllModels.clear() xspecdir = os.path.join(workdir, obs) phaname = os.path.join(xspecdir, 'ni{obs}_0mpu7_cl.pha'.format(obs=obsid)) print "phaname = {phaname}".format(phaname=phaname) try: pha = xspec.Spectrum(phaname) except: print "Can't find {phaname}; returning".format(phaname=phaname) return 0, 0 pha.response = rmffile pha.response.arf = arffile pha.ignore(ignore) # # Define a model # if not model: model = set_model() if showmodel: with sys_pipes(): model.show() if showplot: xspec.Plot.setRebin(minSig=3, maxBins=30) xspec.Plot.device = "/null" xspec.Plot.xAxis = "keV" xspec.Plot.yLog = "True" xspec.Plot("data") plt.figure(figsize=[10, 6]) plt.yscale('log') plt.xscale('log') plt.xlabel('Energy (keV)', fontsize=16) plt.step(xspec.Plot.x(), xspec.Plot.y()) plt.step(xspec.Plot.x(), xspec.Plot.model()) return pha, model
def add_curve(lab, col=None): xs.Plot("ldata") x = xs.Plot.x() y = xs.Plot.model() if col: plt.loglog(x, y, c=col, label=lab) else: plt.loglog(x, y, label=lab)
def posterior_predictions_plot(plottype, callback, analyzer, transformations, nsamples=None): """ Internal Routine used by posterior_predictions_unconvolved, posterior_predictions_convolved """ posterior = analyzer.get_equal_weighted_posterior() # for plotting, we don't need so many points, and especially the # points that barely made it into the analysis are not that interesting. # so pick a random subset of at least nsamples points if nsamples is not None and len(posterior) > nsamples: if hasattr(numpy.random, 'choice'): chosen = numpy.random.choice(numpy.arange(len(posterior)), replace=False, size=nsamples) else: chosen = list( set(numpy.random.randint(0, len(posterior), size=10 * nsamples)))[:nsamples] posterior = posterior[chosen, :] assert len(posterior) == nsamples prefix = analyzer.outputfiles_basename tmpfilename = '%s-wdatatmp.qdp' % prefix olddevice = Plot.device Plot.device = '/null' modelnames = set([t['model'].name for t in transformations]) while len(Plot.commands) > 0: Plot.delCommand(1) Plot.addCommand('wdata "%s"' % tmpfilename.replace('.qdp', '')) oldchatter = Xset.chatter, Xset.logChatter Xset.chatter, Xset.logChatter = 0, 0 # plot models widgets = [progressbar.Percentage()] if hasattr(progressbar, 'Counter'): widgets += [progressbar.Counter('%5d')] widgets += [progressbar.Bar(), progressbar.ETA()] pbar = progressbar.ProgressBar(widgets=widgets, maxval=len(posterior)).start() for k, row in enumerate(posterior): set_parameters(values=row[:-1], transformations=transformations) if os.path.exists(tmpfilename): os.remove(tmpfilename) xspec.Plot(plottype) content = numpy.genfromtxt(tmpfilename, skip_header=3) os.remove(tmpfilename) callback(content) pbar.update(k) pbar.finish() Xset.chatter, Xset.logChatter = oldchatter xspec.Plot.device = olddevice
def posterior_predictions_plot(self, plottype, callback, nsamples=None): """ Internal Routine used by posterior_predictions_unconvolved, posterior_predictions_convolved """ posterior = self.posterior # for plotting, we don't need so many points, and especially the # points that barely made it into the analysis are not that interesting. # so pick a random subset of at least nsamples points if nsamples is not None and len(posterior) > nsamples: if hasattr(numpy.random, 'choice'): chosen = numpy.random.choice(numpy.arange(len(posterior)), replace=False, size=nsamples) else: chosen = list( set( numpy.random.randint(0, len(posterior), size=10 * nsamples)))[:nsamples] posterior = posterior[chosen, :] assert len(posterior) == nsamples prefix = self.outputfiles_basename tmpfilename = os.path.join( os.path.dirname(prefix), os.path.basename(prefix).replace('.', '_') + '-wdatatmp.qdp') if os.path.exists(tmpfilename): os.remove(tmpfilename) with XSilence(): olddevice = Plot.device Plot.device = '/null' #modelnames = set([t['model'].name for t in transformations]) while len(Plot.commands) > 0: Plot.delCommand(1) Plot.addCommand('wdata "%s"' % tmpfilename.replace('.qdp', '')) # plot models for k, row in enumerate(tqdm(posterior, disable=None)): set_parameters(values=row, transformations=self.transformations) if os.path.exists(tmpfilename): os.remove(tmpfilename) xspec.Plot(plottype) content = numpy.genfromtxt(tmpfilename, skip_header=3) os.remove(tmpfilename) callback(content) xspec.Plot.device = olddevice while len(Plot.commands) > 0: Plot.delCommand(1) if os.path.exists(tmpfilename): os.remove(tmpfilename)
def plot_dump_data(spec, model, plt_fname, npz_fname): """spectrum, model should be already set-up/fitted, just like in XSPEC""" xs.Plot.device = plt_fname + '/cps' # Save plot to pltname xs.Plot('ldata', 'residual', 'ratio') # A good default np.savez(npz_fname, x=xs.Plot.x(), xE=xs.Plot.xErr(), y=xs.Plot.y(), yE=xs.Plot.yErr(), m=xs.Plot.model(), bkg=xs.Plot.backgroundVals()) return None
def wdata(fname): """Dump plot data for ALL spectra using iplot wdata command, with all additive components groups. Note that a plot command is invoked in the process. Output QDP file at fname """ old_add = xs.Plot.add xs.Plot.add = True # Dump additive components within each model xs.Plot.addCommand("wdata " + fname) xs.Plot("ldata") xs.Plot.delCommand(len(xs.Plot.commands)) xs.Plot.add = old_add
def plotTrumpetSpecs(evtFiles): mainVals1937 = [0.01, 0.07] mainVals1821 = [0.98, 1.05] interVals1821 = [0.51, 0.59] interVals1937 = [0.54, 0.59] #the lower and upper are the two different phase ranges for the main and interpulse #"Back" refers to the background region/ off pulse region used as background #We use the same background region for each pulsar lowBack = [.2, .4] upBack = [.7, .9] #for num in range(evtplotTrupetFiles): #using old code in genspectra to produce a pha file for a given evt file genspectra.gen_spectra('evtFiles/newfile1821_4.evt', mainVals1821, interVals1821, 0, 1200, 1000, save_pha="ourOnPeakboth.pha", run_xspec=False) genspectra.gen_spectra('evtFiles/newfile1821_4.evt', lowBack, upBack, 0, 1200, 1000, save_pha="ourOffPeak.pha", run_xspec=False) s1 = xspec.Spectrum("ourOnPeakboth.pha") s1.response = "/packages/caldb/data/nicer/xti/cpf/rmf/nixtiref20170601v001.rmf" s1.response.arf = "/packages/caldb/data/nicer/xti/cpf/arf/nixtiaveonaxis20170601v002.arf" s1.background = "ourOffPeak.pha" s1.ignore("**-0.8,10.0-**") #this is the command "abund wilm" xspec.Xset.abund = "wilm" #m1 holds the model that was implemented on the data m1 = xspec.Model("tbabs*pow") #fitting and plotting the data/creating values for the data of the plot xspec.Fit.perform() print("error stuff") xspec.Fit.error("1-3") print("hello") xspec.Plot.device = "/xs" xspec.Plot("ufspec delchi")
def saveintofile(FileName, N=0): if N > 0: XS.AllData.dummyrsp(lowE=0.1, highE=50, nBins=N) XS.Plot('model') Col_E = fits.column.Column(array=n.array([ XS.Plot.x(), ], dtype=n.object), name='ENERGY', format='PE()', unit='keV') Col_F = fits.column.Column(array=n.array([ XS.Plot.model(), ], dtype=n.object), name='FLUXDENSITY', format='PE()', unit='photon/s/cm**2/keV') HDU1 = fits.BinTableHDU.from_columns([Col_E, Col_F]) HDU1.header['EXTNAME'] = 'SPECTRUM' HDU1.header['HDUCLAS1'] = 'SPECTRUM' HDU1.writeto(os.path.join(dir_2_eRO_all, FileName), overwrite=True)
def fit_spectrum(obsid, pha, model, writexcm=True, workdir='/Users/corcoran/research/WR140/NICER/work/', statMethod='cstat' ): import xspec from wurlitzer import sys_pipes import pylab as plt from heasarc.utils import xspec_utils as xu if type(pha) != int: # # do fit # xspec.Fit.statMethod = statMethod xspec.Fit.perform() print("Best Fit Model is\n") with sys_pipes(): model.show() pha.notice("0.4-10.0") xspec.Plot.setRebin(minSig=3, maxBins=30) xspec.Plot.device = "/null" xspec.Plot.xAxis = "keV" xspec.Plot.yLog = "True" xspec.Plot("data") plt.figure(figsize=[10, 6]) plt.yscale('log') plt.xscale('log') plt.xlabel('Energy (keV)', fontsize=16) plt.title("{obs}".format(obs=obsid), fontsize=16) plt.errorbar(xspec.Plot.x(), xspec.Plot.y(), xerr=xspec.Plot.xErr(), yerr=xspec.Plot.yErr(), fmt='.') plt.step(xspec.Plot.x(), xspec.Plot.model(), where="mid") band = "0.5-10 keV" xspec.AllModels.calcFlux(band.replace(' keV', '').replace('-',' ')) print "Flux is {0:.3e} in the {1} band".format(pha.flux[0], band) if writexcm: xcmfile = os.path.join(workdir, str(obsid), 'ni{obsid}_0mpu7_cl'.format(obsid=obsid)) xu.write_xcm(xcmfile, pha, model=model) else: print "Can't fit OBSID {obs}".format(obs=obsid) return pha, model
def fit(data, reference_instrument, model_setter, emin_values, fn_prefix="", systematic_fraction=0): importlib.reload(xspec) fit_by_lt = {} fn_by_lt={} xspec.AllModels.systematic=systematic_fraction for c_emin in emin_values: xspec.AllData.clear() xspec.AllModels.clear() isgri, ref_ind = model_setter(data, reference_instrument, c_emin) max_chi=np.ceil(xspec.Fit.statistic / xspec.Fit.dof) m1=xspec.AllModels(1) if ref_ind is not None: n_spec = 2 if isinstance(ref_ind, list): n_spec = len(ref_ind) + 1 xspec.Fit.error("1.0 max %.1f 1-%d"%(max_chi, n_spec*m1.nParameters)) ref = ref_ind[0] else: xspec.Fit.error("1.0 max %.1f 1-%d" % (max_chi,m1.nParameters)) models={} lt_key='%.10lg'%c_emin fit_by_lt[lt_key]=dict( emin=c_emin, chi2_red=xspec.Fit.statistic/xspec.Fit.dof, chi2=xspec.Fit.statistic, ndof=xspec.Fit.dof, models=models, ) for m, ss in (isgri, 'isgri'), (ref, 'ref'): if m is None: continue #initialize dictionaries models[ss]={} #models[ss]['flux']={} #fills dictionaries for i in range(1,m.nParameters+1): if (not m(i).frozen) and (not bool(m(i).link)): #use the name plus position because there could be parameters with same name from multiple #model components (e.g., several gaussians) print(m(i).name, "%.2f"%(m(i).values[0]), m(i).frozen,bool(m(i).link) ) models[ss][m(i).name+"_%02d"%(i)]=[ m(i).values[0], m(i).error[0], m(i).error[1] ] # for flux_e1, flux_e2 in [(30,80), (80,200)]: # xspec.AllModels.calcFlux("{} {} err".format(flux_e1, flux_e2)) # #print ( xspec.AllData(1).flux) # models['isgri']['flux'][(flux_e1, flux_e2)] = xspec.AllData(1).flux # models['ref']['flux'][(flux_e1, flux_e2)] = xspec.AllData(2).flux xcmfile="saved"+fn_prefix+"_"+reference_instrument+".xcm" if os.path.exists(xcmfile): os.remove(xcmfile) xspec.XspecSettings.save(xspec.XspecSettings, xcmfile, info='a') xspec.Plot.device="/png" #xspec.Plot.addCommand("setplot en") xspec.Plot.xAxis="keV" xspec.Plot("ldata del") xspec.Plot.device="/png" fn="fit_lt%.5lg.png"%c_emin fn_by_lt[lt_key] = fn shutil.move("pgplot.png_2", fn) _=display(Image(filename=fn,format="png")) return fit_by_lt, fn_by_lt
def run_fit(self, e_min_kev, e_max_kev, plot=False, xspec_model='powerlaw', params_setting=None, frozen_list=None): import xspec as xsp xsp.AllModels.clear() xsp.AllData.clear() xsp.AllChains.clear() # PyXspec operations: print('fitting->,', self.spec_file) print('res', self.rmf_file) print('arf', self.arf_file) s = xsp.Spectrum(self.spec_file) s.response = self.rmf_file.encode('utf-8') s.response.arf = self.arf_file.encode('utf-8') s.ignore('**-15.') s.ignore('300.-**') # s.ignore('**-%f'%e_min_kev) # s.ignore('%f-**'%e_max_kev) xsp.AllData.ignore('bad') model_name = xspec_model m = xsp.Model(model_name) self.set_par(m, params_setting) self.set_freeze(m, frozen_list) xsp.Fit.query = 'yes' xsp.Fit.perform() header_str = 'Exposure %f (s)\n' % (s.exposure) header_str += 'Fit report for model %s' % (model_name) _comp = [] _name = [] _val = [] _unit = [] _err = [] colnames = ['component', 'par name', 'value', 'units', 'error'] for model_name in m.componentNames: fit_model = getattr(m, model_name) for name in fit_model.parameterNames: p = getattr(fit_model, name) _comp.append('%s' % (model_name)) _name.append('%s' % (p.name)) _val.append('%5.5f' % p.values[0]) _unit.append('%s' % p.unit) _err.append('%5.5f' % p.sigma) fit_table = dict(columns_list=[_comp, _name, _val, _unit, _err], column_names=colnames) footer_str = 'dof ' + '%d' % xsp.Fit.dof + '\n' footer_str += 'Chi-squared ' + '%5.5f\n' % xsp.Fit.statistic footer_str += 'Chi-squared red. %5.5f\n\n' % (xsp.Fit.statistic / xsp.Fit.dof) try: xsp.AllModels.calcFlux("20.0 60.0 err") (flux, flux_m, flux_p, _1, _2, _3) = s.flux footer_str += 'flux (20.0-60.0) keV %5.5e ergs cm^-2 s^-1\n' % ( flux) footer_str += 'Error range 68.00%% confidence (%5.5e,%5.5e) ergs cm^-2 s^-1\n' % ( flux_m, flux_p) except: footer_str += 'flux calculation failed\n' _passed = False try: _passed = True if self.chain_file_path.exists(): self.chain_file_path.remove() fit_chain = xsp.Chain(self.chain_file_path.path, burn=500, runLength=1000, algorithm='mh') fit_chain.run() except: footer_str += '!chain failed!\n' if _passed: try: xsp.AllModels.calcFlux("20.0 60.0 err") (flux, flux_m, flux_p, _1, _2, _3) = s.flux footer_str += '\n' footer_str += 'flux calculation with Monte Carlo Markov Chain\n' footer_str += 'flux (20.0-60.0) keV %5.5e ergs cm^-2 s^-1\n' % ( flux) footer_str += 'Error range 68.00%% confidence (%5.5e,%5.5e) ergs cm^-2 s^-1\n' % ( flux_m, flux_p) except: footer_str += 'flux calculation with Monte Carlo Markov Chain failed\n' _passed = False try: _passed = True xsp.Fit.error('1-%d' % m.nParameters) _err_m = [] _err_p = [] for model_name in m.componentNames: fit_model = getattr(m, model_name) for name in fit_model.parameterNames: p = getattr(fit_model, name) _err_m.append('%5.5f' % p.error[0]) _err_p.append('%5.5f' % p.error[1]) fit_table['columns_list'].extend([_err_m, _err_p]) fit_table['column_names'].extend(['range-', 'range+']) except: footer_str += '!chain error failed!\n' if plot == True: xsp.Plot.device = "/xs" xsp.Plot.xLog = True xsp.Plot.yLog = True xsp.Plot.setRebin(10., 10) xsp.Plot.xAxis = 'keV' # Plot("data","model","resid") # Plot("data model resid") xsp.Plot("data,delchi") if plot == True: xsp.Plot.show() #import matplotlib.pyplot as plt #import matplotlib.gridspec as gridspec #gs = gridspec.GridSpec(2, 1, height_ratios=[4, 1]) #fig = plt.figure() #ax1 = fig.add_subplot(gs[0]) #ax2 = fig.add_subplot(gs[1]) # fig.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.95, # hspace=0.1, wspace=0.1) x = np.array(xsp.Plot.x()) y = np.array(xsp.Plot.y()) dx = np.array(xsp.Plot.xErr()) dy = np.array(xsp.Plot.yErr()) mx = x > 0. my = y > 0. msk = np.logical_and(mx, my) msk = np.logical_and(msk, dy > 0.) ldx = 0.434 * dx / x ldy = 0.434 * dy / y y_model = np.array(xsp.Plot.model()) msk = np.logical_and(msk, y_model > 0.) if msk.sum() > 0: sp1 = ScatterPlot(w=500, h=350, x_label='Energy (keV)', y_label='normalised counts/s/keV', y_axis_type='log', x_axis_type='log') #y_range=[np.log10(y[msk]).min()-np.log10(y[msk]).min()*0.5,np.log10(y[msk]).max()*1.5]) sp1.add_errorbar(x[msk], y[msk], yerr=dy[msk], xerr=dx[msk]) sp1.add_step_line(x[msk], y_model[msk]) sp2 = ScatterPlot(w=500, h=150, x_label='Energy (keV)', y_label='(data-model)/error', x_range=sp1.fig.x_range, x_axis_type='log', y_axis_type='linear') sp2.add_errorbar(x[msk], (y[msk] - y_model[msk]) / dy[msk], yerr=np.ones(msk.sum())) sp2.add_line([x[msk].min(), x[msk].max()], [0, 0]) gp = GridPlot(sp1, sp2, w=550, h=550) htmlt_dict = gp.get_html_draw() #print('OK 3') xsp.AllModels.clear() xsp.AllData.clear() xsp.AllChains.clear() #if plot == True: # plt.show() #plugins.connect(fig, plugins.MousePosition(fontsize=14)) res_dict = {} res_dict['spectral_fit_image'] = htmlt_dict res_dict['header_text'] = header_str res_dict['table_text'] = fit_table res_dict['footer_text'] = footer_str return res_dict
#Perform Fit xspec.Fit.statMethod = "cstat" xspec.Fit.nIterations = 100 xspec.Fit.criticalDelta = 1e-1 xspec.Fit.query = 'yes' xspec.Fit.perform() #Plotting xspec.Plot.splashPage = False # XSPEC version and build data information will not be printed to the screen when the first plot window is initially opened xspec.Plot.device = f'{observation}_{model}_{i}.gif/gif' xspec.Plot.xAxis = 'keV' xspec.Plot.setRebin(minSig=3, maxBins=4096) xspec.Plot.addCommand( f'label top {observation} {model} Part {i}') xspec.Plot('ldata res model') os.rename( f"{target_dir}/{observation}/rgs/divided_spectra/{observation}_{model}_{i}.gif", f"{target_dir}/Products/RGS_Spectra/{observation}/{observation}_{model}_{i}.gif" ) #use matplotlib chans1 = xspec.Plot.x(1) chans1_err = xspec.Plot.xErr(1) rates1 = xspec.Plot.y(1) rates1_err = xspec.Plot.yErr(1) chans2 = xspec.Plot.x(2) chans2_err = xspec.Plot.xErr(2) rates2 = xspec.Plot.y(2) rates2_err = xspec.Plot.yErr(2)
m.gaussian.LineE = [6.4, -0.1] m.gaussian.Sigma = [0.01, -0.01] m.gaussian.norm = [1e-4, 1e-5, 0, 0, 0.1, 0.1] m.show() try: xspec.Fit.perform() except Exception, errmsg: sys.exit("{0}; Can't proceed; exiting".format(errmsg.value)) m.show() xspec.Plot.xAxis = "KeV" xspec.Plot.device = "/xw" xspec.Plot.add = True xspec.Plot.addCommand("re y 1e-5 20") xspec.Plot("ldata") xspec.AllModels.calcFlux(str(emin) + " " + str(emax)) oflux = src.flux[0] """ Create XCM output """ xcm = ['data ' + src.fileName] xcm.append('back ' + src.background.fileName) xcm.append('resp ' + src.response.rmf) xcm.append('arf ' + src.response.arf) xcm.append('ignore ' + src.ignoredString()) xcm.append('model ' + m.expression) for i in np.arange(m.nParameters) + 1: p = m(i).values parvals = str(p[0]) for k in np.arange(len(p) - 1) + 1:
def annulus_fit(output, error=False, error_rerun=False, free_center_elements=None, free_all_elements=None, four_ann=False, **kwargs): """ Fit radial annuli simultaneously Arguments: output = output products file stem error = run error commands? error_rerun = run error commands 2nd time? four_ann = fit only 4 instead of 5 annuli? free_all_elements = (case-sensitive) elements to free in all annuli. Element names much match XSPEC parameter names. Default: Si, S free free_center_elements = (case-sensitive) additional elements to free in central circle (0-100 arcsec) Element names much match XSPEC parameter names. kwargs - passed to g309_models.load_data_and_models (suffix, mosmerge, marfrmf) Output: n/a loads of stuff dumped to output* XSPEC session left in fitted state """ if free_center_elements is None: free_center_elements = [] if free_all_elements is None: free_all_elements = ['Si', 'S'] regs = ["ann_000_100", "ann_100_200", "ann_200_300", "ann_300_400", "ann_400_500"] if four_ann: regs = ["ann_000_100", "ann_100_200", "ann_200_300", "ann_300_400"] out = g309.load_data_and_models(regs, snr_model='vnei', **kwargs) for reg in regs: set_energy_range(out[reg]) xs.AllData.ignore("bad") # Link nH across annuli # Each region has n spectra (n exposures) # [0] gets 1st of n ExtractedSpectra objects # .models['...'] gets corresponding 1st of n XSPEC models rings = [out[reg][0].models['snr'] for reg in regs] for ring in rings[1:]: # Exclude center ring.tbnew_gas.nH.link = xs_utils.link_name(rings[0], rings[0].tbnew_gas.nH) # Start fit process xs.Fit.renorm() xs.Fit.perform() for ring in rings: ring.tbnew_gas.nH.frozen = False ring.vnei.kT.frozen = False ring.vnei.Tau.frozen = False xs.Fit.perform() for ring in rings: for elem in free_all_elements: comp = ring.vnei.__getattribute__(elem) comp.frozen = False for elem in free_center_elements: comp = rings[0].vnei.__getattribute__(elem) comp.frozen = False xs.Fit.perform() if xs.Plot.device == "/xs": xs.Plot("ldata delchi") # Error runs if error: xs.Xset.openLog(output + "_error.log") print "First error run:", datetime.now() for reg, ring in zip(regs, rings): print "Running", reg, "errors:", datetime.now() xs.Fit.error(error_str_all_free(ring)) print reg, "errors complete:", datetime.now() # Will not appear in error log if error_rerun: print "Second error run:", datetime.now() for reg, ring in zip(regs, rings): print "Running", reg, "errors:", datetime.now() xs.Fit.error(error_str_all_free(ring)) print reg, "errors complete:", datetime.now() # Will not appear in error log xs.Xset.closeLog() print "Error runs complete:", datetime.now() # Output products products(output) for ring in rings: model_log = output + "_{}.txt".format(ring.name) print_model(ring, model_log)
def fit_ecsrcbin10( obsid, WorkDir="/Users/corcoran/Dropbox/Eta_Car/swift/quicklook/work", emin=2.0, emax=10.0, rmfdir='/caldb/data/swift/xrt/cpf/rmf', chatter=0): import xspec import glob import pyfits import numpy as np from astropy.time import Time xspec.AllData.clear() xspec.Xset.chatter = chatter xspec.FitManager.query = "yes" xspec.Fit.query = "yes" xspec.Fit.nIterations = 100 xspecdir = WorkDir + "/" + obsid.strip() + "/xspec" cwd = os.getcwd() print "\n" os.chdir(xspecdir) src = xspec.Spectrum("ec_srcbin10.pha") try: hdu = pyfits.open("ec_srcbin10.arf") except: print "ARF ec_srcbin10.arf not found; Returning" return arfhd = hdu[1].header try: respfile = arfhd['RESPFILE'] except: print "RESPFILE keyword in ec_srcbin10.arf not found; Returning" return try: rmffile = glob.glob(rmfdir + '/' + respfile)[0] except: print "Response file %s does not exist; Returning" % (rmfdir + '/' + respfile) return src.response = rmffile src.response.arf = "ec_srcbin10.arf" src.background = "ec_bkg.pha" src.ignore("0.0-1.0 7.9-**") hdulist = pyfits.open("ec_srcbin10.pha") prihdr = hdulist[0].header """ dateobs=prihdr['DATE-OBS'] dateend=prihdr['DATE-END'] t=Time(dateobs,scale='utc', format='isot') te=Time(dateend,scale='utc',format='isot') """ mjds = prihdr['MJD-OBS'] mjde = prihdr['MJD-OBS'] + (prihdr['TSTOP'] - prihdr['TSTART']) / 86400.0 t = Time(mjds, scale='utc', format='mjd') dateobs = t.iso.replace(' ', 'T') te = Time(mjde, scale='utc', format='mjd') tmid = (te.jd - t.jd) / 2.0 + t.jd xspec.AllData.ignore("bad") """ first fit without the cflux component """ mostring = "wabs*apec + wabs*(apec + gaussian)" m = xspec.Model(mostring) m.wabs.nH = [1.1, 0.1, 0, 0, 5, 5] m.apec.kT = [1.0, 0.1, 0.1, 0.1, 2, 2] m.apec.norm = [0.1, 0.1, 0.0, 0.0, 2, 2] m.wabs_3.nH = [10, 0.1, 0, 0, 100, 100] m.apec_4.kT = [4.5, -0.1, 2.0, 2.0, 6.0, 6.0] m.apec_4.norm = [0.1, 0.1, 0.0, 0.0, 2, 2] m.apec_4.Abundanc = 0.4 m.gaussian.LineE = [6.4, -0.1] m.gaussian.Sigma = [0.01, -0.01] m.gaussian.norm = [1e-4, 1e-5, 0, 0, 0.1, 0.1] m.show() xspec.Fit.perform() m.show() xspec.Plot.xAxis = "KeV" xspec.Plot.device = "/xw" xspec.Plot("ldata") xspec.AllModels.calcFlux(str(emin) + " " + str(emax)) oflux = src.flux[0] """ Create XCM output """ xcm = ['data ' + src.fileName] xcm.append('back ' + src.background.fileName) xcm.append('resp ' + src.response.rmf) xcm.append('arf ' + src.response.arf) xcm.append('ignore ' + src.ignoredString()) xcm.append('model ' + m.expression) for i in np.arange(m.nParameters) + 1: p = m(i).values parvals = str(p[0]) for k in np.arange(len(p) - 1) + 1: parvals = parvals + ', ' + str(p[k]) xcm.append(parvals) xcm.append('statistic ' + xspec.Fit.statMethod) nh = m.wabs.nH.values[0] kt = m.apec.kT.values[0] norm = m.apec.norm.values[0] nh3 = m.wabs_3.nH.values[0] xspec.Fit.error("2.706 6") # param 6 is nh3 p6 = xspec.AllModels(1)(6) nhmin = p6.error[0] nhmax = p6.error[1] kt4 = m.apec_4.kT.values[0] norm4 = m.apec_4.norm.values[0] gnorm = m.gaussian.norm.values[0] """ now add cflux component, set the values to the previous best fit, freeze apec norms, and refit to get the cflux and its errors """ mostring2 = "wabs*apec + cflux*wabs*(apec + gaussian)" m2 = xspec.Model(mostring2) m2.wabs.nH = [nh, -0.1] m2.apec.kT = [kt, -0.1] m2.apec.norm = [norm, -0.1] m2.wabs_4.nH = [nh3, -0.1] m2.apec_5.kT = [kt4, -0.1] m2.apec_5.norm = [norm4, -0.0001] m2.apec_5.Abundanc = 0.4 m2.gaussian.LineE = [6.4, -0.1] m2.gaussian.Sigma = [0.01, -0.01] m2.gaussian.norm = [gnorm, -0.0001] m2.cflux.Emin = emin m2.cflux.Emax = emax xspec.Fit.perform() m2.show() cf = m2.cflux.lg10Flux.values[0] print "%5.1f - %5.1f keV flux from cflux = %10.4e" % (emin, emax, 10**cf) xspec.Fit.error("2.706 8") # param 8 is cflux p8 = xspec.AllModels(1)(8) cfmin = p8.error[0] cfmax = p8.error[1] duration = te.jd - t.jd nhpluserr = nhmax - nh3 nhminerr = nh3 - nhmin output = { 'obsid': obsid, 't_start': t.jd, 't_end': te.jd, 't_mid': tmid, 'duration': duration, 'exposure': src.exposure, 'flux': oflux, 'fluxplus': 10**cfmax - 10**cf, 'fluxmin': 10**cf - 10**cfmin, 'dateobs': dateobs, 'nh': nh3, 'nhplus': nhpluserr, 'nhmin': nhminerr, 'emin': emin, 'emax': emax } """ Write xcm file; warn user if it exists and give option to overwrite """ filename = xspecdir + '/ec_srcbin10.xcm' if os.path.isfile(filename): print "File %s exists" % filename ans = raw_input('Overwrite [y]/n? ') if ans.strip().lower() == 'n': print "File %s not overwritten; Returning" % filename return output, xcm print "Writing file %s" % filename f = open(filename, 'w') for i in xcm: f.write(i + "\n") f.close() #print "Changing directory back to %s" % cwd print "\n" os.chdir(cwd) return output, xcm
# Fit and dump fit information/plot # --------------------------------- xs.Fit.renorm() xs.Fit.perform() if args.free_en: for cname, en in zip(instr.componentNames, lines): comp = instr.__getattribute__(cname) comp.LineE.frozen = False comp.Sigma.frozen = False xs.Fit.perform() xs.Plot.xAxis = "keV" xs.Plot.xLog = True xs.Plot.yLog = True xs.Plot.addCommand("co 2 on 2") xs.Plot.addCommand("rescale y 1e-4 1") xs.Plot.device = f_plot + "/cps" xs.Plot("ldata resid delchi") call(["ps2pdf", f_plot, f_plot + ".pdf"]) call(["rm", f_plot]) # Save current XSPEC state dump_dict(fit_dict(), f_fit) dump_fit_log(f_log)
def epic_spectrum_plot_xspec(observation, expid, model, target_dir): """ Plot spectrum in PyXspec for EPIC-pn. """ xspec.Plot.device = '/null' xspec.Plot.xAxis = 'keV' xspec.Plot.setRebin(minSig=3, maxBins=4096) xspec.Plot.background = True xspec.Plot('data') # Use matplotlib # Store x and y for EPIC-pn chans1 = xspec.Plot.x(1) chans1_err = xspec.Plot.xErr(1) rates1 = xspec.Plot.y(1) rates1_err = xspec.Plot.yErr(1) folded = xspec.Plot.model(1) fig, axs = plt.subplots(3, 1, sharex=True, gridspec_kw={'hspace': 0.1}, figsize=(11, 9)) fig.suptitle(f"Spectrum {observation}, expo {expid}, {model} ", fontsize=15, y=0.92) # First panel: Source Spectrum axs[0].errorbar(chans1, rates1, yerr=rates1_err, xerr=chans1_err, linestyle='', marker='.', markersize=2, color='black', label='EPIC-pn') axs[0].plot(chans1, folded, 'blue', linewidth=0.5, label='Folded model') # First panel: Background Spectrum xspec.Plot('back') axs[0].errorbar(chans1, xspec.Plot.y(1), xerr=chans1_err, yerr=xspec.Plot.yErr(1), color='salmon', linestyle='', marker='.', markersize=0.2, label='Background') axs[0].set_yscale('log') axs[0].set_xscale('log') axs[0].set_xlim(0.6, 12) axs[0].set_ylabel('Normalized counts [s-1 keV-1]', fontsize=10) axs[0].legend(loc='upper right', fontsize='x-large') # Second panel: Residuals xspec.Plot('resid') axs[1].errorbar(chans1, xspec.Plot.y(1), yerr=xspec.Plot.yErr(1), xerr=chans1_err, linestyle='', color='black', label='RGS1') axs[1].hlines(0, plt.xlim()[0], plt.xlim()[1], color='lime') axs[1].set_ylabel('Normalized counts [s-1 keV-1]', fontsize=10) # Third panel: delchi xspec.Plot('delchi') axs[2].errorbar(chans1, xspec.Plot.y(1), yerr=1., xerr=chans1_err, linestyle='', color='black', label='RGS1') axs[2].hlines(0, plt.xlim()[0], plt.xlim()[1], color='lime') axs[2].set_xlabel('Energy [keV]', fontsize=10) axs[2].set_ylabel('(data-model)/error', fontsize=10) plt.savefig( f"{target_dir}/Products/EPIC_Spectra/average_{observation}_{model}.png" ) plt.close()
def spectrum_plot_xspec(observation, expid0, expid1, model, target_dir, i=0): """ Plot spectrum in PyXspec. """ xspec.Plot.device = '/null' xspec.Plot.xAxis = 'keV' xspec.Plot.setRebin(minSig=3, maxBins=4096) xspec.Plot.background = True xspec.Plot('data') # Use matplotlib # Store x and y for RGS1 and RGS2 chans1 = xspec.Plot.x(1) chans1_err = xspec.Plot.xErr(1) rates1 = xspec.Plot.y(1) rates1_err = xspec.Plot.yErr(1) chans2 = xspec.Plot.x(2) chans2_err = xspec.Plot.xErr(2) rates2 = xspec.Plot.y(2) rates2_err = xspec.Plot.yErr(2) fig, axs = plt.subplots(3, 1, sharex=True, gridspec_kw={'hspace': 0.1}, figsize=(20, 15)) if i == 0: fig.suptitle( f"Spectra {observation}, expo {expid0}+{expid1}, {model} ", fontsize=25, y=0.92) else: fig.suptitle(f"{observation} expo {expid0}+{expid1} {model} Part {i}", fontsize=25, y=0.92) # First panel: Source Spectrum axs[0].errorbar(chans1, rates1, yerr=rates1_err, xerr=chans1_err, linestyle='', color='black', label='RGS1') axs[0].errorbar(chans2, rates2, yerr=rates2_err, xerr=chans2_err, linestyle='', color='red', label='RGS2') # First panel: Background Spectrum xspec.Plot('back') axs[0].errorbar(chans1, xspec.Plot.y(1), xerr=chans1_err, yerr=xspec.Plot.yErr(1), color='wheat', linestyle='', marker='.', markersize=0.2, label='Background RGS1') axs[0].errorbar(chans2, xspec.Plot.y(2), xerr=chans2_err, yerr=xspec.Plot.yErr(2), color='tan', linestyle='', marker='.', markersize=0.2, label='Background RGS2') #axs[0].set_yscale('log') axs[0].set_xscale('log') #axs[0].set_ylim(1e-7) axs[0].set_xlim(0.331, 2.001) axs[0].set_ylabel('Normalized counts [s-1 keV-1]', fontsize=17) axs[0].legend(loc='upper right', fontsize='x-large') # Second panel: Residuals xspec.Plot('resid') axs[1].errorbar(chans1, xspec.Plot.y(1), yerr=xspec.Plot.yErr(1), linestyle='', color='black', label='RGS1') axs[1].errorbar(chans2, xspec.Plot.y(2), yerr=xspec.Plot.yErr(2), linestyle='', color='red', label='RGS2') axs[1].hlines(0, plt.xlim()[0], plt.xlim()[1], color='lime') axs[1].set_ylabel('Normalized counts [s-1 keV-1]', fontsize=17) # Third panel: delchi xspec.Plot('delchi') axs[2].errorbar(chans1, xspec.Plot.y(1), yerr=1., linestyle='', color='black', label='RGS1') axs[2].errorbar(chans2, xspec.Plot.y(2), yerr=1., linestyle='', color='red', label='RGS2') axs[2].hlines(0, plt.xlim()[0], plt.xlim()[1], color='lime') axs[2].set_xlabel('Energy [keV]', fontsize=17) axs[2].set_ylabel('(data-model)/error', fontsize=17) if i == 0: plt.savefig( f"{target_dir}/Products/RGS_Spectra/{observation}/average_{observation}_{expid0}+{expid1}_{model}.png" ) else: plt.savefig( f"{target_dir}/Products/RGS_Spectra/{observation}/{observation}_{expid0}+{expid1}_{model}_{i}.png" ) plt.close()
'tbabs*powerlaw', 'wabs*zlogpar', 'wabs*logpar', 'phabs*cutoffpl', 'tbabs*srcut' ] #change if necessary for model in model_list: #Define the model m = xspec.Model(model) if 'zlogpar' in m.componentNames: m.zlogpar.Redshift = 0.03 #otherwise it is freezed to 0. #Fit the model xspec.Fit.nIterations = 100 xspec.Fit.criticalDelta = 1e-1 xspec.Fit.perform() #Calculate Flux and Luminosity xspec.AllModels.calcFlux('0, 1.9, err') xspec.AllModels.calcLumin( ', , 0.03, err') #note: 0.3 is the redshift for Mrk421 #Plotting: set the device, set the axes and title and plot data xspec.Plot.device = f'{instr}_{model}.ps/cps' xspec.Plot.xAxis = 'keV' xspec.Plot.setRebin(minSig=3, maxBins=4096) xspec.Plot.addCommand(f'label top {instr} {model}') xspec.Plot('ldata res') # Close XSPEC's currently opened log file. xspec.Xset.closeLog()
def calculate_hi(low_e=3.0, high_e=16.0, soft=(6.4, 9.7), hard=(9.7, 16.)): ''' Function to calculate hardness & intensity values. Arguments: Energy ranges in keV - low_e (float): Lower energy boundary for selection - high_e (float): Higher energy boundary for selection - soft (tuple of floats): Energy range between which to integrate the soft range - hard (tuple of floats): Energy range between which to integrate the hard range ''' purpose = 'Calculating hardness & intensity values' print len(purpose) * '=' + '\n' + purpose + '\n' + len(purpose) * '=' print 'Soft:', soft, 'Hard:', hard, '\n' + len(purpose) * '-' import os import pandas as pd import glob import xspec from collections import defaultdict from math import isnan from numpy import genfromtxt import paths import logs import execute_shell_commands as shell import database # Set log file filename = __file__.split('/')[-1].split('.')[0] logs.output(filename) # Import data os.chdir(paths.data) db = pd.read_csv(paths.database) # Compile Fortran code for later use cmpl = [ 'gfortran', paths.subscripts + 'integflux.f', '-o', paths.subscripts + 'integflux.xf' ] shell.execute(cmpl) # Only want spectra from std2 d = defaultdict(list) for sp, group in db[(db.modes == 'std2')].groupby('spectra'): # Determine variables obsid = group.obsids.values[0] path_obsid = group.paths_obsid.values[0] bkg_sp = group.spectra_bkg.values[0] rsp = group.rsp.values[0] fltr = group.filters.values[0] print obsid # Check whether response file is there if not os.path.isfile(rsp): print 'ERROR: No response file' continue # XSPEC Commands to unfold spectrum around flat powerlaw # Reason as per Heil et al. (see doi:10.1093/mnras/stv240): # "In order to measure the energy spectral hardness independantly of # long term changes in the PCA instrument response, fluxes are # generated in a model-independant way by dividing the PCA standard # 2 mode spectrum by the effective area of the intstrument response # in each spectral channel. This is carried out by unfolding the # spectrum with respect to a zero-slope power law (i.e. a constant) # in the XSPEC spectral-fitting software, and measuring the unfolded # flux over the specified energy range (interpolating where the # specified energy does not fall neatly at the each of a spectral # channel)." #xspec.Plot.device = '/xs' s1 = xspec.Spectrum(sp) s1.background = bkg_sp s1.response = os.path.join(paths.data, rsp) # Not really sure why you need to do ignore, and then notice s1.ignore('**-' + str(low_e + 1.) + ' ' + str(high_e - 1) + '-**') s1.notice(str(low_e) + '-' + str(high_e)) xspec.Model('powerlaw') xspec.AllModels(1).setPars(0.0, 1.0) # Index, Norm xspec.AllModels(1)(1).frozen = True xspec.AllModels(1)(2).frozen = True xspec.Plot('eufspec') # Output unfolded spectrum to lists e = xspec.Plot.x() e_err = xspec.Plot.xErr() ef = xspec.Plot.y() ef_err = xspec.Plot.yErr() model = xspec.Plot.model() # Pipe output to file eufspec = path_obsid + 'eufspec.dat' with open(eufspec, 'w') as f: #Give header of file - must be three lines h = [ '#Unfolded spectrum', '#', '#Energy EnergyError Energy*Flux Energy*FluxError ModelValues' ] f.write('\n'.join(h) + '\n') for i in range(len(e)): data = [e[i], e_err[i], ef[i], ef_err[i], model[i]] line = [str(j) for j in data] f.write(' '.join(line) + '\n') # Create a file to input into integflux integflux = path_obsid + 'integflux.in' with open(integflux, 'w') as f: #intgr_low, intgr_high, soft_low, soft_high, hard_low, hard_high line = [ 'eufspec.dat', str(low_e), str(high_e), str(soft[0]), str(soft[-1]), str(hard[0]), str(hard[-1]) ] line = [str(e) for e in line] f.write(' '.join(line) + '\n') # Remove previous versions of the output if os.path.isfile(path_obsid + 'hardint.out'): os.remove(path_obsid + 'hardint.out') # Run fortran script to create calculate hardness-intensity values # Will output a file with the columns (with flux in Photons*ergs/cm^2/s) # flux flux_err ratio ratio_error os.chdir(path_obsid) shell.execute(paths.subscripts + 'integflux.xf') os.chdir(paths.data) # Get ouput of the fortran script txt = genfromtxt(path_obsid + 'hardint.out') flux = float(txt[0]) flux_err = float(txt[1]) ratio = float(txt[2]) ratio_err = float(txt[3]) d['spectra'].append(sp) d['flux_i3t16_s6p4t9p7_h9p7t16'].append(flux) d['flux_err_i3t16_s6p4t9p7_h9p7t16'].append(flux_err) d['hardness_i3t16_s6p4t9p7_h9p7t16'].append(ratio) d['hardness_err_i3t16_s6p4t9p7_h9p7t16'].append(ratio_err) # Clear xspec spectrum xspec.AllData.clear() # Update database and save df = pd.DataFrame(d) cols = [ 'flux_i3t16_s6p4t9p7_h9p7t16', 'flux_err_i3t16_s6p4t9p7_h9p7t16', 'hardness_i3t16_s6p4t9p7_h9p7t16', 'hardness_err_i3t16_s6p4t9p7_h9p7t16' ] db = database.merge(db, df, cols) print 'Number of unique elements in database' print '=======================' print db.apply(pd.Series.nunique) print '=======================' print 'Pipeline completed' database.save(db) logs.stop_logging()