예제 #1
0
파일: instrument.py 프로젝트: mirca/sherpa
class RSPModelPHA(RSPModel):

    """
    RMF + ARF convolution model with associated PHA
    """

    def __init__(self, arf, rmf, pha, model):
        self.pha = pha
        self._arf = arf
        self._rmf = rmf
        RSPModel.__init__(self, arf, rmf, model)

    def filter(self):

        RSPModel.filter(self)

        pha = self.pha
        # If PHA is a finer grid than RMF, evaluate model on PHA and
        # rebin down to the granularity that the RMF expects.
        if pha.bin_lo is not None and pha.bin_hi is not None:
            bin_lo, bin_hi = pha.bin_lo, pha.bin_hi

            # If PHA grid is in angstroms then convert to keV for
            # consistency
            if (bin_lo[0] > bin_lo[-1]) and (bin_hi[0] > bin_hi[-1]):
                bin_lo = DataPHA._hc / pha.bin_hi
                bin_hi = DataPHA._hc / pha.bin_lo

            # FIXME: What about filtered option?? bin_lo, bin_hi are
            # unfiltered??

            # Compare disparate grids in energy space
            self.arfargs = ((self.elo, self.ehi), (bin_lo, bin_hi))

            # FIXME: Assumes ARF grid is finest

        elo, ehi = self.rmf.get_indep()
        # self.elo, self.ehi are from ARF
        if len(elo) != len(self.elo) and len(ehi) != len(self.ehi):

            self.rmfargs = ((elo, ehi), (self.elo, self.ehi))

        # Assume energy as default spectral coordinates
        self.xlo, self.xhi = self.elo, self.ehi
        if self.pha.units == 'wavelength':
            self.xlo, self.xhi = self.lo, self.hi

    def startup(self):
        arf = self._arf
        rmf = self._rmf

        # Create a view of original RMF
        self.rmf = DataRMF(rmf.name, rmf.detchans, rmf.energ_lo, rmf.energ_hi,
                           rmf.n_grp, rmf.f_chan, rmf.n_chan, rmf.matrix,
                           rmf.offset, rmf.e_min, rmf.e_max, rmf.header)

        # Create a view of original ARF
        self.arf = DataARF(arf.name, arf.energ_lo, arf.energ_hi, arf.specresp,
                           arf.bin_lo, arf.bin_hi, arf.exposure, arf.header)

        # Filter the view for current fitting session
        _notice_resp(self.pha.get_noticed_channels(), self.arf, self.rmf)

        self.filter()

        # Assume energy as default spectral coordinates
        self.xlo, self.xhi = self.elo, self.ehi
        if self.pha.units == 'wavelength':
            self.xlo, self.xhi = self.lo, self.hi

        RSPModel.startup(self)

    def teardown(self):
        self.arf = self._arf  # restore originals
        self.rmf = self._rmf

        self.filter()
        RSPModel.teardown(self)

    def calc(self, p, x, xhi=None, *args, **kwargs):
        # x could be channels or x, xhi could be energy|wave

        src = self.model.calc(p, self.xlo, self.xhi)
        src = self.arf.apply_arf(src, *self.arfargs)
        return self.rmf.apply_rmf(src, *self.rmfargs)
