示例#1
0
def test_plot_pvalue(make_data_path, clean_astro_ui, hide_log_output):

    fname = make_data_path("qso.pi")
    ui.load_pha(fname)

    ui.set_stat('cstat')
    ui.set_method("neldermead")

    ui.group_counts(10)
    ui.notice(0.3, 8)

    ui.set_model("xsphabs.abs1*xspowerlaw.p1")
    ui.set_model("abs1*(p1+gauss1d.g1)")

    # move the fit close to the best fit to save a small amount
    # of time.
    abs1.nh = 0.05
    p1.phoindex = 1.28
    p1.norm = 2e-4
    g1.ampl = 1.8e-5

    g1.pos = 3.
    ui.freeze(g1.pos)
    g1.fwhm = 0.1
    ui.freeze(g1.fwhm)

    ui.fit()
    ui.plot_pvalue(p1, p1 + g1, num=100)

    tmp = ui.get_pvalue_results()

    assert tmp.null == pytest.approx(210.34566845619273)
    assert tmp.alt == pytest.approx(207.66618095925094)
    assert tmp.lr == pytest.approx(2.679487496941789)
def test_eqwith_err1(make_data_path, restore_xspec_settings):

    def check1(e0, e1, e2):
        assert e0 == pytest.approx(0.028335201547206704, rel=1.0e-3)
        assert e1 == pytest.approx(-0.00744118799274448756, rel=1.0e-3)
        assert e2 == pytest.approx(0.0706249544851336, rel=1.0e-3)

    ui.set_xsabund('angr')
    ui.set_xsxsect('bcmc')

    ui.load_pha(make_data_path('3c273.pi'))
    ui.notice(0.5, 7.0)
    ui.set_stat("chi2datavar")
    ui.set_method("simplex")
    ui.set_model('powlaw1d.p1+gauss1d.g1')
    g1.fwhm = 0.1
    g1.pos = 2.0
    ui.freeze(g1.pos, g1.fwhm)
    ui.fit()

    np.random.seed(2345)
    e = ui.eqwidth(p1, p1 + g1, error=True, niter=100)
    check1(e[0], e[1], e[2])
    params = e[3]

    np.random.seed(2345)
    e = ui.eqwidth(p1, p1 + g1, error=True, params=params, niter=100)
    check1(e[0], e[1], e[2])

    parvals = ui.get_fit_results().parvals
    assert parvals[0] == pytest.approx(1.9055272902160334, rel=1.0e-3)
    assert parvals[1] == pytest.approx(0.00017387966749772638, rel=1.0e-3)
    assert parvals[2] == pytest.approx(1.279415076070516e-05, rel=1.0e-3)
示例#3
0
def test_eqwith_err1(make_data_path, restore_xspec_settings):

    def check1(e0, e1, e2):
        assert e0 == approx(0.028335201547206704, rel=1.0e-3)
        assert e1 == approx(-0.00744118799274448756, rel=1.0e-3)
        assert e2 == approx(0.0706249544851336, rel=1.0e-3)

    ui.set_xsabund('angr')
    ui.set_xsxsect('bcmc')

    ui.load_pha(make_data_path('3c273.pi'))
    ui.notice(0.5, 7.0)
    ui.set_stat("chi2datavar")
    ui.set_method("simplex")
    ui.set_model('powlaw1d.p1+gauss1d.g1')
    g1.fwhm = 0.1
    g1.pos = 2.0
    ui.freeze(g1.pos, g1.fwhm)
    ui.fit()

    numpy.random.seed(2345)
    e = ui.eqwidth(p1, p1 + g1, error=True, niter=100)
    check1(e[0], e[1], e[2])
    params = e[3]

    numpy.random.seed(2345)
    e = ui.eqwidth(p1, p1 + g1, error=True, params=params, niter=100)
    check1(e[0], e[1], e[2])

    parvals = ui.get_fit_results().parvals
    assert parvals[0] == approx(1.9055272902160334, rel=1.0e-3)
    assert parvals[1] == approx(0.00017387966749772638, rel=1.0e-3)
    assert parvals[2] == approx(1.279415076070516e-05, rel=1.0e-3)
示例#4
0
    def fit(self):
        """
        Do a fit of the model parameters using the "onion-peeling" method:   

         - First fit the outside shell model using the outer annulus spectrum
         - Freeze the model parameters for the outside shell
         - Fit the next inward shell / annulus and freeze those parameters
         - Repeat until all datasets have been fit and all shell parameters determined.
         - Return model parameters to original thawed/frozen status

        :rtype: None
        """
        thawed = []                  # Parameter objects that are not already frozen
        for annulus in reversed(range(self.nshell)):
            dataids = [x['id'] for x in self.datasets if x['annulus'] == annulus]
            print 'Fitting', dataids
            SherpaUI.fit(*dataids)
            for model_comp in self.model_comps:
                name = model_comp['name']
                if model_comp['shell'] == annulus:
                    # Remember parameters that are currently thawed
                    for par in [SherpaUI.get_par('%s.%s'%(name, x))
                                for x in SherpaUI.get_model_pars(name)]:
                        if not par.frozen:
                            thawed.append(par)
                    print 'Freezing', model_comp['name']
                    SherpaUI.freeze(model_comp['name'])

        # Unfreeze parameters
        for par in thawed:
            print 'Thawing', par.fullname
            par.thaw()
示例#5
0
文件: pcaUtil.py 项目: neobar/BXA
def loadPars(amodel, readFrom):
    """
    """
    with open(readFrom, 'r') as f:
        parDict = json.load(f)
    for p in amodel.pars:
        val, frozen = parDict[p.name]
        p.val = val
        if frozen:
            ui.freeze(p)
示例#6
0
文件: utils.py 项目: evantey14/nustar
def setup(imgfile, emapfile):
    shp.load_data(imgfile)

    shp.load_table_model('emap', emapfile)
    shp.freeze(emap.ampl)

    # we're using an on axis psf provided in 
    # /packages/CALDB/data/nustar/fpm/bcf/psf/
    shp.load_psf('psf', 'nuA2dpsf20100101v003_onaxis.fits')
    shp.set_psf(psf)
    psf.center = (500.0, 500.0)
    psf.size = (200, 200)
示例#7
0
    def run_hspec_fit(self, model, thres_low, thres_high):
        """Run the gammapy.hspec fit

        Parameters
        ----------
        model : str
            Sherpa model
        thres_high : `~gammapy.spectrum.Energy`
            Upper threshold of the spectral fit
        thres_low : `~gammapy.spectrum.Energy`
            Lower threshold of the spectral fit
        """

        log.info("Starting HSPEC")
        import sherpa.astro.ui as sau
        from ..hspec import wstat
        from sherpa.models import PowLaw1D

        if model == 'PL':
            p1 = PowLaw1D('p1')
            p1.gamma = 2.2
            p1.ref = 1e9
            p1.ampl = 6e-19
        else:
            raise ValueError('Desired Model is not defined')

        thres = thres_low.to('keV').value
        emax = thres_high.to('keV').value

        sau.freeze(p1.ref)
        sau.set_conf_opt("max_rstat", 100)

        list_data = []
        for obs in self.observations:
            datid = obs.phafile.parts[-1][7:12]
            sau.load_data(datid, str(obs.phafile))
            sau.notice_id(datid, thres, emax)
            sau.set_source(datid, p1)
            list_data.append(datid)
        wstat.wfit(list_data)
        sau.covar()
        fit_val = sau.get_covar_results()
        fit_attrs = ('parnames', 'parvals', 'parmins', 'parmaxes')
        fit = dict((attr, getattr(fit_val, attr)) for attr in fit_attrs)
        fit = self.apply_containment(fit)
        sau.clean()
        self.fit = fit
示例#8
0
文件: pcaUtil.py 项目: neobar/BXA
def fixBkgModel(id=1, freeNorm=True):
    """
    Fix the background model
    Paramaters:
    freeNorm = True
        If freeNorm is True, leave the overall background normalization free.
    """
    bk = ui.get_bkg_model(id=id)
    if freeNorm:
        pars = bk.pars
        c0 = pars[0]
        for p in pars[1:]:
            if p.val != 0 and p.fullname.startswith('pca'):
                ui.link(p, p.val / c0.val * c0)
            else:
                ui.freeze(p)
    else:
        ui.freeze(bk)
