예제 #1
0
    def make_prof(self, sp_datasets):
        """ Utility to make the profile in each region

        Parameters
        ----------
        sp_datasets : `~gammapy.datasets.MapDatasets` of `~gammapy.datasets.SpectrumDataset` or \
        `~gammapy.datasets.SpectrumDatasetOnOff`
            the dataset to use for profile extraction

        Returns
        --------
        results : list of dictionary
            the list of results (list of keys: x_min, x_ref, x_max, alpha, counts, background, excess, ts, sqrt_ts, \
            err, errn, errp, ul, exposure, solid_angle)
        """
        results = []

        distance = self._get_projected_distance()

        for index, spds in enumerate(sp_datasets):
            old_model = None
            if spds.models is not None:
                old_model = spds.models
            spds.models = SkyModel(spectral_model=self.spectrum)
            e_reco = spds.counts.geom.axes["energy"].edges

            # ToDo: When the function to_spectrum_dataset will manage the masks, use the following line
            # mask = spds.mask if spds.mask is not None else slice(None)
            mask = slice(None)
            if isinstance(spds, SpectrumDatasetOnOff):
                stats = WStatCountsStatistic(
                    spds.counts.data[mask][:, 0, 0],
                    spds.counts_off.data[mask][:, 0, 0],
                    spds.alpha.data[mask][:, 0, 0],
                )

            else:
                stats = CashCountsStatistic(
                    spds.counts.data[mask][:, 0, 0],
                    spds.npred_background().data[mask][:, 0, 0],
                )

            result = {
                "x_min": distance.edges[index],
                "x_max": distance.edges[index + 1],
                "x_ref": distance.center[index],
                "energy_edge": e_reco,
            }
            if isinstance(spds, SpectrumDatasetOnOff):
                result["alpha"] = stats.alpha
            result.update(
                {
                    "counts": stats.n_on,
                    "background": stats.mu_bkg,
                    "excess": stats.n_sig,
                }
            )

            result["ts"] = stats.ts
            result["sqrt_ts"] = stats.sqrt_ts

            result["err"] = stats.error * self.n_sigma

            if "errn-errp" in self.selection_optional:
                result["errn"] = stats.compute_errn(self.n_sigma)
                result["errp"] = stats.compute_errp(self.n_sigma)

            if "ul" in self.selection_optional:
                result["ul"] = stats.compute_upper_limit(self.n_sigma_ul)

            npred = spds.npred().data[mask][:, 0, 0]
            e_reco_lo = e_reco[:-1]
            e_reco_hi = e_reco[1:]
            flux = (
                stats.n_sig
                / npred
                * spds.models[0].spectral_model.integral(e_reco_lo, e_reco_hi).value
            )
            result["flux"] = flux

            result["flux_err"] = stats.error / stats.n_sig * flux

            if "errn-errp" in self.selection_optional:
                result["flux_errn"] = np.abs(result["errn"]) / stats.n_sig * flux
                result["flux_errp"] = result["errp"] / stats.n_sig * flux

            if "ul" in self.selection_optional:
                result["flux_ul"] = result["ul"] / stats.n_sig * flux

            solid_angle = spds.counts.geom.solid_angle()
            result["solid_angle"] = (
                np.full(result["counts"].shape, solid_angle.to_value("sr")) * u.sr
            )

            results.append(result)
            if old_model is not None:
                spds.models = old_model

        return results
예제 #2
0
def test_wstat_ul(n_on, n_off, alpha, result):
    stat = WStatCountsStatistic(n_on, n_off, alpha)
    ul = stat.compute_upper_limit()

    assert_allclose(ul, result[0], atol=1e-5)