예제 #2
0
class RSPModelPHA(RSPModel):
    """RMF + ARF convolution model with associated PHA.

    Notes
    -----
    Scaling by the AREASCAL setting (scalar or array) is included in
    this model.
    """
    def __init__(self, arf, rmf, pha, model):
        self.pha = pha
        self._arf = arf
        self._rmf = rmf
        RSPModel.__init__(self, arf, rmf, model)

    def filter(self):

        RSPModel.filter(self)

        pha = self.pha
        # If PHA is a finer grid than RMF, evaluate model on PHA and
        # rebin down to the granularity that the RMF expects.
        if pha.bin_lo is not None and pha.bin_hi is not None:
            bin_lo, bin_hi = pha.bin_lo, pha.bin_hi

            # If PHA grid is in angstroms then convert to keV for
            # consistency
            if (bin_lo[0] > bin_lo[-1]) and (bin_hi[0] > bin_hi[-1]):
                bin_lo = DataPHA._hc / pha.bin_hi
                bin_hi = DataPHA._hc / pha.bin_lo

            # FIXME: What about filtered option?? bin_lo, bin_hi are
            # unfiltered??

            # Compare disparate grids in energy space
            self.arfargs = ((self.elo, self.ehi), (bin_lo, bin_hi))

            # FIXME: Assumes ARF grid is finest

        elo, ehi = self.rmf.get_indep()
        # self.elo, self.ehi are from ARF
        if len(elo) != len(self.elo) and len(ehi) != len(self.ehi):

            self.rmfargs = ((elo, ehi), (self.elo, self.ehi))

        # Assume energy as default spectral coordinates
        self.xlo, self.xhi = self.elo, self.ehi
        if self.pha.units == 'wavelength':
            self.xlo, self.xhi = self.lo, self.hi

    def startup(self, cache):
        arf = self._arf
        rmf = self._rmf

        # Create a view of original RMF
        self.rmf = DataRMF(rmf.name, rmf.detchans, rmf.energ_lo, rmf.energ_hi,
                           rmf.n_grp, rmf.f_chan, rmf.n_chan, rmf.matrix,
                           rmf.offset, rmf.e_min, rmf.e_max, rmf.header)

        # Create a view of original ARF
        self.arf = DataARF(arf.name, arf.energ_lo, arf.energ_hi, arf.specresp,
                           arf.bin_lo, arf.bin_hi, arf.exposure, arf.header)

        # Filter the view for current fitting session
        _notice_resp(self.pha.get_noticed_channels(), self.arf, self.rmf)

        self.filter()

        # Assume energy as default spectral coordinates
        self.xlo, self.xhi = self.elo, self.ehi
        if self.pha.units == 'wavelength':
            self.xlo, self.xhi = self.lo, self.hi

        RSPModel.startup(self, cache)

    def teardown(self):
        self.arf = self._arf  # restore originals
        self.rmf = self._rmf

        self.filter()
        RSPModel.teardown(self)

    def calc(self, p, x, xhi=None, *args, **kwargs):
        # x could be channels or x, xhi could be energy|wave

        src = self.model.calc(p, self.xlo, self.xhi)
        src = self.arf.apply_arf(src, *self.arfargs)
        src = self.rmf.apply_rmf(src, *self.rmfargs)

        # Assume any issues with the binning (between AREASCAL
        # and src) is related to the RMF rather than the ARF.
        return apply_areascal(src, self.pha, "RMF: {}".format(self.rmf.name))
예제 #3
0
파일: instrument.py 프로젝트: mirca/sherpa
class ARFModelPHA(ARFModel):

    """
    ARF convolution model with associated PHA
    """

    def __init__(self, arf, pha, model):
        self.pha = pha
        self._arf = arf  # store a reference to original
        ARFModel.__init__(self, arf, model)

    def filter(self):

        ARFModel.filter(self)

        pha = self.pha
        # If PHA is a finer grid than ARF, evaluate model on PHA and
        # rebin down to the granularity that the ARF expects.
        if pha.bin_lo is not None and pha.bin_hi is not None:
            bin_lo, bin_hi = pha.bin_lo, pha.bin_hi

            # If PHA grid is in angstroms then convert to keV for
            # consistency
            if (bin_lo[0] > bin_lo[-1]) and (bin_hi[0] > bin_hi[-1]):
                bin_lo = DataPHA._hc / pha.bin_hi
                bin_hi = DataPHA._hc / pha.bin_lo

            # FIXME: What about filtered option?? bin_lo, bin_hi are
            # unfiltered??

            # Compare disparate grids in energy space
            self.arfargs = ((self.elo, self.ehi), (bin_lo, bin_hi))

            # FIXME: Assumes ARF grid is finest

        # Assume energy as default spectral coordinates
        self.xlo, self.xhi = self.elo, self.ehi
        if self.pha.units == 'wavelength':
            self.xlo, self.xhi = self.lo, self.hi

    def startup(self):
        arf = self._arf  # original
        pha = self.pha

        # Create a view of original ARF
        self.arf = DataARF(arf.name, arf.energ_lo, arf.energ_hi, arf.specresp,
                           arf.bin_lo, arf.bin_hi, arf.exposure, arf.header)

        # Filter the view for current fitting session
        if numpy.iterable(pha.mask):
            mask = pha.get_mask()
            if len(mask) == len(self.arf.specresp):
                self.arf.notice(mask)

        self.filter()

        # Assume energy as default spectral coordinates
        self.xlo, self.xhi = self.elo, self.ehi
        if pha.units == 'wavelength':
            self.xlo, self.xhi = self.lo, self.hi

        ARFModel.startup(self)

    def teardown(self):
        self.arf = self._arf  # restore original

        self.filter()
        ARFModel.teardown(self)

    def calc(self, p, x, xhi=None, *args, **kwargs):
        # x could be channels or x, xhi could be energy|wave

        src = self.model.calc(p, self.xlo, self.xhi)
        return self.arf.apply_arf(src, *self.arfargs)