示例#9
0
 def test_rsp(self):
     fname = self.make_path("qso.pi")
     ui.load_pha(fname)
     ui.set_stat("chi2xspecvar")
     ui.set_method("neldermead")
     ui.group_counts(10)
     ui.notice(0.3, 8)
     ui.set_model("xsphabs.abs1*xspowerlaw.p1")
     ui.set_model("abs1*(p1+gauss1d.g1)")
     g1.pos = 3.
     ui.freeze(g1.pos)
     g1.fwhm = 0.1
     ui.freeze(g1.fwhm)
     ui.set_stat('cstat')
     ui.fit()
     ui.plot_pvalue(p1, p1 + g1, num=100)
     tmp = ui.get_pvalue_results()
     expected = [210.34566845619273, 207.66618095925094, 2.679487496941789]
     self.compare_results(expected, [tmp.null, tmp.alt, tmp.lr])
def test_eqwith_err(make_data_path, restore_xspec_settings):

    def check(a0, a1, a2):
        assert a0 == pytest.approx(0.16443033244310976, rel=1e-3)
        assert a1 == pytest.approx(0.09205564216156815, rel=1e-3)
        assert a2 == pytest.approx(0.23933118287470895, rel=1e-3)

    ui.set_method('neldermead')
    ui.set_stat('cstat')
    ui.set_xsabund('angr')
    ui.set_xsxsect('bcmc')

    ui.load_data(make_data_path('12845.pi'))
    ui.notice(0.5, 7)

    ui.set_model("xsphabs.gal*xszphabs.zabs*(powlaw1d.p1+xszgauss.g1)")
    ui.set_par(gal.nh, 0.08)
    ui.freeze(gal)

    ui.set_par(zabs.redshift, 0.518)
    ui.set_par(g1.redshift, 0.518)
    ui.set_par(g1.Sigma, 0.01)
    ui.freeze(g1.Sigma)
    ui.set_par(g1.LineE, min=6.0, max=7.0)

    ui.fit()

    np.random.seed(12345)
    result = ui.eqwidth(p1, p1 + g1, error=True, niter=100)
    check(result[0], result[1], result[2])
    params = result[3]

    np.random.seed(12345)
    result = ui.eqwidth(p1, p1 + g1, error=True, params=params, niter=100)
    check(result[0], result[1], result[2])

    parvals = ui.get_fit_results().parvals
    assert parvals[0] == pytest.approx(0.6111340686157877, rel=1.0e-3)
    assert parvals[1] == pytest.approx(1.6409785803466297, rel=1.0e-3)
    assert parvals[2] == pytest.approx(8.960926761312153e-05, rel=1.0e-3)
    assert parvals[3] == pytest.approx(6.620017726014523, rel=1.0e-3)
    assert parvals[4] == pytest.approx(1.9279114810359657e-06, rel=1.0e-3)
示例#11
0
def test_eqwith_err(make_data_path, restore_xspec_settings):

    def check(a0, a1, a2):
        assert a0 == approx(0.16443033244310976, rel=1e-3)
        assert a1 == approx(0.09205564216156815, rel=1e-3)
        assert a2 == approx(0.23933118287470895, rel=1e-3)

    ui.set_method('neldermead')
    ui.set_stat('cstat')
    ui.set_xsabund('angr')
    ui.set_xsxsect('bcmc')

    ui.load_data(make_data_path('12845.pi'))
    ui.notice(0.5, 7)

    ui.set_model("xsphabs.gal*xszphabs.zabs*(powlaw1d.p1+xszgauss.g1)")
    ui.set_par(gal.nh, 0.08)
    ui.freeze(gal)

    ui.set_par(zabs.redshift, 0.518)
    ui.set_par(g1.redshift, 0.518)
    ui.set_par(g1.Sigma, 0.01)
    ui.freeze(g1.Sigma)
    ui.set_par(g1.LineE, min=6.0, max=7.0)

    ui.fit()

    numpy.random.seed(12345)
    result = ui.eqwidth(p1, p1 + g1, error=True, niter=100)
    check(result[0], result[1], result[2])
    params = result[3]

    numpy.random.seed(12345)
    result = ui.eqwidth(p1, p1 + g1, error=True, params=params, niter=100)
    check(result[0], result[1], result[2])

    parvals = ui.get_fit_results().parvals
    assert parvals[0] == approx(0.6111340686157877, rel=1.0e-3)
    assert parvals[1] == approx(1.6409785803466297, rel=1.0e-3)
    assert parvals[2] == approx(8.960926761312153e-05, rel=1.0e-3)
    assert parvals[3] == approx(6.620017726014523, rel=1.0e-3)
    assert parvals[4] == approx(1.9279114810359657e-06, rel=1.0e-3)
示例#12
0
    def conf(self):
        """
        Run conf on each of the model parameters using the "onion-peeling" method:   

         - First conf the outside shell model using the outer annulus spectrum
         - Freeze the model parameters for the outside shell
         - get confidences for the next inward shell / annulus and freeze those parameters
         - Repeat until all datasets have been conf()-ed and all shell-by-shell error parameters determined.
         - Return model parameters to original thawed/frozen status
         - WARNING: This ignores the correlations between parameters

        :rtype: None
        """
        thawed = []                  # Parameter objects that are not already frozen
        conf_results = []
        this_conf_result = []
        for annulus in reversed(range(self.nshell)):
            dataids = [x['id'] for x in self.datasets if x['annulus'] == annulus]
            print 'Getting shell-by-shell confidence for dataset ', dataids
            SherpaUI.conf(*dataids)
            this_conf_result = SherpaUI.get_conf_results()
            conf_results.insert(0, this_conf_result)
            for model_comp in self.model_comps:
                name = model_comp['name']
                if model_comp['shell'] == annulus:
                    # Remember parameters that are currently thawed
                    for par in [SherpaUI.get_par('%s.%s'%(name, x))
                                for x in SherpaUI.get_model_pars(name)]:
                        if not par.frozen:
                            thawed.append(par)
                    print 'Freezing', model_comp['name']
                    SherpaUI.freeze(model_comp['name'])

        # Unfreeze parameters
        for par in thawed:
            print 'Thawing', par.fullname
            par.thaw()
            
        return conf_results
示例#13
0
def make_fixed_temp_multi_apec(kTs, name_template='apec%d', norm=None):
    """Create a model summing multiple APEC components at fixed temperatures.

    *kTs*
      An iterable of temperatures for the components, in keV.
    *name_template* = 'apec%d'
      A template to use for the names of each component; it is string-formatted
      with the 0-based component number as an argument.
    *norm* = None
      An initial normalization to be used for every component, or None to use
      the Sherpa default.
    Returns:
      A tuple ``(total_model, sub_models)``, where *total_model* is a Sherpa
      model representing the sum of the APEC components and *sub_models* is
      a list of the individual models.

    This function creates a vector of APEC model components and sums them.
    Their *kT* parameters are set and then frozen (using
    :func:`sherpa.astro.ui.freeze`), so that upon exit from this function, the
    amplitude of each component is the only free parameter.

    """
    total_model = None
    sub_models = []

    for i, kT in enumerate(kTs):
        component = ui.xsapec(name_template % i)
        component.kT = kT
        ui.freeze(component.kT)
        if norm is not None:
            component.norm = norm
        sub_models.append(component)

        if total_model is None:
            total_model = component
        else:
            total_model = total_model + component

    return total_model, sub_models
示例#14
0
    def _run_hspec_fit(self):
        """Run the gammapy.hspec fit
        """

        log.info("Starting HSPEC")
        import sherpa.astro.ui as sau
        from ..hspec import wstat

        sau.set_conf_opt("max_rstat", 100)

        thres_lo = self.energy_threshold_low.to('keV').value
        thres_hi = self.energy_threshold_high.to('keV').value
        sau.freeze(self.model.ref)

        list_data = []
        for pha in self.pha:
            datid = pha.parts[-1][7:12]
            sau.load_data(datid, str(pha))
            sau.notice_id(datid, thres_lo, thres_hi)
            sau.set_source(datid, self.model)
            list_data.append(datid)

        wstat.wfit(list_data)
