Пример #1
0
    def get_scales(self, fit, myscales=None):

        scales = []
        thawedpars = [par for par in fit.model.pars if not par.frozen]

        if None == myscales:

            oldestmethod = fit.estmethod

            covar = Covariance()
            covar.config['sigma'] = self.sigma
            fit.estmethod = Covariance()

            try:
                r = fit.est_errors()
            finally:
                fit.estmethod = oldestmethod

            for par, val, lo, hi in izip(thawedpars, r.parvals, r.parmins, r.parmaxes):
                scale = None
                if lo is not None and hi is not None:
                    scale = numpy.abs(lo)
                else:
                    warning("Covariance failed for '%s', trying Confidence..." %
                            par.fullname)

                    conf = Confidence()
                    conf.config['sigma'] = self.sigma
                    fit.estmethod = conf
                    try:
                        t = fit.est_errors(parlist=(par,))
                        if t.parmins[0] is not None and t.parmaxes[0] is not None:
                            scale = numpy.abs(t.parmins[0])

                        else:

                            if t.parmins[0] is None and t.parmaxes[0] is not None:
                                scale = numpy.abs(t.parmaxes[0])

                            else:

                                warning('1 sigma bounds for parameter ' +
                                        par.fullname +
                                        ' could not be found, using soft limit minimum')
                                if 0.0 == numpy.abs(par.min):
                                    scale = 1.0e-16
                                else:
                                    scale = numpy.abs(par.min)

                    finally:
                        fit.estmethod = oldestmethod
                scales.append(scale)

        else:
            if not numpy.iterable(myscales):
                raise TypeError(
                    "scales option must be iterable of length %d " % len(thawedpars))
            scales = map(abs, myscales)
        scales = numpy.asarray(scales).transpose()
        return scales
Пример #2
0
    def get_scales(self, fit, myscales=None):

        scales = []
        thawedpars = [par for par in fit.model.pars if not par.frozen]

        if None == myscales:

            oldestmethod = fit.estmethod

            covar = Covariance()
            covar.config['sigma'] = self.sigma
            fit.estmethod = Covariance()

            try:
                r = fit.est_errors()
            finally:
                fit.estmethod = oldestmethod

            for par, val, lo, hi in zip(thawedpars, r.parvals, r.parmins, r.parmaxes):
                scale = None
                if lo is not None and hi is not None:
                    scale = numpy.abs(lo)
                else:
                    warning("Covariance failed for '%s', trying Confidence..." %
                            par.fullname)

                    conf = Confidence()
                    conf.config['sigma'] = self.sigma
                    fit.estmethod = conf
                    try:
                        t = fit.est_errors(parlist=(par,))
                        if t.parmins[0] is not None and t.parmaxes[0] is not None:
                            scale = numpy.abs(t.parmins[0])

                        else:

                            if t.parmins[0] is None and t.parmaxes[0] is not None:
                                scale = numpy.abs(t.parmaxes[0])

                            else:

                                warning('1 sigma bounds for parameter ' +
                                        par.fullname +
                                        ' could not be found, using soft limit minimum')
                                if 0.0 == numpy.abs(par.min):
                                    scale = 1.0e-16
                                else:
                                    scale = numpy.abs(par.min)

                    finally:
                        fit.estmethod = oldestmethod
                scales.append(scale)

        else:
            if not numpy.iterable(myscales):
                raise TypeError(
                    "scales option must be iterable of length %d " % len(thawedpars))
            scales = list(map(abs, myscales))
        scales = numpy.asarray(scales).transpose()
        return scales
Пример #3
0
def test_covar():
    standard = numpy.array([[0.4935702, 0.06857833, numpy.nan],
                            [0.06857833, 0.26405554, numpy.nan],
                            [numpy.nan, numpy.nan, 2.58857314]])

    cov = Covariance()
    results = cov.compute(stat, None, fittedpars, minpars, maxpars,
                          hardminpars, hardmaxpars, limit_parnums, freeze_par,
                          thaw_par, report_progress, get_par_name)

    # These tests used to have a tolerance of 1e-4 but it appears to
    # be able to use a more-restrictive tolerance.
    #
    expected = standard.diagonal()
    assert results[1] == pytest.approx(expected)
Пример #4
0
 def setUp(self):
     self.method = LevMar()
     self.stat = Chi2Gehrels()
     self.est = Covariance()
     self.gro_fname = self.make_path('gro.txt')
     self.gro_delta_fname = self.make_path('gro_delta.txt')        
     return
