Example #1
0
    def _test_xspec_tablemodel(self, loadfunc):
        # Just test one table model; use the same scheme as
        # test_xspec_models_noncontiguous().
        #
        # The table model is from
        # https://heasarc.gsfc.nasa.gov/xanadu/xspec/models/rcs.html
        # retrieved July 9 2015. The exact model is irrelevant for this
        # test, so this was chosen as it's relatively small.
        loadfunc('tmod', self.make_path('xspec-tablemodel-RCS.mod'))

        # when used in the test suite it appears that the tmod
        # global symbol is not created, so need to access the component
        tmod = ui.get_model_component('tmod')

        self.assertEqual(tmod.name, 'xstablemodel.tmod')

        egrid, elo, ehi, wgrid, wlo, whi = make_grid()

        evals1 = tmod(egrid)
        evals2 = tmod(elo, ehi)

        wvals1 = tmod(wgrid)
        wvals2 = tmod(wlo, whi)

        self.assertFinite(evals1, tmod, "energy")
        self.assertFinite(wvals1, tmod, "wavelength")

        emsg = "table model evaluation failed: "
        assert_array_equal(evals1[:-1], evals2,
                           err_msg=emsg + "energy comparison")

        assert_allclose(evals1, wvals1,
                        err_msg=emsg + "single arg")
        assert_allclose(evals2, wvals2,
                        err_msg=emsg + "two args")
Example #2
0
def test_bug_276(make_data_path):
    ui.load_pha(make_data_path('3c273.pi'))
    ui.set_model('polynom1d.p1')
    ui.fit()
    ui.covar()
    scal = ui.get_covar_results().parmaxes
    ui.sample_flux(ui.get_model_component('p1'), 0.5, 1, num=5, correlated=False, scales=scal)
Example #3
0
def load_pars(filename, modcomps=[]):
    """
    Load Sherpa model parameter attributes from an ASCII file
    and set the input model components with the parameter attributes.

    `filename`  ASCII file name
    `modcomps`  list of model components (strings or objects) to load

    :author: Brian Refsdal

    See `save_pars` for an example.

    """

    if not isinstance(filename, basestring):
        raise TypeError("filename '%s' is not a string" % str(filename))

    if not os.path.isfile(filename):
        raise IOError("file '%s' does not exist" % str(filename))

    fd = open(filename, 'r')
    saved = json.loads(fd.readline().strip())
    fd.close()

    for comp in modcomps:
        for par in get_model_component(comp).pars:
            set_parameter_from_dict(par, saved, name='fullname')
Example #4
0
 def test_fit(self):
     ui.load_arrays(1, self.x, self.y)
     ui.set_source("polynom1d.p")
     ui.thaw("p.c1")
     ui.set_method("levmar")
     ui.fit()
     model = ui.get_model_component("p")
     expected = [0, 1]
     observed = [model.c0.val, model.c1.val]
     assert_almost_equal(observed, expected)
Example #5
0
 def test_xspec(self):
     ui.load_arrays(1, self.x, self.y)
     ui.set_source("xspowerlaw.p")
     ui.set_method("moncar")
     ui.set_stat("chi2xspecvar")
     ui.fit()
     model = ui.get_model_component("p")
     expected = [-1.3686404, 0.5687635]
     observed = [model.PhoIndex.val, model.norm.val]
     assert_almost_equal(observed, expected)
Example #6
0
 def test_psf_model2d(self):
     ui.dataspace2d([216, 261])
     for model in self.models2d:
         try:
             ui.load_psf("psf2d", model + ".mdl")
             ui.set_psf("psf2d")
             mdl = ui.get_model_component("mdl")
             self.assert_((numpy.array(mdl.get_center()) == numpy.array([108, 130])).all())
         except:
             print model
             raise
Example #7
0
 def test_psf_model1d(self):
     ui.dataspace1d(1, 10)
     for model in self.models1d:
         try:
             ui.load_psf("psf1d", model + ".mdl")
             ui.set_psf("psf1d")
             mdl = ui.get_model_component("mdl")
             self.assert_((numpy.array(mdl.get_center()) == numpy.array([4])).all())
         except:
             print model
             raise
Example #8
0
 def test_psf_model1d(self):
     ui.dataspace1d(1, 10)
     for model in self.models1d:
         try:
             ui.load_psf('psf1d', model + '.mdl')
             ui.set_psf('psf1d')
             mdl = ui.get_model_component('mdl')
             self.assertTrue((numpy.array(mdl.get_center()) ==
                              numpy.array([4])).all())
         except:
             print model
             raise