示例#15
0
def test_plot_pvalue(make_data_path, clean_astro_ui, hide_logging):
    """Check plot_pvalue with PHA data."""

    fname = make_data_path("qso.pi")
    ui.load_pha(fname)

    ui.set_stat('cstat')
    ui.set_method("neldermead")

    ui.group_counts(10)
    ui.notice(0.3, 8)

    ui.set_model("xsphabs.abs1*(xspowerlaw.p1 +gauss1d.g1)")

    # move the fit close to the best fit to save a small amount
    # of time.
    abs1.nh = 0.05
    p1.phoindex = 1.28
    p1.norm = 2e-4
    g1.ampl = 1.8e-5

    g1.pos = 3.
    ui.freeze(g1.pos)
    g1.fwhm = 0.1
    ui.freeze(g1.fwhm)

    # Could we reduce the number of bins to save evaluation time?
    # We do want a non-default num value when checking the shapes
    # of the output attributes.
    #
    ui.fit()
    ui.plot_pvalue(p1, p1 + g1, num=100, bins=20)

    tmp = ui.get_pvalue_results()

    assert tmp.null == pytest.approx(210.34566845619273)
    assert tmp.alt == pytest.approx(207.66618095925094)
    assert tmp.lr == pytest.approx(2.679487496941789)

    # Have we returned the correct info?
    #
    # Is it worth checking the stored data (aka how randomised is this
    # output)?
    #
    assert tmp.samples.shape == (100, 2)
    assert tmp.stats.shape == (100, 2)
    assert tmp.ratios.shape == (100, )

    # Check the plot
    #
    tmp = ui.get_pvalue_plot()

    assert tmp.lr == pytest.approx(2.679487496941789)

    assert tmp.xlabel == 'Likelihood Ratio'
    assert tmp.ylabel == 'Frequency'
    assert tmp.title == 'Likelihood Ratio Distribution'

    # It would be nice to check the values here
    #
    assert tmp.ratios.shape == (100, )
    assert tmp.xlo.shape == (21, )
    assert tmp.xhi.shape == (21, )
    assert tmp.y.shape == (21, )
示例#16
0
def assign_model(model_name, i):
    """Dedicated set up for the most common models."""
    if model_name == 'powlaw1d':
        from sherpa.models import PowLaw1D

        p1 = PowLaw1D('PowLaw' + str(i))
        p1.gamma = 2.6
        p1.ampl = 1e-20
        p1.ref = 1e9
        sau.freeze(p1.ref)
    elif model_name == 'logparabola':
        p1 = logparabola('LogPar' + str(i))
        p1.ampl = 1e-20
        p1.c1 = 2.
        p1.c2 = 1.
        p1.ref = 1e9
        sau.freeze(p1.ref)
    elif model_name == 'plexpcutoff':  # all parameters in TeV here
        from .models.plexpcutoff import MyPLExpCutoff

        p1 = MyPLExpCutoff('PLexpCutoff' + str(i))
        p1.gamma = 2.
        p1.No = 1e-11
        p1.beta = 1e-1  # 1/Ecutoff
        p1.Eo = 1
        sau.freeze(p1.Eo)
    elif model_name == 'Finke':  # EBL model from Finke et al. 2010
        # enable_table_model()
        from ..datasets import gammapy_extra
        filename = gammapy_extra.filename('datasets/ebl/frd_abs.fits.gz')
        sau.load_table_model('p1', filename)
    elif model_name == 'Franceschini':  # EBL model from Franceschini et al. 2012
        # enable_table_model()
        from ..datasets import gammapy_extra
        filename = gammapy_extra.filename(
            'datasets/ebl/ebl_franceschini.fits.gz')
        sau.load_table_model('p1', filename)
    elif model_name == 'synchro':
        # print('Synchrotron model not available yet, sorry.')
        # quit() # Stops with an error: ValueError: slice step cannot be zero
        from naima.sherpamod import Synchrotron

        p1 = Synchrotron('Synchro' + str(i))
        p1.index = 2.
        p1.ampl = 1.
    elif model_name == 'ic':  # Inverse Compton peak
        # Weird, it returns the fit results twice (actually, it seems to do everything twice)
        # Returns error except if --noplot: TypeError: calc() takes exactly 4 arguments (3 given)
        from naima.sherpamod import InverseCompton

        p1 = InverseCompton('IC' + str(i))
        p1.index = 2.
        p1.ampl = 1e-7  # Not sure if the units are OK
    elif model_name == 'pion':  # Pion-decay gamma-ray spectrum
        # Veeery slow convergence
        # also doubled operations and problems for plotting, like in ic.
        from naima.sherpamod import PionDecay

        p1 = PionDecay('Pion' + str(i))
        p1.index = 2.
        p1.ampl = 10.
    else:  # set initial parameter values manually
        # (user-defined models and models that need some extra import will not work)
        p1 = globals()[model_name](model_name + str(i))
        set_manual_model(p1)

    return p1