Пример #5
0
    def setUp(self):
        try:
            from sherpa.astro.io import read_pha
            from sherpa.astro.xspec import XSwabs, XSpowerlaw
        except:
            return
        # self.startdir = os.getcwd()
        self.old_level = logger.getEffectiveLevel()
        logger.setLevel(logging.CRITICAL)

        pha = self.make_path("refake_0934_1_21_1e4.fak")
        # rmf = self.make_path("ccdid7_default.rmf")
        # arf = self.make_path("quiet_0934.arf")

        self.simarf = self.make_path("aref_sample.fits")
        self.pcaarf = self.make_path("aref_Cedge.fits")

        data = read_pha(pha)
        data.ignore(None, 0.3)
        data.ignore(7.0, None)

        rsp = Response1D(data)
        self.abs1 = XSwabs('abs1')
        self.p1 = XSpowerlaw('p1')
        model = rsp(self.abs1 * self.p1)

        self.fit = Fit(data, model, CStat(), NelderMead(), Covariance())
Пример #6
0
    def fit(self, current):
        self._fit.model.thawedpars = current

        # nm = NelderMead()
        # nm.config['iquad'] = 0
        # nm.config['finalsimplex'] = 1

        #lm = LevMar()
        #lm.config['maxfev'] = 5

        cv = Covariance()

        # Use the fit method defined before called get_draws().  This way the user
        # does not have to pass in the fitting method and method options.
        fit = Fit(self._fit.data, self._fit.model, self._fit.stat,
                  self._fit.method, cv)

        fit_result = fit.fit()
        covar_result = fit.est_errors()
        sigma = np.array(covar_result.extra_output)

        if np.isnan(sigma).any():
            raise CovarError("NaNs found in covariance matrix")

        # cache the fitting scales
        self._sigma = sigma
Пример #7
0
def setup(make_data_path):
    from sherpa.astro.io import read_pha
    from sherpa.astro.xspec import XSwabs, XSpowerlaw

    old_level = logger.getEffectiveLevel()
    logger.setLevel(logging.CRITICAL)

    pha = make_data_path("refake_0934_1_21_1e4.fak")

    simarf = make_data_path("aref_sample.fits")
    pcaarf = make_data_path("aref_Cedge.fits")

    data = read_pha(pha)
    data.ignore(None, 0.3)
    data.ignore(7.0, None)

    rsp = Response1D(data)
    abs1 = XSwabs('abs1')
    p1 = XSpowerlaw('p1')
    model = rsp(abs1 * p1)

    abs1.nh = 0.092886
    p1.phoindex = 0.994544
    p1.norm = 9.26369

    fit = Fit(data, model, CStat(), NelderMead(), Covariance())

    yield {'simarf': simarf,
           'pcaarf': pcaarf,
           'niter': 10,
           'fit': fit}

    # Reset the logger
    logger.setLevel(old_level)
Пример #8
0
def setup():
    data = Data1D('fake', _x, _y, _err)

    g1 = Gauss1D('g1')
    g1.fwhm.set(1.0, _tiny, _max, frozen=False)
    g1.pos.set(1.0, -_max, _max, frozen=False)
    g1.ampl.set(1.0, -_max, _max, frozen=False)
    p1 = PowLaw1D('p1')
    p1.gamma.set(1.0, -10, 10, frozen=False)
    p1.ampl.set(1.0, 0.0, _max, frozen=False)
    p1.ref.set(1.0, -_max, _max, frozen=True)
    model = p1 + g1

    method = LevMar()
    method.config['maxfev'] = 10000
    method.config['ftol'] = float(_eps)
    method.config['epsfcn'] = float(_eps)
    method.config['gtol'] = float(_eps)
    method.config['xtol'] = float(_eps)
    method.config['factor'] = float(100)

    fit = Fit(data, model, Chi2DataVar(), method, Covariance())
    results = fit.fit()

    for key in ["succeeded", "numpoints", "nfev"]:
        assert _fit_results_bench[key] == int(getattr(results, key))

    for key in ["rstat", "qval", "statval", "dof"]:
        # used rel and abs tol of 1e-7 with numpy allclose
        assert float(getattr(results,
                             key)) == pytest.approx(_fit_results_bench[key])

    for key in ["parvals"]:
        try:
            # used rel and abs tol of 1e-4 with numpy allclose
            assert getattr(results,
                           key) == pytest.approx(_fit_results_bench[key])
        except AssertionError:
            print('parvals bench: ', _fit_results_bench[key])
            print('parvals fit:   ', getattr(results, key))
            print('results', results)
            raise

    fields = [
        'data', 'model', 'method', 'fit', 'results', 'covresults', 'dof', 'mu',
        'num'
    ]
    out = namedtuple('Results', fields)

    out.data = data
    out.model = model
    out.method = method
    out.fit = fit
    out.results = results
    out.covresults = fit.est_errors()
    out.dof = results.dof
    out.mu = numpy.array(results.parvals)
    out.cov = numpy.array(out.covresults.extra_output)
    out.num = 10
    return out