Example #9
0
 def test_psf_model2d(self):
     ui.dataspace2d([216, 261])
     for model in self.models2d:
         try:
             ui.load_psf('psf2d', model + '.mdl')
             ui.set_psf('psf2d')
             mdl = ui.get_model_component('mdl')
             self.assertTrue((numpy.array(mdl.get_center()) ==
                              numpy.array([108, 130])).all())
         except:
             print model
             raise
Example #10
0
    def _test_xspec_tablemodel_checks_input_length(self, loadfunc):

        loadfunc('mdl', self.make_path('xspec-tablemodel-RCS.mod'))
        mdl = ui.get_model_component('mdl')

        # Check when input array is too small (< 2 elements)
        self.assertRaises(TypeError, mdl, [0.1])

        # Check when input arrays are not the same size (when the
        # low and high bin edges are given)
        self.assertRaises(TypeError, mdl, [0.1, 0.2, 0.3], [0.2, 0.3])
        self.assertRaises(TypeError, mdl, [0.1, 0.2], [0.2, 0.3, 0.4])
Example #11
0
def save_pars(filename, modcomps=[], clobber=False):
    """
    Save Sherpa model parameter attributes to an ASCII file

    `filename`  ASCII file name
    `modcomps`  list of model components (strings or objects) to save
    `clobber`   clobber the file if it exists

    :author: Brian Refsdal

    Example:

        from sherpa.astro.ui import *
        from save_pars import save_pars, load_pars

        set_model(gauss1d.g1 + gauss1d.g2)

        ... set up parameters, fit

        save_pars('mypars.out', [g1, g2])
        or
        save_pars('mypars.out', list_model_components(), clobber=True)
        load_pars('mypars.out', [g1, g2])
    """

    if not isinstance(filename, basestring):
        raise TypeError("filename '%s' is not a string" % str(filename))

    clobber = bool(clobber)
    if os.path.isfile(filename) and not clobber:
        raise ValueError("file '%s' exists and clobber is not set" %
                         str(filename))

    saved = {}
    for comp in modcomps:
        for par in get_model_component(comp).pars:
            for elem in ["val", "min", "max"]:
                key = par.fullname + "." + elem
                saved[key] = getattr(par, elem)

            elem = "frozen"
            key = par.fullname + "." + elem
            saved[key] = int(getattr(par, elem))

            elem = "link"
            key = par.fullname + "." + elem
            attr = getattr(par, elem)
            if attr:
                saved[key] = str(attr.fullname)

    fd = file(filename, 'w')
    fd.write(json.dumps(saved))
    fd.close()
Example #12
0
 def test_fit(self):
     """
     Perform a very simple fit with built-in models, and check that the results make sense.
     """
     ui.load_arrays(1, self.x, self.y)
     ui.set_source("polynom1d.p")
     ui.thaw("p.c1")
     ui.set_method("levmar")
     ui.fit()
     model = ui.get_model_component("p")
     expected = [0, 1]
     observed = [model.c0.val, model.c1.val]
     assert_almost_equal(observed, expected)
Example #13
0
    def test_xspec_tablemodel_noncontiguous2(self):

        ui.load_table_model('tmod',
                            self.make_path('xspec/tablemodel/RCS.mod'))
        tmod = ui.get_model_component('tmod')

        elo, ehi, wlo, whi = make_grid_noncontig2()

        evals2 = tmod(elo, ehi)
        wvals2 = tmod(wlo, whi)

        emsg = "table model non-contiguous evaluation failed: "
        rtol = 1e-3
        assert_allclose(evals2, wvals2, rtol=rtol,
                        err_msg=emsg + "energy to wavelength")
