示例#1
0
def test_rmf1d_matrix_arf_no_pha_call():
    "Can we call an RMF () with ARF (no PHA)"

    # NOTE: there is no check that the grids are compatible
    #       so this is probably not that useful a test
    #
    rdata = create_non_delta_rmf()
    elo = rdata.e_min
    ehi = rdata.e_max
    adata = create_arf(elo, ehi)
    rmf = RMF1D(rdata, arf=adata)

    mdl = Const1D('flat')
    mdl.c0 = 2.3

    wrapped = rmf(mdl)

    # It seems like the wrapper should match the following:
    #     assert isinstance(wrapped, RSPModelNoPHA)
    # but at the time the test was written (June 2017) it
    # does not.
    #
    assert isinstance(wrapped, RMFModelNoPHA)

    wmdl = wrapped.model
    assert wmdl == mdl
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)
示例#3
0
def test_arf1d_no_pha_no_exposure_call(exposure):
    "Can we call an ARF (no PHA)"

    egrid = np.arange(0.1, 0.6, 0.1)
    specresp = np.asarray([1.1, 1.2, 1.3, 1.4])
    adata = create_arf(egrid[:-1], egrid[1:], specresp, exposure=exposure)
    arf = ARF1D(adata)

    mdl = Const1D('flat')
    mdl.c0 = 2.3

    wrapped = arf(mdl)
    assert isinstance(wrapped, ARFModelNoPHA)

    wmdl = wrapped.model
    if exposure is None:
        assert wmdl == mdl
    else:
        # It looks like equality is not well defined for the model
        # classes, since the following assertion fails
        #     assert wmdl == (exposure * mdl)
        # so manually check
        #
        assert isinstance(wmdl, BinaryOpModel)
        assert wmdl.op == np.multiply
        assert wmdl.rhs == mdl
        assert isinstance(wmdl.lhs, ArithmeticConstantModel)
        assert wmdl.lhs.val == pytest.approx(exposure)
示例#4
0
def test_psf1d_combined_v2():
    """See test_psf1d_step_v2"""

    smdl = StepLo1D()
    smdl.xcut = 100
    smdl.ampl = 10

    cmdl = Const1D()
    cmdl.c0 = -500

    imdl = smdl + cmdl

    gsmooth = Gauss1D()
    psf = PSFModel('psf', gsmooth)

    x = np.arange(0, 200, 0.5)
    d = Data1D('fake', x, x * 0)
    psf.fold(d)

    smoothed = psf(imdl)
    y = smoothed(x)

    # So the output is not easy to describe analytically, hence
    # we just check parts of it.
    #
    assert y[(x >= 19.5) & (x <= 100)] == pytest.approx([-490] * 162, abs=1e-4)
    assert y[x >= 119] == pytest.approx([-500] * 162, abs=1e-4)

    # check that the x <= 19 values are in ascending order
    y1 = y[x <= 19]
    assert (y1[1:] > y1[:-1]).all()
示例#5
0
def test_binop_arithmeticxxx(model, mtype):
    """Can we create and combine Arithmetic*Model objects?"""

    m1 = Const1D()
    m1.c0 = 2

    mleft = model + m1
    assert isinstance(mleft, BinaryOpModel)
    assert mleft.op == numpy.add
    assert len(mleft.parts) == 2
    assert isinstance(mleft.parts[0], mtype)
    assert isinstance(mleft.parts[1], Const1D)

    mright = m1 + model
    assert isinstance(mright, BinaryOpModel)
    assert mright.op == numpy.add
    assert len(mright.parts) == 2
    assert isinstance(mright.parts[0], Const1D)
    assert isinstance(mright.parts[1], mtype)

    x = numpy.linspace(0.1, 0.5, 5)
    if mtype == ArithmeticConstantModel:
        y1 = 25 * numpy.ones(5)
    else:
        y1 = model(x) + 2

    y2 = mleft(x)
    y3 = mright(x)
    assert y2 == pytest.approx(y1)
    assert y3 == pytest.approx(y1)
