Exemplo n.º 1
0
 def test_chi2datavar(self):
     num = 3
     xy = numpy.array(range(num))
     ui.load_arrays(1, xy, xy, Data1D)
     ui.set_stat('chi2datavar')
     err = ui.get_staterror()
     numpy.testing.assert_allclose(err, numpy.sqrt(xy), rtol=1e-7, atol=1e-7)
Exemplo n.º 2
0
def test_chi2datavar(hide_logging):
    num = 3
    xy = numpy.array(range(num))
    ui.load_arrays(1, xy, xy, Data1D)
    ui.set_stat('chi2datavar')
    err = ui.get_staterror()
    assert err == pytest.approx(numpy.sqrt(xy))
Exemplo n.º 3
0
def test_calc_flux_pha_invalid_range(id, func, clean_astro_ui):
    """Ensure an error is raised if lo > hi"""

    x = np.arange(3, 6)
    y = np.ones(x.size - 1)

    ui.load_arrays(id, x[:-1], x[1:], y, ui.Data1DInt)
    mdl = ui.create_model_component('const1d', 'm')

    if id is None:
        ui.set_source(mdl)
    else:
        ui.set_source(id, mdl)

    # Note: really the error message should not include energy since in
    # this case (Data1DInt) there's no energy, and if this were
    # a DataPHA case the message says energy even if analysis=wave
    # or channel.
    #
    emsg = 'the energy range is not consistent, 12 !< 5'
    with pytest.raises(IOErr, match=emsg):
        if id is None:
            func(12, 5)
        else:
            func(12, 5, id=id)
def test_default_background_issue_fit(clean_astro_ui):
    """Test issue #943 with fit

    See https://github.com/sherpa/sherpa/issues/943#issuecomment-696119982
    """

    ui.set_default_id('x')

    # use least-square as we don't really care about the fit
    ui.set_stat('leastsq')

    ui.load_arrays('x', [1, 2, 3, 4], [5, 4, 3, 4], ui.DataPHA)
    bkg = ui.DataPHA('bkg', np.asarray([1, 2, 3, 4]), [1, 1, 0, 1])
    arf = ui.create_arf(np.asarray([0.1, 0.2, 0.3, 0.4]),
                        np.asarray([0.2, 0.3, 0.4, 0.5]))
    ui.set_arf(arf)
    bkg.set_arf(arf)
    ui.set_bkg(bkg)

    # The model being fitted is a constant to 1,1,0,1 for
    # the background, so that should be 0.75 / 0.1 (as the
    # bin width is constant), and for the source it is
    # 5,4,3,4 - <0.75> [here ignoring the bin-width],
    # so [4.25,3.25,2.25,3.25] -> 13 / 4 -> 3.25
    #
    ui.set_source(ui.const1d.mdl1)
    ui.set_bkg_source(ui.const1d.mdl2)

    # Prior to #943 this would give a confusing error.
    #
    ui.fit()
    assert mdl1.c0.val == pytest.approx(3.25 / 0.1)
    assert mdl2.c0.val == pytest.approx(0.75 / 0.1)
def test_save_data_data2d(tmp_path):
    """Does save_data work for Data2D?"""

    from sherpa.astro.io import backend

    y, x = np.mgrid[20:22, 10:13]
    x = x.flatten()
    y = y.flatten()
    z = (x - 15)**2 + (y - 12)**2
    ui.load_arrays(1, x, y, z, (2, 3), ui.Data2D)

    out = tmp_path / "data.dat"
    outfile = str(out)
    ui.save_data(outfile)

    cts = out.read_text()

    # the output depends on the backend, and neither seems ideal
    #
    if backend.__name__ == 'sherpa.astro.io.crates_backend':
        expected = ["#TEXT/SIMPLE", "# X0 X1 Y SHAPE"]
        s = [2, 3, 0, 0, 0, 0]
        for xi, yi, zi, si in zip(x, y, z, s):
            expected.append(f"{xi} {yi} {zi} {si}")

        expected = "\n".join(expected) + "\n"

    elif backend.__name__ == 'sherpa.astro.io.pyfits_backend':
        expected = "\n".join([str(zz) for zz in z]) + "\n"
    else:
        raise RuntimeError(f"UNKNOWN I/O BACKEND: {backend.__name__}")

    assert cts == expected
