示例#1
0
文件: data.py 项目: DougBurke/sherpa
    def notice(self, mins, maxes, axislist, ignore=False):

        ignore = bool_cast(ignore)
        if str in [type(min) for min in mins]:
            raise DataErr('typecheck', 'lower bound')
        elif str in [type(max) for max in maxes]:
            raise DataErr('typecheck', 'upper bound')
        elif str in [type(axis) for axis in axislist]:
            raise DataErr('typecheck', 'grid')

        mask = filter_bins(mins, maxes, axislist)

        if mask is None:
            self.mask = not ignore
        elif not ignore:
            if self.mask is True:
                self.mask = mask
            else:
                self.mask |= mask
        else:
            mask = ~mask
            if self.mask is False:
                self.mask = mask
            else:
                self.mask &= mask
示例#2
0
    def notice(self, mins, maxes, axislist, ignore=False):

        ignore = bool_cast(ignore)
        if str in [type(min) for min in mins]:
            raise DataErr('typecheck', 'lower bound')
        elif str in [type(max) for max in maxes]:
            raise DataErr('typecheck', 'upper bound')
        elif str in [type(axis) for axis in axislist]:
            raise DataErr('typecheck', 'grid')

        mask = filter_bins(mins, maxes, axislist)

        if mask is None:
            self.mask = not ignore
        elif not ignore:
            if self.mask is True:
                self.mask = mask
            else:
                self.mask |= mask
        else:
            mask = ~mask
            if self.mask is False:
                self.mask = mask
            else:
                self.mask &= mask
示例#3
0
def test_filter_bins_empty(los, his, axis):
    """Ensure filter_bins returns None if one input is empty."""

    # just check the input parameters include an empty array
    assert len(los) == 0 or len(his) == 0 or len(axis) == 0

    assert utils.filter_bins(los, his, [axis]) is None
示例#4
0
文件: plot.py 项目: wmclaugh/sherpa
    def prepare(self, data, src, lo=None, hi=None):
        # Note: src is source model before folding
        if not isinstance(data, DataPHA):
            raise IOErr('notpha', data.name)

        lo, hi = bounds_check(lo, hi)

        self.units = data.units
        if self.units == "channel":
            warning("Channel space is unappropriate for the PHA unfolded" +
                    " source model,\nusing energy.")
            self.units = "energy"

        self.xlabel = data.get_xlabel()
        self.title = f'Source Model of {data.name}'
        self.xlo, self.xhi = data._get_indep(filter=False)

        # Why do we not apply the mask at the end of prepare?
        #
        self.mask = filter_bins((lo, ), (hi, ), (self.xlo, ))

        # The source model is assumed to not contain an instrument model,
        # and so it evaluates the expected number of photons/cm^2/s in
        # each bin (or it can be thought of as a 1 second exposure).
        #
        self.y = src(self.xlo, self.xhi)
        prefix_quant = 'E'
        quant = 'keV'

        if self.units == "wavelength":
            # No other labels use the LaTeX forms for lambda and
            # Angstrom, so use the text version here too.
            # prefix_quant = to_latex('\\lambda')
            # quant = to_latex('\\AA')
            prefix_quant = 'lambda'
            quant = 'Angstrom'
            (self.xlo, self.xhi) = (self.xhi, self.xlo)

        xmid = abs(self.xhi - self.xlo)

        sqr = to_latex('^2')

        self.xlabel = f'{self.units.capitalize()} ({quant})'
        self.ylabel = f'%s  Photons/sec/cm{sqr}%s'

        if data.plot_fac == 0:
            self.y /= xmid
            self.ylabel = self.ylabel % (f'f({prefix_quant})', f'/{quant} ')

        elif data.plot_fac == 1:
            self.ylabel = self.ylabel % (f'{prefix_quant} f({prefix_quant})',
                                         '')

        elif data.plot_fac == 2:
            self.y *= xmid
            self.ylabel = self.ylabel % (
                f'{prefix_quant}{sqr} f({prefix_quant})', f' {quant} ')
        else:
            raise PlotErr('plotfac', 'Source', data.plot_fac)
示例#5
0
def test_filter_bins_two_none():
    """Use two different arrays for filtering with no filter.
    """

    y1 = [1, 2, 3, 4, 5]
    y2 = [10, 20, 30, 40, 50]

    flags = utils.filter_bins((None, None), (None, None), (y1, y2))
    assert flags is None
示例#6
0
def test_filter_bins_unordered():
    """What happens if the array is unordered?"""

    flags = utils.filter_bins((3, ), (8, ), [[1,4,3,7,8,10,5]])

    expected = [False, True, True, True, True, False, True]

    assert len(flags) == len(expected)
    for got, exp in zip(flags, expected):
        assert got == exp