示例#6
0
def test_arfmodelpha_call(ignore):
    """What happens calling an arf with a pha?

    The ignore value indicates what channel to ignore (0 means
    nothing is ignored). The aim is to check edge effects,
    and as there are only a few channels, it was decided to
    test all channels.
    """

    # Note: the exposure is set in the PHA and ARF, but should not be
    #       used when evaluating the model; it's value has been
    #       set to a value that the test will fail it it is.
    #
    exposure = 200.1
    estep = 0.01
    egrid = np.arange(0.01, 0.06, estep)
    svals = [1.1, 1.2, 1.3, 1.4]
    specresp = np.asarray(svals)
    adata = create_arf(egrid[:-1], egrid[1:], specresp, exposure=exposure)

    constant = 2.3
    mdl = Const1D('flat')
    mdl.c0 = constant

    channels = np.arange(1, 5, dtype=np.int16)
    counts = np.asarray([10, 5, 12, 7], dtype=np.int16)
    pha = DataPHA('test-pha',
                  channel=channels,
                  counts=counts,
                  exposure=exposure)
    pha.set_arf(adata)

    # force energy units (only needed if ignore is set)
    pha.set_analysis('energy')

    if ignore is not None:
        de = estep * 0.9
        e0 = egrid[ignore]
        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, True, True, True]
        mask[ignore] = False
        assert (pha.mask == mask).all()

    wrapped = ARFModelPHA(adata, pha, mdl)

    # The model is evaluated on the ARF grid, not whatever
    # is sent in. It is also integrated across the bins,
    # which is why there is a multiplication by the
    # grid width (for this constant model).
    #
    # Note that the filter doesn't change the grid.
    #
    de = egrid[1:] - egrid[:-1]
    expected = constant * np.asarray(svals) * de
    out = wrapped([4, 5])
    assert_allclose(out, expected)
def test_chisquare():
    """Is the chi square correct?

    This uses the data-variance calculation.
    """

    dset = setup_basic_dataset()
    dset.ignore_bad()

    cpt1 = Const1D()
    cpt2 = StepHi1D()
    cpt1.c0 = 20
    cpt2.ampl = 20
    cpt2.xcut = 6.5
    mdl = cpt1 + cpt2

    # Since the model does not contain a *PHA instrument model
    # it will not include the area-scaling, so the data and
    # errors should not be scaled.
    #
    scale = False
    counts = expected_basic_counts(scale=scale)[1:]
    errors = expected_basic_chisquare_errors(scale=scale)
    mvals = mdl(dset.channel[1:])

    expected = (counts - mvals)**2 / (errors**2)
    expected = expected.sum()

    stat = Chi2DataVar()
    sval = stat.calc_stat(dset, mdl)

    assert sval[0] == pytest.approx(expected)
示例#8
0
def test_sourceplot_channels(caplog, make_basic_datapha):
    """Although we ask for channels we get energy units"""

    data = make_basic_datapha
    data.units = "channel"

    # use a model that is "okay" to use with keV bins
    #
    m1 = Const1D('bgnd')
    m2 = Gauss1D('abs1')
    src = 100 * m1 * (1 - m2) * 10000

    m1.c0 = 0.01
    m2.pos = 5.0
    m2.fwhm = 4.0
    m2.ampl = 0.1

    sp = SourcePlot()
    with caplog.at_level(logging.INFO, logger='sherpa'):
        sp.prepare(data, src)

    assert len(caplog.records) == 1
    lname, lvl, msg = caplog.record_tuples[0]
    assert lname == 'sherpa.astro.plot'
    assert lvl == logging.WARN
    assert msg == 'Channel space is unappropriate for the PHA unfolded source model,\nusing energy.'

    check_sourceplot_energy(sp)
示例#9
0
def test_modelphahistogram_prepare_wavelength(make_data_path):
    """Check we can use wavelength setting"""

    from sherpa.astro.io import read_pha

    # could fake a dataset but it's easier to use one
    infile = make_data_path('3c273.pi')
    pha = read_pha(infile)
    pha.name = 'my-name.pi'

    pha.set_analysis('wave')
    pha.notice(3, 5)

    mdl = Const1D()

    # not bothered too much about the model (e.g. setting a response)
    #
    plot = aplot.ModelPHAHistogram()
    plot.prepare(pha, mdl)

    assert plot.xlabel == 'Wavelength (Angstrom)'
    assert plot.ylabel == 'Counts/sec/Angstrom'
    assert plot.title == 'Model'

    # data is inverted
    assert plot.xlo[0] > plot.xlo[-1]
    assert plot.xlo[0] > plot.xhi[0]
    assert np.all(plot.y > 0)
    assert plot.y.size == 9