예제 #4
0
class ARFModelPHA(ARFModel):
    """ARF convolution model with associated PHA data set.

    Notes
    -----
    Scaling by the AREASCAL setting (scalar or array) is included in
    this model. It is not yet clear if this is handled correctly.
    """
    def __init__(self, arf, pha, model):
        self.pha = pha
        self._arf = arf  # store a reference to original
        ARFModel.__init__(self, arf, model)

    def filter(self):

        ARFModel.filter(self)

        pha = self.pha
        # If PHA is a finer grid than ARF, evaluate model on PHA and
        # rebin down to the granularity that the ARF expects.
        if pha.bin_lo is not None and pha.bin_hi is not None:
            bin_lo, bin_hi = pha.bin_lo, pha.bin_hi

            # If PHA grid is in angstroms then convert to keV for
            # consistency
            if (bin_lo[0] > bin_lo[-1]) and (bin_hi[0] > bin_hi[-1]):
                bin_lo = DataPHA._hc / pha.bin_hi
                bin_hi = DataPHA._hc / pha.bin_lo

            # FIXME: What about filtered option?? bin_lo, bin_hi are
            # unfiltered??

            # Compare disparate grids in energy space
            self.arfargs = ((self.elo, self.ehi), (bin_lo, bin_hi))

            # FIXME: Assumes ARF grid is finest

        # Assume energy as default spectral coordinates
        self.xlo, self.xhi = self.elo, self.ehi
        if self.pha.units == 'wavelength':
            self.xlo, self.xhi = self.lo, self.hi

    def startup(self, cache):
        arf = self._arf  # original
        pha = self.pha

        # Create a view of original ARF
        self.arf = DataARF(arf.name, arf.energ_lo, arf.energ_hi, arf.specresp,
                           arf.bin_lo, arf.bin_hi, arf.exposure, arf.header)

        # Filter the view for current fitting session
        if numpy.iterable(pha.mask):
            mask = pha.get_mask()
            if len(mask) == len(self.arf.specresp):
                self.arf.notice(mask)

        self.filter()

        # Assume energy as default spectral coordinates
        self.xlo, self.xhi = self.elo, self.ehi
        if pha.units == 'wavelength':
            self.xlo, self.xhi = self.lo, self.hi

        ARFModel.startup(self, cache)

    def teardown(self):
        self.arf = self._arf  # restore original

        self.filter()
        ARFModel.teardown(self)

    def calc(self, p, x, xhi=None, *args, **kwargs):
        # x could be channels or x, xhi could be energy|wave

        src = self.model.calc(p, self.xlo, self.xhi)
        src = self.arf.apply_arf(src, *self.arfargs)

        return apply_areascal(src, self.pha, "ARF: {}".format(self.arf.name))