Example #1
0
    def test_proj_bubble(self):

        def cmp_proj_bubble(mylocals, convarerr, proj, conf):
            mek1 = mylocals['mek1']
            assert covarerr[0] == approx(0, rel=1e-4)
            assert covarerr[1] == approx(8.74608e-07, rel=1e-3)
            assert mek1.kt.val == approx(17.8849, rel=1e-2)
            assert mek1.norm.val == approx(4.15418e-06, rel=1e-2)
            # Proj -- Upper bound of kT can't be found
            #
            assert proj.parmins[0] == approx(-12.048069, rel=0.01)
            assert proj.parmins[1] == approx(-9.510913e-07, rel=0.01)
            assert proj.parmaxes[1] == approx(2.403640e-06, rel=0.01)
            assert proj.parmaxes[0] is None
            assert conf.parmins[0] == approx(-12.1073, rel=0.01)
            assert conf.parmaxes[0] == approx(62.0585, rel=0.01)
            assert conf.parmins[1] == approx(-9.5568e-07, rel=0.01)
            assert conf.parmaxes[1] == approx(2.39937e-06, rel=0.01)

        self.run_thread('proj_bubble')
        fit_results = ui.get_fit_results()
        covarerr = sqrt(fit_results.extra_output['covar'].diagonal())
        proj = ui.get_proj_results()
        conf = ui.get_conf_results()
        cmp_proj_bubble(self.locals, covarerr, proj, conf)

        self.run_thread('proj_bubble_ncpus')
        fit_results = ui.get_fit_results()
        covarerr = sqrt(fit_results.extra_output['covar'].diagonal())
        proj = ui.get_proj_results()
        conf = ui.get_conf_results()
        cmp_proj_bubble(self.locals, covarerr, proj, conf)
Example #2
0
    def fit(self, conf = False):


        ui.ignore(None, None)
        ui.notice(self.start, self.stop)
        self.set_source()
        ui.fit(1)
        if conf:
            ui.conf()
        res = ui.get_fit_results()

        for line in (self.H2lines + self.nonH2lines):
            sourcename = line['source'].split('.')[1]
            print sourcename
            for p in ['pos', 'fwhm', 'ampl']:
                n = '{0}.{1}'.format(sourcename, p)
                _place_val(line, p, ui.get_par(n).val)

        self.const = ui.get_par('c1.c0').val
        self.redchi2 = res.rstat


        if conf:
            res = ui.get_conf_results()
            for line in (self.H2lines + self.nonH2lines):
                sourcename = line['source'].split('.')[1]
                for p in ['pos', 'fwhm', 'ampl']:
                    n = '{0}.{1}'.format(sourcename, p)
                    parmin, parmax = _parminmax(res, n)
                    line[p+'_max'] = parmax
                    line[p+'_min'] = parmin
            # deal with error on const
            parmin, parmax = _parminmax(res, 'c1.c0')
            self.const_min = parmin
            self.const_max = parmax
Example #3
0
def save_conf(filename, energy_flux=None, absorbpars=[]):
    '''
    Parameters
    ----------
    filename : string
    energy_flux : string or integer
        Identifier of Sherpa model for which the energy flux will be calculated.
    absorbpars : sherpa parameter instances
        These parameters are set to 0 before the flux is calculated.
    '''
    confres = ui.get_conf_results()
    fitres = ui.get_fit_results()

    if energy_flux is not None:
        oldval = [getattr(a, 'val') for a in absorbpars]
        for a in absorbpars:
            setattr(a, 'val', 0.)
        energy_flux = ui.calc_energy_flux(0.3, 9., energy_flux)
        for a, v in zip(absorbpars, oldval):
            setattr(a, 'val', v)

    with open(join(articlepath, filename), 'w') as f:
        json.dump(
            {
                'name': confres.parnames,
                'val': confres.parvals,
                'up': confres.parmaxes,
                'down': confres.parmins,
                'redchi2': fitres.rstat,
                'dof': fitres.dof,
                'flux': energy_flux
            }, f)