示例#10
0
def test_sourceplot_wavelength_counts(caplog):
    """test_sourceplot_wavelength but when rate=False is chosen"""

    bins = np.arange(0.1, 10.1, 0.1)
    data = DataPHA('',
                   np.arange(10),
                   np.ones(10),
                   bin_lo=bins[:-1].copy(),
                   bin_hi=bins[1:].copy())
    data.units = "wave"
    data.rate = False

    # use a model that is "okay" to use with keV bins
    #
    m1 = Const1D('bgnd')
    m2 = Gauss1D('abs1')
    src = 100 * m1 * (1 - m2) * 10000

    m1.c0 = 0.01
    m2.pos = 5.0
    m2.fwhm = 4.0
    m2.ampl = 0.1

    sp = SourcePlot()
    with caplog.at_level(logging.INFO, logger='sherpa'):
        sp.prepare(data, src)

    assert len(caplog.records) == 0
    check_sourceplot_wavelength(sp)
示例#11
0
def test_sourceplot_facn(factor, caplog, make_basic_datapha):
    """Change plot factor for test_sourceplot"""

    data = make_basic_datapha
    data.units = "energy"
    data.plot_fac = factor
    assert data.rate

    # use a model that is "okay" to use with keV bins
    #
    m1 = Const1D('bgnd')
    m2 = Gauss1D('abs1')
    src = 100 * m1 * (1 - m2) * 10000

    m1.c0 = 0.01
    m2.pos = 5.0
    m2.fwhm = 4.0
    m2.ampl = 0.1

    sp = SourcePlot()
    with caplog.at_level(logging.INFO, logger='sherpa'):
        sp.prepare(data, src)

    assert len(caplog.records) == 0
    check_sourceplot_energy(sp, factor=factor)
示例#12
0
def test_sourceplot_wavelength_facn(factor, caplog):
    """Change plot factor for test_sourceplot_wavelength"""

    bins = np.arange(0.1, 10.1, 0.1)
    data = DataPHA('',
                   np.arange(10),
                   np.ones(10),
                   bin_lo=bins[:-1].copy(),
                   bin_hi=bins[1:].copy())
    data.units = "wavelength"
    data.plot_fac = factor
    assert data.rate

    m1 = Const1D('bgnd')
    m2 = Gauss1D('abs1')
    src = 100 * m1 * (1 - m2) * 10000

    m1.c0 = 0.01
    m2.pos = 5.0
    m2.fwhm = 4.0
    m2.ampl = 0.1

    sp = SourcePlot()
    with caplog.at_level(logging.INFO, logger='sherpa'):
        sp.prepare(data, src)

    assert len(caplog.records) == 0
    check_sourceplot_wavelength(sp, factor=factor)
示例#13
0
def test_sourceplot_wavelength(caplog):
    """Check we get wavelength units"""

    bins = np.arange(0.1, 10.1, 0.1)
    data = DataPHA('',
                   np.arange(10),
                   np.ones(10),
                   bin_lo=bins[:-1].copy(),
                   bin_hi=bins[1:].copy())
    data.units = "wave"

    # Note that the model evaluation in done in Angstroms
    #
    m1 = Const1D('bgnd')
    m2 = Gauss1D('abs1')
    src = 100 * m1 * (1 - m2) * 10000

    m1.c0 = 0.01
    m2.pos = 5.0
    m2.fwhm = 4.0
    m2.ampl = 0.1

    sp = SourcePlot()
    with caplog.at_level(logging.INFO, logger='sherpa'):
        sp.prepare(data, src)

    assert len(caplog.records) == 0
    check_sourceplot_wavelength(sp)