Пример #9
0
 def test_covar(self):
     standard = numpy.array([[ 0.4935702,  0.06857833, numpy.nan],
                             [ 0.06857833, 0.26405554, numpy.nan],
                             [ numpy.nan,  numpy.nan,  2.58857314]])
     results = Covariance().compute(stat, None, fittedpars,
                                    minpars, maxpars,
                                    hardminpars, hardmaxpars,
                                    limit_parnums, freeze_par, thaw_par,
                                    report_progress, get_par_name)
     self.assertEqualWithinTol(standard.diagonal(),
                               # results[2].diagonal(), 1e-4)
                               results[1], 1e-4)
Пример #10
0
    def test_covar_failures(self):
        self.assertRaises(TypeError, Covariance().compute,
                          None, fitter, fittedpars,
                          minpars, maxpars,
                          hardminpars, hardmaxpars,
                          limit_parnums, freeze_par, thaw_par, report_progress)

        self.assertRaises(RuntimeError, Covariance().compute,
                          stat, fitter, None, minpars, maxpars,
                          hardminpars, hardmaxpars, limit_parnums, freeze_par,
                          thaw_par, report_progress, get_par_name)

        self.assertRaises(RuntimeError, Covariance().compute,
                          stat, fitter, numpy.array([1, 2]),
                          minpars, maxpars, hardminpars, hardmaxpars,
                          limit_parnums, freeze_par, thaw_par,
                          report_progress, get_par_name)

        self.assertRaises(RuntimeError, Covariance().compute,
                          stat, fitter, fittedpars, numpy.array([1, 2]),
                          maxpars, hardminpars, hardmaxpars, limit_parnums,
                          freeze_par, thaw_par, report_progress, get_par_name)
Пример #11
0
    def setUp(self):
        data = Data1D('fake', self._x, self._y, self._err)

        g1 = Gauss1D('g1')
        g1.fwhm.set(1.0, _tiny, _max, frozen=False)
        g1.pos.set(1.0, -_max, _max, frozen=False)
        g1.ampl.set(1.0, -_max, _max, frozen=False)
        p1 = PowLaw1D('p1')
        p1.gamma.set(1.0, -10, 10, frozen=False)
        p1.ampl.set(1.0, 0.0, _max, frozen=False)
        p1.ref.set(1.0, -_max, _max, frozen=True)
        model = p1 + g1

        method = LevMar()
        method.config['maxfev'] = 10000
        method.config['ftol'] = float(_eps)
        method.config['epsfcn'] = float(_eps)
        method.config['gtol'] = float(_eps)
        method.config['xtol'] = float(_eps)
        method.config['factor'] = float(100)

        self.fit = Fit(data, model, Chi2DataVar(), method, Covariance())
        results = self.fit.fit()

        for key in ["succeeded", "numpoints", "nfev"]:
            assert self._fit_results_bench[key] == int(getattr(results, key))

        for key in ["rstat", "qval", "statval", "dof"]:
            assert numpy.allclose(float(self._fit_results_bench[key]),
                                  float(getattr(results, key)),
                                  1.e-7, 1.e-7)

        for key in ["parvals"]:
            try:
                assert numpy.allclose(self._fit_results_bench[key],
                                      getattr(results, key),
                                      1.e-4, 1.e-4)
            except AssertionError:
                print('parvals bench: ', self._fit_results_bench[key])
                print('parvals fit:   ', getattr(results, key))
                print('results', results)
                raise

        covresults = self.fit.est_errors()
        self.dof = results.dof
        self.mu = numpy.array(results.parvals)
        self.cov = numpy.array(covresults.extra_output)
        self.num = 10
