Example #1
0
    def _fit_sherpa(self):
        """Wrapper around sherpa minimizer."""
        from sherpa.fit import Fit
        from sherpa.data import Data1DInt
        from sherpa.optmethods import NelderMead
        from .sherpa_utils import SherpaModel, SherpaStat

        binning = self.obs_list[0].e_reco
        # The sherpa data object is not usued in the fit. It is set to the
        # first observation for debugging purposes, see below
        data = self.obs_list[0].on_vector.data.data.value
        data = Data1DInt('Dummy data', binning[:-1].value, binning[1:].value,
                         data)
        # DEBUG
        # from sherpa.models import PowLaw1D
        # from sherpa.stats import Cash
        # model = PowLaw1D('sherpa')
        # model.ref = 0.1
        # fit = Fit(data, model, Cash(), NelderMead())

        # NOTE: We cannot use the Levenbergr-Marquart optimizer in Sherpa
        # because it relies on the fvec return value of the fit statistic (we
        # return None). The computation of fvec is not straightforwad, not just
        # stats per bin. E.g. for a cash fit the sherpa stat computes it
        # according to cstat
        # see https://github.com/sherpa/sherpa/blob/master/sherpa/include/sherpa/stats.hh#L122

        self._sherpa_fit = Fit(data, SherpaModel(self), SherpaStat(self),
                               NelderMead())
        fitresult = self._sherpa_fit.fit()
        log.debug(fitresult)
        self._make_fit_result(self.model.parameters)
def setup_data(elo=0.1, ehi=10.0, ebin=0.01):
    """Return a data set.

    Parameters
    ----------
    elo, ehi : number, optional
        The start and end energy of the grid, in keV.
    ebin : number, optional
        The bin width, in keV.

    Returns
    -------
    data : Data1DInt
        The data object. The Y values are not expected to be used,
        so are set to 1.

    """

    if elo >= ehi:
        raise ValueError("elo >= ehi")
    if elo <= 0:
        raise ValueError("elo <= 0")
    if ebin <= 0:
        raise ValueError("ebin <= 0")

    x = np.arange(elo, ehi + ebin, ebin)
    if x.size < 2:
        raise ValueError("elo, ehi, ebin not sensible")

    y = np.ones(x.size - 1)
    return Data1DInt('dummy', x[:-1], x[1:], y)
Example #3
0
def make_data(data_class):
    """Create a test data object of the given class.

    Using a string means it is easier to support the various PHA
    "types" - eg basic, grouping, grouping+quality.

    """

    x0 = np.asarray([1, 3, 7, 12])
    y = np.asarray([2, 3, 4, 5])
    if data_class == "1d":
        return Data1D('x1', x0, y)

    if data_class == "1dint":
        return Data1DInt('xint1', x0, np.asarray([3, 5, 8, 15]), y)

    chans = np.arange(1, 5)
    if data_class == "pha":
        return DataPHA('pha', chans, y)

    # We want to provide PHA tests that check out the grouping and
    # quality handling (but it is not worth trying all different
    # variants), so we have "grp" for grouping and no quality [*], and
    # "qual" for grouping and quality.
    #
    # [*] by which I mean we have not called ignore_bad, not that
    # there is no quality array.
    #
    grp = np.asarray([1, -1, 1, 1])
    qual = np.asarray([0, 0, 2, 0])
    pha = DataPHA('pha', chans, y, grouping=grp, quality=qual)
    if data_class == "grp":
        return pha

    if data_class == "qual":
        pha.ignore_bad()
        return pha

    x0 = np.asarray([1, 2, 3] * 2)
    x1 = np.asarray([1, 1, 1, 2, 2, 2])
    y = np.asarray([2, 3, 4, 5, 6, 7])
    if data_class == "2d":
        return Data2D('x2', x0, x1, y, shape=(2, 3))

    if data_class == "2dint":
        return Data2DInt('xint2', x0, x1, x0 + 1, x1 + 1, y, shape=(2, 3))

    if data_class == "img":
        return DataIMG('img', x0, x1, y, shape=(2, 3))

    if data_class == "imgint":
        return DataIMGInt('imgi', x0, x1, x0 + 1, x1 + 1, y, shape=(2, 3))

    assert False