Exemplo n.º 6
0
def test_user_stat_unit():
    given_stat_error = [1.1, 2.2, 3.3]
    given_sys_error = [10.1, 10.2, 10.3]

    def calc_stat(data, _model, staterror, syserror=None, weight=None):
        # Make sure values are being injected correctly
        np.testing.assert_array_equal(given_stat_error, staterror)
        np.testing.assert_array_equal(given_sys_error, syserror)
        return 3.235, np.ones_like(data)

    xdata = [1, 2, 3]
    ydata = xdata

    ui.load_arrays(1, xdata, ydata, None, given_sys_error, Data1D)

    ui.set_model(1, 'polynom1d.p')

    ui.load_user_stat('customstat', calc_stat, lambda x: given_stat_error)
    ui.set_stat(eval('customstat'))

    try:
        ui.fit(1)
    except StatErr:
        pytest.fail("Call should not be throwing any exception (bug #341)")

    # Test the result is what we made the user stat return
    assert 3.235 == ui.get_fit_results().statval
Exemplo n.º 7
0
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_save_source_pha_fits(clean_astro_ui, tmp_path):
    """Can we write out data for save_source? DataPHA and FITS
    """

    from sherpa.astro.io import read_table_blocks

    ui.load_arrays(1, [1, 2], [5, 10], ui.DataPHA)

    # we need a response
    egrid = np.asarray([0.1, 0.2, 0.4])
    elo = egrid[:-1]
    ehi = egrid[1:]
    rmf = create_delta_rmf(elo, ehi, e_min=elo, e_max=ehi)
    ui.set_rmf(rmf)

    yarf = np.asarray([10, 20])
    arf = create_arf(elo, ehi, yarf)
    ui.set_arf(arf)

    ui.set_source(ui.const1d.cmdl)
    cmdl.c0 = 2

    out = tmp_path / 'model.dat'
    outfile = str(out)
    ui.save_source(outfile)

    ans = read_table_blocks(outfile)
    blocks = ans[1]
    assert len(blocks) == 2
    check_table(blocks[2], {
        'XLO': [0.1, 0.2],
        'XHI': [0.2, 0.4],
        'SOURCE': [2, 2]
    })
Exemplo n.º 9
0
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
Exemplo n.º 10
0
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
Exemplo n.º 11
0
def setup_imgdata_model():
    """Use a model for the PSF"""

    # Fake an image
    #
    x1, x0 = np.mgrid[0:8, 0:10]
    ymod = 10 + 100 / ((x0 - 5.5)**2 + (x1 - 3.5)**2)

    x0 = x0.flatten()
    x1 = x1.flatten()
    y = ymod.flatten()

    y = y.astype(int)  # convert to integers

    ui.load_arrays(1, x0, x1, y, (8, 10), ui.DataIMG)

    pmodel = ui.create_model_component('gauss2d', 'pmodel')
    pmodel.xpos = 0
    pmodel.ypos = 0
    pmodel.fwhm = 3

    ui.load_psf('psf', pmodel)
    psf.size = [10, 10]  # not sure if this is useful but leave in
    psf.center = [5, 4]
    ui.set_psf(psf)

    setup_imgdata_source()
Exemplo n.º 12
0
def test_dax_if():
    '''Test script'''
    import sherpa.astro.ui as sherpa
    sherpa.load_arrays(1, [1, 2, 3], [4, 5, 6], sherpa.Data1D)
    sherpa.set_source("polynom1d.ply")
    # DaxModelEditor([ply], "ds9").run()
    DaxModelEditor([ply]).run(sherpa.fit)
Exemplo n.º 13
0
def test_save_model_pha_ascii(clean_astro_ui, tmp_path):
    """Can we write out data for save_model? DataPHA and ASCII"""

    ui.load_arrays(1, [1, 2], [5, 10], ui.DataPHA)

    # we need a response
    egrid = np.asarray([0.1, 0.2, 0.4])
    elo = egrid[:-1]
    ehi = egrid[1:]
    rmf = create_delta_rmf(elo, ehi, e_min=elo, e_max=ehi)
    ui.set_rmf(rmf)

    yarf = np.asarray([10, 20])
    arf = create_arf(elo, ehi, yarf)
    ui.set_arf(arf)

    ui.set_source(ui.const1d.cmdl)
    cmdl.c0 = 2

    out = tmp_path / 'model.dat'
    ui.save_model(str(out), ascii=True)

    cts = out.read_text()
    check_output(cts, ['XLO', 'XHI', 'MODEL'],
                 [[0.1, 0.2, 20], [0.2, 0.4, 40]])