Пример #12
0
    def get_scales(self, fit, myscales=None):

        def get_size_of_covar(pars):
            thawedpars = [par for par in pars if not par.frozen]
            npar = len(thawedpars)
            msg = 'scales must be a numpy array of size (%d,%d)' % (npar, npar)
            return npar, msg

        if myscales is None:
            oldestmethod = fit.estmethod
            fit.estmethod = Covariance()

            try:
                r = fit.est_errors()
            finally:
                fit.estmethod = oldestmethod

            cov = r.extra_output

        else:
            if isinstance(myscales, (numpy.ndarray)):
                npar, msg = get_size_of_covar(fit.model.pars)
                if (npar, npar) == myscales.shape:
                    cov = myscales
                else:
                    raise EstErr(msg)
            else:
                npar, msg = get_size_of_covar(fit.model.pars)
                raise EstErr(msg)
            cov = myscales

        if cov is None:
            raise EstErr('nocov')

        cov = numpy.asarray(cov)

        # Investigate spectral decomposition to avoid requirement that the cov be
        # semi-positive definite.  Nevermind, NumPy already uses SVD to generate
        # deviates from a multivariate normal.  An alternative is to use Cholesky
        # decomposition, but it assumes that the matrix is semi-positive
        # definite.
        if numpy.min(numpy.linalg.eigvalsh(cov)) <= 0:
            raise TypeError("The covariance matrix is not positive definite")

        return cov
Пример #13
0
)
center = SkyCoord(83.633083, 22.0145, unit="deg").galactic
source_model.gamma = 2.2
source_model.xpos = center.l.value
source_model.ypos = center.b.value
source_model.fwhm = 0.12
source_model.ampl = 1.0
# Define the model
flux_factor = 1e-11
model = bkg + flux_factor * source_model
fit = Fit(
    data=cube,
    model=model,
    stat=Cash(),
    method=NelderMead(),
    estmethod=Covariance(),
)
fit_results = fit.fit()
print(fit_results.format())
fit = Fit(
    data=cube,
    model=model,
    stat=Cash(),
    method=NelderMead(),
    estmethod=Covariance(),
)
fit_results = fit.fit()
fit_results
fit_results.format()
print(fit_results.format())
err_est_results = fit.est_errors()
Пример #14
0
    def get_scales(self, fit, myscales=None):
        """Return the samples.

        Parameters
        ----------
        fit : sherpa.fit.Fit instance
            This defines the thawed parameters that are used to
            generate the samples, along with any possible error
            analysis.
        myscales : numpy array or None, optional
            The scales to use. If None then they are
            calculated from the fit.

        Returns
        -------
        scales : numpy array
            One-dimensional scales array (npar elements, matching the
            free parameters in fit). The values are the sigma errors
            for the parameters (or the input values if given).

        """

        scales = []
        thawedpars = [par for par in fit.model.pars if not par.frozen]

        if myscales is None:

            oldestmethod = fit.estmethod

            covar = Covariance()
            covar.config['sigma'] = self.sigma
            fit.estmethod = Covariance()

            try:
                r = fit.est_errors()
            finally:
                fit.estmethod = oldestmethod

            for par, val, lo, hi in zip(thawedpars, r.parvals, r.parmins, r.parmaxes):
                scale = None
                if lo is not None and hi is not None:
                    scale = numpy.abs(lo)
                else:
                    wmsg = "Covariance failed for '{}',".format(par.fullname) + \
                           " trying Confidence..."
                    warning(wmsg)

                    conf = Confidence()
                    conf.config['sigma'] = self.sigma
                    fit.estmethod = conf
                    try:
                        t = fit.est_errors(parlist=(par,))
                        if t.parmins[0] is not None and t.parmaxes[0] is not None:
                            scale = numpy.abs(t.parmins[0])

                        else:

                            if t.parmins[0] is None and t.parmaxes[0] is not None:
                                scale = numpy.abs(t.parmaxes[0])

                            else:

                                warning('1 sigma bounds for parameter ' +
                                        par.fullname +
                                        ' could not be found, using soft limit minimum')
                                if 0.0 == numpy.abs(par.min):
                                    scale = 1.0e-16
                                else:
                                    scale = numpy.abs(par.min)

                    finally:
                        fit.estmethod = oldestmethod
                scales.append(scale)

        else:
            if not numpy.iterable(myscales):
                emsg = "scales option must be iterable of " + \
                       "length {}".format(len(thawedpars))
                raise TypeError(emsg)
            scales = list(map(abs, myscales))
        scales = numpy.asarray(scales).transpose()
        return scales