Example #14
0
def fit_lines(linelist, id = None, delta_lam = .2, plot = False, outfile = None):
    mymodel = filili.multilinemanager.GaussLines('const1d', id = id, baseline = baseline)
    linelist['fililiname'] = [''] * len(linelist['linename'])
    for i in range(len(linelist['linename'])):
        lname = linelist['linename'][i]
        lwave = linelist['wave'][i]
        previouslines = set(mymodel.line_name_list())
        mymodel.add_line(linename = filter(lambda x: x.isalnum(), lname), pos = lwave)
        linenamelist = mymodel.line_name_list()
        newline = (set(linenamelist) - previouslines).pop()
        linelist['fililiname'][i] = newline
        if i ==0:
            firstline = linenamelist[0]
            ui.get_model_component(firstline).pos.max = lwave + delta_lam/10.
            ui.get_model_component(firstline).pos.min = lwave - delta_lam/10.
        else:
            dl = lwave - linelist['wave'][0]
            ui.link(ui.get_model_component(newline).pos, ui.get_model_component(firstline).pos + dl)
    
    #ui.set_analysis("wave")
    ui.ignore(None, None) #ignores all data
    ui.notice(min(linelist['wave'])-delta_lam, max(linelist['wave']) + delta_lam)
    ui.fit(id)
    if plot:
        ui.plot_fit(id)
        if has_chips:
            pychips.set_curve("crv1",["err.*","true"])
            pychips.set_plot_title(linelist['name'])
            if outfile is not None:
                pychips.print_window(outfile, ['clobber','true'])
        elif has_mpl:
            plt.title(linelist['name'])
            if outfile is not None:
                plt.savefig(outfile)
        else:
            raise NoPlottingSystemError("Neither pychips nor matplotlib are found.")
Example #15
0
    def test_tablemodel_checks_input_length(self):

        # see test_table_model for more information on the table
        # model being used.
        #
        ui.load_table_model('mdl',
                            self.make_path('xspec-tablemodel-RCS.mod'))
        mdl = ui.get_model_component('mdl')

        # Check when input array is too small (< 2 elements)
        self.assertRaises(TypeError, mdl, [0.1])

        # Check when input arrays are not the same size (when the
        # low and high bin edges are given)
        self.assertRaises(TypeError, mdl, [0.1, 0.2, 0.3], [0.2, 0.3])
        self.assertRaises(TypeError, mdl, [0.1, 0.2], [0.2, 0.3, 0.4])
Example #16
0
    def _test_xspec_tablemodel_noncontiguous2(self, loadfunc):

        loadfunc('tmod', self.make_path('xspec-tablemodel-RCS.mod'))
        tmod = ui.get_model_component('tmod')

        elo, ehi, wlo, whi = make_grid_noncontig2()

        evals2 = tmod(elo, ehi)
        wvals2 = tmod(wlo, whi)

        self.assertFinite(evals2, tmod, "energy")
        self.assertFinite(wvals2, tmod, "wavelength")

        emsg = "table model non-contiguous evaluation failed: "
        rtol = 1e-3
        assert_allclose(evals2, wvals2, rtol=rtol,
                        err_msg=emsg + "energy to wavelength")
Example #17
0
    def test_xspec(self):
        """
        Perform a very simple fit with an xspec model.

        Also check that the results make sense.

        This test proves that the xspec extension properly works, and that there are no obvious building, linking, or
        environment issues that would prevent the xspec model from running.
        """
        ui.load_arrays(1, self.x, self.y)
        ui.set_source("xspowerlaw.p")
        ui.set_method("moncar")
        ui.set_stat("chi2xspecvar")
        ui.fit()
        model = ui.get_model_component("p")
        expected = [-1.3686404, 0.5687635]
        observed = [model.PhoIndex.val, model.norm.val]
        assert_almost_equal(observed, expected)
Example #18
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 #19
0
def set_parameter_from_dict(par, d, name='name', strict=True):
    '''Set Sherpa parameter from a dictionary.

    Parameters
    ----------
    par : Sherpa parameter

    d : dict

    name : string
        Can be 'name' (if the dictionary keys do not contain the model name)
        or 'fullname' (for dictionary keys like ``mymodel.pos.val``)

    strict : bool
        If ``True`` this will raise a `KeyError` if any key in the dictionary
        starts with the parameter name but there is no corresponding parameter
        property.

    Example
    -------

    >>> from sherpa.models import Polynom1D
    >>> mdl = Polynom1D('mdl')
    >>> vals = {'c0.val': 1.2, 'c0.min': 0.7, 'c2.frozen': False}
    >>> set_parameter_from_dict(mdl.c0, vals)
    >>> print mdl
    mdl
       Param        Type          Value          Min          Max      Units
       -----        ----          -----          ---          ---      -----
       mdl.c0       thawed          1.2          0.7  3.40282e+38
       mdl.c1       frozen            0 -3.40282e+38  3.40282e+38
       mdl.c2       frozen            0 -3.40282e+38  3.40282e+38
       mdl.c3       frozen            0 -3.40282e+38  3.40282e+38
       mdl.c4       frozen            0 -3.40282e+38  3.40282e+38
       mdl.c5       frozen            0 -3.40282e+38  3.40282e+38
       mdl.c6       frozen            0 -3.40282e+38  3.40282e+38
       mdl.c7       frozen            0 -3.40282e+38  3.40282e+38
       mdl.c8       frozen            0 -3.40282e+38  3.40282e+38
       mdl.offset   frozen            0 -3.40282e+38  3.40282e+38

    '''
    # dicts are mutable. Make a local copy, so the dict on the caller is unmodified.
    d = copy(d)
    for elem in ["min", "max", "val"]:
        key = getattr(par, name) + "." + elem
        if key in d:
            setattr(par, elem, d.pop(key))

    elem = "frozen"
    key = getattr(par, name) + "." + elem
    if key in d:
        setattr(par, elem, bool(int(d.pop(key))))

    elem = "link"
    key = getattr(par, name) + "." + elem
    attr = str(d.pop(key, ''))
    if attr:
        mdl, param = attr.split('.')
        param = getattr(get_model_component(mdl), param)
        setattr(par, elem, param)

    if strict:
        for k in d.keys():
            if k.startswith(getattr(par, name)):
                raise KeyError('The following key is not understood: {0} - Did you mean {1}?'.format(k, k + '.val'))