示例#17
0
def fit_sherpa(obsid_list,
               redshift,
               nH_Gal,
               energy,
               min_counts=25,
               kT_guess=3,
               Ab_guess=1,
               fix_nH_Gal=True,
               fix_abund=False,
               find_errors=True):

    spectra = []
    for obs in obsid_list:
        temp = glob.glob('xaf_*_' + obs + '.pi')  # get spectra of regions
        spectra.append(
            temp
        )  # spectra will be made of lists which have xaf_*_obs.pi filenames - access with spectra[i][j]
    spectra.sort()
    num_obs = len(obsid_list)
    num_reg = len(temp)
    filename = 'spectra_wabs_mekal.dat'
    results_file = open(filename, "w")
    results_file.write(
        '# Fit results for wabs*mekal (zeros indicate that no fitting was performed)\n'
    )
    results_file.write(
        '# Reg_no.  kT  kT_loerr kT_hierr   Z    Z_loerr  Z_hierr  norm    norm_loerr norm_hierr nH_Gal  nH_loerr nH_hierr red_chisq total_counts num_bins\n'
    )
    for i in range(num_reg):
        sherpa.clean()  # clean everything
        cnts = numpy.zeros(
            num_obs
        )  # make array of zeros with index length same as num_obs to store counts
        max_rate = numpy.zeros(num_obs)  # max count rate [counts/s/keV]
        data_set = 0  # data set number
        good_src_ids = numpy.zeros(num_obs, dtype=int) - 1

        for j in range(num_obs):
            sherpa.load_pha(
                data_set, spectra[j]
                [i])  # load xaf_#_obs_####.pi and .arf and .rmf files.
            sherpa.ignore_id(data_set, 0.0, energy[0])
            sherpa.ignore_id(data_set, energy[1], None)
            cnts[j] = sherpa.calc_data_sum(energy[0], energy[1], data_set)
            cnt_rate = sherpa.get_rate(data_set, filter=True)
            if len(cnt_rate) == 0:
                max_rate[
                    j] = 0.0  # when few counts (<50), get_rate can return zero-length array
            else:
                max_rate[j] = numpy.max(cnt_rate)
            sherpa.subtract(data_set)  # subtract background
            sherpa.set_source(
                data_set, sherpa.xswabs.abs1 *
                sherpa.xsmekal.plsm1)  # 1 temperature mekal model fit
            good_src_ids[j] = data_set
            data_set += 1  # same run for region but different obs

        # Filter out ignored obs
        good_src_ids_indx = numpy.where(good_src_ids >= 0)
        good_src_ids = good_src_ids[good_src_ids_indx]
        max_rate = max_rate[good_src_ids_indx]
        cnts = cnts[good_src_ids_indx]

        totcnts = numpy.sum(cnts)
        if totcnts >= min_counts:
            print('Fitting spectra in region: ' + str(i))
            abs1.nH = nH_Gal
            abs1.cache = 0
            if fix_nH_Gal:
                sherpa.freeze(abs1.nH)
            else:
                sherpa.thaw(abs1.nH)
            plsm1.kt = kT_guess
            sherpa.thaw(plsm1.kt)
            plsm1.Abundanc = Ab_guess
            if fix_abund:
                sherpa.freeze(plsm1.Abundanc)
            else:
                sherpa.thaw(plsm1.Abundanc)
            plsm1.redshift = redshift
            sherpa.freeze(plsm1.redshift)
            plsm1.cache = 0

            sherpa.fit()
            fit_result = sherpa.get_fit_results()
            red_chi2 = fit_result.rstat
            num_bins = fit_result.numpoints
            if fix_nH_Gal:
                nH = nH_Gal
                kT = fit_result.parvals[0]
                if fix_abund:
                    Z = Ab_guess
                    norm = fit_result.parvals[1]
                else:
                    Z = fit_result.parvals[1]
                    norm = fit_result.parvals[2]
            else:
                nH = fit_result.parvals[0]
                kT = fit_result.parvals[1]
                if fix_abund:
                    Z = Ab_guess
                    norm = fit_result.parvals[2]
                else:
                    Z = fit_result.parvals[2]
                    norm = fit_result.parvals[3]
            del fit_result

            if find_errors:
                sherpa.covar()
                covar_result = sherpa.get_covar_results()
                if fix_nH_Gal:
                    nH_loerr = 0.0
                    nH_hierr = 0.0
                    kT_loerr = covar_result.parmins[0]
                    kT_hierr = covar_result.parmaxes[0]
                    if fix_abund:
                        Z_loerr = 0.0
                        Z_hierr = 0.0
                        norm_loerr = covar_result.parmins[1]
                        norm_hierr = covar_result.parmaxes[1]
                    else:
                        Z_loerr = covar_result.parmins[1]
                        Z_hierr = covar_result.parmaxes[1]
                        norm_loerr = covar_result.parmins[2]
                        norm_hierr = covar_result.parmaxes[2]
                else:
                    nH_loerr = covar_result.parmins[0]
                    nH_hierr = covar_result.parmaxes[0]
                    kT_loerr = covar_result.parmins[1]
                    kT_hierr = covar_result.parmaxes[1]
                    if fix_abund:
                        Z_loerr = 0.0
                        Z_hierr = 0.0
                        norm_loerr = covar_result.parmins[2]
                        norm_hierr = covar_result.parmaxes[2]
                    else:
                        Z_loerr = covar_result.parmins[2]
                        Z_hierr = covar_result.parmaxes[2]
                        norm_loerr = covar_result.parmins[3]
                        norm_hierr = covar_result.parmaxes[3]
                del covar_result

                # Check for failed errors (= None) and set them to +/- best-fit value
                if not fix_nH_Gal:
                    if nH_loerr is None: nH_loerr = -nH  # is was ==
                    if nH_hierr is None: nH_hierr = nH
                if kT_loerr is None: kT_loerr = -kT
                if kT_hierr is None: kT_hierr = kT
                if not fix_abund:
                    if Z_loerr is None: Z_loerr = -Z
                    if Z_hierr is None: Z_hierr = Z
                if norm_loerr is None: norm_loerr = -norm
                if norm_hierr is None: norm_hierr = norm
            else:
                kT_loerr = 0.0
                Z_loerr = 0.0
                nH_loerr = 0.0
                norm_loerr = 0.0
                kT_hierr = 0.0
                Z_hierr = 0.0
                nH_hierr = 0.0
                norm_hierr = 0.0

        else:  # if total counts < min_counts, just write zeros
            print('\n Warning: no fit performed for for region: ' + str(i))
            print(
                '\n Spectra have insufficient counts after filtering or do not exist.'
            )
            print('\n --> All parameters for this region set to 0.0.')
            kT = 0.0
            Z = 0.0
            nH = 0.0
            norm = 0.0
            kT_loerr = 0.0
            Z_loerr = 0.0
            nH_loerr = 0.0
            norm_loerr = 0.0
            kT_hierr = 0.0
            Z_hierr = 0.0
            nH_hierr = 0.0
            norm_hierr = 0.0
            red_chi2 = 0.0
            num_bins = 0

        reg_id = spectra[0][i].split(
            '_'
        )  # Splits string after every underscore so that region number can be accessed. reg_id[1] is accessed because that is the region number after 'xaf'
        results_file.write(
            '%7r %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %6.4e %6.4e %6.4e %7.4f %7.4f %7.4f %7.4f %8.1f %8r\n'
            % (int(reg_id[1]), kT, kT_loerr, kT_hierr, Z, Z_loerr, Z_hierr,
               norm, norm_loerr, norm_hierr, nH, nH_loerr, nH_hierr, red_chi2,
               totcnts, num_bins))  # Write all data to a file

    results_file.close()
示例#18
0
def test_beta_model_flux():
    tmpdir = tempfile.mkdtemp()
    curdir = os.getcwd()
    os.chdir(tmpdir)

    r_c = 20.0
    beta = 1.0

    prng = 34

    e = spec.generate_energies(exp_time, area, prng=prng)

    beta_src = BetaModel(ra0, dec0, r_c, beta, e.size, prng=prng)

    write_photon_list("beta",
                      "beta",
                      e.flux,
                      beta_src.ra,
                      beta_src.dec,
                      e,
                      overwrite=True)

    instrument_simulator("beta_simput.fits",
                         "beta_evt.fits",
                         exp_time,
                         "acisi_cy0", [ra0, dec0],
                         ptsrc_bkgnd=False,
                         instr_bkgnd=False,
                         foreground=False,
                         roll_angle=37.0,
                         prng=prng)

    ph_flux = spec.get_flux_in_band(0.5, 7.0)[0].value
    S0 = 3.0 * ph_flux / (2.0 * np.pi * r_c * r_c)

    wspec = spec.new_spec_from_band(0.5, 7.0)

    make_exposure_map("beta_evt.fits",
                      "beta_expmap.fits",
                      wspec.emid.value,
                      weights=wspec.flux.value,
                      overwrite=True)

    write_radial_profile("beta_evt.fits",
                         "beta_evt_profile.fits", [ra0, dec0],
                         0.0,
                         100.0,
                         200,
                         ctr_type="celestial",
                         emin=0.5,
                         emax=7.0,
                         expmap_file="beta_expmap.fits",
                         overwrite=True)

    load_data(1, "beta_evt_profile.fits", 3,
              ["RMID", "SUR_FLUX", "SUR_FLUX_ERR"])
    set_stat("chi2")
    set_method("levmar")
    set_source("beta1d.src")
    src.beta = 1.0
    src.r0 = 10.0
    src.ampl = 0.8 * S0
    freeze(src.xpos)

    fit()
    set_covar_opt("sigma", 1.645)
    covar()
    res = get_covar_results()

    assert np.abs(res.parvals[0] - r_c) < res.parmaxes[0]
    assert np.abs(res.parvals[1] - beta) < res.parmaxes[1]
    assert np.abs(res.parvals[2] - S0) < res.parmaxes[2]

    os.chdir(curdir)
    shutil.rmtree(tmpdir)
示例#19
0
def test_beta_model():
    tmpdir = tempfile.mkdtemp()
    curdir = os.getcwd()
    os.chdir(tmpdir)

    r_c = 20.0
    beta = 1.0

    exp_time = Quantity(500.0, "ks")

    e = spec.generate_energies(exp_time, area, prng=prng)

    beta_src = BetaModel(ra0, dec0, r_c, beta, e.size, prng=prng)

    write_photon_list("beta",
                      "beta",
                      e.flux,
                      beta_src.ra,
                      beta_src.dec,
                      e,
                      overwrite=True)

    instrument_simulator("beta_simput.fits",
                         "beta_evt.fits",
                         exp_time,
                         "hdxi", [ra0, dec0],
                         ptsrc_bkgnd=False,
                         instr_bkgnd=False,
                         foreground=False,
                         prng=prng)

    inst = get_instrument_from_registry("hdxi")
    arf = AuxiliaryResponseFile(inst["arf"])
    cspec = ConvolvedSpectrum(spec, arf)
    ph_flux = cspec.get_flux_in_band(0.5, 7.0)[0].value
    S0 = 3.0 * ph_flux / (2.0 * np.pi * r_c * r_c)

    write_radial_profile("beta_evt.fits",
                         "beta_evt_profile.fits", [ra0, dec0],
                         0.0,
                         100.0,
                         200,
                         ctr_type="celestial",
                         emin=0.5,
                         emax=7.0,
                         overwrite=True)

    load_data(1, "beta_evt_profile.fits", 3,
              ["RMID", "SUR_BRI", "SUR_BRI_ERR"])
    set_stat("chi2")
    set_method("levmar")
    set_source("beta1d.src")
    src.beta = 1.0
    src.r0 = 10.0
    src.ampl = 0.8 * S0
    freeze(src.xpos)

    fit()
    set_covar_opt("sigma", 1.645)
    covar()
    res = get_covar_results()

    assert np.abs(res.parvals[0] - r_c) < res.parmaxes[0]
    assert np.abs(res.parvals[1] - beta) < res.parmaxes[1]
    assert np.abs(res.parvals[2] - S0) < res.parmaxes[2]

    os.chdir(curdir)
    shutil.rmtree(tmpdir)