Example #4
0
def test_histogram_can_not_set_x():
    """We cannot change the x accessor"""

    xlo = [10, 20, 40, 80]
    xhi = [20, 40, 60, 90]
    y = [1, 2, 3, 4]
    d = Data1DInt('xx', xlo, xhi, y)

    dp = sherpaplot.DataHistogramPlot()
    dp.prepare(d)

    with pytest.raises(AttributeError):
        dp.x = xlo
Example #5
0
def test_low_level_regrid1d_non_overlapping_not_allowed():
    """Integrated data space must not overlap"""

    tmp = np.linspace(1, 100, 10)
    y = np.ones((9, ))
    d = Data1DInt('tst', tmp[:-1], tmp[1:], np.ones((9, )))
    c = Box1D()
    lo = np.linspace(1, 100, 600)
    hi = np.linspace(2, 101, 600)
    with pytest.raises(ModelErr) as excinfo:
        c.regrid(lo, hi)

    assert ModelErr.dict['needsint'] in str(excinfo.value)
Example #6
0
def test_warning_plot_hist_linecolor(caplog):
    """We get a warning when using linecolor: ModelHistogramPlot"""

    data = Data1DInt('tst', np.asarray([1, 2, 3]), np.array([2, 2.5, 4]),
                     np.asarray([10, 12, 10.5]))
    mdl = Const1D()
    plot = ModelHistogramPlot()
    plot.prepare(data, mdl, stat=None)
    with caplog.at_level(logging.INFO, logger='sherpa'):
        plot.plot(linecolor='mousey')

    assert len(caplog.records) == 1
    lname, lvl, msg = caplog.record_tuples[0]
    assert lname == 'sherpa.plot.pylab_backend'
    assert lvl == logging.WARNING
    assert msg == 'The linecolor attribute (mousey) is unused.'
Example #7
0
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
Example #8
0
def test_low_level_regrid1d_int_full_overlap(requested, tol):
    """Base case of test_low_level_regrid1d_int_partial_overlap
    """

    # The range over which we want the model evaluated
    dx = 0.1
    xgrid = np.arange(2, 6, dx)
    xlo = xgrid[:-1]
    xhi = xgrid[1:]
    d = Data1DInt('tst', xlo, xhi, np.ones_like(xlo))

    mdl = Box1D()
    mdl.xlow = 3.1
    mdl.xhi = 4.2
    mdl.ampl = 0.4

    yexpected = d.eval_model(mdl)
    assert yexpected.min() == pytest.approx(0.0)
    assert yexpected.max() == pytest.approx(0.4 * dx)

    ygot = d.eval_model(mdl.regrid(requested[:-1], requested[1:]))
    assert ygot == pytest.approx(yexpected, abs=tol)
Example #9
0
def test_histogram_returns_x():
    """We support x accessor for histogram plots."""

    xlo = [10, 20, 40, 80]
    xhi = [20, 40, 60, 90]
    y = [1, 2, 3, 4]
    d = Data1DInt('xx', xlo, xhi, y)

    dp = sherpaplot.DataHistogramPlot()
    dp.prepare(d)

    xlo = numpy.asarray(xlo)
    xhi = numpy.asarray(xhi)

    assert dp.xlo == pytest.approx(xlo)
    assert dp.xhi == pytest.approx(xhi)
    assert dp.x == pytest.approx(0.5 * (xlo + xhi))

    # check x is not in the str output
    #
    for line in str(dp).split('\n'):
        toks = line.split()
        assert len(toks) > 2
        assert toks[0] != 'x'
