def set_fit_parameters(self): xspec.AllData.clear() xspec.Fit.statMethod = str(self.statistic) xspec.Fit.query = "yes" os.chdir(self.path) self.spec_mos1 = xspec.Spectrum(self.spectrum_files["mos1"]) self.spec_mos1.ignore(self.energy_range["mos1"]) self.spec_mos2 = xspec.Spectrum(self.spectrum_files["mos2"]) self.spec_mos2.ignore(self.energy_range["mos2"]) self.spec_pn = xspec.Spectrum(self.spectrum_files["pn"]) self.spec_pn.ignore(self.energy_range["pn"]) self.spec_rass = xspec.Spectrum(self.spectrum_files["rass"]) print(self.spec_mos1, self.spec_mos2, self.spec_pn, self.spec_rass) #self.m1 = xspec.Model("{}+{}*{}".format(Spectrum.esas_bkg_model, self.abs_model, self.src_model)) self.m1 = xspec.Model(Spectrum.esas_model) gau1 = Gaussian(component_number=1, LineE=1.48516) self.m1.gaussian.LineE.values, self.m1.gaussian.Sigma.values, self.m1.gaussian.norm.values = gau1.get_params( ) gau2 = Gaussian(component_number=2, LineE=1.74000) self.m1.gaussian_2.LineE.values, self.m1.gaussian_2.Sigma.values, self.m1.gaussian_2.norm.values = gau2.get_params( ) gau3 = Gaussian(component_number=3, LineE=7.11) self.m1.gaussian_3.LineE.values, self.m1.gaussian_3.Sigma.values, self.m1.gaussian_3.norm.values = gau3.get_params( ) gau4 = Gaussian(component_number=4, LineE=7.49) self.m1.gaussian_4.LineE.values, self.m1.gaussian_4.Sigma.values, self.m1.gaussian_4.norm.values = gau4.get_params( ) gau5 = Gaussian(component_number=5, LineE=8.05) self.m1.gaussian_5.LineE.values, self.m1.gaussian_5.Sigma.values, self.m1.gaussian_5.norm.values = gau5.get_params( ) gau6 = Gaussian(component_number=6, LineE=8.62) self.m1.gaussian_6.LineE.values, self.m1.gaussian_6.Sigma.values, self.m1.gaussian_6.norm.values = gau6.get_params( ) gau7 = Gaussian(component_number=7, LineE=8.90) self.m1.gaussian_7.LineE.values, self.m1.gaussian_7.Sigma.values, self.m1.gaussian_7.norm.values = gau7.get_params( ) print(dir(self.m1)) print(self.m1.show()) print(self.m1.componentNames) print(self.m1.setPars())
def fit_spectrum(ob): spec = xspec.Spectrum(ob.path + ob.spectrum) spec.ignore("**-0.5 10.0-**") xspec.AllData.ignore("bad") model = xspec.Model("ph(bb+po)") xspec.Fit.query = 'yes' xspec.Fit.perform() energy_ranges = np.asarray(spec.energies) energy = (energy_ranges[:, 0] + energy_ranges[:, 1]) / 2 energy_err = energy - energy_ranges[:, 0] x1 = energy ex_1 = energy_err y1 = spec.values ey1 = np.sqrt(spec.variance) xspec.AllData.notice("all") energy_ranges = np.asarray(spec.energies) energy = energy_ranges[:, 0] + energy_ranges[:, 1] / 2 x2 = energy y2 = model.folded(1) plt.errorbar(x1, y1, ey1, ex1, fmt="o") plt.plot(x2, y2)
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 test_read_xspec(): import xspec synth_phaI().to_fits("phaI.fits") synth_rmf().to_fits("rmf.fits") s = xspec.Spectrum("phaI.fits") s.response = "rmf.fits"
def LoadNaiPHAs(self,phaFiles): ''' Load The GBM NaI PHAs in time order ''' for pha in phaFiles: s = xs.Spectrum(pha) s.ignore("**-8. 1999..-**") cnts = sum(s.values) self.nai.append(cnts)
def LoadBGOPHAs(self,phaFiles): ''' Load The GBM BGO PHAs in time order ''' for pha in phaFiles: s = xs.Spectrum(pha) s.ignore("**-250. 10000.-**") cnts = sum(s.values) self.bgo.append(cnts)
def __init__(self, file_path, **kwargs): """ """ xspec.AllData.clear() self.count_spectrum = xBinnedCountSpectrum(file_path) irf_name = self.count_spectrum.primary_header_keyword('IRFNAME') self.spectrum = xspec.Spectrum(file_path) self.spectrum.response = irf_file_path(irf_name, 'rmf') self.spectrum.response.arf = irf_file_path(irf_name, 'arf') self.spectrum.ignore('**-%f' % kwargs['emin']) self.spectrum.ignore('%f-**' % kwargs['emax']) self.model = xspec.Model(kwargs['model']) xspec.Fit.perform()
def LoadSwiftPHAs(self,phaFiles): ''' Load The Swift PHAs in time order ''' for pha in phaFiles: s = xs.Spectrum(pha) s.ignore("**-15. 150.-**") cnts = sum(s.values) self.swift.append(cnts)
def call_xspec(): import xspec print "starting fit_srcbin10" import glob import pyfits import numpy as np from astropy.time import Time import xspec xspec.AllData.clear() xspec.Xset.chatter = 0 xspec.FitManager.query = "yes" xspec.Fit.query = "yes" xspec.Fit.nIterations = 100 pcmode = False WorkDir = '/Users/corcoran/research/WR140/Swift/data/2016/work' rmfdir = '/caldb/data/swift/xrt/cpf/rmf' if pcmode: mode = 'pc' else: mode = 'wt' xspecdir = WorkDir + "/" + obsid.strip() + "/" + mode + "/xspec" cwd = os.getcwd() print "\n" os.chdir(xspecdir) src = xspec.Spectrum("srcbin10.pha") try: hdu = pyfits.open("src.arf") except: print "ARF src.arf not found; Returning" return arfhd = hdu[1].header try: respfile = arfhd['RESPFILE'] except: print "RESPFILE keyword in 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 xspec.AllData.clear() mostring = "wabs*apec + wabs*(apec + gaussian)" print "test1.55" m = xspec.Model(mostring) return
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 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
def get_obsid_specparams(obsid, model=None, get_errors = True, phaname=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/", datadir="/Volumes/SXDC/Data/NICER/wr140", fluxband="2.0 10.0", statMethod="cstat", ignore = "0.0-0.45, 7.5.0-**", interval=None, chatter=False ): """Get spectrum parameters from fit gets the observation and spectrum parameters from the model fit for the given obsid. A NICER spectrum fit using the absorbed two-component thermal models (defined in the model1 function) should have been done prior to running this function. :param obsid: nicer observation id (integer) :param rmffile: nicer response file :param arffile: nicer effective area file :param workdir: user-defined nicer work directory :param datadir: user-defined directory holding nicer data :param phaname: name of phafile (with directory path); will be constructed if not specified """ import xspec from heasarc.utils import xspec_utils as xu if interval is None: obs = str(obsid) else: obs = "{0}_{1}".format(obsid, interval) xspecdir = os.path.join(workdir, obs) if not phaname: phaname = os.path.join(xspecdir, 'ni{0}_0mpu7_cl.pha'.format(obsid)) xspec.AllData.clear() try: pha = xspec.Spectrum(phaname) skip_calc = False except: print "Can't get flux for {0}".format(obsid) flux = np.nan skip_calc = True nobsDF = '' if not skip_calc: pha.response = rmffile pha.response.arf = arffile pha.ignore(ignore) # # read base model # if not model: modelname = os.path.join(xspecdir, 'ni{0}_0mpu7_cl_mo.xcm'.format(obsid)) print("Reading {0}".format(modelname)) model = xu.read_model_xcm(modelname, chatter=chatter) xspec.Fit.statMethod = statMethod xspec.Fit.perform() xspec.AllModels.calcFlux(fluxband) flux = pha.flux[0] print "{0} flux = {1:.3e} {2}".format(obsid, flux, fluxband) modict = xu.get_mo_params(model, chatter=chatter) nobsDF = get_obsDF(obsid, model, datadir=datadir, interval=interval) # update JDSTART, JDEND, JDMID using GTI info from pha file hdu = fits.open(phaname) gti = list(hdu['GTI'].data) mjdoff = hdu['GTI'].header['MJDREFI'] + hdu['GTI'].header['MJDREFF'] gtimjd = [[x / 86400.0 + mjdoff, y / 86400. + mjdoff, y-x] for x, y in gti] # print gtimjd gtijd = [[Time(x, format='mjd').jd, Time(y, format='mjd').jd, z] for x, y, z in gtimjd] # print gtijd # jdstart, jdend requires gtijd array to be time ordered jdstart = gtijd[0][0] jdend = gtijd[-1][1] nobsDF[obs]['JDSTART'] = jdstart nobsDF[obs]['JDEND'] = jdend nobsDF[obs]['JDMID'] = (jdend-jdstart)/2.0 + jdstart nobsDF[obs]['EXPOSURE'] = sum([y-x for x, y in gti]) nobsDF[obs]['Num_GTI'] = len(gti) # store the spectral parameters in the data frame nobsDF[obs]['FLUX'] = flux nobsDF[obs]['FluxBand'] = fluxband nobsDF[obs]['Fit_Statistic'] = xspec.Fit.statistic nobsDF[obs]['dof'] = xspec.Fit.dof # get non-frozen model parameter values for c in model.componentNames: for p in model.__getattribute__(c).parameterNames: froz = model.__getattribute__(c).__getattribute__(p).frozen if not froz: nobsDF[obs]["{c}_{p}".format(c=c, p=p)] = modict[c][p][0] if get_errors: # return parameter's Sigma by accessing the component/parameter dictionary nobsDF[obs]["{c}_{p}_err".format(c=c, p=p)] = model.__getattribute__(c).__getattribute__(p).sigma return nobsDF
def main(): """Parse input and tell XSPEC what to do""" parser = argparse.ArgumentParser( description=('Apply XSPEC model fits to all spectra w/ given filestem ' 'and output best fit plots, parameters. ' 'Run from spectra-containing directory ' 'so XSPEC can locate response/background files.')) parser.add_argument('specroot', help='Directory stem for spectra') parser.add_argument('fittype', help=('Type of fit to apply: ' '0=phabs*po, ' '1=excise Si,S lines, ' '2=fit Si,S lines, ' '3=phabs*srcutlog'), type=int) parser.add_argument('plotroot', help='Output stem for plots') parser.add_argument('fitproot', help='Output stem for fit logs, data') parser.add_argument('-v', '--verbose', action='store_true', help='verbose mode') parser.add_argument( '-e', '--error', action='store_true', help=('Compute/output errors from 90pct confidence lims' ' (may need user input / take extra time).')) parser.add_argument('-p', '--path', help=('Override path to srcutlog local model; default ' 'is: ' + SRCUTLOG_PATH_DEFAULT)) parser.add_argument('-a', '--alpha', help='alpha value for SNR (default 0.58 for Tycho)') args = parser.parse_args() specroot, pltroot, fitproot = args.specroot, args.plotroot, args.fitproot ftype = args.fittype verbose = args.verbose wanterr = args.error srcutlog_path, alpha = args.path, args.alpha # Check and create new directories if needed regparse.check_dir(pltroot, verbose) regparse.check_dir(fitproot, verbose) n = regparse.count_files_regexp(specroot + r'_src[0-9]+_grp\.pi') if verbose: print '\n{} spectra to process'.format(n) if verbose and wanterr: print 'Computing errors from 90% confidence limits' # Set up XSPEC for fitting xsutils.init_xspec(verbose) xs.Fit.nIterations = 2000 if ftype == 3: # srcutlog fits need to load local model if srcutlog_path is None: srcutlog_path = SRCUTLOG_PATH_DEFAULT if alpha is None: alpha = ALPHA_DEFAULT if verbose: print 'Using alpha = {}'.format(alpha) xs.AllModels.lmod('neipkg', srcutlog_path) # Fit spectra and dump output on each iteration for num in xrange(n): grp_path = '{}_src{:d}_grp.pi'.format(specroot, num + 1) plt_path = '{}_src{:d}_grp.ps'.format(pltroot, num + 1) log_root = '{}_src{:d}_grp'.format(fitproot, num + 1) if not os.path.isfile(grp_path): print 'Bad path: {}'.format(grp_path) raise Exception('ERROR: spectrum does not exist!') if verbose: print '\nProcessing file: {}'.format(grp_path) print 'Output plot: {}'.format(plt_path) # Most XSPEC interaction here - the rest is set-up s = xs.Spectrum(grp_path) # Default "full-spectrum" fits s.ignore('**-0.5, 7.0-**') # 0.5 keV to verify no oxygen line if ftype < 3: model = phabspo_fit(s, ftype) elif ftype == 3: model = srcutlog_fit(s, alpha) dump_fit(s, model, plt_path, log_root, ftype, wanterr) if verbose: print '\nDone!'
def test_beta_model(): import xspec xspec.Fit.statMethod = "cstat" xspec.Xset.addModelString("APECTHERMAL", "yes") xspec.Fit.query = "yes" xspec.Fit.method = ["leven", "10", "0.01"] xspec.Fit.delta = 0.01 xspec.Xset.chatter = 5 my_prng = RandomState(24) tmpdir = tempfile.mkdtemp() curdir = os.getcwd() os.chdir(tmpdir) R = 1.0 r_c = 0.05 rho_c = 0.04 * mass_hydrogen_grams beta = 1. kT_sim = 6.0 v_shift = 4.0e7 v_width = 4.0e7 nx = 128 ddims = (nx, nx, nx) x, y, z = np.mgrid[-R:R:nx * 1j, -R:R:nx * 1j, -R:R:nx * 1j] r = np.sqrt(x**2 + y**2 + z**2) dens = np.zeros(ddims) dens[r <= R] = rho_c * (1. + (r[r <= R] / r_c)**2)**(-1.5 * beta) dens[r > R] = 0.0 temp = kT_sim * K_per_keV * np.ones(ddims) bbox = np.array([[-0.5, 0.5], [-0.5, 0.5], [-0.5, 0.5]]) velz = my_prng.normal(loc=v_shift, scale=v_width, size=ddims) data = {} data["density"] = (dens, "g/cm**3") data["temperature"] = (temp, "K") data["velocity_x"] = (np.zeros(ddims), "cm/s") data["velocity_y"] = (np.zeros(ddims), "cm/s") data["velocity_z"] = (velz, "cm/s") ds = load_uniform_grid(data, ddims, length_unit=(2 * R, "Mpc"), nprocs=64, bbox=bbox) A = 3000. exp_time = 1.0e5 redshift = 0.05 nH_sim = 0.02 apec_model = XSpecThermalModel("bapec", 0.1, 11.5, 20000, thermal_broad=True) abs_model = XSpecAbsorbModel("TBabs", nH_sim) sphere = ds.sphere("c", (0.5, "Mpc")) mu_sim = -v_shift / 1.0e5 sigma_sim = v_width / 1.0e5 Z_sim = 0.3 thermal_model = ThermalPhotonModel(apec_model, Zmet=Z_sim, X_H=0.76, prng=my_prng) photons = PhotonList.from_scratch(sphere, redshift, A, exp_time, thermal_model) D_A = photons.parameters["FiducialAngularDiameterDistance"] norm_sim = sphere.quantities.total_quantity("emission_measure") norm_sim *= 1.0e-14 / (4 * np.pi * D_A * D_A * (1. + redshift) * (1. + redshift)) norm_sim = float(norm_sim.in_cgs()) events = photons.project_photons("z", responses=[arf, rmf], absorb_model=abs_model, convolve_energies=True, prng=my_prng) events.write_spectrum("beta_model_evt.pi", clobber=True) s = xspec.Spectrum("beta_model_evt.pi") s.ignore("**-0.5") s.ignore("9.0-**") m = xspec.Model("tbabs*bapec") m.bapec.kT = 5.5 m.bapec.Abundanc = 0.25 m.bapec.norm = 1.0 m.bapec.Redshift = 0.05 m.bapec.Velocity = 300.0 m.TBabs.nH = 0.02 m.bapec.Velocity.frozen = False m.bapec.Abundanc.frozen = False m.bapec.Redshift.frozen = False m.TBabs.nH.frozen = True xspec.Fit.renorm() xspec.Fit.nIterations = 100 xspec.Fit.perform() kT = m.bapec.kT.values[0] mu = (m.bapec.Redshift.values[0] - redshift) * ckms Z = m.bapec.Abundanc.values[0] sigma = m.bapec.Velocity.values[0] norm = m.bapec.norm.values[0] dkT = m.bapec.kT.sigma dmu = m.bapec.Redshift.sigma * ckms dZ = m.bapec.Abundanc.sigma dsigma = m.bapec.Velocity.sigma dnorm = m.bapec.norm.sigma assert np.abs(mu - mu_sim) < dmu assert np.abs(kT - kT_sim) < dkT assert np.abs(Z - Z_sim) < dZ assert np.abs(sigma - sigma_sim) < dsigma assert np.abs(norm - norm_sim) < dnorm xspec.AllModels.clear() xspec.AllData.clear() os.chdir(curdir) shutil.rmtree(tmpdir)
xs.Xset.abund = "wilm" # irrelevant xs.Fit.query = "yes" xs.Fit.statMethod = "cstat" # outputs f_plot = root + "-fit" f_log = root + "-fit.log" f_fit = root + "-fit.json" # Set up FWC models # ----------------- if pha_dir: # for xspec to resolve rmf/arf/bkg files (else script execution blocks) os.chdir(pha_dir) spec = xs.Spectrum(pha) # Use a flat response for broken power law background if instr_id in ["mosmerge"]: spec.multiresponse[1] = os.environ['XMM_PATH'] + "/caldb/mos1-diag.rsp" else: spec.multiresponse[1] = (os.environ['XMM_PATH'] + "/caldb/{}-diag.rsp".format(instr_id)) spec.multiresponse[1].arf = "none" # Not needed, just to be explicit if instr_id in ["mos1", "mos2", "mosmerge"]: # MOS spec.ignore("**-0.5, 5.0-**") instr = xs.Model("gauss + gauss", "instr", 1) lines = [1.49, 1.75] elif instr_id == "pn": # PN spec.ignore("**-1.0,12.0-**")
def main(): """Parse input and tell XSPEC what to do""" parser = argparse.ArgumentParser(description= ('Apply XSPEC model fits to all spectra w/ given filestem ' 'and output best fit plots, parameters. ' 'Run from spectra-containing directory ' 'so XSPEC can locate response/background files.')) parser.add_argument('specroot', help='Directory stem for spectra') parser.add_argument('fittype', help=('Type of fit to apply: ' '0=phabs*po, ' '1=excise S line, ' '2=excise S, Ar lines, ' '3=fit S line ' '4=phabs*po, 2.6-7keV'), type=int) parser.add_argument('plotroot', help='Output stem for plots') parser.add_argument('fitproot', help='Output stem for fit logs, data') parser.add_argument('-v', '--verbose', action='store_true', help='verbose mode') args = parser.parse_args() specroot, pltroot, fitproot = args.specroot, args.plotroot, args.fitproot ftype = args.fittype verbose = args.verbose # Check and create new directories if needed regparse.check_dir(pltroot, verbose) regparse.check_dir(fitproot, verbose) n = regparse.count_files_regexp(specroot + r'_src[0-9]+_grp\.pi') if verbose: print '\n{} spectra to process'.format(n) # Set up XSPEC for fitting xsutils.init_xspec(verbose) xs.Fit.nIterations = 2000 # Fit spectra and dump output on each iteration for num in xrange(n): grp_path = '{}_src{:d}_grp.pi'.format(specroot, num+1) plt_path = '{}_src{:d}_grp.ps'.format(pltroot, num+1) log_root = '{}_src{:d}_grp'.format(fitproot, num+1) if not os.path.isfile(grp_path): print 'Bad path: {}'.format(grp_path) raise Exception('ERROR: spectrum does not exist!') if verbose: print '\nProcessing file: {}'.format(grp_path) print 'Output plot: {}'.format(plt_path) spec = xs.Spectrum(grp_path) model = run_fit(spec, ftype) # XSPEC fitting here # Collective dump and clean-up xsutils.plot_dump_data(spec, model, plt_path, log_root+'.npz') xsutils.dump_fit_log(spec, model, log_root+'.log') xsutils.dump_fit_dict(xsutils.fit_dict(spec, model, want_err=False), log_root+'.json') xs.AllData.clear() xs.AllModels.clear() if verbose: print '\nDone!'
import matplotlib.pyplot as plt import argparse import sys #Parser options parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('RGS', type=str, help='Type R1 or R2.') args = parser.parse_args() #load data try: if args.RGS == 'R1': logFile = xspec.Xset.openLog( "RGS1LogFile.txt") #Create and open a log file for XSPEC output logFile = xspec.Xset.log # Get the Python file object for the currently opened log s1 = xspec.Spectrum('P0658801601R1U002SRSPEC1001.FIT') s1.background = 'P0658801601R1U002BGSPEC1001.FIT' s1.response = 'P0658801601R1U002RSPMAT1001.FIT' instr = 'RGS1' elif args.RGS == 'R2': logFile = xspec.Xset.openLog("RGS2LogFile.txt") logFile = xspec.Xset.log s1 = xspec.Spectrum('P0658801601R2U002SRSPEC1001.FIT') s1.background = 'P0658801601R2U002BGSPEC1001.FIT' s1.response = 'P0658801601R2U002RSPMAT1001.FIT' instr = 'RGS2' else: raise ValueError except ValueError: print('Please enter a valid instrument.') sys.exit(1)
def ecfs_calc(file, model_name, parameters, obj_id, obs_id, save_dir, ins, redshift): os.chdir(save_dir) x_mod = x.Model(model_name) x_mod.setPars(*list(parameters.values())) x_mod(3).frozen = False if "abs" in model_name: # This should zero nH, which means the calculated fluxes will be unabsorbed (according to Paul) x_mod(1).frozen = True spectrum = x.Spectrum(file) spectrum.ignore("**-0.3 10.0-**") x.Fit.perform() # Now to find source frame limits z_lowen = [limit / (redshift + 1) for limit in [0.5, 2.0]] z_highen = [limit / (redshift + 1) for limit in [2.0, 10.0]] # Count rate measurements have to come before I zero the absorption, as we'll be measuring absorbed c/r # Luminosity errors also have to come before I zero the absorption x.AllModels.calcLumin("{l} {u} {red} err".format(l=z_lowen[0], u=z_lowen[1], red=redshift)) lowen_lx_p = (spectrum.lumin[2] * 1e+44) - (spectrum.lumin[0] * 1e+44) lowen_lx_m = (spectrum.lumin[0] * 1e+44) - (spectrum.lumin[1] * 1e+44) x.AllModels.calcLumin("{l} {u} {red} err".format(l=z_highen[0], u=z_highen[1], red=redshift)) highen_lx_p = (spectrum.lumin[2] * 1e+44) - (spectrum.lumin[0] * 1e+44) highen_lx_m = (spectrum.lumin[0] * 1e+44) - (spectrum.lumin[1] * 1e+44) # Have to use an ignore to get a count rate for the energy range I care about spectrum.ignore("**-{l} {u}-**".format(l=z_lowen[0], u=z_lowen[1])) # the 0th element of rate is the background subtracted rate, but doesn't matter -> no background! lowen_rate = spectrum.rate[0] # Now reset the ignore to ignore nothing spectrum.notice("all") # And now ignore to get the high energy range spectrum.ignore("**-{l} {u}-**".format(l=z_highen[0], u=z_highen[1])) highen_rate = spectrum.rate[0] fitted_pars = [ x_mod(par_ind).values[0] for par_ind in range(1, x_mod.nParameters + 1) ] spectrum.notice("all") # Sort of janky way of finding of one of nH absorption models is being used, definitely not rigorous if "abs" in model_name: # This should zero nH, which means the calculated fluxes will be unabsorbed (according to Paul) x_mod.setPars(0) x.AllModels.calcFlux("{l} {u}".format(l=z_lowen[0], u=z_lowen[1])) lowen_flux = spectrum.flux[0] x.AllModels.calcLumin("{l} {u} {red} err".format(l=z_lowen[0], u=z_lowen[1], red=redshift)) lowen_lx = spectrum.lumin[0] * 1e+44 x.AllModels.calcFlux("{l} {u}".format(l=z_highen[0], u=z_highen[1])) highen_flux = spectrum.flux[0] x.AllModels.calcLumin("{l} {u} {red} err".format(l=z_highen[0], u=z_highen[1], red=redshift)) highen_lx = spectrum.lumin[0] * 1e+44 x.AllData.clear() x.AllModels.clear() return [lowen_rate, lowen_flux, highen_rate, highen_flux], fitted_pars, [lowen_lx, lowen_lx_m, lowen_lx_p], \ [highen_lx, highen_lx_m, highen_lx_p]
def fit(i, n): while (i < n + 1): xspec.AllData.clear() s1 = xspec.Spectrum("reg-" + str(i) + "_grp.pi") m1 = xspec.Model("phabs*apec") m1.phabs.nH = "0.0197" m1.phabs.nH.frozen = True m1.apec.Abundanc = "0.35" m1.apec.Abundanc.frozen = True m1.apec.Redshift = "0.1427" #xspec.Plot.device = "/xs" #xspec.Plot.xAxis = "keV" #xspec.Plot.xLog = True #xspec.Plot.yLog = True s1.ignore("0.0-0.5,7.0-**") xspec.Fit.statMethod = "cstat" xspec.Fit.query = "yes" xspec.Fit.perform() xspec.Fit.perform() m1.apec.Abundanc.frozen = False xspec.Fit.perform() xspec.Fit.perform() #m1.phabs.nH.frozen = False #xspec.Fit.perform() #xspec.Plot.device = "/xs" #xspec.Plot.xAxis = "keV" #xspec.Plot.xLog = True #xspec.Plot.yLog = True #xspec.Plot("data delchi") try: xspec.Fit.error("1.0 2") statistic = xspec.Fit.statistic dof = xspec.Fit.dof chi = statistic / dof note = " Nice" if chi > 1.5: note = " Attention!!!" except: chi = 0 note = " Can't fit!!!" kt = m1.apec.kT.values[0] kt_err_n = kt - m1.apec.kT.error[0] kt_err_p = m1.apec.kT.error[1] - kt kt = str(kt) kt_err_n = str(kt_err_n) kt_err_p = str(kt_err_p) file = open("../outputs/fit_outputs.txt", "a") file.write( str(i) + ") " + kt + " (-" + kt_err_n + ",+" + kt_err_p + ") chi=" + str(chi) + note + "\n") file.close() i = i + 1
def fit_srcbin10( 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, pcmode=False): print "starting fit_srcbin10" 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 if pcmode: mode = 'pc' else: mode = 'wt' xspecdir = WorkDir + "/" + obsid.strip() + "/" + mode + "/xspec" cwd = os.getcwd() print "\n" os.chdir(xspecdir) # change to use unbinned data and cstat to avoid problems with low count rate binned data xspec.Fit.statMethod = "cstat" src = xspec.Spectrum("src.pha") xspec.Plot.setRebin(minSig=3.0, maxBins=10.0) #src=xspec.Spectrum("srcbin10.pha") try: hdu = pyfits.open("src.arf") except: print "ARF src.arf not found; Returning" return arfhd = hdu[1].header try: respfile = arfhd['RESPFILE'] except: print "RESPFILE keyword in 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 = "src.arf" src.background = "bkg.pha" src.ignore("0.0-1.0 7.9-**") hdulist = pyfits.open("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() try: xspec.Fit.perform() except Exception, errmsg: sys.exit("{0}; Can't proceed; exiting".format(errmsg.value))
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()
import matplotlib.pyplot as plt #import numpy as np import xspec as xs # Deliberately populate global scope for interactive use (%run in iPython) # Incredibly ugly code but it's good enough for a one-off job # "Global" settings xs.Plot.device = "/xw" xs.Plot.xAxis = "keV" xs.Xset.abund = "wilm" #xs.Plot.yLog = True #xs.Plot.background = True s = xs.Spectrum("mos1S001-src.fak") s.ignore("**-0.4, 10.0-**") m = xs.Model("tbabs*vnei") ## SET UP SOME METHODS def m_default(): m.vnei.kT = 1 m.vnei.Tau = 1e11 m.TBabs.nH = 1 m.vnei.S = 1 m.vnei.Si = 1 m.vnei.Fe = 1
def zero(engs, params, flux): energy_binsizes = np.ediff1d(engs) flux[:] = energy_binsizes * 1e-150 zeroInfo = () xs.AllModels.addPyMod(zero, zeroInfo, 'add', spectrumDependent=False) normZERO = np.zeros((30, 2001)) chi_stat = np.zeros((30, 2001)) Fit_st = np.zeros((30, 2001)) xs.AllData.clear() # clear all data, if any. for j in range(30): for i in range(1, 2001): xs.AllData.clear() s = xs.Spectrum("bn150416773_fakeit_%s.fak{%s}" % (j, i)) s.response = "bn150416773_LAT-LLE_weightedrsp.rsp" s.background = ("bn150416773_LAT-LLE_bkgspectra.bak{1}") xs.AllModels.clear() m = xs.Model("zero") xs.Fit.statMethod = "pgstat" xs.Fit.perform() chi_stat[j, i] = xs.Fit.testStatistic Fit_st[j, i] = xs.Fit.statistic np.save('TS_pgfit_ZERO.npy', chi_stat) np.save('pgfit_ZERO.npy', Fit_st)
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