示例#20
0
import sherpa.astro.ui as shp

shp.restore('20-40 keV/fits/chxepwnblob.sav')

shp.set_conf_opt('numcores', 3)
shp.set_conf_opt('maxiters', 50)
shp.set_conf_opt('fast', True)
shp.set_conf_opt('remin', 10000.0)
shp.set_conf_opt('soft_limits', True)
shp.set_conf_opt('verbose', True)

shp.freeze(chxe)
shp.thaw(chxe.ampl)

print(shp.get_model())

shp.conf(blob.xpos, blob.ypos, blob.ellip, blob.fwhm, blob.theta, blob.ampl)
shp.save('20-40 keV/fits/chxepwnblobconf.sav')
示例#21
0
sh.load_image("analysis_3d/counts_2D.fits")
sh.set_coord("logical")

sh.load_table_model("expo", "analysis_3d/exposure_2D.fits")
sh.load_table_model("bkg", "analysis_3d/background_2D.fits")
sh.load_psf("psf", "analysis_3d/psf_2D.fits")


# In principle one might first want to fit the background amplitude. However the background estimation method already yields the correct normalization, so we freeze the background amplitude to unity instead of adjusting it. The (smoothed) residuals from this background model are then computed and shown.

# In[ ]:


sh.set_full_model(bkg)
bkg.ampl = 1
sh.freeze(bkg)


# In[ ]:


resid = Map.read("analysis_3d/counts_2D.fits")
resid.data = sh.get_data_image().y - sh.get_model_image().y
resid_smooth = resid.smooth(width=4)
resid_smooth.plot(add_cbar=True);


# ### Find and fit the brightest source
# We then find the position of the maximum in the (smoothed) residuals map, and fit a (symmetrical) Gaussian source with that initial position:

# In[ ]:
示例#22
0
src_models = [src_model1, src_model1 * ui.const1d.ratio_12]

vals_iter = izip(count(1), src_models, ds.get_response(), bkg_models, ds.get_bkg_scale())
for i, src_model, rsp, bkg_model, bkg_scale in vals_iter:
    ds[i].set_full_model(rsp(src_model) + bkg_scale * bkg_model)
    ds[i].set_bkg_full_model(bkg_model)

## Fit background
ds.notice(0.5, 8.0)
ui.set_method("neldermead")
ui.set_stat("cash")

ui.thaw(c1.c0)
ui.thaw(c2.c0)
ui.fit_bkg()
ui.freeze(c1.c0)
ui.freeze(c2.c0)

ui.set_par(abs1.nh, 0.0398)
ui.freeze(abs1)
ui.fit()
ds.plot_fit()
# ds.plot_bkg_fit()

# FIT OUTPUT:
#
# Datasets              = 1, 2
# Method                = neldermead
# Statistic             = cash
# Initial fit statistic = -11105.6
# Final fit statistic   = -11105.6 at function evaluation 64
示例#23
0
    def prepare_spectra(nH: float,
                        group: int = 1,
                        add_gal: bool = False,
                        redshift: Optional[float] = None,
                        **kwargs) -> float:
        """
        Fit the spectra using an absorbed powerlaw model using the Wstat statistic. The function also returns a p-value for the gof.
        :param nH: The galactic absorption column density in units of 10^22 /cm3
        :param group: The number of counts per energy bin
        :param add_gal: Setting this to True would add an intrinsic abrosption column density along side the galactic one
        :param redshift: The redshift to use in the fit. Only takes effect if add_gal is set to True
        ...
        :return: Returns the p-value of the gof. The null hypothesis states that the model and the observation differ while alternate says that the model explains the data
        """

        pha = read_pha("core_spectrum.pi")
        pha.set_analysis("energy")
        pha.notice(0.5, 7.0)
        tabs = ~pha.mask
        pha.group_counts(group, tabStops=tabs)
        x = pha.get_x()
        x = pha.apply_filter(x, pha._middle)
        y = pha.get_y(filter=True)
        pha.set_analysis("energy")

        model = xsphabs.abs1 * powlaw1d.srcp1
        print("Fitting the spectrum")

        zFlag = False
        if (nH is not None) and (nH > 0.0):
            if add_gal == 1:
                model = xsphabs.gal * xszphabs.abs1 * powlaw1d.srcp
                gal.nH = nH
                freeze(gal.nH)
                zFlag = True

            else:
                model = xsphabs.abs1 * powlaw1d.srcp1
                abs1.nH = nH
                freeze(abs1.nH)
        else:
            model = xszphabs.abs1 * powlaw1d.srcp1
            zFlag = True

        if zFlag is True and add_gal == 1:
            # print('REDSHIFT',redshift)
            abs1.redshift = redshift
            freeze(abs1.redshift)

        full_model = RSPModelPHA(pha.get_arf(), pha.get_rmf(), pha,
                                 pha.exposure * model)

        print(full_model)

        fit = Fit(pha, full_model, method=MonCar(), stat=WStat())
        res = fit.fit()

        print(res.format())
        print(fit.est_errors())

        # calculate the p-value for wstat
        mplot2 = ModelPlot()
        mplot2.prepare(pha, full_model)

        miu = mplot2.y * pha.exposure * 0.0146
        obs = y * pha.exposure * 0.0146

        c, ce, cv = SpecUtils.estimate_gof_cstat(miu, obs)

        #print(f"C0={c},C_e={ce},C_v={cv}")

        zval = (fit.calc_stat() - ce) / np.sqrt(cv)

        if zval > 0:
            pval = special.erfc(zval / np.sqrt(2))
        else:
            pval = special.erf(abs(zval) / np.sqrt(2))

        print(f"p-value for wstat = {pval}")

        set_data(pha)
        set_model(model)
        save_chart_spectrum("core_flux_chart.dat", elow=0.5, ehigh=7.0)
        # save_chart_spectrum("core_flux_chart.rdb",format='text/tsv', elow=0.5, ehigh=7.0)
        SAOTraceUtils.save_spectrum_rdb("core_flux_chart.dat")

        return pval
示例#24
0
def acis_bkg_model(detnam, root='bkg_', as_str=False):
    """Empirically derived background model for the ACIS detector, based on
    fitting a broken powerlaw plus 6 gaussians to ACIS background data.  These
    models *require* that the corresponding ARF be set to a constant value of 100
    and that the RMF be the correct RMF for the source and detector.  The model
    is only calibrated between 0.5 and 9 keV.  The following code is an example::

       from acis_bkg_model import acis_bkg_model

       load_pha(1, 'acisf04938_000N002_r0043_pha3.fits')
       arf = get_arf()
       rmf = get_rmf()

       # Load the background ARF/RMF.  This must be done in addition
       # to load_pha, otherwise the source and background arfs are
       # always identical.
       load_bkg_arf(1, arf.name)
       load_bkg_rmf(1, rmf.name)
       bkg_arf = get_bkg_arf(1)
       bkg_rmf = get_bkg_rmf(1)

       # Stub the bkg_arf to be a constant.  This is required for use
       # of the acis_bkg_model models.
       bkg_arf.specresp = bkg_arf.specresp * 0 + 100.

       # Set scaling between background and source apertures
       # Roughly equivalent to
       # bkg_scale = get_exposure() * get_backscal() / (get_exposure(bkg_id=1) * get_backscal(bkg_id=1))
       bkg_scale = get_data(1).sum_background_data(lambda x,y: 1)

       # Set source and background models.  This source is on ACIS-I CCDID = 2 (acis2i).
       bkg_model = const1d.c1 * acis_bkg_model('acis2i')
       set_full_model(rsp(powlaw1d.pow1) + bkg_scale * bkg_rsp(bkg_model))
       set_bkg_full_model(bkg_rmf(bkg(arf(bkg_model))))

       set_full_model(powlaw1d.pow1)
       set_bkg_full_model(bkg_rmf(bkg_arf( const1d.c1 * acis_bkg_model('acis2i'))))

       fit()  # or fit_bkg() to only fit the background

    :param detnam: detector name 'acis<CCD_ID><aimpoint det: i or s>'
    :returns: sherpa model for background
    """
    comps = (('powlaw1d', 'pow1'),
             ('powlaw1d', 'pow2'),
             ('gauss1d', 'g1'),
             ('gauss1d', 'g2'),
             ('gauss1d', 'g3'),
             ('gauss1d', 'g4'),
             ('gauss1d', 'g5'),
             ('gauss1d', 'g6'))

    model_comps = dict()
    for mtype, name in comps:
        ui.create_model_component(mtype, root + name)
        model_comp = model_comps[name] = eval(root + name)
        if mtype == 'gauss1d':
            model_comp.ampl.min = 0.0
        ui.freeze(model_comp)
        model_comp.integrate = True
    
    if detnam in pars:
        for parname, parval in pars[detnam].items():
            name, attr = parname.split('.')
            setattr(model_comps[name], attr, parval)
    else:
        raise ValueError('No background model available for "{0}".  Must be one of {1}'.format(
            detnam, sorted(pars.keys())))

    if as_str:
        out = ' + '.join([root + name for mtype, name in comps])
    else:
        mc = model_comps
        out = mc['pow1'] + mc['pow2'] + mc['g1'] + mc['g2'] + mc['g3'] + mc['g4'] + mc['g5'] + mc['g6']
    return out
