def test_arf1d_no_pha_zero_energy_bin_replace(): "What happens when the first bin starts at 0, with replacement" ethresh = 1e-5 exposure = 0.1 egrid = np.asarray([0.0, 0.1, 0.2, 0.4, 0.5, 0.7, 0.8]) elo = egrid[:-1] ehi = egrid[1:] specresp = np.asarray([10.2, 9.8, 10.0, 12.0, 8.0, 10.0]) with warnings.catch_warnings(record=True) as ws: warnings.simplefilter("always") adata = create_arf(elo, ehi, specresp, exposure=exposure, ethresh=ethresh) validate_zero_replacement(ws, 'ARF', 'user-arf', ethresh) arf = ARF1D(adata) mdl = MyPowLaw1D() tmdl = PowLaw1D() wrapped = arf(mdl) out = wrapped([0.1, 0.2]) elo[0] = ethresh expected = exposure * specresp * tmdl(elo, ehi) assert_allclose(out, expected) assert not np.isnan(out[0])
def test_has_pha_response(): """Check the examples from the docstring""" exposure = 200.1 rdata = create_non_delta_rmf() specresp = create_non_delta_specresp() adata = create_arf(rdata.energ_lo, rdata.energ_hi, specresp, exposure=exposure) nchans = rdata.e_min.size channels = np.arange(1, nchans + 1, dtype=np.int16) counts = np.ones(nchans, dtype=np.int16) pha = DataPHA('test-pha', channel=channels, counts=counts, exposure=exposure) pha.set_arf(adata) pha.set_rmf(rdata) rsp = Response1D(pha) m1 = Gauss1D() m2 = PowLaw1D() assert not has_pha_response(m1) assert has_pha_response(rsp(m1)) assert not has_pha_response(m1 + m2) assert has_pha_response(rsp(m1 + m2)) assert has_pha_response(m1 + rsp(m2)) # reflexivity check assert has_pha_response(rsp(m1) + m2) assert has_pha_response(rsp(m1) + rsp(m2))
def test_link_parameter_evaluation(): """See also test_link_parameter_setting A version of this test, using an XSPEC table model, is found in sherpa/astro/xspec/tests/test_xspec_unit::test_xstbl_link_parameter_evaluation """ # What happens when we try to evaluate a model whose # parameter is out-of-range thanks to a link? # mdl = PowLaw1D() lmdl = Const1D() grid = arange(1, 5) mdl.gamma = lmdl.c0 lmdl.c0 = 2 y2 = mdl(grid) assert (y2 > 0).all() lmdl.c0 = 12 emsg = 'parameter powlaw1d.gamma has a maximum of 10' with pytest.raises(ParameterErr, match=emsg): mdl(grid)
def test_rmf1d_delta_no_pha_zero_energy_bin_replace(): "What happens when the first bin starts at 0, with replacement" ethresh = 1e-8 egrid = np.asarray([0.0, 0.1, 0.2, 0.4, 0.5, 0.7, 0.8]) elo = egrid[:-1] ehi = egrid[1:] with warnings.catch_warnings(record=True) as ws: warnings.simplefilter("always") rdata = create_delta_rmf(elo, ehi, ethresh=ethresh) validate_zero_replacement(ws, 'RMF', 'delta-rmf', ethresh) rmf = RMF1D(rdata) mdl = MyPowLaw1D() tmdl = PowLaw1D() wrapped = rmf(mdl) out = wrapped([0.1, 0.2]) elo[0] = ethresh expected = tmdl(elo, ehi) assert_allclose(out, expected) assert not np.isnan(out[0])
def setUp(self): self.old_level = logger.getEffectiveLevel() logger.setLevel(logging.ERROR) self.data = DataPHA('', numpy.arange(10), numpy.ones(10), bin_lo=numpy.arange(0.1, 10, 0.1), bin_hi=numpy.arange(0.2, 10.1, 0.1)) self.data.units = "energy" self.src = PowLaw1D('p1') * AbsorptionGaussian('abs1')
def test_orderplot_check_title(): """Is the title set?""" oplot = OrderPlot() pha = example_pha_data() model = PowLaw1D('example-pl') assert oplot.title == 'Model' oplot.prepare(pha, model) assert oplot.title == 'Model Orders [1]'
def test_rsp1d_delta_pha_zero_energy_bin(): "What happens when the first bin starts at 0, with replacement" ethresh = 2.0e-7 # PHA and ARF have different exposure ties exposure1 = 0.1 exposure2 = 2.4 egrid = np.asarray([0.0, 0.1, 0.2, 0.4, 0.5, 0.7, 0.8]) elo = egrid[:-1] ehi = egrid[1:] specresp = np.asarray([10.2, 9.8, 10.0, 12.0, 8.0, 10.0]) with warnings.catch_warnings(record=True) as ws: warnings.simplefilter("always") adata = create_arf(elo, ehi, specresp, exposure=exposure1, ethresh=ethresh) validate_zero_replacement(ws, 'ARF', 'user-arf', ethresh) with warnings.catch_warnings(record=True) as ws: warnings.simplefilter("always") rdata = create_delta_rmf(elo, ehi, ethresh=ethresh) validate_zero_replacement(ws, 'RMF', 'delta-rmf', ethresh) channels = np.arange(1, 7, dtype=np.int16) counts = np.ones(6, dtype=np.int16) pha = DataPHA('test-pha', channel=channels, counts=counts, exposure=exposure2) pha.set_rmf(rdata) pha.set_arf(adata) pha.set_analysis('energy') mdl = MyPowLaw1D() tmdl = PowLaw1D() wrapped = RSPModelPHA(adata, rdata, pha, mdl) out = wrapped([0.1, 0.2]) elo[0] = ethresh expected = specresp * tmdl(elo, ehi) assert_allclose(out, expected) assert not np.isnan(out[0])
def test_arf1d_pha_zero_energy_bin(): "What happens when the first bin starts at 0, with replacement" ethresh = 1.0e-10 # Note: the two exposures are different to check which is # used (the answer is neither, which seems surprising) # exposure1 = 0.1 egrid = np.asarray([0.0, 0.1, 0.2, 0.4, 0.5, 0.7, 0.8]) elo = egrid[:-1] ehi = egrid[1:] specresp = np.asarray([10.2, 9.8, 10.0, 12.0, 8.0, 10.0]) with warnings.catch_warnings(record=True) as ws: warnings.simplefilter("always") adata = create_arf(elo, ehi, specresp, exposure=exposure1, ethresh=ethresh) validate_zero_replacement(ws, 'ARF', 'user-arf', ethresh) arf = ARF1D(adata) exposure2 = 2.4 channels = np.arange(1, 7, dtype=np.int16) counts = np.ones(6, dtype=np.int16) pha = DataPHA('test-pha', channel=channels, counts=counts, exposure=exposure2) pha.set_arf(adata) pha.set_analysis('energy') mdl = MyPowLaw1D() tmdl = PowLaw1D() wrapped = ARFModelPHA(arf, pha, mdl) out = wrapped([0.1, 0.2]) elo[0] = ethresh expected = specresp * tmdl(elo, ehi) assert_allclose(out, expected) assert not np.isnan(out[0])
def setUp(self): self._old_logger_level = logger.getEffectiveLevel() logger.setLevel(logging.ERROR) ui.clean() self.ascii = self.make_path('sim.poisson.1.dat') self.wrong_stat_msg = "Fit statistic must be cash, cstat or wstat, not {}" self.wstat_err_msg = "No background data has been supplied. Use cstat" self.no_covar_msg = "covariance has not been performed" self.fail_msg = "Call should not have succeeded" self.right_stats = {'cash', 'cstat', 'wstat'} self.model = PowLaw1D("p1") ui.load_data(self.ascii) ui.set_model(self.model)
def test_cflux_calc_sherpa(): """Test the CFLUX convolution model calculations (sherpa model) This is a test of the convolution interface, as the results of the convolution can be easily checked. The model being convolved is a Sherpa model. See Also -------- test_cflux_calc_xspec """ mdl = PowLaw1D('sherpa') mdl.gamma = 1.7 mdl.ampl = 0.025 _test_cflux_calc(mdl, mdl.gamma.val, mdl.ampl.val)
def test_cflux_nbins(): """Check that the number of bins created by cflux is correct. The test_cflux_calc_xxx routines do include a test of the number of bins, but that is just for a Data1DInt dataset, so the model only ever gets called with explicit lo and hi edges. This test calls the model directly to check both 1 and 2 argument variants. Notes ----- There's no check of a non-contiguous grid. """ from sherpa.astro import xspec spl = PowLaw1D('sherpa') xpl = xspec.XSpowerlaw('xspec') spl.gamma = 0.7 xpl.phoindex = 0.7 egrid = np.arange(0.1, 2, 0.01) elo = egrid[:-1] ehi = egrid[1:] nbins = elo.size def check_bins(lbl, mdl): y1 = mdl(egrid) y2 = mdl(elo, ehi) assert y1.size == nbins + 1, '{}: egrid'.format(lbl) assert y2.size == nbins, '{}: elo/ehi'.format(lbl) # verify assumptions # check_bins('Sherpa model', spl) check_bins('XSPEC model', xpl) # Now try the convolved versions # cflux = xspec.XScflux("conv") check_bins('Convolved Sherpa', cflux(spl)) check_bins('Convolved XSPEC', cflux(xpl))
def test_cflux_nbins(): """Check that the number of bins created by cflux is correct. The test_cflux_calc_xxx routines do include a test of the number of bins, but that is just for a Data1DInt dataset, so the model only ever gets called with explicit lo and hi edges. Now that we no-longer support evaluating the model with a single grid this test may not add much power, but leave in for now. Notes ----- There's no check of a non-contiguous grid. """ from sherpa.astro import xspec spl = PowLaw1D('sherpa') xpl = xspec.XSpowerlaw('xspec') spl.gamma = 0.7 xpl.phoindex = 0.7 egrid = np.arange(0.1, 2, 0.01) elo = egrid[:-1] ehi = egrid[1:] nbins = elo.size def check_bins(lbl, mdl): y = mdl(elo, ehi) assert y.size == nbins, f'{lbl}: elo/ehi' # verify assumptions # check_bins('Sherpa model', spl) check_bins('XSPEC model', xpl) # Now try the convolved versions # cflux = xspec.XScflux("conv") check_bins('Convolved Sherpa', cflux(spl)) check_bins('Convolved XSPEC', cflux(xpl))
def test_link_parameter_setting(): """See https://github.com/sherpa/sherpa/issues/742 See also test_link_parameter_evaluation. """ mdl = PowLaw1D() lmdl = Const1D() # check we have the -10/10 range for the gamma # (so that if this changes we know to change this test) # assert mdl.gamma.min == pytest.approx(-10) assert mdl.gamma.max == pytest.approx(10) # Just check we can link the parameter lmdl.c0 = 2 mdl.gamma = lmdl.c0 assert mdl.gamma.val == pytest.approx(2) lmdl.c0 = 3 assert mdl.gamma.val == pytest.approx(3) # What happens when we set lmdl.c0 to a value outside # the valid range for mdl? # # The error is raised when we try to access the value # of the parameter with the link, and *not* when we set # the parameter that is linked to. # lmdl.c0 = 23 emsg = 'parameter powlaw1d.gamma has a maximum of 10' with pytest.raises(ParameterErr, match=emsg): mdl.gamma.val lmdl.c0 = -23 emsg = 'parameter powlaw1d.gamma has a minimum of -10' with pytest.raises(ParameterErr, match=emsg): mdl.gamma.val lmdl.c0 = -2 assert mdl.gamma.val == pytest.approx(-2)
def test_orderplot_checks_colors_explicit_orders(orders): """Check we raise a PlotErr. We check both the default orders setting (None) and an explicit setting as, when writing this test, I found an error in the handling of the None case. """ oplot = OrderPlot() pha = example_pha_data() model = PowLaw1D('example-pl') with pytest.raises(PlotErr) as pe: oplot.prepare(pha, model, orders=orders, colors=['green', 'orange']) assert str( pe.value ) == "orders list length '1' does not match colors list length '2'"
def test_regrid1d_int_flux(): """Check integration models using an XSPEC-style c[p]flux model. """ gamma = 1.7 pmdl = PowLaw1D() pmdl.gamma = gamma fluxmdl = ReNormalizerKernel1DInt() fluxmdl.flux = 20.0 fluxmdl.lo = 10.0 fluxmdl.hi = 20 grid = np.arange(1.0, 9.0, 0.01) glo = grid[:-1] ghi = grid[1:] mdl = fluxmdl(pmdl) regrid = ModelDomainRegridder1D() rmdl = regrid.apply_to(mdl) # ensure it covers the 10 - 20 range as well as 1-9. Pick # a smaller grid size than the output grid. # xfull = np.arange(0, 22, 0.005) regrid.grid = xfull[:-1], xfull[1:] y_regrid = rmdl(glo, ghi) assert y_regrid.shape == glo.shape # Model flux in lo/hi range is int_lo^hi x^-gamma dx (since norm # and reference of the power law are both 1.0). This is, since # gamma is not 1, [x^(1-gamma)]^hi_lo / (1 - gamma). # term = 1.0 - gamma renorm = (20**term - 10**term) / term y_expected = pmdl(glo, ghi) * 20 / renorm assert_allclose(y_regrid, y_expected, atol=1e-10, rtol=0)
def test_cflux_settings(): """Do the expected things happen when a model is calculated?""" from sherpa.astro import xspec kern = xspec.XScflux('cflux') assert isinstance(kern, xspec.XSConvolutionKernel), \ "cflux creates XSConvolutionKernel" cfluxpars = [('Emin', 0.5, True, 'keV'), ('Emax', 10.0, True, 'keV'), ('lg10Flux', -12, False, 'cgs')] _check_pars('cflux', kern, cfluxpars) mdl = kern(PowLaw1D('pl')) assert isinstance(mdl, xspec.XSConvolutionModel), \ "cflux(mdl) creates XSConvolutionModel" plpars = [('gamma', 1.0, False, ''), ('ref', 1.0, True, ''), ('ampl', 1.0, False, '')] _check_pars('model', mdl, cfluxpars + plpars)
def test_rmf1d_delta_pha_zero_energy_bin(): "What happens when the first bin starts at 0, with replacement" ethresh = 2e-7 egrid = np.asarray([0.0, 0.1, 0.2, 0.4, 0.5, 0.7, 0.8]) elo = egrid[:-1] ehi = egrid[1:] with warnings.catch_warnings(record=True) as ws: warnings.simplefilter("always") rdata = create_delta_rmf(elo, ehi, ethresh=ethresh) validate_zero_replacement(ws, 'RMF', 'delta-rmf', ethresh) exposure = 2.4 channels = np.arange(1, 7, dtype=np.int16) counts = np.ones(6, dtype=np.int16) pha = DataPHA('test-pha', channel=channels, counts=counts, exposure=exposure) pha.set_rmf(rdata) pha.set_analysis('energy') mdl = MyPowLaw1D() tmdl = PowLaw1D() wrapped = RMFModelPHA(rdata, pha, mdl) out = wrapped([0.1, 0.2]) elo[0] = ethresh expected = tmdl(elo, ehi) assert_allclose(out, expected) assert not np.isnan(out[0])
def test_rsp1d_delta_no_pha_zero_energy_bin(): "What happens when the first bin starts at 0, with replacement" ethresh = 1.0e-9 exposure = 0.1 egrid = np.asarray([0.0, 0.1, 0.2, 0.4, 0.5, 0.7, 0.8]) elo = egrid[:-1] ehi = egrid[1:] specresp = np.asarray([10.2, 9.8, 10.0, 12.0, 8.0, 10.0]) with warnings.catch_warnings(record=True) as ws: warnings.simplefilter("always") adata = create_arf(elo, ehi, specresp, exposure=exposure, ethresh=ethresh) validate_zero_replacement(ws, 'ARF', 'test-arf', ethresh) with warnings.catch_warnings(record=True) as ws: warnings.simplefilter("always") rdata = create_delta_rmf(elo, ehi, ethresh=ethresh) validate_zero_replacement(ws, 'RMF', 'delta-rmf', ethresh) mdl = MyPowLaw1D() tmdl = PowLaw1D() wrapped = RSPModelNoPHA(adata, rdata, mdl) out = wrapped([0.1, 0.2]) elo[0] = ethresh expected = specresp * tmdl(elo, ehi) assert_allclose(out, expected) assert not np.isnan(out[0])
def savefig(name): outfile = os.path.join(savedir, name) plt.savefig(outfile) print("# Created: {}".format(name)) os.chdir('../../../../sherpa-test-data/sherpatest/') from sherpa.astro.io import read_arf, read_rmf arf = read_arf('3c273.arf') rmf = read_rmf('3c273.rmf') dump("rmf.detchans") from sherpa.models.basic import PowLaw1D mdl = PowLaw1D() from sherpa.astro.instrument import RSPModelNoPHA inst = RSPModelNoPHA(arf, rmf, mdl) dump("inst") report("inst") from sherpa.models.model import ArithmeticModel dump("isinstance(inst, ArithmeticModel)") dump("inst.pars") dump("inst(np.arange(1, 1025))") dump("inst([0.1, 0.2, 0.3])") dump("inst([0.1, 0.2, 0.3]).size") dump("inst([10, 20]) == inst([])")
y = pha.get_y(filter=True) dplot.plot(xlog=True, ylog=True) plt.plot(x, y) savefig('pha_data_compare.png') pha.set_analysis('wave') dump("pha.get_x().max()") wplot = DataPlot() wplot.prepare(pha) wplot.plot() savefig('pha_data_wave.png') pha.set_analysis('energy') from sherpa.models.basic import PowLaw1D from sherpa.astro.xspec import XSphabs pl = PowLaw1D() gal = XSphabs() mdl = gal * pl pl.gamma = 1.7 gal.nh = 0.2 report("mdl") egrid = np.arange(0.1, 10, 0.01) elo, ehi = egrid[:-1], egrid[1:] emid = (elo + ehi) / 2 plt.clf() plt.plot(emid, mdl(elo, ehi), label='Absorbed') plt.plot(emid, pl(elo, ehi), ':', label='Unabsorbed') plt.xscale('log')
def calc(self, pars, *args, **kwargs): out = PowLaw1D.calc(self, pars, *args, **kwargs) if args[0][0] <= 0.0: out[0] = np.nan return out
def calc(self, pars, *args, **kwargs): out = PowLaw1D.calc(self, pars, *args, **kwargs) if args[0][0] <= 0.0: out[0] = np.nan return out
def setup_covar(make_data_path): print("A") ui.load_data(make_data_path('sim.poisson.1.dat')) ui.set_model(PowLaw1D("p1"))