Example #4
0
def test_proj_bubble(parallel, clean_astro_ui, fix_xspec, run_thread):

    # How sensitive are the results to the change from bcmc to vern
    # made in XSPEC 12.10.1? It looks like the mekal best-fit
    # temperature can jump from ~17.9 to 18.6, so require bcmc
    # in this test (handled by fix_xspec).
    #
    # Note that the error on kT is large, so we can expect that
    # changes to the system could change these results. In particular,
    # the covariance errors on kt are < 1 but from other error
    # analysis they are > 10 or even unbound, so it is likely that the
    # covariance error results can change significantly.
    #
    # The fit results change in XSPEC 12.10.0 since the mekal model
    # was changed (FORTRAN to C++). A 1% difference is used for the
    # parameter ranges from covar and proj (matches the tolerance for
    # the fit results). Note that this tolerance has been relaced to
    # 10% for the kT errors, as there is a significant change seen
    # with different XSPEC versions for the covariance results.
    #
    # fit_results is unused
    def cmp_thread(fit_results, mek1, covarerr):

        assert covarerr[0] == approx(0, rel=1e-4)
        assert covarerr[1] == approx(8.74608e-07, rel=1e-3)
        assert mek1.kt.val == approx(17.8849, rel=1e-2)
        assert mek1.norm.val == approx(4.15418e-06, rel=1e-2)

    check_thread(run_thread, 'proj_bubble', parallel, cmp_thread, ['mek1'])

    # Covar
    #
    # TODO: should this check that parmaxes is -1 * parmins instead?
    covar = ui.get_covar_results()
    assert covar.parmins[0] == approx(-0.653884, rel=0.1)
    assert covar.parmins[1] == approx(-8.94436e-07, rel=0.01)
    assert covar.parmaxes[0] == approx(0.653884, rel=0.1)
    assert covar.parmaxes[1] == approx(8.94436e-07, rel=0.01)

    # Proj -- Upper bound of kT can't be found
    #
    proj = ui.get_proj_results()
    assert proj.parmins[0] == approx(-12.048069, rel=0.01)
    assert proj.parmins[1] == approx(-9.510913e-07, rel=0.01)
    assert proj.parmaxes[0] is None
    assert proj.parmaxes[1] == approx(2.403640e-06, rel=0.01)

    # Conf
    #
    conf = ui.get_conf_results()
    assert conf.parmins[0] == approx(-12.1073, rel=0.01)
    assert conf.parmins[1] == approx(-9.5568e-07, rel=0.01)
    assert conf.parmaxes[0] is None
    assert conf.parmaxes[1] == approx(2.39937e-06, rel=0.01)
Example #5
0
def get_gamma_param(params, fitstats, fixgamma):
    if fixgamma:
        params["PhoIndex"] = fixgamma
    else:
        if fitstats.rstat <= 3:
            dsmod.conf(po1.PhoIndex)
            confstats = shp.get_conf_results()
            params["PhoIndex"] = confstats.parvals[0]
            params["PhoIndex_ErrMin"] = confstats.parmins[0]
            params["PhoIndex_ErrMax"] = confstats.parmaxes[0]
        else:
            params["PhoIndex"] = fitstats.parvals[1]

    return params