示例#14
0
def test_sourceplot(caplog):

    bins = np.arange(0.1, 10.1, 0.1)
    data = DataPHA('',
                   np.arange(10),
                   np.ones(10),
                   bin_lo=bins[:-1].copy(),
                   bin_hi=bins[1:].copy())
    data.units = "energy"
    assert data.rate
    assert data.plot_fac == 0

    # use a model that is "okay" to use with keV bins
    #
    m1 = Const1D('bgnd')
    m2 = Gauss1D('abs1')
    src = 100 * m1 * (1 - m2) * 10000

    m1.c0 = 0.01
    m2.pos = 5.0
    m2.fwhm = 4.0
    m2.ampl = 0.1

    sp = SourcePlot()
    with caplog.at_level(logging.INFO, logger='sherpa'):
        sp.prepare(data, src)

    assert len(caplog.records) == 0
    check_sourceplot_energy(sp)
示例#15
0
def test_intproj(old_numpy_printing, override_plot_backend):
    p = plot.IntervalProjection()
    r = p._repr_html_()

    check_empty(r, 'IntervalProjection', nsummary=8)

    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 = Const1D()

    fit = Fit(d, m, stat=Chi2())
    fr = fit.fit()
    assert fr.succeeded

    p.prepare(min=1, max=6, nloop=10)
    p.calc(fit, m.c0)

    r = p._repr_html_()
    assert r is not None

    if plot.backend.name == 'pylab':
        assert '<summary>IntervalProjection</summary>' in r
        assert '<svg ' in r
        return

    assert '<summary>IntervalProjection (8)</summary>' in r

    assert '<div class="dataname">x</div><div class="dataval">[ 1.        1.555556  2.111111  2.666667  3.222222  3.777778  4.333333  4.888889\n  5.444444  6.      ]</div>' in r
    assert '<div class="dataname">nloop</div><div class="dataval">10</div>' in r
示例#16
0
def test_sourceplot_prepare_wavelength(make_data_path):
    """Check we can use wavelength setting"""

    from sherpa.astro.io import read_pha

    # could fake a dataset but it's easier to use one
    infile = make_data_path('3c273.pi')
    pha = read_pha(infile)
    pha.name = 'my-name.pi'

    pha.set_analysis('wave')
    pha.notice(3, 5)

    mdl = Const1D()

    # not bothered too much about the model (e.g. setting a response)
    #
    plot = aplot.SourcePlot()
    plot.prepare(pha, mdl)

    assert plot.xlabel == 'Wavelength (Angstrom)'
    assert plot.ylabel.startswith('f(lambda)  Photons/sec/cm')
    assert plot.ylabel.find('^2') != -1
    assert plot.ylabel.endswith('/Angstrom ')
    assert plot.title == 'Source Model of my-name.pi'

    # data is inverted
    assert plot.xlo[0] > plot.xlo[-1]
    assert plot.xlo[0] > plot.xhi[0]
    assert np.all(plot.y > 0)
    assert plot.y.size == 1090
示例#17
0
def test_rspmodelnopha_delta_call():
    "What happens calling an RMF (delta)+ARF with no pha?"

    exposure = 200.1
    egrid = np.arange(0.01, 0.06, 0.01)
    elo = egrid[:-1]
    ehi = egrid[1:]
    specresp = np.asarray([1.2, 0.0, 0.5, 4.3])
    rdata = create_delta_rmf(elo, ehi)
    adata = create_arf(elo, ehi, specresp, exposure=exposure)

    constant = 2.3
    mdl = Const1D('flat')
    mdl.c0 = constant

    wrapped = RSPModelNoPHA(adata, rdata, mdl)

    # The model is evaluated on the RMF grid, not whatever
    # is sent in. It is also integrated across the bins,
    # which is why there is a multiplication by the
    # grid width (for this constant model).
    #
    de = egrid[1:] - egrid[:-1]
    expected = constant * specresp * de
    out = wrapped([4, 5])
    assert_allclose(out, expected)