Пример #15
0
    def get_scales(self, fit, myscales=None):
        """Return the samples.

        Parameters
        ----------
        fit : sherpa.fit.Fit instance
            This defines the thawed parameters that are used to
            generate the samples, along with any possible error
            analysis.
        myscales : numpy array or None, optional
            The scales to use. If None then they are
            calculated from the fit.

        Returns
        -------
        scales : numpy array
            Two-dimensional scales array (npar by npar elements,
            matching the free parameters in fit). The values are the
            covariance matrix for the parameters (or the input values if
            given).

        """

        if myscales is None:
            oldestmethod = fit.estmethod
            fit.estmethod = Covariance()

            try:
                r = fit.est_errors()
            finally:
                fit.estmethod = oldestmethod

            cov = r.extra_output

        else:

            thawedpars = [par for par in fit.model.pars if not par.frozen]
            npar = len(thawedpars)
            msg = 'scales must be a numpy array of size ({0},{0})'.format(npar)

            if not isinstance(myscales, numpy.ndarray):
                raise EstErr(msg)

            if (npar, npar) != myscales.shape:
                raise EstErr(msg)

            cov = myscales

        if cov is None:
            raise EstErr('nocov')

        cov = numpy.asarray(cov)

        # Investigate spectral decomposition to avoid requirement that the cov be
        # semi-positive definite.  Nevermind, NumPy already uses SVD to generate
        # deviates from a multivariate normal.  An alternative is to use Cholesky
        # decomposition, but it assumes that the matrix is semi-positive
        # definite.
        if numpy.min(numpy.linalg.eigvalsh(cov)) <= 0:
            raise TypeError("The covariance matrix is not positive definite")

        return cov
Пример #16
0
def test_covar_failures1():
    with pytest.raises(TypeError):
        Covariance().compute(None, fitter, fittedpars, minpars, maxpars,
                             hardminpars, hardmaxpars, limit_parnums,
                             freeze_par, thaw_par, report_progress)
Пример #17
0
def test_covar_failures4():
    with pytest.raises(RuntimeError):
        Covariance().compute(stat, fitter, fittedpars, numpy.array([1, 2]),
                             maxpars, hardminpars, hardmaxpars, limit_parnums,
                             freeze_par, thaw_par, report_progress,
                             get_par_name)
Пример #18
0
bkg = TableModel('bkg')
bkg.load(None, bkg_3D.data[index_region_selected_3d].value.ravel())
# Freeze bkg amplitude
bkg.ampl = 1
bkg.ampl.freeze()
model = bkg + 1E-11 * (source_model_SgrA)

# Fit
# For now only Chi2 statistics seems to work, using Cash, the optimizer doesn't run at all,
# maybe because of missing background model?
fit = Fit(data=cube,
          model=model,
          stat=Cash(),
          method=NelderMead(),
          estmethod=Covariance())
result = fit.fit()
err = fit.est_errors()
print(err)

# Set starting values G0p9
if "dec" in input_param["param_G0p9"]["sourde_name_skycoord"]:
    source_center_G0p9 = SkyCoord(
        input_param["param_G0p9"]["sourde_name_skycoord"]["ra"],
        input_param["param_G0p9"]["sourde_name_skycoord"]["dec"],
        unit="deg").galactic
else:
    source_center_G0p9 = SkyCoord.from_name(
        input_param["param_G0p9"]["sourde_name_skycoord"]).galactic