Example #6
0
def fit_multiplets(multipletlist, id = None, outpath = None, plot = False, delta_lam = .2):
    #
    n_lines =  np.sum([len(mult['wave']) for mult in multipletlist])
    result = np.zeros(n_lines, dtype = {'names': ['multname', 'linename', 'wave', 'flux', 'errup', 'errdown', 'photons', 'photonflux'], 'formats': ['S30', 'S30', 'f4', 'f4', 'f4', 'f4', 'f4', 'f4']})
    currentline = 0
    #
    for mult in multipletlist:
        if outpath is not None:
            outfile = os.path.join(outpath, filter(lambda x: x.isalnum(), mult['name']))
        else:
            outfile = None
        fit_lines(mult, id, delta_lam = delta_lam, plot = plot, outfile = outfile)
        #    
        ui.conf(id)
        conf_res = ui.get_conf_results()
        source = ui.get_source(id)
        #set all ampl to 0 and only for 1 line to real value
        set_all_val('c0', 0., id)
        for lname, lfili, lwave in zip(mult['linename'], mult['fililiname'], mult['wave']):
            print 'Fitting line '+str(currentline+1)+'/'+str(n_lines)
            par = ui.get_model_component(lfili)
            indconf_res = ( np.array(conf_res.parnames) == lfili+'.ampl').nonzero()[0]
            set_all_val('ampl', 0., id)
            
            par.ampl.val = conf_res.parvals[indconf_res]
            counts = ui.calc_model_sum(None, None, id)
            #
            print(lname, counts)
            photonflux = ui.calc_photon_flux(None, None, id)
            # determine scaling between ampl and flux
            par.ampl.val = 1
            amp2flux = ui.calc_energy_flux(None, None, id)

            par.ampl.val = conf_res.parvals[indconf_res]
            #
            val = conf_res.parvals[indconf_res] * amp2flux
            errdown = conf_res.parmins[indconf_res] * amp2flux if conf_res.parmins[indconf_res] else np.nan
            errup  = conf_res.parmaxes[indconf_res] * amp2flux if conf_res.parmaxes[indconf_res] else np.nan
            #
            result[currentline] = (mult['name'], lname, lwave, val, errup, errdown, counts, photonflux)
            #
            currentline +=1
    return result
Example #7
0
def get_nh_param(params, fitstats, fixgamma):
    nH = fitstats.parvals[0]

    if fitstats.rstat <= 3.0:
        dsmod.conf(abs1.nH)
        confstats = shp.get_conf_results()
        nHmin = confstats.parmins[0]
        nHmax = confstats.parmaxes[0]

        # Estimate nH upper-limit if nH=0, or nH-nHmin<0, or nHmin = nan
        if (nH == 0) or (nHmin is None) or (nH - nHmin <= 0):
            params["nH"] = _nH_uplimit(fixgamma)
        else:
            params["nH"] = nH
            params["nH_ErrMin"] = nHmin
            params["nH_ErrMax"] = nHmax
    else:
        params["nH"] = nH

    return params
Example #8
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
Example #9
0
def write_all(filename='results.json'):
    """Dump source, fit results and conf results to a JSON file.

    http://www.astropython.org/snippet/2010/7/Save-sherpa-fit-and-conf-results-to-a-JSON-file
    """
    import sherpa.astro.ui as sau
    out = dict()

    if 0:
        src = sau.get_source()
        src_par_attrs = ('name', 'frozen', 'modelname', 'units', 'val',
                         'fullname')
        out['src'] = dict(name=src.name,
                          pars=[
                              dict((attr, getattr(par, attr))
                                   for attr in src_par_attrs)
                              for par in src.pars
                          ])

    try:
        fit_attrs = ('methodname', 'statname', 'succeeded', 'statval',
                     'numpoints', 'dof', 'rstat', 'qval', 'nfev', 'message',
                     'parnames', 'parvals')
        fit = sau.get_fit_results()
        out['fit'] = dict((attr, getattr(fit, attr)) for attr in fit_attrs)
    except Exception as err:
        print(err)

    try:
        conf_attrs = ('datasets', 'methodname', 'fitname', 'statname', 'sigma',
                      'percent', 'parnames', 'parvals', 'parmins', 'parmaxes',
                      'nfits')
        conf = sau.get_conf_results()
        out['conf'] = dict((attr, getattr(conf, attr)) for attr in conf_attrs)
    except Exception as err:
        print(err)

    try:
        covar_attrs = ('datasets', 'methodname', 'fitname', 'statname',
                       'sigma', 'percent', 'parnames', 'parvals', 'parmins',
                       'parmaxes', 'nfits')
        covar = sau.get_covar_results()
        out['covar'] = dict(
            (attr, getattr(covar, attr)) for attr in covar_attrs)
    except Exception as err:
        print(err)

    if 0:
        out['pars'] = []
        for par in src.pars:
            fullname = par.fullname
            if any(fullname == x['name'] for x in out['pars']):
                continue  # Parameter was already processed
            outpar = dict(name=fullname, kind=par.name)

            # None implies no calculated confidence interval for Measurement
            parmin = None
            parmax = None
            try:
                if fullname in conf.parnames:  # Confidence limits available from conf
                    i = conf.parnames.index(fullname)
                    parval = conf.parvals[i]
                    parmin = conf.parmins[i]
                    parmax = conf.parmaxes[i]
                if parmin is None:
                    parmin = -float(
                        'inf'
                    )  # None from conf means infinity, so set accordingly
                if parmax is None:
                    parmax = float('inf')
                elif fullname in fit.parnames:  # Conf failed or par is uninteresting and wasn't sent to conf
                    i = fit.parnames.index(fullname)
                    parval = fit.parvals[i]
                else:  # No fit or conf value (maybe frozen)
                    parval = par.val
            except Exception as err:
                print(err)

            out['pars'].append(outpar)
    if filename is None:
        return out
    else:
        json.dump(out, open(filename, 'w'), sort_keys=True, indent=4)