示例#7
0
def test_filter_bins_one(lo, hi, res):
    """Can we filter the array between [lo,hi] [unintegrated]?

    This test is a regression test rather than a from-first-principles
    test: this is mainly relevant for the edge cases like: lo=hi and
    lo>hi.
    """

    dvals = numpy.asarray([1, 2, 3, 4, 5])
    flags = utils.filter_bins([lo], [hi], [dvals])
    assert flags == pytest.approx(res)

    # We can also check an identity: that
    #    a <= x <= b
    # is the same as
    #    a <= x
    #    x <= b
    #
    flags = utils.filter_bins([lo, None], [None, hi], [dvals, dvals])
    assert flags == pytest.approx(res)
示例#8
0
    def prepare(self, data, src, lo=None, hi=None):
        # Note: src is source model before folding
        if not isinstance(data, DataPHA):
            raise IOErr('notpha', data.name)

        lo, hi = bounds_check(lo, hi)

        self.units = data.units
        if self.units == "channel":
            warning("Channel space is unappropriate for the PHA unfolded" +
                    " source model,\nusing energy.")
            self.units = "energy"

        self.xlabel = data.get_xlabel()
        self.title = 'Source Model of %s' % data.name
        self.xlo, self.xhi = data._get_indep(filter=False)
        self.mask = filter_bins((lo, ), (hi, ), (self.xlo, ))
        self.y = src(self.xlo, self.xhi)
        prefix_quant = 'E'
        quant = 'keV'

        if self.units == "wavelength":
            # No other labels use the LaTeX forms for lambda and
            # Angstrom, so use the text version here too.
            # prefix_quant = to_latex('\\lambda')
            # quant = to_latex('\\AA')
            prefix_quant = 'lambda'
            quant = 'Angstrom'
            (self.xlo, self.xhi) = (self.xhi, self.xlo)

        xmid = abs(self.xhi - self.xlo)

        sqr = to_latex('^2')

        self.xlabel = '%s (%s)' % (self.units.capitalize(), quant)
        self.ylabel = '%s  Photons/sec/cm' + sqr + '%s'

        if data.plot_fac == 0:
            self.y /= xmid
            self.ylabel = self.ylabel % ('f(%s)' % prefix_quant,
                                         '/%s ' % quant)

        elif data.plot_fac == 1:
            self.ylabel = self.ylabel % ('%s f(%s)' %
                                         (prefix_quant, prefix_quant), '')

        elif data.plot_fac == 2:
            self.y *= xmid
            self.ylabel = self.ylabel % ('%s%s f(%s)' %
                                         (prefix_quant, sqr, prefix_quant),
                                         ' %s ' % quant)
        else:
            raise PlotErr('plotfac', 'Source', data.plot_fac)
示例#9
0
文件: plot.py 项目: DougBurke/sherpa
    def prepare(self, data, src, lo=None, hi=None):
        # Note: src is source model before folding
        if not isinstance(data, DataPHA):
            raise IOErr('notpha', data.name)

        lo, hi = bounds_check(lo, hi)

        self.units = data.units
        if self.units == "channel":
            warning("Channel space is unappropriate for the PHA unfolded" +
                    " source model,\nusing energy.")
            self.units = "energy"

        self.xlabel = data.get_xlabel()
        self.title  = 'Source Model of %s' % data.name
        self.xlo, self.xhi = data._get_indep(filter=False)
        self.mask = filter_bins((lo,), (hi,), (self.xlo,))
        self.y = src(self.xlo, self.xhi)
        prefix_quant = 'E'
        quant = 'keV'

        if self.units == "wavelength":
            # No other labels use the LaTeX forms for lambda and
            # Angstrom, so use the text version here too.
            # prefix_quant = to_latex('\\lambda')
            # quant = to_latex('\\AA')
            prefix_quant = 'lambda'
            quant = 'Angstrom'
            (self.xlo, self.xhi) = (self.xhi, self.xlo)

        xmid = abs(self.xhi - self.xlo)

        sqr = to_latex('^2')

        self.xlabel = '%s (%s)' % (self.units.capitalize(), quant)
        self.ylabel = '%s  Photons/sec/cm' + sqr + '%s'

        if data.plot_fac == 0:
            self.y /= xmid
            self.ylabel = self.ylabel % ('f(%s)' % prefix_quant,
                                         '/%s ' % quant)

        elif data.plot_fac == 1:
            self.ylabel = self.ylabel % ('%s f(%s)' % (prefix_quant,
                                                       prefix_quant), '')

        elif data.plot_fac == 2:
            self.y *= xmid
            self.ylabel = self.ylabel % ('%s%s f(%s)' % (prefix_quant, sqr,
                                                         prefix_quant),
                                         ' %s ' % quant)
        else:
            raise PlotErr('plotfac', 'Source', data.plot_fac)