Exemplo n.º 14
0
def test_save_resid_dataimg_fits(tmp_path):
    """Residual, DataIMG, FITS"""

    from sherpa.astro.io import read_image

    y, x = np.mgrid[10:12, 20:23]
    x = x.flatten()
    y = y.flatten()
    z = (x - 11)**2 + (y - 21)**2
    ui.load_arrays(1, x, y, z, (2, 3), ui.DataIMG)

    ui.set_source(1, ui.const2d.cmdl)
    cmdl.c0 = 100

    out = tmp_path / "resid"
    outfile = str(out)
    ui.save_resid(outfile)

    ans = read_image(outfile)
    assert ans.shape == (2, 3)  # Is this correct?

    yl, xl = np.mgrid[1:3, 1:4]
    xl = xl.flatten()
    yl = yl.flatten()
    assert ans.x0 == pytest.approx(xl)
    assert ans.x1 == pytest.approx(yl)
    assert ans.y == pytest.approx(z - 100)
Exemplo n.º 15
0
def test_save_resid_datapha_fits(tmp_path):
    """Residual, DataPHA, FITS"""

    from sherpa.astro.io import read_table_blocks

    ui.load_arrays(1, [1, 2], [5, 10], ui.DataPHA)

    # we need a response
    egrid = np.asarray([0.1, 0.2, 0.4])
    elo = egrid[:-1]
    ehi = egrid[1:]
    rmf = create_delta_rmf(elo, ehi, e_min=elo, e_max=ehi)
    ui.set_rmf(rmf)

    yarf = np.asarray([10, 20])
    arf = create_arf(elo, ehi, yarf)
    ui.set_arf(arf)

    ui.set_source(ui.const1d.cmdl)
    cmdl.c0 = 2

    out = tmp_path / 'resid.out'
    outfile = str(out)
    ui.save_resid(outfile)

    ans = read_table_blocks(outfile)
    blocks = ans[1]
    assert len(blocks) == 2
    check_table(blocks[2], {'X': [0.15, 0.3], 'RESID': [30, 10]})
Exemplo n.º 16
0
def test_save_resid_datapha(tmp_path):
    """Residual, DataPHA, ASCII"""

    ui.load_arrays(1, [1, 2], [5, 10], ui.DataPHA)

    # we need a response
    egrid = np.asarray([0.1, 0.2, 0.4])
    elo = egrid[:-1]
    ehi = egrid[1:]
    rmf = create_delta_rmf(elo, ehi, e_min=elo, e_max=ehi)
    ui.set_rmf(rmf)

    yarf = np.asarray([10, 20])
    arf = create_arf(elo, ehi, yarf)
    ui.set_arf(arf)

    ui.set_source(ui.const1d.cmdl)
    cmdl.c0 = 2

    out = tmp_path / 'resid.out'
    outfile = str(out)
    ui.save_resid(outfile, ascii=True)

    cts = out.read_text()
    check_output(cts, ['X', 'RESID'], [[0.15, 30], [0.3, 10]])
Exemplo n.º 17
0
 def test_chi2datavar(self):
     num = 3
     xy = numpy.array(range(num))
     ui.load_arrays(1, xy, xy, Data1D)
     ui.set_stat('chi2datavar')
     err = ui.get_staterror()
     numpy.testing.assert_allclose(err, numpy.sqrt(xy),
                                   rtol=1e-7, atol=1e-7)
Exemplo n.º 18
0
 def test_warnings_are_gone_arrays(self):
     ui.load_arrays(1, [1, 2, 3], [4, 5, 6])
     #  We now have logic in conftest.py to catch white-listed warnings and fail on unexpected ones.
     #  We just need to make any warnings bubble up, here and in the following test.
     with NamedTemporaryFile() as f:
         ui.save_data(1, f.name, ascii=True, clobber=True)
     with NamedTemporaryFile() as f:
         ui.save_data(1, f.name, ascii=False, clobber=True)