Example #10
0
def print_conf():
    res = sau.get_conf_results()
    print("Confidence limits on fitted parameters:")
    for index, parn in enumerate(res.parnames):
        print(parn, "\t\t{0:.3e}".format(res.parvals[index]), "\t{0:.3e}".format(res.parmins[index]),
              "\t{0:.3e}".format(res.parmaxes[index]))
Example #11
0
def write_all(filename='results.json'):
    """Dump source, fit results and conf results to a JSON file.
    http://www.astropython.org/snippet/2010/7/Save-sherpa-fit-and-conf-results-to-a-JSON-file
    """
    import sherpa.astro.ui as sau
    out = dict()

    if 0:
        src = sau.get_source()
        src_par_attrs = ('name', 'frozen', 'modelname', 'units', 'val', 'fullname')
        out['src'] = dict(name=src.name,
                          pars=[dict((attr, getattr(par, attr)) for attr in src_par_attrs)
                                for par in src.pars])

    try:
        fit_attrs = ('methodname', 'statname', 'succeeded', 'statval', 'numpoints', 'dof',
                     'rstat', 'qval', 'nfev', 'message', 'parnames', 'parvals')
        fit = sau.get_fit_results()
        out['fit'] = dict((attr, getattr(fit, attr)) for attr in fit_attrs)
    except Exception as err:
        print(err)

    try:
        conf_attrs = ('datasets', 'methodname', 'fitname', 'statname', 'sigma', 'percent',
                      'parnames', 'parvals', 'parmins', 'parmaxes', 'nfits')
        conf = sau.get_conf_results()
        out['conf'] = dict((attr, getattr(conf, attr)) for attr in conf_attrs)
    except Exception as err:
        print(err)

    try:
        covar_attrs = ('datasets', 'methodname', 'fitname', 'statname', 'sigma', 'percent',
                       'parnames', 'parvals', 'parmins', 'parmaxes', 'nfits')
        covar = sau.get_covar_results()
        out['covar'] = dict((attr, getattr(covar, attr)) for attr in covar_attrs)
    except Exception as err:
        print(err)

    if 0:
        out['pars'] = []
        for par in src.pars:
            fullname = par.fullname
            if any(fullname == x['name'] for x in out['pars']):
                continue  # Parameter was already processed
            outpar = dict(name=fullname, kind=par.name)

            # None implies no calculated confidence interval for Measurement
            parmin = None
            parmax = None
            try:
                if fullname in conf.parnames:  # Confidence limits available from conf
                    i = conf.parnames.index(fullname)
                    parval = conf.parvals[i]
                    parmin = conf.parmins[i]
                    parmax = conf.parmaxes[i]
                if parmin is None:
                    parmin = -float('inf')  # None from conf means infinity, so set accordingly
                if parmax is None:
                    parmax = float('inf')
                elif fullname in fit.parnames:  # Conf failed or par is uninteresting and wasn't sent to conf
                    i = fit.parnames.index(fullname)
                    parval = fit.parvals[i]
                else:  # No fit or conf value (maybe frozen)
                    parval = par.val
            except Exception as err:
                print(err)

            out['pars'].append(outpar)
    if filename is None:
        return out
    else:
        json.dump(out, open(filename, 'w'), sort_keys=True, indent=4)