spatial_model_G0p9 = NormGauss2DInt('spatial-model_G0p9')
spectral_model_G0p9 = PowLaw1D('spectral-model_G0p9')
Пример #19
0
    def run(fit,
            null_comp,
            alt_comp,
            conv_mdl=None,
            stat=None,
            method=None,
            niter=500,
            numcores=None):

        if stat is None: stat = CStat()
        if method is None: method = NelderMead()

        if not isinstance(stat, (Cash, CStat)):
            raise TypeError("Sherpa fit statistic must be Cash or CStat" +
                            " for likelihood ratio test")

        niter = int(niter)

        alt = alt_comp
        null = null_comp

        oldaltvals = numpy.array(alt.thawedpars)
        oldnullvals = numpy.array(null.thawedpars)

        data = fit.data

        if conv_mdl is not None:
            # Copy the PSF
            null_conv_mdl = deepcopy(conv_mdl)

            alt = conv_mdl(alt_comp)
            if hasattr(conv_mdl, 'fold'):
                conv_mdl.fold(data)

            # Convolve the null model
            null = null_conv_mdl(null_comp)
            if hasattr(null_conv_mdl, 'fold'):
                null_conv_mdl.fold(data)

        nullfit = Fit(data, null, stat, method, Covariance())

        # Fit with null model
        nullfit_results = nullfit.fit()
        debug(nullfit_results.format())

        null_stat = nullfit_results.statval
        null_vals = nullfit_results.parvals

        # Calculate niter samples using null best-fit and covariance
        sampler = NormalParameterSampleFromScaleMatrix()
        samples = sampler.get_sample(nullfit, None, niter)

        # Fit with alt model, null component starts at null's best fit params.
        altfit = Fit(data, alt, stat, method, Covariance())
        altfit_results = altfit.fit()
        debug(altfit_results.format())

        alt_stat = altfit_results.statval
        alt_vals = altfit_results.parvals

        LR = -(alt_stat - null_stat)

        def worker(proposal, *args, **kwargs):
            return LikelihoodRatioTest.calculate(nullfit, altfit, proposal,
                                                 null_vals, alt_vals)

        olddep = data.get_dep(filter=False)
        try:
            #statistics = map(worker, samples)
            statistics = parallel_map(worker, samples, numcores)
        finally:
            data.set_dep(olddep)
            alt.thawedpars = list(oldaltvals)
            null.thawedpars = list(oldnullvals)

        debug("statistic null = " + repr(null_stat))
        debug("statistic alt = " + repr(alt_stat))
        debug("LR = " + repr(LR))

        statistics = numpy.asarray(statistics)

        pppvalue = numpy.sum(statistics[:, 2] > LR) / (1.0 * niter)

        debug('ppp value = ' + str(pppvalue))

        return LikelihoodRatioResults(statistics[:, 2], statistics[:, 0:2],
                                      samples, LR, pppvalue, null_stat,
                                      alt_stat)
Пример #20
0
def testCombinedModel3DInt():
    from sherpa.models import PowLaw1D, TableModel
    from sherpa.estmethods import Covariance
    from sherpa.optmethods import NelderMead
    from sherpa.stats import Cash
    from sherpa.fit import Fit
    from ..sherpa_ import CombinedModel3DInt, NormGauss2DInt

    # Set the counts
    filename = gammapy_extra.filename('test_datasets/cube/counts_cube.fits')
    counts_3d = SkyCube.read(filename)
    cube = counts_3d.to_sherpa_data3d(dstype='Data3DInt')

    # Set the bkg
    filename = gammapy_extra.filename('test_datasets/cube/bkg_cube.fits')
    bkg_3d = SkyCube.read(filename)
    bkg = TableModel('bkg')
    bkg.load(None, bkg_3d.data.value.ravel())
    bkg.ampl = 1
    bkg.ampl.freeze()

    # Set the exposure
    filename = gammapy_extra.filename('test_datasets/cube/exposure_cube.fits')
    exposure_3d = SkyCube.read(filename)
    i_nan = np.where(np.isnan(exposure_3d.data))
    exposure_3d.data[i_nan] = 0
    # In order to have the exposure in cm2 s
    exposure_3d.data = exposure_3d.data * 1e4

    # Set the mean psf model
    filename = gammapy_extra.filename('test_datasets/cube/psf_cube.fits')
    psf_3d = SkyCube.read(filename)

    # Setup combined spatial and spectral model
    spatial_model = NormGauss2DInt('spatial-model')
    spectral_model = PowLaw1D('spectral-model')

    coord = counts_3d.sky_image_ref.coordinates(mode="edges")
    energies = counts_3d.energies(mode='edges').to("TeV")
    source_model = CombinedModel3DInt(coord=coord,
                                      energies=energies,
                                      use_psf=True,
                                      exposure=exposure_3d,
                                      psf=psf_3d,
                                      spatial_model=spatial_model,
                                      spectral_model=spectral_model)

    # Set starting values
    center = SkyCoord(83.633083, 22.0145, unit="deg").galactic
    source_model.gamma = 2.2
    source_model.xpos = center.l.value
    source_model.ypos = center.b.value
    source_model.fwhm = 0.12
    source_model.ampl = 1.0

    # Fit
    model = bkg + 1E-11 * (source_model)
    fit = Fit(data=cube,
              model=model,
              stat=Cash(),
              method=NelderMead(),
              estmethod=Covariance())
    result = fit.fit()

    # TODO: The fact that it doesn't converge to the right Crab postion is due to the dummy psf
    reference = [
        184.19524957441664, -6.1693008203971562, 6.1666646581766011,
        0.076340497278248376, 2.305912037549
    ]

    assert_allclose(result.parvals, reference, rtol=1E-5)

    # Add a region to exclude in the fit: Here we will exclude some events from the Crab since there is no region to
    # exclude in the FOV for this example. It's just an example to show how it works and how to proceed in the fit.
    # Read the mask for the exclude region
    filename_mask = gammapy_extra.filename('test_datasets/cube/mask.fits')
    cube_mask = SkyCube.read(filename_mask)
    index_region_selected_3d = np.where(cube_mask.data.value == 1)

    # Set the counts and create a gammapy Data3DInt object on which we apply a mask for the region we don't want to use in the fit
    cube = counts_3d.to_sherpa_data3d(dstype='Data3DInt')
    cube.mask = cube_mask.data.value.ravel()

    # Set the bkg and select only the data points of the selected region
    bkg = TableModel('bkg')
    bkg.load(None, bkg_3d.data.value[index_region_selected_3d].ravel())
    bkg.ampl = 1
    bkg.ampl.freeze()

    # The model is evaluated on all the points then it is compared with the data only on the selected_region
    source_model = CombinedModel3DInt(
        coord=coord,
        energies=energies,
        use_psf=True,
        exposure=exposure_3d,
        psf=psf_3d,
        spatial_model=spatial_model,
        spectral_model=spectral_model,
        select_region=True,
        index_selected_region=index_region_selected_3d)
    # Set starting values
    source_model.gamma = 2.2
    source_model.xpos = center.l.value
    source_model.ypos = center.b.value
    source_model.fwhm = 0.12
    source_model.ampl = 1.0

    # Fit
    model = bkg + 1E-11 * (source_model)
    fit = Fit(data=cube,
              model=model,
              stat=Cash(),
              method=NelderMead(),
              estmethod=Covariance())
    result2 = fit.fit()

    # TODO: The fact that it doesn't converge to the right Crab postion is due to the dummy psf
    reference2 = [
        184.20146538191321, -6.1600047997645975, 5.4193056837212374,
        0.08635929788659219, 2.2979723660330
    ]
    assert_allclose(result2.parvals, reference2, rtol=1E-5)