Exemplo n.º 19
0
def test_fake_pha_background_model(clean_astro_ui, reset_seed):
    """Check we can add a background component.

    See also test_fake_pha_basic.

    For simplicity we use perfect responses.
    """

    np.random.seed(27347)

    id = 'qwerty'
    channels = np.arange(1, 4, dtype=np.int16)
    counts = np.ones(3, dtype=np.int16)
    bcounts = 100 * counts

    ui.load_arrays(id, channels, counts, ui.DataPHA)
    ui.set_exposure(id, 100)
    ui.set_backscal(id, 0.1)

    bkg = ui.DataPHA('bkg', channels, bcounts, exposure=200, backscal=0.4)

    ebins = np.asarray([1.1, 1.2, 1.4, 1.6])
    elo = ebins[:-1]
    ehi = ebins[1:]
    arf = ui.create_arf(elo, ehi)
    rmf = ui.create_rmf(elo, ehi, e_min=elo, e_max=ehi)

    mdl = ui.create_model_component('const1d', 'mdl')
    mdl.c0 = 0
    bkgmdl = ui.create_model_component('const1d', 'mdl')
    bkgmdl.c0 = 2
    ui.set_source(id, mdl)
    ui.set_bkg(id, bkg)
    ui.set_bkg_source(id, bkgmdl)
    ui.set_arf(id, arf, bkg_id=1)
    ui.set_rmf(id, rmf, bkg_id=1)

    ui.fake_pha(id, arf, rmf, 1000.0, bkg='model')

    faked = ui.get_data(id)
    assert faked.exposure == pytest.approx(1000.0)
    assert (faked.channel == channels).all()

    # check we've faked counts (the scaling is such that it is
    # very improbable that this condition will fail)
    assert (faked.counts > counts).all()

    # For reference the predicted source signal is
    #    [200, 400, 400]
    # and the background signal is
    #    [125, 125, 125]
    # so, even with randomly drawn values, the following
    # checks should be robust.
    #
    predicted_by_source = 1000 * mdl(elo, ehi)
    predicted_by_bkg = (1000 / 200) * (0.1 / 0.4) * bcounts
    assert (faked.counts > predicted_by_source).all()
    assert (faked.counts > predicted_by_bkg).all()
Exemplo n.º 20
0
 def test_warnings_are_gone_arrays(self):
     with warnings.catch_warnings(record=True) as w:
         warnings.simplefilter("always")
         with NamedTemporaryFile() as f:
             ui.load_arrays(1, [1,2,3], [4,5,6])
             ui.save_data(1, f.name, ascii=True, clobber=True)
         with NamedTemporaryFile() as f:
             ui.save_data(1, f.name, ascii=False, clobber=True)
         assert len(w) == 0
Exemplo n.º 21
0
 def test_warnings_are_gone_arrays(self):
     with warnings.catch_warnings(record=True) as w:
         warnings.simplefilter("always")
         with NamedTemporaryFile() as f:
             ui.load_arrays(1, [1, 2, 3], [4, 5, 6])
             ui.save_data(1, f.name, ascii=True, clobber=True)
         with NamedTemporaryFile() as f:
             ui.save_data(1, f.name, ascii=False, clobber=True)
         assert len(w) == 0
Exemplo n.º 22
0
def test_xxx_not_pha(callfunc):
    """Just check that these commands require a PHA dataset"""

    ui.load_arrays(1, [1, 2, 3], [4, 5, 6])

    with pytest.raises(ArgumentErr) as exc:
        callfunc()

    assert str(exc.value) == 'data set 1 does not contain PHA data'
Exemplo n.º 23
0
 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)
Exemplo n.º 24
0
 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)
Exemplo n.º 25
0
def test_get_syserror_missing(bid):
    """Does get_syserror error out?"""

    ui.load_arrays(1, [1, 2, 3], [5, 4, 3], ui.DataPHA)
    bkg = ui.DataPHA('bkg', np.asarray([1, 2, 3]), [1, 1, 0])
    ui.set_bkg(bkg)
    with pytest.raises(DataErr) as exc:
        ui.get_syserror(bkg_id=bid)

    assert str(exc.value) == "data set '1' does not specify systematic errors"
Exemplo n.º 26
0
def test_list_pileup_ids_single(id, clean_astro_ui):

    # Note: do not need to set a source model
    ui.load_arrays(id, [1, 2, 3], [1, 1, 1], ui.DataPHA)
    ui.set_pileup_model(id, ui.jdpileup.jdp)

    if id is None:
        id = 1

    assert ui.list_pileup_model_ids() == [id]