示例#25
0
def assign_model(model_name, i):
    """Dedicated set up for the most common models."""
    if model_name == 'powlaw1d':
        from sherpa.models import PowLaw1D

        p1 = PowLaw1D('PowLaw' + str(i))
        p1.gamma = 2.6
        p1.ampl = 1e-20
        p1.ref = 1e9
        sau.freeze(p1.ref)
    elif model_name == 'logparabola':
        p1 = logparabola('LogPar' + str(i))
        p1.ampl = 1e-20
        p1.c1 = 2.
        p1.c2 = 1.
        p1.ref = 1e9
        sau.freeze(p1.ref)
    elif model_name == 'plexpcutoff':  # all parameters in TeV here
        from .models.plexpcutoff import MyPLExpCutoff

        p1 = MyPLExpCutoff('PLexpCutoff' + str(i))
        p1.gamma = 2.
        p1.No = 1e-11
        p1.beta = 1e-1  # 1/Ecutoff
        p1.Eo = 1
        sau.freeze(p1.Eo)
    elif model_name == 'Finke':  # EBL model from Finke et al. 2010
        # enable_table_model()
        from ..datasets import gammapy_extra
        filename = gammapy_extra.filename('datasets/ebl/frd_abs.fits.gz')
        sau.load_table_model('p1', filename)
    elif model_name == 'Franceschini':  # EBL model from Franceschini et al. 2012
        # enable_table_model()
        from ..datasets import gammapy_extra
        filename = gammapy_extra.filename('datasets/ebl/ebl_franceschini.fits.gz')
        sau.load_table_model('p1', filename)
    elif model_name == 'synchro':
        # print('Synchrotron model not available yet, sorry.')
        # quit() # Stops with an error: ValueError: slice step cannot be zero
        from naima.sherpamod import Synchrotron

        p1 = Synchrotron('Synchro' + str(i))
        p1.index = 2.
        p1.ampl = 1.
    elif model_name == 'ic':  # Inverse Compton peak
        # Weird, it returns the fit results twice (actually, it seems to do everything twice)
        # Returns error except if --noplot: TypeError: calc() takes exactly 4 arguments (3 given)
        from naima.sherpamod import InverseCompton

        p1 = InverseCompton('IC' + str(i))
        p1.index = 2.
        p1.ampl = 1e-7  # Not sure if the units are OK
    elif model_name == 'pion':  # Pion-decay gamma-ray spectrum
        # Veeery slow convergence
        # also doubled operations and problems for plotting, like in ic.
        from naima.sherpamod import PionDecay

        p1 = PionDecay('Pion' + str(i))
        p1.index = 2.
        p1.ampl = 10.
    else:  # set initial parameter values manually
        # (user-defined models and models that need some extra import will not work)
        p1 = globals()[model_name](model_name + str(i))
        set_manual_model(p1)

    return p1
示例#26
0
    def fit(self):
        # try a PCA decomposition of this spectrum
        initial = self.decompose()
        ui.set_method('neldermead')
        bkgmodel = PCAModel('pca%s' % self.id, data=self.pca)
        self.bkgmodel = bkgmodel
        response = get_identity_response(self.id)
        convbkgmodel = response(bkgmodel)
        ui.set_bkg_full_model(self.id, convbkgmodel)
        for p, v in zip(bkgmodel.pars, initial):
            p.val = v
        srcmodel = ui.get_model(self.id)
        ui.set_full_model(self.id, srcmodel)
        initial_v = self.calc_bkg_stat()
        # print('before fit: stat: %s' % (initial_v))
        ui.fit_bkg(id=self.id)
        # print('fit: first full fit done')
        final = [p.val for p in ui.get_bkg_model(self.id).pars]
        # print('fit: parameters: %s' % (final))
        initial_v = self.calc_bkg_stat()
        # print('fit: stat: %s' % (initial_v))

        # lets try from zero
        # logf.info('fit: second full fit from zero')
        for p in bkgmodel.pars:
            p.val = 0
        ui.fit_bkg(id=self.id)
        initial_v0 = self.calc_bkg_stat()
        # logf.info('fit: parameters: %s' % (final))
        # logf.info('fit: stat: %s' % (initial_v0))

        # pick the better starting point
        if initial_v0 < initial_v:
            # logf.info('fit: using zero-fit')
            initial_v = initial_v0
            final = [p.val for p in ui.get_bkg_model(self.id).pars]
        else:
            # logf.info('fit: using decomposed-fit')
            for p, v in zip(bkgmodel.pars, final):
                p.val = v

        # start with the full fit and remove(freeze) parameters
        print('%d parameters, stat=%.2f' % (len(initial), initial_v))
        results = [(2 * len(final) + initial_v, final, len(final), initial_v)]
        for i in range(len(initial) - 1, 0, -1):
            bkgmodel.pars[i].val = 0
            bkgmodel.pars[i].freeze()
            ui.fit_bkg(id=self.id)
            final = [p.val for p in ui.get_bkg_model(self.id).pars]
            v = self.calc_bkg_stat()
            print('--> %d parameters, stat=%.2f' % (i, v))
            results.insert(0, (v + 2 * i, final, i, v))

        print()
        print('Background PCA fitting AIC results:')
        print('-----------------------------------')
        print()
        print('stat Ncomp AIC')
        for aic, params, nparams, val in results:
            print('%-05.1f %2d %-05.1f' % (val, nparams, aic))
        aic, final, nparams, val = min(results)
        for p, v in zip(bkgmodel.pars, final):
            p.val = v
        for i in range(nparams):
            bkgmodel.pars[i].thaw()

        print()
        print('Increasing parameters again...')
        # now increase the number of parameters again
        # results = [(aic, final, nparams, val)]
        last_aic, last_final, last_nparams, last_val = aic, final, nparams, val
        for i in range(last_nparams, len(bkgmodel.pars)):
            next_nparams = i + 1
            bkgmodel.pars[i].thaw()
            for p, v in zip(bkgmodel.pars, last_final):
                p.val = v
            ui.fit_bkg(id=self.id)
            next_final = [p.val for p in ui.get_bkg_model(self.id).pars]
            v = self.calc_bkg_stat()
            next_aic = v + 2 * next_nparams
            if next_aic < last_aic:  # accept
                print('%d parameters, aic=%.2f ** accepting' %
                      (next_nparams, next_aic))
                last_aic, last_final, last_nparams, last_val = next_aic, next_final, next_nparams, v
            else:
                print('%d parameters, aic=%.2f' % (next_nparams, next_aic))
            # stop if we are 3 parameters ahead what we needed
            if next_nparams >= last_nparams + 3:
                break

        print('Final choice: %d parameters, aic=%.2f' %
              (last_nparams, last_aic))
        # reset to the last good solution
        for p, v in zip(bkgmodel.pars, last_final):
            p.val = v

        last_model = convbkgmodel
        for i in range(10):
            print('Adding Gaussian#%d' % (i + 1))
            # find largest discrepancy
            ui.set_analysis(self.id, "ener", "rate")
            m = ui.get_bkg_fit_plot(self.id)
            y = m.dataplot.y.cumsum()
            z = m.modelplot.y.cumsum()
            diff_rate = np.abs(y - z)
            ui.set_analysis(self.id, "ener", "counts")
            m = ui.get_bkg_fit_plot(self.id)
            x = m.dataplot.x
            y = m.dataplot.y.cumsum()
            z = m.modelplot.y.cumsum()
            diff = np.abs(y - z)
            i = np.argmax(diff)
            energies = x
            e = x[i]
            print(
                'largest remaining discrepancy at %.3fkeV[%d], need %d counts'
                % (x[i], i, diff[i]))
            # e = x[i]
            power = diff_rate[i]
            # lets try to inject a gaussian there

            g = ui.xsgaussian('g_%d_%d' % (self.id, i))
            print('placing gaussian at %.2fkeV, with power %s' % (e, power))
            # we work in energy bins, not energy
            g.LineE.min = energies[0]
            g.LineE.max = energies[-1]
            g.LineE.val = e
            if i > len(diff) - 2:
                i = len(diff) - 2
            if i < 2:
                i = 2
            g.Sigma = (x[i + 1] - x[i - 1])
            g.Sigma.min = (x[i + 1] - x[i - 1]) / 3
            g.Sigma.max = x[-1] - x[0]
            g.norm.min = power * 1e-6
            g.norm.val = power
            convbkgmodel2 = response(g)
            next_model = last_model + convbkgmodel2
            ui.set_bkg_full_model(self.id, next_model)
            ui.fit_bkg(id=self.id)
            next_final = [p.val for p in ui.get_bkg_model(self.id).pars]
            next_nparams = len(next_final)
            v = self.calc_bkg_stat()
            next_aic = v + 2 * next_nparams
            print('with Gaussian:', next_aic,
                  '; change: %.1f (negative is good)' % (next_aic - last_aic))
            if next_aic < last_aic:
                print('accepting')
                last_model = next_model
                last_aic, last_final, last_nparams, last_val = next_aic, next_final, next_nparams, v
            else:
                print('not significant, rejecting')
                ui.set_bkg_full_model(self.id, last_model)
                for p, v in zip(last_model.pars, last_final):
                    p.val = v
                    if v == 0:  # the parameter was frozen.
                        ui.freeze(p)
                break

        self.cstat, self.dof = self.calc_bkg_stat(
            dof=True)  # Save the final cstat and dof (dof = ihi - ilo)
        self.filter_energy = ui.get_filter(
        )  # Save the filter for background fitting.
        ui.set_analysis('channel')
        ui.ignore()
        ui.notice(self.filter0)  # restore filter
        ui.set_analysis('energy')