示例#18
0
def test_orderplot_check_range():
    """Are the x/y values as expected?

    Note that this is not a proper test as the dataset only
    contains a single response. However, the code is not
    clear as what is meant to happen with multiple responses
    so do not spend too much time on this test here.
    """

    oplot = OrderPlot()

    pha = example_pha_data()
    model = Const1D('example-mdl')

    oplot.prepare(pha, model, orders=[2])
    assert len(oplot.xlo) == 1
    assert len(oplot.xhi) == 1
    assert len(oplot.y) == 1

    assert oplot.xlo[0] == pytest.approx(np.arange(1, 11))
    assert oplot.xhi[0] == pytest.approx(np.arange(2, 12))

    # constant model / exposure time
    yexp = np.ones(10) / 1201
    assert oplot.y[0] == pytest.approx(yexp)
示例#19
0
def test_regrid1d_wrapping_str():
    """Check the str output of a wrapped model.

    Since this includes the name field, it subsumes
    test_regrid1d_wrapping_name but leave that test alone
    as it is an explicit check.
    """

    # This is basically checking that __str__ comes from
    # the CompositeModel and that everything is set up
    # correctly.
    #
    internal_model = Const1D('con')
    internal_model.c0 = 2
    internal_model.c0.freeze()

    imodel_name = internal_model.name

    rmdl = ModelDomainRegridder1D(name='test')
    mdl = rmdl.apply_to(internal_model)

    expected_name = 'test({})'.format(imodel_name)

    # need to strip off the first line and replace it with
    # the new model name
    expected_params = "\n".join(str(internal_model).split('\n')[1:])

    expected_str = expected_name + "\n" + expected_params

    assert str(mdl) == expected_str
示例#20
0
def test_show_model():
    """Can we show the model?"""

    m = ShowableModel()
    n = Const1D()
    n.c0 = 2

    # add a test of parameter linking
    m.norm = 10 + n.c0

    toks = str(m).split('\n')
    assert len(toks) == 6
    assert toks[0] == 'thetestmodel'
    assert toks[1].strip().split() == [
        'Param', 'Type', 'Value', 'Min', 'Max', 'Units'
    ]
    assert toks[2].strip().split() == [
        '-----', '----', '-----', '---', '---', '-----'
    ]
    assert toks[3].strip().split() == [
        'thetestmodel.P1', 'thawed', '1', '0', '10'
    ]
    assert toks[4].strip().split() == [
        'thetestmodel.accent', 'frozen', '2', '0', '10'
    ]
    assert toks[5].strip().split() == [
        'thetestmodel.norm', 'linked', '12', 'expr:', '(10', '+', 'const1d.c0)'
    ]

    # Should hidden parameters be capable of being thawed?
    assert m.notseen.val == 10
    assert m.notseen.min == 5
    assert m.notseen.max == 15
    assert not m.notseen.frozen
示例#21
0
def test_psf1d_combined():
    """This is based on
    sherpa.models.tests.test_regrid_unit.test_regrid1_works_with_convolution_style
    but I wanted to make sure we have an explicit check of the underlying
    code.
    """

    smdl = StepLo1D()
    smdl.xcut = 12.5
    smdl.ampl = 10

    cmdl = Const1D()
    cmdl.c0 = -500

    imdl = smdl + cmdl

    gsmooth = Gauss1D()
    gsmooth.fwhm = 3
    psf = PSFModel('psf', gsmooth)

    x = np.arange(5, 23, 3)
    d = Data1D('fake', x, x * 0)
    psf.fold(d)

    smoothed = psf(imdl)
    y = smoothed(x)

    assert y == pytest.approx([-490, -490, -490, -500, -500, -500], rel=7e-3)
示例#22
0
def test_arfmodelnopha_call():
    "What happens calling an arf with no pha?"

    # Note: the exposure is set in the ARF, but should not be
    #       used when evaluating the model; it's value has been
    #       set to a value that the test will fail it it is.
    #
    egrid = np.arange(0.01, 0.06, 0.01)
    svals = [1.1, 1.2, 1.3, 1.4]
    specresp = np.asarray(svals)
    adata = create_arf(egrid[:-1], egrid[1:], specresp, exposure=200.1)

    constant = 2.3
    mdl = Const1D('flat')
    mdl.c0 = constant

    wrapped = ARFModelNoPHA(adata, mdl)

    # The model is evaluated on the ARF grid, not whatever
    # is sent in. It is also integrated across the bins,
    # which is why there is a multiplication by the
    # grid width (for this constant model).
    #
    de = egrid[1:] - egrid[:-1]
    expected = constant * np.asarray(svals) * de
    out = wrapped([4, 5])
    assert_allclose(out, expected)
