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)
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)
def fit_coeffs(method='simplex'): method = method dummy_data = np.zeros(100) dummy_times = np.arange(100) ui.load_arrays(1, dummy_times, dummy_data) ui.set_method(method) ui.get_method().config.update(SHERPA_CONFIGS.get(method, {})) calc_model = CalcModel() ui.load_user_model(calc_model, 'axo_mod') # sets global axo_mod parnames = [] for row in range(N_ROWS): for col in range(N_COLS): parnames.append('adj_{}_{}'.format(row, col)) ui.add_user_pars('axo_mod', parnames) ui.set_model(1, 'axo_mod') calc_stat = CalcStat(axo_mod, M_2d, displ_x) ui.load_user_stat('axo_stat', calc_stat, lambda x: np.ones_like(x)) ui.set_stat(axo_stat) calc_model.set_calc_stat(calc_stat) # Set frozen, min, and max attributes for each axo_mod parameter for par in axo_mod.pars: par.val = 0.0 par.min = -5 par.max = 5 ui.fit(1) coeffs = np.array([(par.val) for pars in axo_mod.pars]) return coeffs
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 fit_coeffs(method='simplex'): method = method dummy_data = np.zeros(100) dummy_times = np.arange(100) ui.load_arrays(1, dummy_times, dummy_data) ui.set_method(method) ui.get_method().config.update(SHERPA_CONFIGS.get(method, {})) calc_model = CalcModel() ui.load_user_model(calc_model, 'axo_mod') # sets global axo_mod parnames = [] for row in range(N_ROWS): for col in range(N_COLS): parnames.append('adj_{}_{}'.format(row, col)) ui.add_user_pars('axo_mod', parnames) ui.set_model(1, 'axo_mod') calc_stat = CalcStat(axo_mod, M_2d, displ_x) ui.load_user_stat('axo_stat', calc_stat, lambda x: np.ones_like(x)) ui.set_stat(axo_stat) calc_model.set_calc_stat(calc_stat) # Set frozen, min, and max attributes for each axo_mod parameter for par in axo_mod.pars: par.val = 0.0 par.min = -5 par.max = 5 ui.fit(1) coeffs = np.array([(par.val) for pars in axo_mod.pars]) return coeffs
def match_wcs(wcs_img, sky_img, sky_ref, opt_alg='scipy'): """Adjust ``wcs_img`` (CRVAL{1,2} and CD{1,2}_{1,2}) using a rotation and linear offset so that ``coords_img`` matches ``coords_ref``. :param sky_img: list of (world_x, world_y) [aka RA, Dec] coords in input image :param sky_ref: list of reference (world_x, world_y) coords to match :param wcs_img: pywcs WCS object for input image :returns: d_ra, d_dec, d_theta """ pix_img = wcs_img.wcs_sky2pix(sky_img, 1) wcsmodel = WcsModel(wcs_img, sky_ref, pix_img) y = np.array(pix_img).flatten() if opt_alg == 'sherpa': x = np.arange(len(y)) import sherpa.astro.ui as ui ui.load_user_model(wcsmodel.calc_pix, 'wcsmod') ui.add_user_pars('wcsmod', ['d_ra', 'd_dec', 'd_theta']) wcsmod.d_ra = 0.0 wcsmod.d_dec = 0.0 wcsmod.d_theta = 0.0 ui.load_arrays(1, x, y, np.ones(len(y))) ui.set_model(1, wcsmod) ui.set_method('simplex') ui.fit() else: import scipy.optimize x0 = np.array([0.0, 0.0, 0.0]) d_ra, d_dec, d_theta = scipy.optimize.fmin(wcsmodel.calc_resid2, x0) print 'Scipy fit values:', d_ra, d_dec, d_theta return wcsmodel.wcs
def test_background(): tmpdir = tempfile.mkdtemp() curdir = os.getcwd() os.chdir(tmpdir) kT_sim = 1.0 Z_sim = 0.0 norm_sim = 4.0e-2 nH_sim = 0.04 redshift = 0.01 exp_time = (200., "ks") area = (1000., "cm**2") wcs = create_dummy_wcs() abs_model = WabsModel(nH_sim) events = EventList.create_empty_list(exp_time, area, wcs) spec_model = TableApecModel(0.05, 12.0, 5000, thermal_broad=False) spec = spec_model.return_spectrum(kT_sim, Z_sim, redshift, norm_sim) new_events = events.add_background(spec_model.ebins, spec, prng=prng, absorb_model=abs_model) new_events = ACIS_I(new_events, rebin=False, convolve_psf=False, prng=prng) new_events.write_spectrum("background_evt.pi", clobber=True) os.system("cp %s ." % new_events.parameters["ARF"]) os.system("cp %s ." % new_events.parameters["RMF"]) load_user_model(mymodel, "wapec") add_user_pars("wapec", ["nH", "kT", "metallicity", "redshift", "norm"], [0.01, 4.0, 0.2, redshift, norm_sim*0.8], parmins=[0.0, 0.1, 0.0, -20.0, 0.0], parmaxs=[10.0, 20.0, 10.0, 20.0, 1.0e9], parfrozen=[False, False, False, True, False]) load_pha("background_evt.pi") set_stat("cstat") set_method("simplex") ignore(":0.5, 8.0:") set_model("wapec") fit() set_covar_opt("sigma", 1.6) covar() res = get_covar_results() assert np.abs(res.parvals[0]-nH_sim) < res.parmaxes[0] assert np.abs(res.parvals[1]-kT_sim) < res.parmaxes[1] assert np.abs(res.parvals[2]-Z_sim) < res.parmaxes[2] assert np.abs(res.parvals[3]-norm_sim) < res.parmaxes[3] os.chdir(curdir) shutil.rmtree(tmpdir)
def test_background(): tmpdir = tempfile.mkdtemp() curdir = os.getcwd() os.chdir(tmpdir) kT_sim = 1.0 Z_sim = 0.0 norm_sim = 4.0e-2 nH_sim = 0.04 redshift = 0.01 exp_time = (200., "ks") area = (1000., "cm**2") fov = (10.0, "arcmin") prng = 24 agen = ApecGenerator(0.05, 12.0, 5000, broadening=False) spec = agen.get_spectrum(kT_sim, Z_sim, redshift, norm_sim) spec.apply_foreground_absorption(norm_sim) events = make_background(area, exp_time, fov, (30.0, 45.0), spec, prng=prng) events.write_simput_file("bkgnd", overwrite=True) instrument_simulator("bkgnd_simput.fits", "bkgnd_evt.fits", exp_time, "sq_acisi_cy19", [30.0, 45.0], overwrite=True, foreground=False, ptsrc_bkgnd=False, instr_bkgnd=False, prng=prng) write_spectrum("bkgnd_evt.fits", "background_evt.pi", overwrite=True) os.system("cp %s %s ." % (arf.filename, rmf.filename)) load_user_model(mymodel, "wapec") add_user_pars("wapec", ["nH", "kT", "metallicity", "redshift", "norm"], [0.01, 4.0, 0.2, redshift, norm_sim*0.8], parmins=[0.0, 0.1, 0.0, -20.0, 0.0], parmaxs=[10.0, 20.0, 10.0, 20.0, 1.0e9], parfrozen=[False, False, False, True, False]) load_pha("background_evt.pi") set_stat("cstat") set_method("simplex") ignore(":0.5, 8.0:") set_model("wapec") fit() res = get_fit_results() assert np.abs(res.parvals[0]-nH_sim)/nH_sim < 0.1 assert np.abs(res.parvals[1]-kT_sim)/kT_sim < 0.05 assert np.abs(res.parvals[2]-Z_sim) < 0.05 assert np.abs(res.parvals[3]-norm_sim)/norm_sim < 0.05 os.chdir(curdir) shutil.rmtree(tmpdir)
def test_point_source(): tmpdir = tempfile.mkdtemp() curdir = os.getcwd() os.chdir(tmpdir) nH_sim = 0.02 norm_sim = 1.0e-4 alpha_sim = 0.95 redshift = 0.02 exp_time = (100., "ks") area = (3000., "cm**2") spec = Spectrum.from_powerlaw(alpha_sim, redshift, norm_sim, emin=0.1, emax=11.5, nbins=2000) spec.apply_foreground_absorption(nH_sim, model="tbabs") positions = [(30.01, 45.0)] events = make_point_sources(area, exp_time, positions, (30.0, 45.0), spec, prng=prng) events.write_simput_file("ptsrc", overwrite=True) instrument_simulator("ptsrc_simput.fits", "ptsrc_evt.fits", exp_time, "sq_aciss_cy19", [30.0, 45.0], overwrite=True, foreground=False, ptsrc_bkgnd=False, instr_bkgnd=False, prng=prng) write_spectrum("ptsrc_evt.fits", "point_source_evt.pi", overwrite=True) os.system("cp %s %s ." % (arf.filename, rmf.filename)) load_user_model(mymodel, "tplaw") add_user_pars("tplaw", ["nH", "norm", "redshift", "alpha"], [0.02, norm_sim*0.8, redshift, 0.9], parmins=[0.0, 0.0, 0.0, 0.1], parmaxs=[10.0, 1.0e9, 10.0, 10.0], parfrozen=[True, False, True, False]) load_pha("point_source_evt.pi") set_stat("cstat") set_method("simplex") ignore(":0.4, 9.0:") set_model("tplaw") fit() res = get_fit_results() assert np.abs(res.parvals[0]-norm_sim)/norm_sim < 0.05 assert np.abs(res.parvals[1]-alpha_sim)/alpha_sim < 0.05 os.chdir(curdir) shutil.rmtree(tmpdir)
def test_point_source(): tmpdir = tempfile.mkdtemp() curdir = os.getcwd() os.chdir(tmpdir) nH_sim = 0.02 norm_sim = 1.0e-4 alpha_sim = 0.95 redshift = 0.02 exp_time = (100., "ks") area = (3000., "cm**2") spec = Spectrum.from_powerlaw(alpha_sim, redshift, norm_sim, emin=0.1, emax=11.5, nbins=2000) spec.apply_foreground_absorption(nH_sim, model="tbabs") positions = [(30.01, 45.0)] events = make_point_sources(area, exp_time, positions, (30.0, 45.0), spec, prng=prng) events.write_simput_file("ptsrc", overwrite=True) instrument_simulator("ptsrc_simput.fits", "ptsrc_evt.fits", exp_time, "sq_aciss_cy20", [30.0, 45.0], overwrite=True, foreground=False, ptsrc_bkgnd=False, instr_bkgnd=False, prng=prng) write_spectrum("ptsrc_evt.fits", "point_source_evt.pi", overwrite=True) os.system("cp %s %s ." % (arf.filename, rmf.filename)) load_user_model(mymodel, "tplaw") add_user_pars("tplaw", ["nH", "norm", "redshift", "alpha"], [0.02, norm_sim*0.8, redshift, 0.9], parmins=[0.0, 0.0, 0.0, 0.1], parmaxs=[10.0, 1.0e9, 10.0, 10.0], parfrozen=[True, False, True, False]) load_pha("point_source_evt.pi") set_stat("cstat") set_method("simplex") ignore(":0.4, 9.0:") set_model("tplaw") fit() res = get_fit_results() assert np.abs(res.parvals[0]-norm_sim)/norm_sim < 0.05 assert np.abs(res.parvals[1]-alpha_sim)/alpha_sim < 0.05 os.chdir(curdir) shutil.rmtree(tmpdir)
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_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_load_multi_arfsrmfs(make_data_path, clean_astro_ui): """Added in #728 to ensure cache parameter is sent along by MultiResponseSumModel (fix #717). This has since been simplified to switch from xsapec to powlaw1d as it drops the need for XSPEC and is a simpler model, so is less affected by changes in the model code. A fit of the Sherpa powerlaw-model to 3c273.pi with a single response in CIAO 4.11 (background subtracted, 0.5-7 keV) returns gamma = 1.9298, ampl = 1.73862e-4 so doubling the response should halve the amplitude but leave the gamma value the same when using two responses, as below. This is with chi2datavar. """ pha_pi = make_data_path("3c273.pi") ui.load_pha(1, pha_pi) ui.load_pha(2, pha_pi) arf = make_data_path("3c273.arf") rmf = make_data_path("3c273.rmf") ui.load_multi_arfs(1, [arf, arf], [1, 2]) ui.load_multi_arfs(2, [arf, arf], [1, 2]) ui.load_multi_rmfs(1, [rmf, rmf], [1, 2]) ui.load_multi_rmfs(2, [rmf, rmf], [1, 2]) ui.notice(0.5, 7) ui.subtract(1) ui.subtract(2) src = ui.create_model_component('powlaw1d', 'src') ui.set_model(1, src) ui.set_model(2, src) # ensure the test is repeatable by running with a known # statistic and method # ui.set_method('levmar') ui.set_stat('chi2datavar') # Really what we care about for fixing #717 is that # fit does not error out, but it's useful to know that # the fit has changed the parameter values (which were # both 1 before the fit). # ui.fit() fr = ui.get_fit_results() assert fr.succeeded assert fr.datasets == (1, 2) assert src.gamma.val == pytest.approx(1.9298, rel=1.0e-4) assert src.ampl.val == pytest.approx(1.73862e-4 / 2, rel=1.0e-4)
def fit_adjuster_set(coeffs, adj_idxs, method='simplex'): """ Find best fit parameters for an arbitrary subset of adjustors specified by the array ``adj_idxs``. The input ``coeffs`` are the best-fit adjustor coefficients for the last iteration. """ import sherpa.astro.ui as ui dummy_data = np.zeros(100) dummy_times = np.arange(100) ui.load_arrays(1, dummy_times, dummy_data) ui.set_method(method) ui.get_method().config.update(SHERPA_CONFIGS.get(method, {})) calc_model = CalcModel() ui.load_user_model(calc_model, 'axo_mod') # sets global axo_mod parnames = [] for adj_idx in adj_idxs: parnames.append('adj_{}'.format(adj_idx)) ui.add_user_pars('axo_mod', parnames) ui.set_model(1, 'axo_mod') coeffs = coeffs.copy() # Don't modify input coeffs coeffs[coeffs < 0] = 0 # Don't allow negative coeffs # Set frozen, min, and max attributes for each axo_mod parameter for adj_idx, par in zip(adj_idxs, axo_mod.pars): par.min = -1000 par.max = 1000 par.val = coeffs[adj_idx] print 'Setting {} to {}'.format(adj_idx, par.val) # Compute base adjusted displacements assuming all the fitted actuators # have zero drive level. coeffs[adj_idxs] = 0 base_adj_displ = M_2d.dot(coeffs) m_2d = M_2d[:, adj_idxs].copy() print m_2d.shape calc_stat = CalcStat(base_adj_displ, m_2d, DISPL_X) ui.load_user_stat('axo_stat', calc_stat, lambda x: np.ones_like(x)) ui.set_stat(axo_stat) calc_model.set_calc_stat(calc_stat) ui.fit(1) # Update coeffs with the values determined in fitting for adj_idx, par in zip(adj_idxs, axo_mod.pars): coeffs[adj_idx] = abs(par.val) return coeffs, ui.get_fit_results()
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_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_missmatch_arf(make_data_path): ui.load_pha(1, make_data_path("source1.pi")) ui.load_bkg(1, make_data_path("back1.pi")) ui.load_arf(1, make_data_path("arf_1024.fits")) ui.load_rmf(1, make_data_path("rmf_1024.fits")) ui.set_method('levmar') ui.set_model(ui.powlaw1d.p1 * ui.xswabs.abs1) ui.set_par('p1.ampl', 0.0001) ui.set_stat('cash') ui.fit() parvals = ui.get_fit_results().parvals assert parvals[0] == approx(1.47969, rel=1.0e-3) assert parvals[1] == approx(0.0019491, rel=1.0e-3) assert parvals[2] == approx(2.35452, rel=1.0e-3)
def wfit(dataids=None): listids = () if dataids is None: listids = sau.list_data_ids() else: listids = dataids wstat = w_statistic(listids) sau.load_user_stat("mystat", wstat, wstat.CATstat_err_LV) sau.set_stat(mystat) sau.set_method("neldermead") # set_method("moncar") sau.set_conf_opt("max_rstat", 1000) # We don't use a specific maximum reduced statistic value # since we don't expect the cstat to be anywhere near the # large number limit sau.fit(*listids) sau.conf()
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 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(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 setup_imgdata_source(): """Set the model and fit setup""" ui.set_source(ui.gauss2d.g1 + ui.const2d.c1) c1.c0 = 10 g1.fwhm = 4 g1.xpos = 4 g1.ypos = 3 g1.ampl = 100 ui.set_stat('cstat') ui.set_method("simplex") # Fit and check we are in the expected place (so this is a # pre-condition for the tests). # ui.fit() assert ui.calc_stat() == pytest.approx(362.9264257040166)
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 wfit(dataids=None): listids = () if dataids is None: listids = sau.list_data_ids() else: listids = dataids wstat = w_statistic(listids) sau.load_user_stat("mystat", wstat, wstat.CATstat_err_LV) sau.set_stat(mystat) sau.set_method("neldermead") # set_method("moncar") sau.set_conf_opt( "max_rstat", 1000) # We don't use a specific maximum reduced statistic value # since we don't expect the cstat to be anywhere near the # large number limit sau.fit(*listids) sau.conf()
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)
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)
def setup_data1d_fit(): """Create a 1D dataset for fitting a gaussian-like profile. This sets the random seed to a fixed value, so use the reset_seed fixture. """ x = np.linspace(2300, 2400, 51) cpt = ui.voigt1d('cpt') cpt.pos = 2345 cpt.fwhm_g = 20 cpt.fwhm_l = 15 cpt.ampl = 480 np.random.seed(72383) y = poisson_noise(cpt(x)) ui.load_arrays(1, x, y, ui.Data1D) ui.set_stat('leastsq') ui.set_method('simplex') ui.delete_model_component('cpt')
def plaw_fit(alpha_sim): tmpdir = tempfile.mkdtemp() curdir = os.getcwd() os.chdir(tmpdir) nH_sim = 0.02 norm_sim = 1.0e-4 redshift = 0.01 exp_time = 5.0e4 area = 40000.0 inst_name = "hdxi" spec = Spectrum.from_powerlaw(alpha_sim, redshift, norm_sim) spec.apply_foreground_absorption(nH_sim) e = spec.generate_energies(exp_time, area) pt_src = PointSourceModel(30.0, 45.0, e.size) write_photon_list("plaw_model", "plaw_model", e.flux, pt_src.ra, pt_src.dec, e, clobber=True) instrument_simulator("plaw_model_simput.fits", "plaw_model_evt.fits", exp_time, inst_name, [30.0, 45.0], astro_bkgnd=None, instr_bkgnd_scale=0.0) inst = get_instrument_from_registry(inst_name) arf = AuxiliaryResponseFile(inst["arf"]) rmf = RedistributionMatrixFile(inst["rmf"]) os.system("cp %s ." % arf.filename) os.system("cp %s ." % rmf.filename) write_spectrum("plaw_model_evt.fits", "plaw_model_evt.pha", clobber=True) load_user_model(mymodel, "wplaw") add_user_pars("wplaw", ["nH", "norm", "redshift", "alpha"], [0.01, norm_sim * 0.8, redshift, 0.9], parmins=[0.0, 0.0, 0.0, 0.1], parmaxs=[10.0, 1.0e9, 10.0, 10.0], parfrozen=[False, False, True, False]) load_pha("plaw_model_evt.pha") set_stat("cstat") set_method("simplex") ignore(":0.5, 9.0:") set_model("wplaw") fit() set_covar_opt("sigma", 1.645) covar() res = get_covar_results() assert np.abs(res.parvals[0] - nH_sim) < res.parmaxes[0] assert np.abs(res.parvals[1] - norm_sim) < res.parmaxes[1] assert np.abs(res.parvals[2] - alpha_sim) < res.parmaxes[2] os.chdir(curdir) shutil.rmtree(tmpdir)
def do_beta_model(source, v_field, em_field): tmpdir = tempfile.mkdtemp() curdir = os.getcwd() os.chdir(tmpdir) ds = source.ds A = 3000. exp_time = 1.0e5 redshift = 0.05 nH_sim = 0.02 apec_model = TableApecModel(0.1, 11.5, 20000, thermal_broad=False) abs_model = TBabsModel(nH_sim) sphere = ds.sphere("c", (0.5, "Mpc")) kT_sim = source.kT Z_sim = source.Z thermal_model = ThermalSourceModel(apec_model, Zmet=Z_sim, prng=source.prng) photons = PhotonList.from_data_source(sphere, redshift, A, exp_time, thermal_model) D_A = photons.parameters["FiducialAngularDiameterDistance"] norm_sim = sphere.quantities.total_quantity(em_field) norm_sim *= 1.0e-14 / (4 * np.pi * D_A * D_A * (1. + redshift) * (1. + redshift)) norm_sim = float(norm_sim.in_cgs()) v1, v2 = sphere.quantities.weighted_variance(v_field, em_field) sigma_sim = float(v1.in_units("km/s")) mu_sim = -float(v2.in_units("km/s")) events = photons.project_photons("z", absorb_model=abs_model, prng=source.prng) events = ACIS_I(events, rebin=False, convolve_psf=False, prng=source.prng) events.write_spectrum("beta_model_evt.pi", clobber=True) os.system("cp %s ." % events.parameters["ARF"]) os.system("cp %s ." % events.parameters["RMF"]) load_user_model(mymodel, "tbapec") add_user_pars("tbapec", ["nH", "kT", "metallicity", "redshift", "norm"], [0.01, 4.0, 0.2, redshift, norm_sim * 0.8], parmins=[0.0, 0.1, 0.0, -20.0, 0.0], parmaxs=[10.0, 20.0, 10.0, 20.0, 1.0e9], parfrozen=[False, False, False, True, False]) load_pha("beta_model_evt.pi") set_stat("cstat") set_method("simplex") ignore(":0.5, 8.0:") set_model("tbapec") fit() set_covar_opt("sigma", 1.645) covar() res = get_covar_results() assert np.abs(res.parvals[0] - nH_sim) < res.parmaxes[0] assert np.abs(res.parvals[1] - kT_sim) < res.parmaxes[1] assert np.abs(res.parvals[2] - Z_sim) < res.parmaxes[2] assert np.abs(res.parvals[3] - norm_sim) < res.parmaxes[3] os.chdir(curdir) shutil.rmtree(tmpdir)
maps["exposure"].write("analysis_3d/exposure_2D.fits", overwrite=True) fits.writeto("analysis_3d/psf_2D.fits", psf2D.data, overwrite=True) # ### Read the maps and store them in a sherpa model # # We now have the prepared files which sherpa can read. # This part of the notebook shows how to do image analysis using sherpa # In[ ]: import sherpa.astro.ui as sh sh.set_stat("cash") sh.set_method("simplex") 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)
def do_beta_model(source, v_field, em_field, axis="z", prng=None): tmpdir = tempfile.mkdtemp() curdir = os.getcwd() os.chdir(tmpdir) if prng is None: prng = source.prng ds = source.ds A = 30000. exp_time = 1.0e4 redshift = 0.05 nH_sim = 0.02 sphere = ds.sphere("c", (0.5, "Mpc")) kT_sim = source.kT Z_sim = source.Z thermal_model = ThermalSourceModel("apec", 0.1, 11.5, 20000, Zmet=Z_sim, prng=prng) photons = PhotonList.from_data_source(sphere, redshift, A, exp_time, thermal_model) D_A = photons.parameters["fid_d_a"] norm_sim = sphere.quantities.total_quantity(em_field) norm_sim *= 1.0e-14/(4*np.pi*D_A*D_A*(1.+redshift)*(1.+redshift)) norm_sim = float(norm_sim.in_cgs()) v1, v2 = sphere.quantities.weighted_variance(v_field, em_field) if isinstance(axis, string_types): if axis == "z": fac = 1.0 else: fac = 0.0 else: axis /= np.sqrt(np.dot(axis, axis)) fac = np.dot(axis, [0.0, 0.0, 1.0]) sigma_sim = fac*float(v1.in_units("km/s")) mu_sim = -fac*float(v2.in_units("km/s")) events = photons.project_photons(axis, [30.0, 45.0], absorb_model="tbabs", nH=nH_sim, prng=prng) events.write_simput_file("beta_model", overwrite=True) instrument_simulator("beta_model_simput.fits", "beta_model_evt.fits", exp_time, "mucal", [30.0, 45.0], overwrite=True, foreground=False, ptsrc_bkgnd=False, instr_bkgnd=False, prng=prng) write_spectrum("beta_model_evt.fits", "beta_model_evt.pi", overwrite=True) os.system("cp %s %s ." % (arf.filename, rmf.filename)) load_user_model(mymodel, "tbapec") add_user_pars("tbapec", ["nH", "kT", "metallicity", "redshift", "norm", "velocity"], [0.02, 4.0, 0.2, 0.04, norm_sim*0.8, 300.0], parmins=[0.0, 0.1, 0.0, -200.0, 0.0, 0.0], parmaxs=[10.0, 20.0, 10.0, 200.0, 1.0e9, 20000.0], parfrozen=[True, False, False, False, False, False]) load_pha("beta_model_evt.pi") set_stat("cstat") set_method("levmar") ignore(":0.6, 8.0:") set_model("tbapec") fit() res = get_fit_results() redshift_sim = (1.0+mu_sim/ckms)*(1.0+redshift) - 1.0 assert np.abs(res.parvals[0]-kT_sim)/kT_sim < 0.05 assert np.abs(res.parvals[1]-Z_sim)/Z_sim < 0.05 assert np.abs(res.parvals[2]-redshift_sim)/redshift_sim < 0.05 assert np.abs(res.parvals[3]-norm_sim) < 0.05 assert np.abs(res.parvals[4]-sigma_sim) < 30.0 os.chdir(curdir) shutil.rmtree(tmpdir)
# Specify Galactic absorption dep.set_par('xswabs.nh', 0.0255) dep.freeze('xswabs.nh') # Initialize abundance to 0.5 and thaw dep.set_par('xsmekal.abundanc', 0.5) dep.thaw('xsmekal.abundanc') # Set redshift dep.set_par('xsmekal.redshift', redshift) # Do the initial onion-peeling fit with # Levenberg-Marquardt optimization method # XSPEC variance with a Chi^2 fit statistic # set_method("levmar") set_stat("chi2xspecvar") dep.guess() # Display the central annulus (using Sherpa routines) set_xlog() plot_fit(0) plt.savefig('m87_ann0_guess.png') onion = dep.fit() # Display the central annulus (using Sherpa routines) plot_fit_delchi(0) plt.savefig('m87_ann0_fit.png')
def test_vapec_beta_model(): bms = BetaModelSource() tmpdir = tempfile.mkdtemp() curdir = os.getcwd() os.chdir(tmpdir) prng = 45 ds = bms.ds A = 30000. exp_time = 1.0e4 redshift = 0.05 nH_sim = 0.02 sphere = ds.sphere("c", (0.5, "Mpc")) kT_sim = bms.kT Z_sim = bms.Z O_sim = bms.O Ca_sim = bms.Ca var_elem = {"O": ("stream", "oxygen"), "Ca": ("stream", "calcium")} thermal_model = ThermalSourceModel("apec", 0.1, 11.5, 20000, var_elem=var_elem, Zmet=("gas","metallicity"), prng=prng) photons = PhotonList.from_data_source(sphere, redshift, A, exp_time, thermal_model) D_A = photons.parameters["fid_d_a"] norm_sim = sphere.quantities.total_quantity("emission_measure") norm_sim *= 1.0e-14/(4*np.pi*D_A*D_A*(1.+redshift)*(1.+redshift)) norm_sim = float(norm_sim.in_cgs()) events = photons.project_photons("z", [30.0, 45.0], absorb_model="tbabs", nH=nH_sim, prng=prng, no_shifting=True) new_events = Lynx_Calorimeter(events, prng=prng) os.system("cp %s %s ." % (arf.filename, rmf.filename)) new_events.write_channel_spectrum("var_abund_beta_model_evt.pha", overwrite=True) load_user_model(mymodel_var, "tbapec") add_user_pars("tbapec", ["nH", "kT", "abund", "redshift", "norm", "O", "Ca"], [nH_sim, 4.0, Z_sim, redshift, norm_sim*0.8, 0.3, 0.5], parmins=[0.0, 0.1, 0.0, -20.0, 0.0, 0.0, 0.0], parmaxs=[10.0, 20.0, 10.0, 20.0, 1.0e9, 10.0, 10.0], parfrozen=[True, False, True, True, False, False, False]) load_pha("var_abund_beta_model_evt.pha") set_stat("cstat") set_method("levmar") ignore(":0.6, 8.0:") set_model("tbapec") fit() res = get_fit_results() assert np.abs(res.parvals[0]-kT_sim)/kT_sim < 0.05 assert np.abs(res.parvals[1]-norm_sim)/norm_sim < 0.05 assert np.abs(res.parvals[2]-O_sim)/O_sim < 0.05 assert np.abs(res.parvals[3]-Ca_sim)/Ca_sim < 0.15 os.chdir(curdir) shutil.rmtree(tmpdir)
def plaw_fit(alpha_sim, prng=None): tmpdir = tempfile.mkdtemp() curdir = os.getcwd() os.chdir(tmpdir) bms = BetaModelSource() ds = bms.ds if prng is None: prng = bms.prng def _hard_emission(field, data): return YTQuantity( 1.0e-18, "s**-1*keV**-1") * data["density"] * data["cell_volume"] / mp ds.add_field(("gas", "hard_emission"), function=_hard_emission, units="keV**-1*s**-1") nH_sim = 0.02 A = YTQuantity(2000., "cm**2") exp_time = YTQuantity(2.0e5, "s") redshift = 0.01 sphere = ds.sphere("c", (100., "kpc")) plaw_model = PowerLawSourceModel(1.0, 0.01, 11.0, "hard_emission", alpha_sim, prng=prng) photons = PhotonList.from_data_source(sphere, redshift, A, exp_time, plaw_model) D_A = photons.parameters["fid_d_a"] dist_fac = 1.0 / (4. * np.pi * D_A * D_A * (1. + redshift)**3).in_cgs() norm_sim = float( (sphere["hard_emission"]).sum() * dist_fac.in_cgs()) * (1. + redshift) events = photons.project_photons("z", [30., 45.], absorb_model="wabs", nH=nH_sim, prng=bms.prng, no_shifting=True) events.write_simput_file("plaw", overwrite=True) instrument_simulator("plaw_simput.fits", "plaw_evt.fits", exp_time, "sq_acisi_cy19", [30.0, 45.0], overwrite=True, foreground=False, ptsrc_bkgnd=False, instr_bkgnd=False, prng=prng) write_spectrum("plaw_evt.fits", "plaw_model_evt.pi", overwrite=True) os.system("cp %s %s ." % (arf.filename, rmf.filename)) load_user_model(mymodel, "wplaw") add_user_pars("wplaw", ["nH", "norm", "redshift", "alpha"], [0.01, norm_sim * 1.1, redshift, 0.9], parmins=[0.0, 0.0, 0.0, 0.1], parmaxs=[10.0, 1.0e9, 10.0, 10.0], parfrozen=[False, False, True, False]) load_pha("plaw_model_evt.pi") set_stat("cstat") set_method("simplex") ignore(":0.6, 7.0:") set_model("wplaw") fit() res = get_fit_results() assert np.abs(res.parvals[0] - nH_sim) / nH_sim < 0.1 assert np.abs(res.parvals[1] - norm_sim) / norm_sim < 0.05 assert np.abs(res.parvals[2] - alpha_sim) / alpha_sim < 0.05 os.chdir(curdir) shutil.rmtree(tmpdir)
def test_background(): tmpdir = tempfile.mkdtemp() curdir = os.getcwd() os.chdir(tmpdir) kT_sim = 1.0 Z_sim = 0.0 norm_sim = 4.0e-2 nH_sim = 0.04 redshift = 0.01 exp_time = (200., "ks") area = (1000., "cm**2") fov = (10.0, "arcmin") prng = 24 agen = ApecGenerator(0.05, 12.0, 5000, broadening=False) spec = agen.get_spectrum(kT_sim, Z_sim, redshift, norm_sim) spec.apply_foreground_absorption(norm_sim) events = make_background(area, exp_time, fov, (30.0, 45.0), spec, prng=prng) events.write_simput_file("bkgnd", overwrite=True) instrument_simulator("bkgnd_simput.fits", "bkgnd_evt.fits", exp_time, "sq_acisi_cy19", [30.0, 45.0], overwrite=True, foreground=False, ptsrc_bkgnd=False, instr_bkgnd=False, prng=prng) write_spectrum("bkgnd_evt.fits", "background_evt.pi", overwrite=True) os.system("cp %s %s ." % (arf.filename, rmf.filename)) load_user_model(mymodel, "wapec") add_user_pars("wapec", ["nH", "kT", "metallicity", "redshift", "norm"], [0.01, 4.0, 0.2, redshift, norm_sim * 0.8], parmins=[0.0, 0.1, 0.0, -20.0, 0.0], parmaxs=[10.0, 20.0, 10.0, 20.0, 1.0e9], parfrozen=[False, False, False, True, False]) load_pha("background_evt.pi") set_stat("cstat") set_method("simplex") ignore(":0.5, 8.0:") set_model("wapec") fit() res = get_fit_results() assert np.abs(res.parvals[0] - nH_sim) / nH_sim < 0.1 assert np.abs(res.parvals[1] - kT_sim) / kT_sim < 0.05 assert np.abs(res.parvals[2] - Z_sim) < 0.05 assert np.abs(res.parvals[3] - norm_sim) / norm_sim < 0.05 os.chdir(curdir) shutil.rmtree(tmpdir)
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, )
# fit_logger.info('Fit statistic: {:.20f} {}'.format(fit_stat, self.parvals)) if self.min_fit_stat is None or fit_stat < self.min_fit_stat: self.min_fit_stat = fit_stat self.min_parvals = self.parvals return fit_stat, np.ones_like(self.displ) # def fit(method='levmar'): method = "simplex" dummy_data = np.zeros(100) dummy_times = np.arange(100) ui.load_arrays(1, dummy_times, dummy_data) ui.set_method(method) ui.get_method().config.update(SHERPA_CONFIGS.get(method, {})) calc_model = CalcModel() ui.load_user_model(calc_model, "axo_mod") # sets global axo_mod parnames = [] for row in range(N_ROWS): for col in range(N_COLS): parnames.append("adj_{}_{}".format(row, col)) ui.add_user_pars("axo_mod", parnames) ui.set_model(1, "axo_mod") calc_stat = CalcStat(axo_mod, M_2d, displ_x) ui.load_user_stat("axo_stat", calc_stat, lambda x: np.ones_like(x)) ui.set_stat(axo_stat)
maps["exposure"].write("analysis_3d/exposure_2D.fits", overwrite=True) fits.writeto("analysis_3d/psf_2D.fits", psf2D.data, overwrite=True) # ## 2. Analysis using sherpha # # ### Read the maps and store them in a sherpa model # # We now have the prepared files which sherpa can read. # This part of the notebook shows how to do image analysis using sherpa # In[ ]: import sherpa.astro.ui as sh sh.set_stat("cash") sh.set_method("simplex") 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") # To speed up this tutorial, we change the fit optimazation method to Levenberg-Marquardt and fix a required tolerance. This can make the fitting less robust, and in practise, you can skip this step unless you understand what is going on. # In[ ]: sh.set_method("levmar") sh.set_method_opt("xtol", 1e-5) sh.set_method_opt("ftol", 1e-5)
# pure python verstion of single_gaussian_component_model.ipynb because this is faster import sherpa.astro.ui as shp import utils shp.set_stat('cash') shp.set_method('simplex') shp.set_method_opt('verbose', 1) utils.setup('numosaic_fin_combined_40-50keV.img') utils.load_components('40-50 keV/bg 150-212.5.model') # CHXE model shp.set_full_model(psf(shp.gauss2d.chxe * emap) + bg * emap) # inner radii chosen for r in [20, 24, 28, 32]: # from KP15, (ra, dec) = (266.4172 deg, -29.00716 deg) # systematic shifting error = 6" = 2.4 px # ellip = .52 # 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())
## set_bkg_full_model(bkg_model) ## Define source models abs1 = ui.xsphabs.abs1 pow1 = ui.powlaw1d.pow1 src_model1 = abs1 * pow1 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:
def test_point_source(): tmpdir = tempfile.mkdtemp() curdir = os.getcwd() os.chdir(tmpdir) nH_sim = 0.02 norm_sim = 1.0e-4 alpha_sim = 0.95 redshift = 0.02 exp_time = (100., "ks") area = (3000., "cm**2") wcs = create_dummy_wcs() ebins = np.linspace(0.1, 11.5, 2001) emid = 0.5*(ebins[1:]+ebins[:-1]) spec = norm_sim*(emid*(1.0+redshift))**(-alpha_sim) de = np.diff(ebins)[0] abs_model = TBabsModel(nH_sim) events = EventList.create_empty_list(exp_time, area, wcs) positions = [(30.01, 45.0)] new_events = events.add_point_sources(positions, ebins, spec, prng=prng, absorb_model=abs_model) new_events = ACIS_S(new_events, prng=prng) scalex = float(np.std(new_events['xpix'])*sigma_to_fwhm*new_events.parameters["dtheta"]) scaley = float(np.std(new_events['ypix'])*sigma_to_fwhm*new_events.parameters["dtheta"]) psf_scale = ACIS_S.psf_scale assert (scalex - psf_scale)/psf_scale < 0.01 assert (scaley - psf_scale)/psf_scale < 0.01 new_events.write_spectrum("point_source_evt.pi", clobber=True) os.system("cp %s ." % new_events.parameters["ARF"]) os.system("cp %s ." % new_events.parameters["RMF"]) load_user_model(mymodel, "tplaw") add_user_pars("tplaw", ["nH", "norm", "redshift", "alpha"], [0.01, norm_sim*0.8, redshift, 0.9], parmins=[0.0, 0.0, 0.0, 0.1], parmaxs=[10.0, 1.0e9, 10.0, 10.0], parfrozen=[False, False, True, False]) load_pha("point_source_evt.pi") set_stat("cstat") set_method("simplex") ignore(":0.5, 9.0:") set_model("tplaw") fit() set_covar_opt("sigma", 1.6) covar() res = get_covar_results() assert np.abs(res.parvals[0]-nH_sim) < res.parmaxes[0] assert np.abs(res.parvals[1]-norm_sim/de) < res.parmaxes[1] assert np.abs(res.parvals[2]-alpha_sim) < res.parmaxes[2] os.chdir(curdir) shutil.rmtree(tmpdir)
def test_341(): """ The original reporter of bug #341 had a special implementation that should be captured by this test. The implementation has a proxy model that takes care of updating the actual model when it is evaluated. During a recent refactoring of the Stat and Fit code (PR #287) a regression was introduced by short-circuiting the evaluation of the model. """ class ExampleModel(object): """ Class to define model """ def __init__(self, x, y): self.x = np.array(x) self.y = np.array(y) self.parvals = [1, 2] self.parnames = ("m", "b") def calc_stat(self): return float(np.sum(np.abs(self.y - self.model()))) def model(self): return self.parvals[0] * self.x + self.parvals[1] class CalcModel(object): """ Class to update model parameters """ def __init__(self, model): self.model = model def __call__(self, pars, x): self.model.parvals = pars return np.ones_like(x) class CalcStat(object): """ Class to determine fit statistic """ def __init__(self, model): self.model = model def __call__(self, _data, _model, *args, **kwargs): fit_stat = self.model.calc_stat() return fit_stat, np.ones(1) xdata = [1, 2, 3] ydata = [4, 5, 6] newmodel = ExampleModel(xdata, ydata) dummy_data = np.zeros(1) dummy_times = np.arange(1) ui.load_arrays(1, dummy_times, dummy_data) method = 'simplex' ui.set_method(method) ui.load_user_model(CalcModel(newmodel), 'simplemodel') ui.add_user_pars('simplemodel', newmodel.parnames) ui.set_model(1, 'simplemodel') calc_stat = CalcStat(newmodel) ui.load_user_stat('customstat', calc_stat, lambda x: np.ones_like(x)) ui.set_stat(eval('customstat')) ui.fit(1) assert ui.get_par("simplemodel.m").val == approx(1, abs=0.00001) assert ui.get_par("simplemodel.b").val == approx(3, abs=0.00001)