示例#27
0
def acis_bkg_model(detnam, root='bkg_', as_str=False):
    """Empirically derived background model for the ACIS detector, based on
    fitting a broken powerlaw plus 6 gaussians to ACIS background data.  These
    models *require* that the corresponding ARF be set to a constant value of 100
    and that the RMF be the correct RMF for the source and detector.  The model
    is only calibrated between 0.5 and 9 keV.  The following code is an example::

       from acis_bkg_model import acis_bkg_model

       load_pha(1, 'acisf04938_000N002_r0043_pha3.fits')
       arf = get_arf()
       rmf = get_rmf()

       # Load the background ARF/RMF.  This must be done in addition
       # to load_pha, otherwise the source and background arfs are
       # always identical.
       load_bkg_arf(1, arf.name)
       load_bkg_rmf(1, rmf.name)
       bkg_arf = get_bkg_arf(1)
       bkg_rmf = get_bkg_rmf(1)

       # Stub the bkg_arf to be a constant.  This is required for use
       # of the acis_bkg_model models.
       bkg_arf.specresp = bkg_arf.specresp * 0 + 100.

       # Set scaling between background and source apertures
       # Roughly equivalent to
       # bkg_scale = get_exposure() * get_backscal() / (get_exposure(bkg_id=1) * get_backscal(bkg_id=1))
       bkg_scale = get_data(1).sum_background_data(lambda x,y: 1)

       # Set source and background models.  This source is on ACIS-I CCDID = 2 (acis2i).
       bkg_model = const1d.c1 * acis_bkg_model('acis2i')
       set_full_model(rsp(powlaw1d.pow1) + bkg_scale * bkg_rsp(bkg_model))
       set_bkg_full_model(bkg_rmf(bkg(arf(bkg_model))))

       set_full_model(powlaw1d.pow1)
       set_bkg_full_model(bkg_rmf(bkg_arf( const1d.c1 * acis_bkg_model('acis2i'))))

       fit()  # or fit_bkg() to only fit the background

    :param detnam: detector name 'acis<CCD_ID><aimpoint det: i or s>'
    :returns: sherpa model for background
    """
    from sherpa.astro import ui
    global pars

    comps = (('powlaw1d', 'pow1'), ('powlaw1d', 'pow2'), ('gauss1d', 'g1'),
             ('gauss1d', 'g2'), ('gauss1d', 'g3'), ('gauss1d', 'g4'),
             ('gauss1d', 'g5'), ('gauss1d', 'g6'))

    model_comps = dict()
    for mtype, name in comps:
        ui.create_model_component(mtype, root + name)
        model_comp = model_comps[name] = ui.get_model_component(root + name)
        if mtype == 'gauss1d':
            model_comp.ampl.min = 0.0
        ui.freeze(model_comp)
        model_comp.integrate = True

    if detnam in pars:
        for parname, parval in pars[detnam].items():
            name, attr = parname.split('.')
            setattr(model_comps[name], attr, parval)
    else:
        raise ValueError(
            'No background model available for "{0}".  Must be one of {1}'.
            format(detnam, sorted(pars.keys())))

    if as_str:
        out = ' + '.join([root + name for mtype, name in comps])
    else:
        mc = model_comps
        out = mc['pow1'] + mc['pow2'] + mc['g1'] + mc['g2'] + mc['g3'] + mc[
            'g4'] + mc['g5'] + mc['g6']
    return out
示例#28
0
import sherpa.astro.ui as sh
sh.set_stat("cash")
sh.set_method("simplex")
sh.load_image('../datasets/images/MSH15-52_counts.fits.gz')
sh.set_coord("logical")

sh.load_table_model("expo", "../datasets/images/MSH15-52_exposure.fits.gz")
sh.load_table_model("bkg", "../datasets/images/MSH15-52_background.fits.gz")
sh.load_psf("psf", "../datasets/images/MSH15-52_psf.fits.gz")

# In[54]:

sh.set_full_model(bkg)
bkg.ampl = 1
sh.freeze(bkg)

data = sh.get_data_image().y - sh.get_model_image().y
resid = SkyImage(data=data, wcs=ref_image.wcs)

resid_table = []  #Keep residual images in a list to show them later
resid_smo6 = resid.smooth(radius=6)
resid_smo6.plot(vmax=5, add_cbar=True)
resid_table.append(resid_smo6)

# In[55]:

maxcoord = resid_smo6.lookup_max()
maxpix = resid_smo6.wcs_skycoord_to_pixel(maxcoord[0])
print(maxcoord)
print(maxpix)
示例#29
0
    # theta = 57 deg (from positive north)
    shp.set_par(chxe.xpos, 497.4, 497.4 - 4, 497.4 + 4)
    shp.set_par(chxe.ypos, 499.1, 499.1 - 4, 499.1 + 4)
    shp.set_par(chxe.fwhm, 30, 1, 200)
    shp.set_par(chxe.ellip, .5)
    shp.set_par(chxe.theta, -.9948)
    shp.set_par(chxe.ampl, 1e-5)
    shp.thaw(chxe.ellip, chxe.xpos, chxe.ypos)

    print(shp.get_model())

    shp.ignore2d('circle(500,500,1000)')
    shp.notice2d('circle(500,500,60)')
    shp.ignore2d('circle(500,500,' + str(r) + ')')
    shp.fit()

    print(shp.get_model())

    shp.set_conf_opt('numcores', 3)
    shp.set_conf_opt('maxiters', 50)
    shp.set_conf_opt('fast', True)
    shp.set_conf_opt('remin', 10000.0)
    shp.set_conf_opt('soft_limits', True)
    shp.freeze(chxe.xpos, chxe.ypos)

    #shp.conf(chxe.ellip, chxe.fwhm)

    utils.save_components('40-50 keV/chxe' + str(int(r * 2.5)) + '.model',
                          ['chxe'])
    shp.save('40-50 keV/fits/chxe150/chxe' + str(int(r * 2.5)) + 'fit.sav')