示例#23
0
def test_fit(override_plot_backend):
    p = plot.FitPlot()
    r = p._repr_html_()
    assert r is None  # note: always None

    x = np.arange(5, 8, 0.5)
    y = np.ones(x.size)
    d = Data1D('n n', x, y)

    m = Const1D()

    dplot = plot.DataPlot()
    dplot.prepare(d)

    mplot = plot.ModelPlot()
    mplot.prepare(d, m)

    p.prepare(dplot, mplot)
    r = p._repr_html_()

    # different to previous checks
    assert r is not None

    if plot.backend.name == 'pylab':
        assert '<summary>FitPlot</summary>' in r
        assert '<svg ' in r
        return

    assert '<summary>DataPlot (' in r
    assert '<summary>ModelPlot (' in r
    assert '<div class="dataval">n n</div>' in r
    assert '<div class="dataval">Model</div>' in r
def test_rspmodelpha_delta_call(ignore):
    """What happens calling a rsp with a pha (RMF is a delta fn)?

    The ignore value gives the channel to ignore (counting from 0).
    """

    exposure = 200.1
    estep = 0.025
    egrid = np.arange(0.1, 0.8, estep)
    elo = egrid[:-1]
    ehi = egrid[1:]
    specresp = 2.4 * np.ones(elo.size, dtype=np.float32)
    specresp[2:5] = 0.0
    specresp[16:19] = 3.2
    adata = create_arf(elo, ehi, specresp, exposure=exposure)
    rdata = create_delta_rmf(elo, ehi, e_min=elo, e_max=ehi)
    nchans = elo.size

    constant = 2.3
    mdl = Const1D('flat')
    mdl.c0 = constant

    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:
        de = estep * 0.9
        e0 = egrid[ignore]
        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 model is evaluated on the RMF grid, not whatever
    # is sent in. It is also integrated across the bins,
    # which is why there is a multiplication by the
    # grid width (for this constant model).
    #
    # Note that the filter doesn't change the grid.
    #
    de = egrid[1:] - egrid[:-1]
    expected = constant * specresp * de
    out = wrapped([4, 5])
    assert_allclose(out, expected)
示例#25
0
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_rsp_no_arf_matrix_call(analysis, phaexp):
    """Check out Response1D with matrix but no ARF

    analysis is the analysis setting
    arfexp determines whether the arf has an exposure time
    phaexp determines whether the PHA has an exposure time
    """

    if phaexp:
        pha_exposure = 220.9
    else:
        pha_exposure = None

    if phaexp:
        exposure = pha_exposure
        mdl_label = '({} * flat)'.format(exposure)
    else:
        exposure = 1.0
        mdl_label = 'flat'

    rdata = create_non_delta_rmf()

    constant = 2.3
    mdl = Const1D('flat')
    mdl.c0 = constant

    # Turn off integration on this model, so that it is not integrated
    # across the bin width.
    #
    mdl.integrate = False

    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=pha_exposure)

    pha.set_rmf(rdata)

    rsp = Response1D(pha)
    wrapped = rsp(mdl)

    assert isinstance(wrapped, ArithmeticModel)

    expname = 'apply_rmf({})'.format(mdl_label)
    assert wrapped.name == expname

    modvals = exposure * constant * np.ones(rdata.energ_lo.size)
    matrix = get_non_delta_matrix()
    expected = np.matmul(modvals, matrix)

    pha.set_analysis(analysis)
    out = wrapped([4, 5])
    assert_allclose(out, expected)
