def test_rmfmodelnopha_matrix_call(): "What happens calling an rmf (matrix) with no pha?" rdata = create_non_delta_rmf() # Do not use a flat model as it is not as useful a check # that the RMF is doing its job. # constant = 2.3 slope = -0.1 mdl = Polynom1D('mdl') mdl.c0 = constant mdl.c1 = slope wrapped = RMFModelNoPHA(rdata, mdl) # Calculate the model analytically. # modvals = mdl(rdata.energ_lo, rdata.energ_hi) matrix = get_non_delta_matrix() expected = np.matmul(modvals, matrix) out = wrapped([4, 5]) assert_allclose(out, expected) # the RMF convolution shouldn't lose flux, although # given the previous check it's not clear if this really # adds any extra confidence. # assert out.sum() == pytest.approx(modvals.sum())
def test_evaluate_cache1dint(): """Check we run with cacheing on: 1dint""" xgrid = numpy.arange(2, 10, 1.5) xlo, xhi = xgrid[:-1], xgrid[1:] mdl = Polynom1D() mdl._use_caching = True assert len(mdl._cache) == 0 # Check the default values expected = numpy.ones(5) * 1.5 assert mdl(xlo, xhi) == pytest.approx(expected) check_cache(mdl, expected, xlo, xhi) mdl.c0 = 5 mdl.c1 = 2 def xval(x): return 5 + 2 * x dx = xhi - xlo ylo = xval(xlo) yhi = xval(xhi) expected = dx * (yhi + ylo) / 2 assert mdl(xlo, xhi) == pytest.approx(expected) check_cache(mdl, expected, xlo, xhi)
def test_cache_clear_single(caplog): """Check cache_clear for a single model.""" p = Polynom1D() # There's no official API for accessing the cache data, # so do it directly. # assert len(p._cache) == 0 assert p._cache_ctr['check'] == 0 assert p._cache_ctr['hits'] == 0 assert p._cache_ctr['misses'] == 0 p([1, 2, 3]) p([1, 2, 3]) p([1, 2, 3, 4]) assert len(p._cache) == 1 assert p._cache_ctr['check'] == 3 assert p._cache_ctr['hits'] == 1 assert p._cache_ctr['misses'] == 2 p.cache_clear() assert len(p._cache) == 0 assert p._cache_ctr['check'] == 0 assert p._cache_ctr['hits'] == 0 assert p._cache_ctr['misses'] == 0
def test_rspmodelnopha_matrix_call(): "What happens calling an RMF (matrix)+ARF with no pha?" rdata = create_non_delta_rmf() exposure = 200.1 specresp = np.asarray([ 200.0, 100.0, 0.0, 175.0, 300.0, 400.0, 350.0, 200.0, 250.0, 300.0, 200.0, 100.0, 100.0, 150.0, 175.0, 125.0, 100.0, 90.0, 80.0, 0.0 ]) adata = create_arf(rdata.energ_lo, rdata.energ_hi, specresp, exposure=exposure) constant = 2.3 slope = -0.25 mdl = Polynom1D('mdl') mdl.c0 = constant mdl.c1 = slope wrapped = RSPModelNoPHA(adata, rdata, mdl) # Calculate the model analytically. Note that the exposure # value is ignored. # modvals = specresp * mdl(rdata.energ_lo, rdata.energ_hi) matrix = get_non_delta_matrix() expected = np.matmul(modvals, matrix) out = wrapped([4, 5]) assert_allclose(out, expected)
def setUp(self): # defensive programming (one of the tests has been seen to fail # when the whole test suite is run without this) ui.clean() self._old_logger_level = logger.getEffectiveLevel() logger.setLevel(logging.ERROR) self.data = Data1D('tst', self._x, self._y, self._e) self.mdl = Polynom1D('mdl')
def setUp(hide_logging): x = [-13, -5, -3, 2, 7, 12] y = np.asarray([102.3, 16.7, -0.6, -6.7, -9.9, 33.2]) err = np.ones(6) * 5 data = Data1D('tst', x, y, err) mdl = Polynom1D('mdl') return data, mdl
def test_evaluate_cache_binaryop(): """BinaryOp has no cache""" mdl = Polynom1D() assert hasattr(mdl, '_use_caching') fmdl = mdl + 2 assert isinstance(fmdl, BinaryOpModel) assert not hasattr(fmdl, '_use_caching')
def test_cache_status_multiple(caplog): """Check cache_status for a multi-component model. Unlike test_cache_syayus_single we also have evaluated the model so we can check that the cache status has changed. """ # The model expression includes an ArithmeticConstant model (the # term 2) which does not have a cache and so is ignored by # cache_status. # p = Polynom1D() b = Box1D() c = Const1D() mdl = c * (2 * p + b) # One model is not cached b._use_caching = False mdl([0.1, 0.2, 0.3]) mdl([0.1, 0.2, 0.3]) mdl([0.1, 0.2, 0.3, 0.4]) with caplog.at_level(logging.INFO, logger='sherpa'): mdl.cache_status() assert len(caplog.records) == 3 tokens = [] for lname, lvl, msg in caplog.record_tuples: assert lname == 'sherpa.models.model' assert lvl == logging.INFO toks = msg.split() assert len(toks) == 9 assert toks[1] == 'size:' assert toks[2] == '1' assert toks[3] == 'hits:' assert toks[5] == 'misses:' assert toks[7] == 'check:' assert toks[8] == '3' tokens.append(toks) toks = tokens[0] assert toks[0] == 'const1d' assert toks[4] == '1' assert toks[6] == '2' toks = tokens[1] assert toks[0] == 'polynom1d' assert toks[4] == '1' assert toks[6] == '2' toks = tokens[2] assert toks[0] == 'box1d' assert toks[4] == '0' assert toks[6] == '0'
def test_evaluate_cache_regrid1d(): """How about a regridded model?""" mdl = Polynom1D() x = numpy.arange(2, 20, 0.5) rmdl = mdl.regrid(x) assert isinstance(rmdl, RegridWrappedModel) assert not hasattr(rmdl, '_use_caching')
def test_rspmodelpha_matrix_call(ignore): """What happens calling a rsp with a pha (RMF is a matrix)? The ignore value gives the channel to ignore (counting from 0). """ exposure = 200.1 rdata = create_non_delta_rmf() specresp = create_non_delta_specresp() elo = rdata.energ_lo ehi = rdata.energ_hi adata = create_arf(elo, ehi, specresp, exposure=exposure) nchans = rdata.e_min.size constant = 22.3 slope = -1.2 mdl = Polynom1D('sloped') mdl.c0 = constant mdl.c1 = slope 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_rmf(rdata) # force energy units (only needed if ignore is set) pha.set_analysis('energy') if ignore is not None: e0 = rdata.e_min[ignore] e1 = rdata.e_max[ignore] de = 0.9 * (e1 - e0) pha.notice(lo=e0, hi=e0 + de, ignore=True) # The assert are intended to help people reading this # code rather than being a useful check that the code # is working. mask = [True] * nchans mask[ignore] = False assert (pha.mask == mask).all() wrapped = RSPModelPHA(adata, rdata, pha, mdl) # The filter does not change the grid modvals = specresp * mdl(rdata.energ_lo, rdata.energ_hi) matrix = get_non_delta_matrix() expected = np.matmul(modvals, matrix) out = wrapped([4, 5]) assert_allclose(out, expected)
def test_rmfmodelpha_matrix_call(ignore): """What happens calling an rmf (matrix) with a pha? The ignore value gives the channel to ignore (counting from 0). """ exposure = 200.1 rdata = create_non_delta_rmf() elo = rdata.e_min ehi = rdata.e_max nchans = elo.size constant = 12.2 slope = 0.01 mdl = Polynom1D('not-flat') mdl.c0 = constant mdl.c1 = slope 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_rmf(rdata) # force energy units (only needed if ignore is set) pha.set_analysis('energy') if ignore is not None: e0 = elo[ignore] e1 = ehi[ignore] de = 0.9 * (e1 - e0) pha.notice(lo=e0, hi=e0 + de, ignore=True) # The assert are intended to help people reading this # code rather than being a useful check that the code # is working. mask = [True] * nchans mask[ignore] = False assert (pha.mask == mask).all() wrapped = RMFModelPHA(rdata, pha, mdl) # Note that the evaluation ignores any filter we've applied. # and the exposure time is not used. # modvals = mdl(rdata.energ_lo, rdata.energ_hi) matrix = get_non_delta_matrix() expected = np.matmul(modvals, matrix) out = wrapped([4, 5]) assert_allclose(out, expected)
def test_model_thaw(): """Can we thaw all the parameters in a model?""" mdl = Polynom1D() expected = [2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0] for p, val in zip(mdl.pars, expected): p.val = val assert mdl.thawedpars == pytest.approx([2.0]) mdl.thaw() assert mdl.thawedpars == pytest.approx(expected)
def test_regproj(old_numpy_printing, override_plot_backend): p = plot.RegionProjection() r = p._repr_html_() check_empty(r, 'RegionProjection', nsummary=13) x = np.arange(5, 8, 0.5) y = np.asarray([2, 3, 4, 5, 4, 3]) dy = y / 2 d = Data1D('n n', x, y, staterror=dy) m = Polynom1D() m.c1.thaw() fit = Fit(d, m, stat=Chi2()) fr = fit.fit() assert fr.succeeded p.prepare(min=(-2, -1), max=(2, 2), nloop=(10, 20)) p.calc(fit, m.c0, m.c1) r = p._repr_html_() assert r is not None if plot_backend_is("pylab"): assert "<summary>RegionProjection</summary>" in r assert "<svg " in r return assert "<summary>RegionProjection (13)</summary>" in r # Issue #1372 shows that the numbers here can depend on the platform; as # this test is not about whether the fit converged to the same solution # the tests are very basic. An alternative would be to just place # the values from the fit object into the strings, but then there is # the problem that this test currently requires old_numpy_printing, # so the results would not necessarily match. # assert '<div class="dataname">parval0</div><div class="dataval">-0.5' in r assert '<div class="dataname">parval1</div><div class="dataval">0.5' in r assert '<div class="dataname">sigma</div><div class="dataval">(1, 2, 3)</div>' in r # These values may depend on the platform so only very-limited check. # assert '<div class="dataname">y</div><div class="dataval">[ 30' in r assert '<div class="dataname">levels</div><div class="dataval">[ 3.6' in r assert '<div class="dataname">min</div><div class="dataval">[-2, -1]</div>' in r assert '<div class="dataname">max</div><div class="dataval">[2, 2]</div>' in r assert '<div class="dataname">nloop</div><div class="dataval">(10, 20)</div>' in r
def test_model_freeze(): """Can we freeze all the parameters in a model?""" mdl = Polynom1D() mdl.c2.val = 30 mdl.c7.val = 87 mdl.offset.val = -2 mdl.c2.thaw() mdl.c7.thaw() mdl.offset.thaw() assert mdl.thawedpars == pytest.approx([1.0, 30, 87, -2]) mdl.freeze() assert mdl.thawedpars == []
def setup_single_1dint(stat, sys): """Return a single data set and model. Parameters ---------- stat, sys : bool Should statistical and systematic errors be explicitly set (True) or taken from the statistic (False)? Returns ------- data, model Data1DInt and Model objects. """ xlo = np.asarray([-10, -5, 3, 4]) xhi = np.asarray([-5, 2, 4, 7]) y = np.asarray([16.3, 2.4, 4.3, 5.6]) if stat: # pick values close to sqrt(y) staterr = np.asarray([4.0, 1.6, 2.1, 2.4]) else: staterr = None if sys: syserr = 0.05 * y else: syserr = None data = Data1DInt('tst1', xlo, xhi, y, staterror=staterr, syserror=syserr) # As the model is integrated, the normalization values need to # be divided by the bin width, but the bins are not constant # width, so pick a value which gives reasonable values. # mdl = Polynom1D('mdl1') mdl.c0 = 0 mdl.c2 = 0.08 mdl.offset = -1 mdl.offset.frozen = False mdl.c2.frozen = False return data, mdl
def test_regproj(old_numpy_printing, override_plot_backend): p = plot.RegionProjection() r = p._repr_html_() check_empty(r, 'RegionProjection', nsummary=13) x = np.arange(5, 8, 0.5) y = np.asarray([2, 3, 4, 5, 4, 3]) dy = y / 2 d = Data1D('n n', x, y, staterror=dy) m = Polynom1D() m.c1.thaw() fit = Fit(d, m, stat=Chi2()) fr = fit.fit() assert fr.succeeded p.prepare(min=(-2, -1), max=(2, 2), nloop=(10, 20)) p.calc(fit, m.c0, m.c1) r = p._repr_html_() assert r is not None if plot.backend.name == 'pylab': assert '<summary>RegionProjection</summary>' in r assert '<svg ' in r return print(r) assert '<summary>RegionProjection (13)</summary>' in r assert '<div class="dataname">parval0</div><div class="dataval">-0.5315772076542427</div>' in r assert '<div class="dataname">parval1</div><div class="dataval">0.5854611101216837</div>' in r assert '<div class="dataname">sigma</div><div class="dataval">(1, 2, 3)</div>' in r assert '<div class="dataname">y</div><div class="dataval">[ 306.854444 282.795953 259.744431 237.699877 216.662291 196.631674\n' in r assert '<div class="dataname">levels</div><div class="dataval">[ 3.606863 7.491188 13.140272]</div>' in r assert '<div class="dataname">min</div><div class="dataval">[-2, -1]</div>' in r assert '<div class="dataname">max</div><div class="dataval">[2, 2]</div>' in r assert '<div class="dataname">nloop</div><div class="dataval">(10, 20)</div>' in r
def test_evaluate_no_cache1d(): """Check we can turn off cacheing: 1d""" xgrid = numpy.arange(2, 10, 1.5) mdl = Polynom1D() mdl.integrate = False mdl._use_caching = False assert len(mdl._cache) == 0 # Check the default values expected = numpy.ones(6) assert mdl(xgrid) == pytest.approx(expected) assert len(mdl._cache) == 0 mdl.c0 = 5 mdl.c1 = 2 expected = 5 + 2 * xgrid assert mdl(xgrid) == pytest.approx(expected) assert len(mdl._cache) == 0
def test_evaluate_cache1d(): """Check we run with cacheing on: 1d""" xgrid = numpy.arange(2, 10, 1.5) mdl = Polynom1D() mdl.integrate = False mdl._use_caching = True assert len(mdl._cache) == 0 # Check the default values expected = numpy.ones(6) assert mdl(xgrid) == pytest.approx(expected) check_cache(mdl, expected, xgrid) mdl.c0 = 5 mdl.c1 = 2 expected = 5 + 2 * xgrid assert mdl(xgrid) == pytest.approx(expected) check_cache(mdl, expected, xgrid)
def test_cache_status_single(caplog): """Check cache_status for a single model.""" p = Polynom1D() with caplog.at_level(logging.INFO, logger='sherpa'): p.cache_status() assert len(caplog.records) == 1 lname, lvl, msg = caplog.record_tuples[0] assert lname == 'sherpa.models.model' assert lvl == logging.INFO toks = msg.split() assert toks[0] == 'polynom1d' assert toks[1] == 'size:' assert toks[2] == '1' assert toks[3] == 'hits:' assert toks[4] == '0' assert toks[5] == 'misses:' assert toks[6] == '0' assert toks[7] == 'check:' assert toks[8] == '0' assert len(toks) == 9
def test_pha_model_with_gaps_977(): """If the lo/hi edges don't quite match what happens? See test_pha_data_with_gaps_977. """ chans = np.arange(1, 6) vals = np.arange(1, 6) blo = np.asarray([100, 99, 98, 97, 96]) bhi = np.asarray([101, 100.0000000001, 99, 98, 97]) d = DataPHA('x', chans, vals, bin_lo=blo, bin_hi=bhi) d.set_analysis('wave') mdl = Polynom1D() mdl.c0 = 0.1 mdl.c1 = 1.1 p = ModelPHAHistogram() p.prepare(d, mdl) assert p.y == pytest.approx([1.2, 2.3, 3.4, 4.5, 5.6]) xlo = p.xlo xhi = p.xhi assert xlo.size == 5 assert xlo[0] == pytest.approx(101) assert xhi[0] == pytest.approx(100) assert xlo[-1] == pytest.approx(97) assert xhi[-1] == pytest.approx(96) # This is an equality check, not with pytest.approx, # since this is enforced by the plot code. This fails # before #977 is fixed. # assert (xlo[1:] == xhi[:-1]).all()
def test_evaluate_cache_swap(): """Check issue #959 when swapping integrate flag caused problems. Note that the problem causing #959 is actually tested in test_evaluate_cache1dint but it's nice to have this separate check in case things change. """ xgrid = numpy.arange(2, 10, 1.5) xlo, xhi = xgrid[:-1], xgrid[1:] mdl = Polynom1D() mdl._use_caching = True mdl.c0 = 5 mdl.c1 = 2 mdl.integrate = False expected = 5 + 2 * xlo y1 = mdl(xlo, xhi) assert y1 == pytest.approx(expected) check_cache(mdl, expected, xlo, xhi) mdl.integrate = True def xval(x): return 5 + 2 * x dx = xhi - xlo ylo = xval(xlo) yhi = xval(xhi) expected = dx * (yhi + ylo) / 2 y2 = mdl(xlo, xhi) assert y2 == pytest.approx(expected) check_cache(mdl, expected, xlo, xhi)
def setup_single(stat, sys): """Return a single data set and model. Parameters ---------- stat, sys : bool Should statistical and systematic errors be explicitly set (True) or taken from the statistic (False)? Returns ------- data, model Data1D and Model objects. """ x = np.asarray([-10, -5, 3, 4]) y = np.asarray([16.3, 2.4, 4.3, 5.6]) if stat: # pick values close to sqrt(y) staterr = np.asarray([4.0, 1.6, 2.1, 2.4]) else: staterr = None if sys: syserr = 0.05 * y else: syserr = None data = Data1D('tst1', x, y, staterror=staterr, syserror=syserr) mdl = Polynom1D('mdl1') mdl.c0 = 0 mdl.c2 = 0.2 mdl.offset = -1 return data, mdl
def setup_single_pha(stat, sys, background=True, areascal="none"): """Return a single data set and model. This is aimed at wstat calculation, and so the DataPHA object has no attached response. The data set is grouped. Parameters ---------- stat, sys : bool Should statistical and systematic errors be explicitly set (True) or taken from the statistic (False)? background : bool Should a background data set be included (True) or not (False)? The background is *not* subtracted when True. areascal : {'none', 'scalar', 'array'} Is the AREASCAL set and, if so, to a scalar or array value? If background is True then it is also applied to the background data set. Returns ------- data, model DataPHA and Model objects. """ # For the array of areascals, ensure that areascal is not # constant within at least one group # areascals = { 'source': { 'none': None, 'scalar': 1.0, 'array': np.asarray([0.9, 0.9, 0.8, 0.9, 0.7], dtype=np.float32) }, 'background': { 'none': None, 'scalar': 0.8, 'array': np.asarray([1.2, 1.2, 1.2, 1.1, 1.4], dtype=np.float32) } } # If used the same bins as setup_single_1dint then could # re-use the results, but the bins are different, and it # is useful for the Data1DInt case to test non-consecutive # histogram bins. # channels = np.arange(1, 6, dtype=np.int16) counts = np.asarray([10, 13, 9, 17, 21], dtype=np.int16) if stat: staterror = np.asarray([3.0, 4.0, 3.0, 4.0, 5.0]) else: staterror = None if sys: syserror = 0.2 * counts else: syserror = None grouping = np.asarray([1, -1, 1, -1, 1], dtype=np.int16) # quality = np.asarray([0, 0, 0, 0, 0], dtype=np.int16) quality = None exposure = 150.0 backscal = 0.01 ascal = areascals['source'][areascal] # does not set areascal or header data = DataPHA(name='tstpha', channel=channels, counts=counts, staterror=staterror, syserror=syserror, grouping=grouping, quality=quality, exposure=exposure, backscal=backscal, areascal=ascal) if background: bgcounts = np.asarray([2, 1, 0, 2, 2], dtype=np.int16) if stat: bgstaterror = np.asarray([0.2, 0.4, 0.5, 0.3, 0.2]) else: bgstaterror = None if sys: bgsyserror = 0.3 * bgcounts else: bgsyserror = None bggrouping = None bgquality = None bgexposure = 550.0 bgbackscal = np.asarray([0.05, 0.06, 0.04, 0.04, 0.07]) bgascal = areascals['background'][areascal] bgdata = DataPHA(name='bgpha', channel=channels, counts=bgcounts, staterror=bgstaterror, syserror=bgsyserror, grouping=bggrouping, quality=bgquality, exposure=bgexposure, backscal=bgbackscal, areascal=bgascal) data.set_background(bgdata) # Trying a multi-component model, even though this actual # model is degenerate (cnst.c0 and poly.c0) cnst = Const1D('cnst') poly = Polynom1D('poly') cnst.c0 = 1.2 poly.c0 = 7.9 poly.c1 = 2.1 poly.c1.frozen = False mdl = cnst + poly return data, mdl
def test_cache_clear_multiple(caplog): """Check cache_clear for a combined model.""" p = Polynom1D() b = Box1D() c = Const1D() mdl = c * (p + 2 * b) # Ensure one component doesn't use the cache c._use_caching = False # There's no official API for accessing the cache data, # so do it directly. # assert len(p._cache) == 0 assert p._cache_ctr['check'] == 0 assert p._cache_ctr['hits'] == 0 assert p._cache_ctr['misses'] == 0 assert len(b._cache) == 0 assert b._cache_ctr['check'] == 0 assert b._cache_ctr['hits'] == 0 assert b._cache_ctr['misses'] == 0 assert len(c._cache) == 0 assert c._cache_ctr['check'] == 0 assert c._cache_ctr['hits'] == 0 assert c._cache_ctr['misses'] == 0 mdl([1, 2, 3]) mdl([1, 2, 3]) mdl([1, 2, 3, 4]) assert len(p._cache) == 1 assert p._cache_ctr['check'] == 3 assert p._cache_ctr['hits'] == 1 assert p._cache_ctr['misses'] == 2 assert len(b._cache) == 1 assert b._cache_ctr['check'] == 3 assert b._cache_ctr['hits'] == 1 assert b._cache_ctr['misses'] == 2 assert len(c._cache) == 0 assert c._cache_ctr['check'] == 3 assert c._cache_ctr['hits'] == 0 assert c._cache_ctr['misses'] == 0 mdl.cache_clear() assert len(p._cache) == 0 assert p._cache_ctr['check'] == 0 assert p._cache_ctr['hits'] == 0 assert p._cache_ctr['misses'] == 0 assert len(b._cache) == 0 assert b._cache_ctr['check'] == 0 assert b._cache_ctr['hits'] == 0 assert b._cache_ctr['misses'] == 0 assert len(c._cache) == 0 assert c._cache_ctr['check'] == 0 assert c._cache_ctr['hits'] == 0 assert c._cache_ctr['misses'] == 0
def dump(name): print("# dump") print("{}".format(name)) print(repr(eval(name))) print("----------------------------------------") def savefig(name): plt.savefig(name) print("# Created: {}".format(name)) from sherpa.models.basic import Polynom1D mdl = Polynom1D() mdl.c2.thaw() report("mdl") from sherpa.fit import Fit f = Fit(d, mdl) report("f") report("f.data") report("f.model") dump("f.model.c2.val") mdl.c2 = 1 dump("f.model.c2.val") print("Starting statistic: {:.3f}".format(f.calc_stat()))
from sherpa.ui.utils import Session from sherpa.data import Data1DInt from sherpa.models.basic import Polynom1D def savefig(name): plt.savefig(name) print("# Created: {}".format(name)) s = Session() xlo = [2, 3, 5, 7, 8] xhi = [3, 5, 6, 8, 9] y = [10, 27, 14, 10, 14] s.load_arrays(1, xlo, xhi, y, Data1DInt) mdl = Polynom1D('mdl') mdl.c0 = 6 mdl.c1 = 1 s.set_source(mdl) s.plot_fit() savefig('ui_plot_fit_basic.png') s.plot_data(color='black') p = s.get_model_plot_prefs() p['marker'] = '*' p['markerfacecolor'] = 'green' p['markersize'] = 12 s.plot_model(linestyle=':', alpha=0.7, overplot=True) savefig('ui_plot_fit_manual.png')