Exemplo n.º 27
0
def test_save_xxx_data1d_nodata(func, etype, emsg):
    """Does save_xxx error out if there's no data to save? Data1D
    """

    ui.load_arrays(1, [1, 2, 3], [5, 4, 3], ui.Data1D)

    with pytest.raises(etype) as exc:
        func("temp-file-that-should-not-be-created")

    assert str(exc.value) == emsg
Exemplo n.º 28
0
def test_save_data_data1d_no_clobber(tmp_path):
    """save_data: does clobber=False work? Data1D"""

    ui.load_arrays(1, [1, 2, 3], [5, 4, 3], ui.Data1D)

    out = tmp_path / "data.dat"
    outfile = str(out)

    out.write_text('some text')
    check_clobber(out, ui.save_data)
Exemplo n.º 29
0
def test_list_pileup_ids_multi(clean_astro_ui):

    jdp = ui.create_model_component('jdpileup', "jdp")

    for id in [1, "2"]:
        ui.load_arrays(id, [1, 2, 3], [1, 1, 1], ui.DataPHA)
        ui.set_pileup_model(id, jdp)

    ans = ui.list_pileup_model_ids()
    assert ans == [1, "2"]
Exemplo n.º 30
0
 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)
Exemplo n.º 31
0
 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)
Exemplo n.º 32
0
def test_fix_background_id_error_checks1():
    """Check error handling of background id"""

    ui.load_arrays(2, [1, 2, 3], [5, 4, 3], ui.DataPHA)
    bkg = ui.DataPHA('bkg', np.asarray([1, 2, 3]), [1, 1, 0])
    ui.set_bkg(2, bkg)

    with pytest.raises(ArgumentTypeErr) as exc:
        ui.get_bkg_source(id=2, bkg_id=bkg)

    assert str(exc.value) == 'identifiers must be integers or strings'
Exemplo n.º 33
0
def test_fix_background_id_error_checks2():
    """Check error handling of background id"""

    ui.load_arrays(2, [1, 2, 3], [5, 4, 3], ui.DataPHA)
    bkg = ui.DataPHA('bkg', np.asarray([1, 2, 3]), [1, 1, 0])
    ui.set_bkg(2, bkg)

    with pytest.raises(IdentifierErr) as exc:
        ui.get_bkg_source(id=2, bkg_id='bkg')

    assert str(exc.value) == "identifier 'bkg' is a reserved word"
Exemplo n.º 34
0
def test_set_filter_mismatch(f, bid):
    """Does set_filter error when there's a mis-match?
    """

    ui.load_arrays(1, [1, 2, 3], [5, 4, 3], ui.DataPHA)
    bkg = ui.DataPHA('bkg', np.asarray([1, 2, 3]), [1, 1, 0])
    ui.set_bkg(bkg)
    with pytest.raises(DataErr) as exc:
        ui.set_filter(f, bkg_id=bid)

    assert str(exc.value) == 'size mismatch between 3 and 2'
Exemplo n.º 35
0
def test_save_data_data1dint(tmp_path):
    """Does save_data work for Data1DInt?"""

    ui.load_arrays(1, [1, 2, 4], [2, 3, 5], [5, 4, 3], ui.Data1DInt)

    out = tmp_path / "data.dat"
    outfile = str(out)
    ui.save_data(outfile)

    cts = out.read_text()
    check_output(cts, ['XLO', 'XHI', 'Y'], [[1, 2, 5], [2, 3, 4], [4, 5, 3]])
Exemplo n.º 36
0
 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)
Exemplo n.º 37
0
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()
Exemplo n.º 38
0
 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)