def test_sourceplot():

    bins = np.arange(0.1, 10.1, 0.1)
    data = DataPHA('', np.arange(10), np.ones(10),
                   bin_lo=bins[:-1].copy(),
                   bin_hi=bins[1:].copy())
    data.units = "energy"

    # use a model that is "okay" to use with keV bins
    #
    m1 = Const1D('bgnd')
    m2 = Gauss1D('abs1')
    src = 100 * m1 * (1 - m2) * 10000

    m1.c0 = 0.01
    m2.pos = 5.0
    m2.fwhm = 4.0
    m2.ampl = 0.1

    sp = SourcePlot()
    sp.prepare(data, src)

    # add in several asserts to check that something has been
    # added to the object
    #
    assert sp.xlabel == 'Energy (keV)'

    # the following depends on the backend
    # assert sp.ylabel == 'f(E)  Photons/sec/cm$^2$/keV'

    assert sp.title == 'Source Model of '

    assert sp.xlo == pytest.approx(bins[:-1])
    assert sp.xhi == pytest.approx(bins[1:])

    # The check of the values is just to check that things are going
    # as expected, so the model values have been adjusted so that
    # an "integer" check can be used with enough precision to make
    # sure that the model is being evaluated correctly, but without
    # a very-high-precision check
    #
    yexp = np.asarray([9998, 9997, 9997, 9997, 9996, 9996, 9995, 9994,
                       9994, 9993, 9992, 9991, 9990, 9988, 9987, 9985,
                       9983, 9982, 9980, 9977, 9975, 9973, 9970, 9967,
                       9964, 9961, 9958, 9955, 9951, 9948, 9944, 9941,
                       9937, 9934, 9930, 9927, 9923, 9920, 9917, 9914,
                       9911, 9909, 9907, 9905, 9903, 9902, 9901, 9900,
                       9900, 9900, 9900, 9901, 9902, 9903, 9905, 9907,
                       9909, 9911, 9914, 9917, 9920, 9923, 9927, 9930,
                       9934, 9937, 9941, 9944, 9948, 9951, 9955, 9958,
                       9961, 9964, 9967, 9970, 9973, 9975, 9977, 9980,
                       9982, 9983, 9985, 9987, 9988, 9990, 9991, 9992,
                       9993, 9994, 9994, 9995, 9996, 9996, 9997, 9997,
                       9997, 9998, 9998])

    assert (sp.y.astype(np.int) == yexp).all()
示例#28
0
def test_regrid1d_wrapping_create_composite_instance():
    # This test depends on what we want the regridded model to look like, which is
    # somewhat arbitrary
    cmdl = Const1D()
    gmdl = Gauss1D()
    imdl = cmdl + gmdl
    rmdl = ModelDomainRegridder1D()
    mdl = rmdl.apply_to(imdl)
    assert isinstance(mdl, CompositeModel)
    assert len(mdl.parts) == 1
    assert mdl.parts[0] is imdl
示例#29
0
def test_functionmodel_check():
    """ArithmeticFunctionModel errors out with invalid input"""

    with pytest.raises(ModelErr) as exc:
        ArithmeticFunctionModel(Const1D())

    assert str(exc.value) == 'ArithmeticFunctionModel instance cannot be created from another model'

    with pytest.raises(ModelErr) as exc:
        ArithmeticFunctionModel(23)

    assert str(exc.value) == 'attempted to create ArithmeticFunctionModel from non-callable object of type int'
def test_model_linked():
    """Check linking of models"""
    m = Gauss1D('g1')
    c = Const1D('c1')
    m.fwhm = 8 * c.c0
    r = m._repr_html_()

    assert r is not None

    assert '<tr><th class="model-odd" scope="rowgroup" rowspan=3>g1</th><td>fwhm</td><td>linked</td><td>8.0</td><td colspan=2>&#8656; 8 * c1.c0</td><td></td></tr>' in r
    assert '<tr><td>pos</td><td><input disabled type="checkbox" checked></input></td><td>0.0</td><td>-MAX</td><td>MAX</td><td></td></tr>' in r
    assert '<tr><td>ampl</td><td><input disabled type="checkbox" checked></input></td><td>1.0</td><td>-MAX</td><td>MAX</td><td></td></tr>' in r
示例#31
0
 def calc(self, *args, **kwargs):
     self._calc_store.append((args, kwargs))
     return Const1D.calc(self, *args, **kwargs)
示例#32
0
 def __init__(self, name='myconst1d'):
     self._calc_store = []
     Const1D.__init__(self, name)