Example #20
0
    def set_source(self):
        if self.FN == 'F':
            modelstring = 'empG160M'
        elif self.FN == 'N':
            modelstring = 'tabNUV'
        else:
            raise ValueError('F - FUV/G160M, N - NUV/G285M, not recognized: {0}').format(self.FN)


        modelstring = modelstring + '(const1d.c1'
        for i, line in enumerate(self.H2lines):
            line['source'] = 'lorentz1d.h{0}'.format(i)
            modelstring = modelstring + '+ ' + line['source']
        for i, line in enumerate(self.nonH2lines):
            line['source'] = 'lorentz1d.l{0}'.format(i)
            modelstring = modelstring + '+ ' + line['source']
        modelstring = modelstring + ')'
        print modelstring
        ui.set_source(modelstring)

        # set some reasonable limits for the model parameters
        # to increase the chances of achieving a reasonable fit

        # If there is more than 1 H_2 line, we link the wavelength together
        if len(self.H2lines) > 0:
            wave_base = self.H2lines[0]['wave']
            model_base = ui.get_model_component('h0')
            set_wave(model_base, wave_base)
            model_base.fwhm = 0.07
            model_base.fwhm.min = .04
            model_base.fwhm.max = .09
            model_base.ampl.max = 1e-12
            model_base.ampl = 2e-13
            model_base.ampl.min = 0
            for i, line in enumerate(self.H2lines[1:]):
                modelcomp = ui.get_model_component('h{0}'.format(i+1))
                set_wave(modelcomp, line['wave'])
                modelcomp.pos = model_base.pos + (line['wave'] - wave_base)
                modelcomp.fwhm = 0.07
                modelcomp.fwhm.min = .04
                modelcomp.fwhm.max = .09
                modelcomp.ampl.max = 1e-12
                modelcomp.ampl = 2e-13
                modelcomp.ampl.min = 0

        for i, line in enumerate(self.nonH2lines):
            modelcomp = ui.get_model_component('l{0}'.format(i))
            set_wave(modelcomp, line['wave'])
            modelcomp.fwhm = 0.07
            modelcomp.fwhm.min = .04
            modelcomp.fwhm.max = 1.
            modelcomp.ampl.max = 5e-12
            modelcomp.ampl = 2e-13
            modelcomp.ampl.min = 0
            if line['abs']:
                # The order of these statements is important, because you cannot
                # set a value below the min.
                modelcomp.ampl.min = -2e-12
                modelcomp.ampl = -2e-13
                modelcomp.ampl.max = 0


        # If the input file specified those values, they take precedence
        # over the hard-coded default value
        for line in (self.H2lines + self.nonH2lines):
            for n in ['pos','fwhm','ampl']:
                if n in line:
                    model = ui.get_model_component(line['source'].split('.')[1])
                    _set_val(model, n, line[n])

        model = ui.get_model_component('c1')
        _set_val(model, 'c0', self.const)
Example #21
0
 def test_psf_pars_are_frozen(self):
     ui.create_model_component("beta2d", "p1")
     p1 = ui.get_model_component("p1")
     ui.load_psf('psf', p1)
     self.assertEqual([], p1.thawedpars)
Example #22
0
 def test_mod_fits(self):
     tablemodelfile = self.make_path("xspec-tablemodel-RCS.mod")
     ui.load_table_model("tmod", tablemodelfile)
     tmod = ui.get_model_component("tmod")
     self.assertEqual("xstablemodel.tmod", tmod.name)
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