Example #10
0
def test_low_level_regrid1d_int_partial_overlap(requested, tol):
    """What happens if there is partial overlap of the grid?

    See test_low_level_regrid1d_partial_overlap.

    See the comments for when the tol value is used (only for
    edges, not "flat" sections of the model).
    """

    # The range over which we want the model evaluated
    dx = 0.1
    xgrid = np.arange(2, 6, dx)
    xlo = xgrid[:-1]
    xhi = xgrid[1:]
    d = Data1DInt('tst', xlo, xhi, np.ones_like(xlo))

    mdl = Box1D()
    mdl.xlow = 3.1
    mdl.xhi = 4.2
    mdl.ampl = 0.4

    yexpected = d.eval_model(mdl)
    assert yexpected.min() == pytest.approx(0.0)
    assert yexpected.max() == pytest.approx(0.4 * dx)

    rlo = requested[:-1]
    rhi = requested[1:]
    ygot = d.eval_model(mdl.regrid(rlo, rhi))

    # Note that due to the different bin widths of the input and
    # output bins, the start and end bins of the integrated box
    # model will not line up nicely, and so the rising and falling
    # edges may cause differences for more than a single bin. We
    # can think of there being five regions (going from left to
    # right along the grid):
    #
    #    before
    #    rising edge
    #    middle of box
    #    falling edge
    #    after
    #
    # The expected bin values for the middle are 0.4 * dx = 0.04
    # and before and after should be 0. The edges depend on the
    # bin widths, so the tolerance here had been adjusted until
    # the tests pass.
    #
    before = np.arange(0, 10)
    rising = np.arange(10, 12)
    middle = np.arange(12, 21)
    trailing = np.arange(21, 23)
    after = np.arange(23, 39)

    # This ensures that if xgrid is changed (in length at least) we
    # have a reminder to check the above ranges.
    #
    assert len(xlo) == 39

    for idxs in [before, middle, after]:
        assert ygot[idxs] == pytest.approx(yexpected[idxs])

    for idxs in [rising, trailing]:
        assert ygot[idxs] == pytest.approx(yexpected[idxs], abs=tol)