示例#30
0
def fit_sherpa(obsid_list, redshift, nH_Gal, energy, min_counts=25, kT_guess=3, Ab_guess=1, fix_nH_Gal=True, fix_abund=False, find_errors=True):

    spectra = []
    for obs in obsid_list:
        temp = glob.glob('xaf_*_' + obs + '.pi')  # get spectra of regions
        spectra.append(temp)  # spectra will be made of lists which have xaf_*_obs.pi filenames - access with spectra[i][j]
    spectra.sort()
    num_obs = len(obsid_list)
    num_reg = len(temp)
    filename = 'spectra_wabs_mekal.dat'
    results_file = open(filename, "w")
    results_file.write('# Fit results for wabs*mekal (zeros indicate that no fitting was performed)\n')
    results_file.write('# Reg_no.  kT  kT_loerr kT_hierr   Z    Z_loerr  Z_hierr  norm    norm_loerr norm_hierr nH_Gal  nH_loerr nH_hierr red_chisq total_counts num_bins\n')
    for i in range(num_reg):
        sherpa.clean()  # clean everything
        cnts = numpy.zeros(num_obs)  # make array of zeros with index length same as num_obs to store counts
        max_rate = numpy.zeros(num_obs)  # max count rate [counts/s/keV]
        data_set = 0  # data set number
        good_src_ids = numpy.zeros(num_obs, dtype=int) - 1

        for j in range(num_obs):
            sherpa.load_pha(data_set, spectra[j][i])  # load xaf_#_obs_####.pi and .arf and .rmf files.
            sherpa.ignore_id(data_set, 0.0, energy[0])
            sherpa.ignore_id(data_set, energy[1], None)
            cnts[j] = sherpa.calc_data_sum(energy[0], energy[1], data_set)
            cnt_rate = sherpa.get_rate(data_set, filter=True)
            if len(cnt_rate) == 0:
                max_rate[j] = 0.0  # when few counts (<50), get_rate can return zero-length array
            else:
                max_rate[j] = numpy.max(cnt_rate)
            sherpa.subtract(data_set)  # subtract background
            sherpa.set_source(data_set, sherpa.xswabs.abs1 * sherpa.xsmekal.plsm1)  # 1 temperature mekal model fit
            good_src_ids[j] = data_set
            data_set += 1  # same run for region but different obs

        # Filter out ignored obs
        good_src_ids_indx = numpy.where(good_src_ids >= 0)
        good_src_ids = good_src_ids[good_src_ids_indx]
        max_rate = max_rate[good_src_ids_indx]
        cnts = cnts[good_src_ids_indx]

        totcnts = numpy.sum(cnts)
        if totcnts >= min_counts:
            print('Fitting spectra in region: ' + str(i))
            abs1.nH = nH_Gal
            abs1.cache = 0
            if fix_nH_Gal:
                sherpa.freeze(abs1.nH)
            else:
                sherpa.thaw(abs1.nH)
            plsm1.kt = kT_guess
            sherpa.thaw(plsm1.kt)
            plsm1.Abundanc = Ab_guess
            if fix_abund:
                sherpa.freeze(plsm1.Abundanc)
            else:
                sherpa.thaw(plsm1.Abundanc)
            plsm1.redshift = redshift
            sherpa.freeze(plsm1.redshift)
            plsm1.cache = 0

            sherpa.fit()
            fit_result = sherpa.get_fit_results()
            red_chi2 = fit_result.rstat
            num_bins = fit_result.numpoints
            if fix_nH_Gal:
                nH = nH_Gal
                kT = fit_result.parvals[0]
                if fix_abund:
                    Z = Ab_guess
                    norm = fit_result.parvals[1]
                else:
                    Z = fit_result.parvals[1]
                    norm = fit_result.parvals[2]
            else:
                nH = fit_result.parvals[0]
                kT = fit_result.parvals[1]
                if fix_abund:
                    Z = Ab_guess
                    norm = fit_result.parvals[2]
                else:
                    Z = fit_result.parvals[2]
                    norm = fit_result.parvals[3]
            del fit_result

            if find_errors:
                sherpa.covar()
                covar_result = sherpa.get_covar_results()
                if fix_nH_Gal:
                    nH_loerr = 0.0
                    nH_hierr = 0.0
                    kT_loerr = covar_result.parmins[0]
                    kT_hierr = covar_result.parmaxes[0]
                    if fix_abund:
                        Z_loerr = 0.0
                        Z_hierr = 0.0
                        norm_loerr = covar_result.parmins[1]
                        norm_hierr = covar_result.parmaxes[1]
                    else:
                        Z_loerr = covar_result.parmins[1]
                        Z_hierr = covar_result.parmaxes[1]
                        norm_loerr = covar_result.parmins[2]
                        norm_hierr = covar_result.parmaxes[2]
                else:
                    nH_loerr = covar_result.parmins[0]
                    nH_hierr = covar_result.parmaxes[0]
                    kT_loerr = covar_result.parmins[1]
                    kT_hierr = covar_result.parmaxes[1]
                    if fix_abund:
                        Z_loerr = 0.0
                        Z_hierr = 0.0
                        norm_loerr = covar_result.parmins[2]
                        norm_hierr = covar_result.parmaxes[2]
                    else:
                        Z_loerr = covar_result.parmins[2]
                        Z_hierr = covar_result.parmaxes[2]
                        norm_loerr = covar_result.parmins[3]
                        norm_hierr = covar_result.parmaxes[3]
                del covar_result

                # Check for failed errors (= None) and set them to +/- best-fit value
                if not fix_nH_Gal:
                    if nH_loerr is None: nH_loerr = -nH  # is was ==
                    if nH_hierr is None: nH_hierr = nH
                if kT_loerr is None: kT_loerr = -kT
                if kT_hierr is None: kT_hierr = kT
                if not fix_abund:
                    if Z_loerr is None: Z_loerr = -Z
                    if Z_hierr is None: Z_hierr = Z
                if norm_loerr is None: norm_loerr = -norm
                if norm_hierr is None: norm_hierr = norm
            else:
                kT_loerr = 0.0
                Z_loerr = 0.0
                nH_loerr = 0.0
                norm_loerr = 0.0
                kT_hierr = 0.0
                Z_hierr = 0.0
                nH_hierr = 0.0
                norm_hierr = 0.0

        else:  # if total counts < min_counts, just write zeros
            print('\n Warning: no fit performed for for region: ' + str(i))
            print('\n Spectra have insufficient counts after filtering or do not exist.')
            print('\n --> All parameters for this region set to 0.0.')
            kT = 0.0
            Z = 0.0
            nH = 0.0
            norm = 0.0
            kT_loerr = 0.0
            Z_loerr = 0.0
            nH_loerr = 0.0
            norm_loerr = 0.0
            kT_hierr = 0.0
            Z_hierr = 0.0
            nH_hierr = 0.0
            norm_hierr = 0.0
            red_chi2 = 0.0
            num_bins = 0

        reg_id = spectra[0][i].split('_')  # Splits string after every underscore so that region number can be accessed. reg_id[1] is accessed because that is the region number after 'xaf'
        results_file.write('%7r %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %6.4e %6.4e %6.4e %7.4f %7.4f %7.4f %7.4f %8.1f %8r\n' % (int(reg_id[1]), kT, kT_loerr, kT_hierr, Z, Z_loerr, Z_hierr, norm, norm_loerr, norm_hierr, nH, nH_loerr, nH_hierr, red_chi2, totcnts, num_bins))  # Write all data to a file

    results_file.close()