Пример #21
0
def testCombinedModel3DIntConvolveEdisp():
    from sherpa.models import PowLaw1D, TableModel
    from sherpa.estmethods import Covariance
    from sherpa.optmethods import NelderMead
    from sherpa.stats import Cash
    from sherpa.fit import Fit
    from ..sherpa_ import CombinedModel3DIntConvolveEdisp, NormGauss2DInt

    # Set the counts
    filename = gammapy_extra.filename('test_datasets/cube/counts_cube.fits')
    counts_3d = SkyCube.read(filename)
    cube = counts_3d.to_sherpa_data3d(dstype='Data3DInt')

    # Set the bkg
    filename = gammapy_extra.filename('test_datasets/cube/bkg_cube.fits')
    bkg_3d = SkyCube.read(filename)
    bkg = TableModel('bkg')
    bkg.load(None, bkg_3d.data.value.ravel())
    bkg.ampl = 1
    bkg.ampl.freeze()

    # Set the exposure
    filename = gammapy_extra.filename(
        'test_datasets/cube/exposure_cube_etrue.fits')
    exposure_3d = SkyCube.read(filename)
    i_nan = np.where(np.isnan(exposure_3d.data))
    exposure_3d.data[i_nan] = 0
    # In order to have the exposure in cm2 s
    exposure_3d.data = exposure_3d.data * 1e4

    # Set the mean psf model
    filename = gammapy_extra.filename('test_datasets/cube/psf_cube_etrue.fits')
    psf_3d = SkyCube.read(filename)

    # Set the mean rmf
    filename = gammapy_extra.filename('test_datasets/cube/rmf.fits')
    rmf = EnergyDispersion.read(filename)

    # Setup combined spatial and spectral model
    spatial_model = NormGauss2DInt('spatial-model')
    spectral_model = PowLaw1D('spectral-model')
    # dimensions = [exposure_3d.data.shape[1], exposure_3d.data.shape[2], rmf.data.data.shape[1],
    #              exposure_3d.data.shape[0]]
    coord = counts_3d.sky_image_ref.coordinates(mode="edges")
    energies = counts_3d.energies(mode='edges').to("TeV")
    source_model = CombinedModel3DIntConvolveEdisp(
        coord=coord,
        energies=energies,
        use_psf=True,
        exposure=exposure_3d,
        psf=psf_3d,
        spatial_model=spatial_model,
        spectral_model=spectral_model,
        edisp=rmf.data.data)

    # Set starting values
    center = SkyCoord(83.633083, 22.0145, unit="deg").galactic
    source_model.gamma = 2.2
    source_model.xpos = center.l.value
    source_model.ypos = center.b.value
    source_model.fwhm = 0.12
    source_model.ampl = 1.0

    # Fit
    model = bkg + 1E-11 * (source_model)
    fit = Fit(data=cube,
              model=model,
              stat=Cash(),
              method=NelderMead(),
              estmethod=Covariance())
    result = fit.fit()

    # TODO: The fact that it doesn't converge to the right Crab postion, flux and source size is due to the dummy psf
    reference = [
        184.19189525423425, -6.1758238877562386, 6.2283155506945755,
        0.071013932890499717, 2.2685809241308674
    ]
    assert_allclose(result.parvals, reference, rtol=1E-5)

    # Add a region to exclude in the fit: Here we will exclude some events from the Crab since there is no region to
    # exclude in the FOV for this example. It's just an example to show how it works and how to proceed in the fit.
    # Read the mask for the exclude region
    filename_mask = gammapy_extra.filename('test_datasets/cube/mask.fits')
    cube_mask = SkyCube.read(filename_mask)
    index_region_selected_3d = np.where(cube_mask.data.value == 1)

    # Set the counts and create a gammapy Data3DInt object on which we apply a mask for the region we don't want to use in the fit
    cube = counts_3d.to_sherpa_data3d(dstype='Data3DInt')
    cube.mask = cube_mask.data.value.ravel()

    # Set the bkg and select only the data points of the selected region
    bkg = TableModel('bkg')
    bkg.load(None, bkg_3d.data.value[index_region_selected_3d].ravel())
    bkg.ampl = 1
    bkg.ampl.freeze()

    # The model is evaluated on all the points then it is compared with the data only on the selected_region
    source_model = CombinedModel3DIntConvolveEdisp(
        coord=coord,
        energies=energies,
        use_psf=True,
        exposure=exposure_3d,
        psf=psf_3d,
        spatial_model=spatial_model,
        spectral_model=spectral_model,
        edisp=rmf.data.data,
        select_region=True,
        index_selected_region=index_region_selected_3d)

    # Set starting values
    source_model.gamma = 2.2
    source_model.xpos = center.l.value
    source_model.ypos = center.b.value
    source_model.fwhm = 0.12
    source_model.ampl = 1.0

    # Fit
    model = bkg + 1E-11 * (source_model)
    fit = Fit(data=cube,
              model=model,
              stat=Cash(),
              method=NelderMead(),
              estmethod=Covariance())
    result2 = fit.fit()

    # TODO: The fact that it doesn't converge to the right Crab postion is due to the dummy psf
    reference2 = [
        184.1919580251583, -6.1692775561065769, 5.4976586957354581,
        0.074821281329729109, 2.2504892463464699
    ]
    assert_allclose(result2.parvals, reference2, rtol=1E-5)