Example #11
0
File: main.py Project: pllim/saba
    def _make_dataset(n_dim, x, y, z=None, xbinsize=None, ybinsize=None, err=None, bkg=None, bkg_scale=1, n=0):
        """
        Parameters
        ----------
        n_dim: int
            Used to veirfy required number of dimentions.
        x : array
            input coordinates
        y : array
            input coordinates
        z : array (optional)
            input coordinatesbkg
        xbinsize : array (optional)
            an array of errors in x
        ybinsize : array (optional)
            an array of errors in y
        err : array (optional)
            an array of errors in z
        n  : int
            used in error reporting

        Returns
        -------
        _data: a sherpa dataset
        """

        if (z is None and n_dim > 1) or (z is not None and n_dim == 1):
            raise ValueError("Model and data dimentions don't match in dataset %i" % n)

        if z is None:
            assert x.shape == y.shape, "shape of x and y don't match in dataset %i" % n
        else:
            z = np.asarray(z)
            assert x.shape == y.shape == z.shape, "shapes x,y and z don't match in dataset %i" % n

        if xbinsize is not None:
            xbinsize = np.array(xbinsize)
            assert x.shape == xbinsize.shape, "x's and xbinsize's shapes do not match in dataset %i" % n

        if z is not None and err is not None:
            err = np.array(err)
            assert z.shape == err.shape, "z's and err's shapes do not match in dataset %i" % n

            if ybinsize is not None:
                ybinsize = np.array(ybinsize)
                assert y.shape == ybinsize.shape, "y's and ybinsize's shapes do not match in dataset %i" % n

        else:
            if err is not None:
                err = np.array(err)
                assert y.shape == err.shape, "y's and err's shapes do not match in dataset %i" % n

        if xbinsize is not None:
            bs = xbinsize / 2.0

        if z is None:
            if xbinsize is None:
                if err is None:
                    if bkg is None:
                        data = Data1D("wrapped_data", x=x, y=y)
                    else:
                        data = Data1DBkg("wrapped_data", x=x, y=y, bkg=bkg, bkg_scale=bkg_scale)
                else:
                    if bkg is None:
                        data = Data1D("wrapped_data", x=x, y=y, staterror=err)
                    else:
                        data = Data1DBkg("wrapped_data", x=x, y=y, staterror=err, bkg=bkg, bkg_scale=bkg_scale)
            else:
                if err is None:
                    if bkg is None:

                        data = Data1DInt("wrapped_data", xlo=x - bs, xhi=x + bs, y=y)
                    else:
                        data = Data1DIntBkg("wrapped_data", xlo=x - bs, xhi=x + bs, y=y, bkg=bkg, bkg_scale=bkg_scale)
                else:
                    if bkg is None:
                        data = Data1DInt("wrapped_data", xlo=x - bs, xhi=x + bs, y=y, staterror=err)
                    else:
                        data = Data1DIntBkg("wrapped_data", xlo=x - bs, xhi=x + bs, y=y, staterror=err, bkg=bkg, bkg_scale=bkg_scale)
        else:
            if xbinsize is None and ybinsize is None:
                if err is None:
                    if bkg is None:
                        data = Data2D("wrapped_data", x0=x, x1=y, y=z)
                    else:
                        data = Data2DBkg("wrapped_data", x0=x, x1=y, y=z, bkg=bkg, bkg_scale=bkg_scale)
                else:
                    if bkg is None:
                        data = Data2D("wrapped_data", x0=x, x1=y, y=z, staterror=err)
                    else:
                        data = Data2DBkg("wrapped_data", x0=x, x1=y, y=z, staterror=err, bkg=bkg, bkg_scale=bkg_scale)
            elif xbinsize is not None and ybinsize is not None:
                ys = ybinsize / 2.0
                if err is None:
                    if bkg is None:
                        data = Data2DInt("wrapped_data", x0lo=x - bs, x0hi=x + bs, x1lo=y - ys, x1hi=y + ys, y=z)
                    else:
                        data = Data2DIntBkg("wrapped_data", x0lo=x - bs, x0hi=x + bs, x1lo=y - ys, x1hi=y + ys, y=z, bkg=bkg, bkg_scale=bkg_scale)
                else:
                    if bkg is None:
                        data = Data2DInt("wrapped_data", x0lo=x - bs, x0hi=x + bs, x1lo=y - ys, x1hi=y + ys, y=z, staterror=err)
                    else:
                        data = Data2DIntBkg("wrapped_data", x0lo=x - bs, x0hi=x + bs, x1lo=y - ys, x1hi=y + ys, y=z, staterror=err, bkg=bkg, bkg_scale=bkg_scale)
            else:
                raise ValueError("Set xbinsize and ybinsize, or set neither!")

        return data
Example #12
0
    print(eval(name))
    print("----------------------------------------")


def dump(name):
    print("# dump")
    print("{}".format(name))
    print(repr(eval(name)))
    print("----------------------------------------")


edges = np.asarray([-10, -5, 5, 12, 17, 20, 30, 56, 60])
y = np.asarray([28, 62, 17, 4, 2, 4, 125, 55])

from sherpa.data import Data1DInt
d = Data1DInt('example histogram', edges[:-1], edges[1:], y)

from sherpa.plot import DataPlot
dplot = DataPlot()
dplot.prepare(d)
dplot.plot()

savefig('dataplot_histogram.png')

from sherpa.plot import Histogram
hplot = Histogram()
hplot.overplot(d.xlo, d.xhi, d.y)

savefig('dataplot_histogram_overplot.png')

from sherpa.models.basic import Const1D, Gauss1D