Exemplo n.º 39
0
def test_user_model_stat_docs():
    """
    This test reproduces the documentation shown at:
    http://cxc.harvard.edu/sherpa4.4/statistics/#userstat

    and:
    http://cxc.harvard.edu/sherpa/threads/user_model/

    I tried to be as faithful as possible to the original, although the examples in thedocs
    are not completely self-contained, so some changes were necessary. I changed the numpy
    reference, as it is imported as `np` here, and added a clean up of the environment
    before doing anything.

    For the model, the difference is that I am not importing the function from an
    external module, plus the dataset is different.

    Also, the stats docs do not perform a fit.
    """
    def my_stat_func(data, model, staterror, syserror=None, weight=None):
        # A simple function to replicate χ2
        fvec = ((data - model) / staterror)**2
        stat = fvec.sum()
        return (stat, fvec)

    def my_staterr_func(data):
        # A simple staterror function
        return np.sqrt(data)

    def myline(pars, x):
        return pars[0]*x + pars[1]

    x = [1, 2, 3]
    y = [4, 5, 6.01]

    ui.clean()
    ui.load_arrays(1, x, y)
    ui.load_user_stat("mystat", my_stat_func, my_staterr_func)
    ui.set_stat(eval('mystat'))
    ui.load_user_model(myline, "myl")
    ui.add_user_pars("myl", ["m", "b"])
    ui.set_model(eval('myl'))

    ui.fit()

    assert ui.get_par("myl.m").val == approx(1, abs=0.01)
    assert ui.get_par("myl.b").val == approx(3, abs=0.01)
Exemplo n.º 40
0
    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)
Exemplo n.º 41
0
    def load_arrays(self, *args, **kwargs):
        """Load multiple data arrays.

        This extends ``sherpa.astro.ui.load_arrays`` to load multiple
        data sets with one call. The array arguments are supplied as an
        array of arrays, one for each data set. The other arguments are
        as supported by ``sherpa.astro.ui.load_arrays``.

        Examples
        --------

        Create three data sets, using the array pairs ``x1, y1``,
        ``x2, y2``, and ``x3, y3``.

        >>> load_arrays([[x1, y1], [x2, y2], [x3, y3]])

        """

        if len(args) == 0:
            raise AttributeError(
                "load_arrays takes at least one argument (got none).")

        if not hasattr(args[0], '__iter__'):
            id, args = args[0], args[1:]
        else:
            id = None

        if id is not None:
            if self._default_instance:
                ui.load_arrays(id, *args, **kwargs)
                return
            else:
                raise AttributeError(load_error_msg(id))

        # Array Stack.
        for arrays in args[0]:
            dataid = self._get_dataid()
            logger.info('Loading dataset id %s' % dataid)
            ui.load_arrays(dataid, *arrays)
            self._add_dataset(dataid)
Exemplo n.º 42
0
    def load_arrays(self, *args, **kwargs):
        if len(args) == 0:
            raise AttributeError("load_arrays takes at least one argument (got none).")

        if not hasattr(args[0], '__iter__'):
            id, args = args[0], args[1:]
        else:
            id = None

        if id is not None:
            if self is DATASTACK:
                ui.load_arrays(id, *args, **kwargs)
                return
            else:
                raise AttributeError("When called from a datastack instance, an ID cannot be provided to a load function ("+id+")")

        # Array Stack.
        for arrays in args[0]:
            dataid = self._get_dataid()
            logger.info('Loading dataset id %s' % dataid)
            ui.load_arrays(dataid, *arrays)
            self._add_dataset(dataid)
Exemplo n.º 43
0
import numpy as np
import sherpa.astro.ui as ui
from bb import BoxBOD, report_results

# Load data
ui.load_arrays(1, BoxBOD.x, BoxBOD.y, np.ones_like(BoxBOD.x))
# @todo: It is possible to give no staterror, but I'm not sure
# what Sherpa does then. fr.statval is no longer the correct chi2.

# Set up the model and load it as a Sherpa model
def boxbod_func(pars, x):
    b1, b2 = pars
    return BoxBOD.model(x, b1, b2)

ui.load_user_model(boxbod_func, "boxbod")
ui.add_user_pars("boxbod", ["b1", "b2"])
bb = boxbod
ui.set_model(bb)
bb.b1, bb.b2 = BoxBOD.p0[0], BoxBOD.p0[1]

# Perform fit
ui.set_stat('chi2datavar')
#ui.set_method('levmar') #  ['levmar', 'moncar', 'neldermead', 'simplex']
ui.set_method_opt('xtol', 1e-10)
ui.fit() # Compute best-fit parameters
ui.set_covar_opt('eps', 1e-5) # @todo: Why does this parameter have no effect
ui.covariance() # Compute covariance matrix (i.e. errors)
#ui.conf() # Compute profile errors
#ui.show_all() # Print a very nice summary of your session to less

# Report results
Exemplo n.º 44
0
        fit_stat = np.sum((adj - self.displ) ** 2)

        # 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)