示例#10
0
def test_filter_bins_two(lo1, lo2, hi1, hi2, expected):
    """Use two different arrays for filtering.

    This version uses tuples rather than arrays as the
    input arguments to filter_bins.

    """

    y1 = [1, 2, 3, 4, 5]
    y2 = [10, 20, 30, 40, 50]

    flags = utils.filter_bins((lo1, lo2), (hi1, hi2), (y1, y2))
    assert len(flags) == 5
    for i in range(5):
        assert flags[i] == expected[i], i
示例#11
0
def test_filter_bins_one_int(lo, hi, res):
    """Can we filter the array between [lo,hi) [integrated]?

    This test is a regression test rather than a from-first-principles
    test: this is mainly relevant for the edge cases like: lo=hi and
    lo>hi.

    The test replicates the logic of Data1DInt.notice
    """

    lovals = numpy.asarray([1, 2, 3, 4, 5])
    hivals = lovals + 1
    flags = utils.filter_bins([None, lo], [hi, None], [lovals, hivals],
                              integrated=True)
    assert flags == pytest.approx(res)
示例#12
0
def _flux(data, lo, hi, src, eflux=False, srcflux=False):
    lo, hi = bounds_check(lo, hi)

    axislist = None
    if hasattr(data, '_get_indep'):
        axislist = data._get_indep(filter=False)
    else:
        axislist = data.get_indep(filter=False)

    y = src(*axislist)

    if srcflux and len(axislist) > 1:
        y /= numpy.asarray(axislist[1] - axislist[0])

    dim = numpy.asarray(axislist).squeeze().ndim
    if eflux:
        # for energy flux, the sum of grid below must be in keV.
        energ = []
        for axis in axislist:
            grid = axis
            if hasattr(data, 'units') and data.units == 'wavelength':
                grid = data._hc / grid
            energ.append(grid)

        if dim == 1:
            y = numpy.asarray(0.5 * y * energ[0], SherpaFloat)
        elif dim == 2:
            y = numpy.asarray(0.5 * y * (energ[0] + energ[1]),
                              SherpaFloat)
        else:
            raise IOErr('>axes', "2")

    mask = filter_bins((lo,), (hi,), (axislist[0],))

    val = y.sum()
    if mask is not None:
        flux = y[mask]
        # flux density at a single bin -> divide by bin width.
        if dim == 2 and len(flux) == 1:
            flux /= numpy.abs(axislist[1][mask] - axislist[0][mask])
        val = flux.sum()

    if eflux:
        val *= _charge_e

    return val
示例#13
0
    def prepare(self, data, src, lo=None, hi=None):
        # Note: src is source model before folding
        if not isinstance(data, DataPHA):
            raise IOErr("notpha", data.name)

        lo, hi = bounds_check(lo, hi)

        self.units = data.units
        if self.units == "channel":
            warning("Channel space is unappropriate for the PHA unfolded" + " source model,\nusing energy.")
            self.units = "energy"

        self.xlabel = data.get_xlabel()
        self.title = "Source Model of %s" % data.name
        self.xlo, self.xhi = data._get_indep(filter=False)
        self.mask = filter_bins((lo,), (hi,), (self.xlo,))
        self.y = src(self.xlo, self.xhi)
        prefix_quant = "E"
        quant = "keV"

        if self.units == "wavelength":
            prefix_quant = "\\lambda"
            quant = "\\AA"
            (self.xlo, self.xhi) = (self.xhi, self.xlo)

        xmid = abs(self.xhi - self.xlo)

        self.xlabel = "%s (%s)" % (self.units.capitalize(), quant)
        self.ylabel = "%s  Photons/sec/cm^2%s"

        if data.plot_fac == 0:
            self.y /= xmid
            self.ylabel = self.ylabel % ("f(%s)" % prefix_quant, "/%s " % quant)

        elif data.plot_fac == 1:
            self.ylabel = self.ylabel % ("%s f(%s)" % (prefix_quant, prefix_quant), "")

        elif data.plot_fac == 2:
            self.y *= xmid
            self.ylabel = self.ylabel % ("%s^{2} f(%s)" % (prefix_quant, prefix_quant), " %s " % quant)
        else:
            raise PlotErr("plotfac", "Source", data.plot_fac)
