def test_pha1_reg_proj(clean_astro_ui, basic_pha1): """This is potentially a time-consuming test to run, so simplify as much as possible. """ from matplotlib import pyplot as plt pl = ui.get_model_component("pl") ui.set_source(ui.xsphabs.gal * pl) gal = ui.get_model_component("gal") ui.fit() ui.reg_proj("pl.gamma", "gal.nh", min=(1.6, 0), max=(2.5, 0.2), nloop=(3, 3)) ax = plt.gca() assert ax.get_xscale() == 'linear' assert ax.get_yscale() == 'linear' assert ax.get_xlabel() == 'pl.gamma' assert ax.get_ylabel() == 'gal.nH' assert ax.get_title() == 'Region-Projection' xmin, xmax = ax.get_xlim() assert xmin == pytest.approx(1.6) assert xmax == pytest.approx(2.5) ymin, ymax = ax.get_ylim() assert ymin == pytest.approx(0.0) assert ymax == pytest.approx(0.2) assert len(ax.lines) == 1 line = ax.lines[0] assert line.get_xdata().size == 1 x0 = line.get_xdata()[0] y0 = line.get_ydata()[0] assert x0 == pytest.approx(pl.gamma.val) assert y0 == pytest.approx(gal.nh.val) # pylab get_confid_point_defaults() returns # {'symbol': '+', 'color': None} # assert line.get_marker() == '+' # the number depends on the matplotlib version: 2 for 2.2.3 and # 3 for 3.1.1; it's not clear what the "extra" one is in matplotlib 3 # (it isn't obviously visible). DJB guesses that this would be # clearer if we ran with more bins along each axis, but this would # take more time. # ncontours = len(ax.collections) assert ncontours in [2, 3]
def setup_model(make_data_path): """Set up a model that is reasonably close to the data. Returns the expected statistic values for various filters. """ infile = make_data_path('q1127_src1_grp30.pi') ui.clean() ui.load_pha(infile) ui.subtract() ui.set_stat('chi2datavar') ui.set_source(ui.powlaw1d.pl) pl = ui.get_model_component('pl') pl.ampl = 5.28e-4 pl.gamma = 1.04 # These statistic values were created using CIAO 4.9 on a # Ubuntu machine. The quality=2 values are for high energies # (above ~ 10 keV or so), and so a filter of 0.5-8.0 keV should # give the same answer with or without ignore_bad. # return { 'all': 2716.7086246284807, 'bad': 2716.682482792285, '0.5-8.0': 1127.7165108405597 }
def example_model(): """Create an example model.""" ui.create_model_component('const1d', 'cpt') cpt = ui.get_model_component('cpt') cpt.c0 = 1.02e2 return cpt
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')
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)
def test_xspec_xstablemodel(loadfunc, clean_astro_ui, make_data_path): # 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', make_data_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') assert 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) assert_is_finite(evals1, tmod, "energy") assert_is_finite(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")
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")
def test_xstablemodel_checks_input_length(loadfunc, clean_astro_ui, make_data_path): loadfunc('mdl', make_data_path('xspec-tablemodel-RCS.mod')) mdl = ui.get_model_component('mdl') # Check when input array is too small (< 2 elements) with pytest.raises(TypeError) as exc1: mdl([0.1], [0.2]) emsg = "input array must have at least 2 elements, found 1" assert str(exc1.value) == emsg # Check when input arrays are not the same size (when the # low and high bin edges are given) with pytest.raises(TypeError) as exc2: mdl([0.1, 0.2, 0.3], [0.2, 0.3]) emsg = "input arrays are not the same size: 3 and 2" assert str(exc2.value) == emsg with pytest.raises(TypeError) as exc3: mdl([0.1, 0.2], [0.2, 0.3, 0.4]) emsg = "input arrays are not the same size: 2 and 3" assert str(exc3.value) == emsg
def _test_can_evaluate_thcompc(): """Does this redistribute some emission? It does not test the result is actualy meaningful, but does check it's done something """ ui.clean() ui.dataspace1d(0.1, 10, 0.01, id='unconv') ui.dataspace1d(0.1, 10, 0.01, id='conv') mconv = ui.create_model_component('xsthcompc', 'conv') ui.set_source('conv', mconv(ui.xsgaussian.m1)) m1 = ui.get_model_component('m1') ui.set_source('unconv', m1) m1.lineE = 5.0 m1.Sigma = 1.0 yunconv = ui.get_model_plot('unconv').y.copy() yconv = ui.get_model_plot('conv').y.copy() assert (yunconv > 0).any() assert (yconv > 0).any() # not guaranteed the peak will be reduced (depends on what # the convolution is doing), and I would hope that flux # is at best conserved (ie not created), and that we don't # have to worry about numerical artifacts here. # assert yunconv.max() > yconv.max() assert yunconv.sum() >= yconv.sum()
def test_psf_model2d(model, clean_astro_ui): ui.dataspace2d([216, 261]) ui.load_psf('psf2d', model + '.mdl') ui.set_psf('psf2d') mdl = ui.get_model_component('mdl') assert (numpy.array(mdl.get_center()) == numpy.array([108, 130])).all()
def test_xpec_tablemodel_outofbound(clean_astro_ui, make_data_path): ui.load_xstable_model('tmod', make_data_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') with pytest.raises(ParameterErr) as e: tmod.calc([0., .2, 1., 1.], numpy.arange(1, 5)) assert 'minimum' in str(e)
def example_bkg_model(): """Create an example background model.""" ui.create_model_component('powlaw1d', 'bcpt') bcpt = ui.get_model_component('bcpt') bcpt.gamma = 0.0 # use a flat model to make it easy to evaluate bcpt.ampl = 1e-1 return bcpt
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)
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)
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
def basic_pha1(make_data_path): """Create a basic PHA-1 data set/setup""" ui.set_default_id('tst') ui.load_pha(make_data_path('3c273.pi')) ui.subtract() ui.notice(0.5, 7) ui.set_source(ui.powlaw1d.pl) pl = ui.get_model_component('pl') pl.gamma = 1.93 pl.ampl = 1.74e-4
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
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
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
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()
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])
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") assert_almost_equal(model.c0.val, 0) assert_almost_equal(model.c1.val, 1)
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
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
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)
def test_xspec_xstablemodel_noncontiguous2(loadfunc, clean_astro_ui, make_data_path): loadfunc('tmod', make_data_path('xspec-tablemodel-RCS.mod')) tmod = ui.get_model_component('tmod') elo, ehi, wlo, whi = make_grid_noncontig2() evals = tmod(elo, ehi) wvals = tmod(wlo, whi) assert_is_finite(evals, tmod, "energy") assert_is_finite(wvals, tmod, "wavelength") assert wvals == pytest.approx(evals) assert (wvals > 0).all()
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")
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])
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.")
def test_numpy_histogram_density_vs_normed(): from sherpa.astro import ui ui.load_arrays(1, [1, 2, 3], [1, 2, 3]) ui.set_source('const1d.c') c = ui.get_model_component('c') ui.fit() res = ui.eqwidth(c, c+c, error=True) ui.plot_pdf(res[4]) plot = ui.get_pdf_plot() expected_x = numpy.linspace(2.5, 3.5, 13) expected_xlo, expected_xhi = expected_x[:-1], expected_x[1:] expected_y = [0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0] assert plot.y == pytest.approx(expected_y) assert plot.xlo == pytest.approx(expected_xlo) assert plot.xhi == pytest.approx(expected_xhi)
def test_xstablemodel_checks_input_length(loadfunc, clean_astro_ui, make_data_path): loadfunc('mdl', make_data_path('xspec-tablemodel-RCS.mod')) mdl = ui.get_model_component('mdl') # Check when input array is too small (< 2 elements) with pytest.raises(TypeError): mdl([0.1]) # Check when input arrays are not the same size (when the # low and high bin edges are given) with pytest.raises(TypeError): mdl([0.1, 0.2, 0.3], [0.2, 0.3]) with pytest.raises(TypeError): mdl([0.1, 0.2], [0.2, 0.3, 0.4])
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")
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)
def save_components(filename, compIDstosave=None): if os.path.isfile(filename): raise Exception("Model already exists.") with open(filename, 'w') as f: print('Saving ' + filename) print(shp.get_model()) if compIDstosave is None: compIDstosave = [c for c in shp.list_model_components() if c not in ['emap', 'psf']] f.write('components: ' + str(len(compIDstosave)) + '\n') for compID in compIDstosave: if compID not in ['psf', 'emap']: comp = shp.get_model_component(compID) f.write(comp.name.replace('.', ' ') + ' ' + str(len(comp.pars)) + '\n') for par in comp.pars: f.write(par.name + ' ' + str(par.min) + ' ' + str(par.val) + ' ' + str(par.max) + '\n') f.close()
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.x2, self.y, ui.Data1DInt) ui.set_source("xspowerlaw.p") ui.set_method("moncar") ui.set_stat("chi2xspecvar") ui.fit() model = ui.get_model_component("p") expected = [-1.2940997851602858, 0.5969328003146177] observed = [model.PhoIndex.val, model.norm.val] assert_allclose(observed, expected, rtol=1e-6)
def test_xspec_xstablemodel_noncontiguous2(loadfunc, clean_astro_ui, make_data_path): loadfunc('tmod', make_data_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) assert_is_finite(evals2, tmod, "energy") assert_is_finite(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")
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
def test_xspec_xstablemodel(loadfunc, clean_astro_ui, make_data_path): # 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', make_data_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') assert tmod.name == 'xstablemodel.tmod' elo, ehi, wlo, whi = make_grid() evals = tmod(elo, ehi) wvals = tmod(wlo, whi) assert_is_finite(evals, tmod, "energy") assert_is_finite(wvals, tmod, "wavelength") assert wvals == pytest.approx(evals)
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'))
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
def test_psf_pars_are_frozen(clean_astro_ui): "bug #12503" ui.create_model_component("beta2d", "p1") p1 = ui.get_model_component("p1") ui.load_psf('psf', p1) assert p1.thawedpars == []
def test_psf_model1d(model, center, clean_astro_ui): ui.dataspace1d(1, 10) ui.load_psf('psf1d', model + '.mdl') ui.set_psf('psf1d') mdl = ui.get_model_component('mdl') assert mdl.get_center() == (center, )
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)
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)