Пример #1
0
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()
Пример #2
0
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")
Пример #3
0
 def plot(self):
     """Plot the fit.
     """
     xspec.Fit.show()
     xspec.Plot.device = '/xs'
     xspec.Plot.xAxis = 'keV'
     xspec.Plot('ldata', 'resid')
Пример #4
0
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
Пример #5
0
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()
Пример #6
0
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
Пример #7
0
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)
Пример #8
0
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
Пример #9
0
    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)
Пример #10
0
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
Пример #11
0
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
Пример #12
0
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")
Пример #13
0
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)
Пример #14
0
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
Пример #15
0
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
Пример #16
0
    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
Пример #17
0
                    #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)
Пример #18
0
    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:
Пример #19
0
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)
Пример #20
0
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
Пример #21
0
# 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)

Пример #22
0
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()
Пример #23
0
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()
Пример #24
0
    '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()
Пример #25
0
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()