Exemplo n.º 45
0
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)
Exemplo n.º 46
0
def fit_draws(draws, parname, nbins=50, params=None, plot=True, verbose=True):
    """Fit a gaussian to the histogram of the given parameter.

    Before using this routine you should use get_parameter_info()
    to extract the parameter info for use by get_draws(). This is
    because using this routine will invalidate the internal
    data structures that get_draws() uses when its params argument
    is None.

    If params is not None then it should be the return value of
    get_parameter_info().

    If plot is True then a plot of the histogram and fit will be
    made.

    If verbose is True then a quick comparison of the fit
    results will be displayed.
    """

    if parname not in draws["parnames"]:
        raise RuntimeError, "Unknown parameter '%s'" % parname

    # Exclude any point with an iteration number of 0
    #
    idx = draws["iteration"] > 0
    parvals = draws[parname][idx]

    (hy, hx) = np.histogram(parvals, bins=nbins, new=True)
    xlo = hx[:-1]
    xhi = hx[1:]

    id = parname
    ui.load_arrays(id, 0.5 * (xlo + xhi), hy)

    # We can guess the amplitude and position fairly reliably;
    # for the FWHM we just use the inter-quartile range of the
    # X axis.
    #
    ui.set_source(id, ui.gauss1d.gparam)
    gparam.pos = xlo[xlo.size // 2]
    gparam.ampl = hy[xlo.size // 2]
    gparam.fwhm = xlo[xlo.size * 3 // 4] - xlo[xlo.size // 4]

    # Get the best-fit value if available
    if params != None:
        p0 = dict(zip(params["parnames"], params["parvals"]))[parname]

    logger = logging.getLogger("sherpa")
    olvl = logger.level
    logger.setLevel(40)

    ostat = ui.get_stat_name()
    ui.set_stat("leastsq")
    ui.fit(id)
    ui.set_stat(ostat)

    logger.setLevel(olvl)

    if plot:
        # We manually create the plot since we want to use a histogram for the
        # data and the Sherpa plots use curves.
        #
        ##dplot = ui.get_data_plot(id)
        mplot = ui.get_model_plot(id)

        chips.lock()
        try:
            chips.open_undo_buffer()
            chips.erase()
            chips.add_histogram(xlo, xhi, hy)
            ##chips.add_histogram(xlo, xhi, mplot.y, ["line.color", "red", "line.style", "dot"])
            chips.add_curve(mplot.x, mplot.y, ["line.color", "red", "symbol.style", "none"])

            if params != None:
                chips.add_vline(p0, ["line.color", "green", "line.style", "longdash"])

            chips.set_plot_xlabel(parname)
        except:
            chips.discard_undo_buffer()
            chips.unlock()
            raise
        chips.close_undo_buffer()
        chips.unlock()

    sigma = gparam.fwhm.val / (2.0 * np.sqrt(2 * np.log(2)))

    if verbose:
        print ""
        print "Fit to histogram of draws for parameter %s gives" % parname
        print "     mean     = %g" % gparam.pos.val
        print "     sigma    = %g" % sigma
        print ""

        if params != None:
            idx = params["parnames"] == parname
            print "     best fit = %g" % p0
            print "  covar sigma = %g" % params["parmaxes"][idx][0]
            print ""

    return (gparam.pos.val, sigma, gparam.ampl.val)
Exemplo n.º 47
0
import sherpa.astro.ui as ui
from spec import load_data, report_results

# Load data
x, y, y_err = load_data()
ui.load_arrays(1, x, y, y_err)

# Set up the model
ui.set_model(ui.powlaw1d.pl)
pl.gamma, pl.ampl = 2, 1e-12

# Perform fit
ui.fit()  # Compute best-fit parameters
ui.covar()  # Compute covariance matrix (i.e. errors)
# ui.conf() # Compute profile errors
# ui.show_all() # Print a very nice summary of your session to less

# Report results
fr = ui.get_fit_results()
cr = ui.get_covar_results()

package = "sherpa"
gamma, norm = fr.parvals
chi2 = fr.statval
gamma_err, norm_err = cr.parmaxes
cov = cr.extra_output[1, 0]
corr = cov / (norm_err * gamma_err)
report_results(package, norm, norm_err, gamma, gamma_err, chi2, cov, corr)