Пример #22
0
# Adding this constant background components the fit works with cash statistics as well
#spatial_model_bkg = Const2D('spatial-model-bkg')
#spectral_model_bkg = PowLaw1D('spectral-model-bkg')
#bkg_model = CombinedModel3D(spatial_model=spatial_model_bkg, spectral_model=spectral_model_bkg)

bkg = TableModel('bkg')
bkg.load(None, bkg_3D.data.value.ravel())
# Freeze bkg amplitude
bkg.ampl=1
bkg.ampl.freeze()
model = bkg+1E-11 * (source_model)

# Fit
# For now only Chi2 statistics seems to work, using Cash, the optimizer doesn't run at all,
# maybe because of missing background model?
fit = Fit(data=cube, model=model, stat=Cash(), method=NelderMead(), estmethod=Covariance())
result = fit.fit()
err=fit.est_errors()
print(err)


def PWL(E,phi_0,gamma):
    return phi_0*E**(-gamma)
def EXP(E,phi_0,gamma,beta):
    return phi_0*E**(-gamma)*np.exp(-beta*E)
coord=exposure_3D.sky_image_ref.coordinates(mode="edges")
d = coord.separation(center)
pix_size=exposure_3D.wcs.to_header()["CDELT2"]
i=np.where(d<pix_size*u.deg)
#i permet de faire la moyenne exposure autour de pixel autour de la source
mean_exposure=list()