示例#14
0
def eqwidth(data, model, combo, lo=None, hi=None):

    lo, hi = bounds_check(lo, hi)

    my = None
    cy = None
    xlo = None
    xhi = None
    num = None
    eqw = 0.0
    if hasattr(data, 'get_response'):
        xlo, xhi = data._get_indep(filter=False)
        my = model(xlo, xhi)
        cy = combo(xlo, xhi)
        num = len(xlo)
    else:
        my = data.eval_model_to_fit(model)
        cy = data.eval_model_to_fit(combo)
        xlo = data.get_indep(filter=True)[0]
        num = len(xlo)

    # TODO: should this follow _flux and handle the case when
    #       we have xlo, xhi differently?
    #
    mask = filter_bins((lo, ), (hi, ), (xlo, ))
    if mask is not None:
        my = my[mask]
        cy = cy[mask]
        xlo = xlo[mask]
        num = len(xlo)

    for ebin, val in enumerate(xlo):
        if ebin < (num - 1):
            eave = numpy.abs(xlo[ebin + 1] - xlo[ebin])
        else:
            eave = numpy.abs(xlo[ebin - 1] - xlo[ebin])
        if my[ebin] != 0.0:
            eqw += eave * (cy[ebin] - my[ebin]) / my[ebin]

    return eqw
示例#15
0
文件: __init__.py 项目: mirca/sherpa
def eqwidth(data, model, combo, lo=None, hi=None):

    lo, hi = bounds_check(lo, hi)

    my = None
    cy = None
    xlo = None
    xhi = None
    num = None
    eqw = 0.0
    if hasattr(data, 'get_response'):
        xlo, xhi = data._get_indep(filter=False)
        my = model(xlo, xhi)
        cy = combo(xlo, xhi)
        num = len(xlo)
    else:
        my = data.eval_model_to_fit(model)
        cy = data.eval_model_to_fit(combo)
        xlo = data.get_indep(filter=True)[0]
        num = len(xlo)

    mask = filter_bins((lo,), (hi,), (xlo,))
    if mask is not None:
        my = my[mask]
        cy = cy[mask]
        xlo = xlo[mask]
        num = len(xlo)

    for ebin, val in enumerate(xlo):
        if ebin < (num - 1):
            eave = numpy.abs(xlo[ebin + 1] - xlo[ebin])
        else:
            eave = numpy.abs(xlo[ebin - 1] - xlo[ebin])
        if my[ebin] != 0.0:
            eqw += eave * (cy[ebin] - my[ebin]) / my[ebin]

    return eqw
示例#16
0
def test_filter_bins_one(lo, hi, res):
    """Can we filter the array between lo and hi?"""

    dvals = numpy.asarray([1, 2, 3, 4, 5])
    flags = utils.filter_bins([lo], [hi], [dvals])
    assert (flags == res).all()
示例#17
0
def _flux(data, lo, hi, src, eflux=False, srcflux=False):
    lo, hi = bounds_check(lo, hi)

    try:
        method = data._get_indep
    except AttributeError:
        method = data.get_indep

    axislist = method(filter=False)
    dim = numpy.asarray(axislist).squeeze().ndim
    if dim > 2:
        raise IOErr('>axes', "2")

    # assume this should not happen, so we do not have to worry
    # about a nice error message
    assert dim > 0

    # To make things simpler, evaluate on the full grid
    y = src(*axislist)

    if srcflux and dim == 2:
        y /= numpy.asarray(axislist[1] - axislist[0])

    if eflux:
        # for energy flux, the sum of grid below must be in keV.
        #
        energ = []
        convert = hasattr(data, 'units') and data.units == 'wavelength'

        for axis in axislist:
            grid = axis
            if convert:
                grid = data._hc / grid
            energ.append(grid)

        if dim == 2:
            ecorr = 0.5 * (energ[0] + energ[1])
        else:
            # why multiply by 0.5?
            ecorr = 0.5 * energ[0]

        y *= ecorr

    # What bins do we use for the calculation? Linear interpolation
    # is used for bin edges (for integrated data sets)
    #
    if dim == 1:
        mask = filter_bins((lo, ), (hi, ), (axislist[0], ))
        assert mask is not None

        # no bin found
        if numpy.all(~mask):
            return 0.0

        # convert boolean to numbers
        scale = 1.0 * mask

    else:
        scale = range_overlap_1dint(axislist, lo, hi)
        if scale is None:
            return 0.0

        assert scale.max() > 0

    # Originally a flux density was calculated if both lo and hi
    # fell in the same bin, but this has been changed so that
    # we only calculate a density if the lo and hi values are the
    # same (which is set by bounds_check when a density is requested).
    #
    if lo is not None and dim == 2 and lo == hi:
        assert scale.sum() == 1, 'programmer error: sum={}'.format(scale.sum())
        y /= numpy.abs(axislist[1] - axislist[0])

    flux = (scale * y).sum()
    if eflux:
        flux *= _charge_e

    return flux
示例#18
0
def test_filter_bins_scalar_array(axval, flag):
    """Edge case: do we care about this result?"""

    f = utils.filter_bins([1], [5], [axval])
    assert f == flag
示例#19
0
def test_filter_bins_scalar_array_empty():
    """Edge case: do we care about this result?"""

    f = utils.filter_bins([1], [2], [[]])
    assert f.dtype == bool
    assert len(f) == 0