示例#1
0
def load_data(input_dir, dataset_config, exclusion_map=None):
    on_region_radius = dataset_config['on_radius']
    e_reco_bins = dataset_config['e_reco_bins']
    e_true_bins = dataset_config['e_true_bins']
    containment = dataset_config['containment_correction']

    ds = DataStore.from_dir(input_dir)
    observations = ds.get_observations(ds.obs_table['OBS_ID'].data)
    # observations = ds.get_observations(ds.hdu_table['OBS_ID'].data)  # this is plenty wrong

    source_position = dataset_config['source_position']
    on_region = CircleSkyRegion(center=source_position,
                                radius=on_region_radius)

    print('Estimating Background')
    bkg_estimate = ReflectedRegionsBackgroundEstimator(
        observations=observations,
        on_region=on_region,
        exclusion_mask=exclusion_map)
    bkg_estimate.run()

    print('Extracting Count Spectra')
    extract = SpectrumExtraction(
        observations=observations,
        bkg_estimate=bkg_estimate.result,
        e_true=e_true_bins,
        e_reco=e_reco_bins,
        containment_correction=containment,
        use_recommended_erange=False,
    )
    extract.run()
    if dataset_config['stack']:
        return [extract.spectrum_observations.stack()]
    else:
        return extract.spectrum_observations
def create_data(input_dir, dataset_config, exclusion_map=None):
    telescope = dataset_config['telescope']
    on_region_radius = dataset_config['on_radius']
    energy_bins = dataset_config['e_reco_bins']
    containment = dataset_config['containment_correction']

    ds = DataStore.from_dir(os.path.join(input_dir, telescope))
    observations = ds.get_observations(ds.obs_table['OBS_ID'].data)
    t_obs = sum([o.observation_live_time_duration for o in observations])
    # from IPython import embed; embed()
    print(f'Total obstime for {telescope} is {t_obs.to("h")}')
    source_position = dataset_config['source_position']
    on_region = CircleSkyRegion(center=source_position,
                                radius=on_region_radius)

    print('Estimating Background')
    bkg_estimate = ReflectedRegionsBackgroundEstimator(
        observations=observations,
        on_region=on_region,
        exclusion_mask=exclusion_map)
    bkg_estimate.run()

    print('Extracting Count Spectra')
    extract = SpectrumExtraction(
        observations=observations,
        bkg_estimate=bkg_estimate.result,
        e_true=energy_bins,
        e_reco=energy_bins,
        containment_correction=containment,
        use_recommended_erange=False,  # TODO this might have to be checked.
    )
    extract.run()
    return extract
示例#3
0
def bkg_estimate(observations, on_region, exclusion_mask):
    """An example background estimate"""
    est = ReflectedRegionsBackgroundEstimator(
        observations=observations,
        on_region=on_region,
        exclusion_mask=exclusion_mask,
        min_distance_input="0.2 deg",
    )
    est.run()
    return est.result
示例#4
0
def bkg_estimator(observations, exclusion_mask, on_region):
    """Example background estimator for testing."""
    maker = ReflectedRegionsBackgroundEstimator(
        observations=observations,
        on_region=on_region,
        exclusion_mask=exclusion_mask,
        min_distance_input="0.2 deg",
    )
    maker.run()
    return maker
示例#5
0
def stats_stacked_bad_on_region(bad_on_region, observations):
    bge = ReflectedRegionsBackgroundEstimator(
        on_region=bad_on_region, observations=observations
    )
    bge.run()

    return ObservationStats.stack(
        [
            ObservationStats.from_observation(obs, bg)
            for obs, bg in zip(observations, bge.result)
        ]
    )
示例#6
0
    def run_extraction(self):
        """Run all steps for the spectrum extraction."""
        self.background_estimator = ReflectedRegionsBackgroundEstimator(
            observations=self.observations, **self.config["background"])
        self.background_estimator.run()

        self.extraction = SpectrumExtraction(
            observations=self.observations,
            bkg_estimate=self.background_estimator.result,
            **self.config["extraction"])

        self.extraction.run()
示例#7
0
    def setup_class(cls):
        datastore = DataStore.from_dir("$GAMMAPY_DATA/hess-dl3-dr1/")
        obs_ids = [23523, 23526]

        on_region = CircleSkyRegion(
            SkyCoord(83.63 * u.deg, 22.01 * u.deg, frame="icrs"), 0.3 * u.deg)

        obs_stats_list = []
        for obs_id in obs_ids:
            obs = datastore.obs(obs_id)
            bkg = ReflectedRegionsBackgroundEstimator(on_region=on_region,
                                                      observations=[obs])
            bkg.run()
            bg_estimate = bkg.result[0]

            obs_stats = ObservationStats.from_observation(obs, bg_estimate)
            obs_stats_list.append(obs_stats)

        cls.obs_summary = ObservationSummary(obs_stats_list)
示例#8
0
def test_extract_cta_1dc_data(caplog):
    datastore = DataStore.from_dir("$GAMMAPY_DATA/cta-1dc/index/gps/")
    obs_ids = [110380, 111140]
    observations = datastore.get_observations(obs_ids)

    pos = SkyCoord(0.0, 0.0, unit="deg", frame="galactic")
    radius = Angle(0.11, "deg")
    on_region = CircleSkyRegion(pos, radius)

    est = ReflectedRegionsBackgroundEstimator(observations=observations,
                                              on_region=on_region,
                                              min_distance_input="0.2 deg")
    est.run()
    # This will test non PSF3D input as well as absence of default thresholds
    extract = SpectrumExtraction(bkg_estimate=est.result,
                                 observations=observations,
                                 containment_correction=True)
    extract.run()

    extract.compute_energy_threshold(method_lo="area_max", area_percent_lo=10)
    actual = extract.spectrum_observations[0].energy_range[0]
    assert_quantity_allclose(actual, 0.774263 * u.TeV, rtol=1e-3)
def extract_spectra_iact(dataset):
    """Extract 1d spectra for IACT dataset"""
    log.info(f"Extracting 1d spectra for {dataset.name} dataset")
    datastore = DataStore.from_dir(f"data/{dataset.name}")
    observations = datastore.get_observations(dataset.obs_ids)

    on_region = CircleSkyRegion(center=config.source_pos,
                                radius=dataset.on_radius)

    exclusion_mask = config.get_exclusion_mask()

    bkg_estimate = ReflectedRegionsBackgroundEstimator(
        observations=observations,
        on_region=on_region,
        exclusion_mask=exclusion_mask)
    bkg_estimate.run()

    extract = SpectrumExtraction(
        observations=observations,
        bkg_estimate=bkg_estimate.result,
        e_true=config.energy_bins,
        e_reco=config.energy_bins,
        containment_correction=dataset.containment_correction,
    )
    extract.run()

    path = f"results/spectra/{dataset.name}/"
    log.info(f"Writing to {path}")

    if dataset.name == "fact":
        # For FACT the IRFs are the same for all observations
        # So we only store a stacked spectrum and response
        # plus we add a LO_THRESHOLD keyword was missing
        obs = extract.spectrum_observations.stack()
        obs.lo_threshold = 0.4 * u.TeV
        # we are writing a single observation, as for Fermi
        obs.write(path, use_sherpa=True, overwrite=True)
    else:
        extract.write(path, ogipdir="", use_sherpa=True, overwrite=True)
示例#10
0
def extract_spectra_IACT(dataset):
    """Extract 1d spectra for IACT dataset"""
    log.info(f"Extracting 1d spectra for {dataset.name} dataset")
    # Dataset class has already the method to obtain the gammapy DataStore object
    datastore = dataset.get_DataStore()
    obs_list = datastore.obs_list(dataset.obs_ids)

    on_region = CircleSkyRegion(center=dataset.source_pos,
                                radius=dataset.on_radius)

    exclusion_mask = config.get_exclusion_mask()

    bkg_estimate = ReflectedRegionsBackgroundEstimator(
        obs_list=obs_list, on_region=on_region, exclusion_mask=exclusion_mask)
    bkg_estimate.run()

    extract = SpectrumExtraction(
        obs_list=obs_list,
        bkg_estimate=bkg_estimate.result,
        containment_correction=dataset.containment_correction,
    )
    extract.run()

    path = f"{config.repo_path}/results/spectra/{dataset.name}/"
    log.info(f"Writing to {path}")

    if dataset.name == "fact":
        # For FACT the IRFs are the same for all observations
        # So we only store a stacked spectrum and response
        # plus we add a LO_THRESHOLD keyword was missing
        obs = extract.observations.stack()
        obs.lo_threshold = 0.4 * u.TeV
        # we are writing a single observation, as for Fermi
        obs.write(path, use_sherpa=True, overwrite=True)
    else:
        extract.write(path, ogipdir="", use_sherpa=True, overwrite=True)
示例#11
0
def stats_bad_on_region(bad_on_region, observations):
    obs = observations[0]
    bge = ReflectedRegionsBackgroundEstimator(on_region=bad_on_region, observations=obs)
    bg = bge.process(obs)
    return ObservationStats.from_observation(obs, bg)
示例#12
0
from gammapy.background import ReflectedRegionsBackgroundEstimator

data_store = DataStore.from_dir("$GAMMAPY_DATA/hess-dl3-dr1/")
mask = data_store.obs_table["TARGET_NAME"] == "Crab"
obs_ids = data_store.obs_table["OBS_ID"][mask].data
observations = data_store.get_observations(obs_ids)

crab_position = SkyCoord(83.63, 22.01, unit="deg", frame="icrs")

# The ON region center is defined in the icrs frame. The angle is defined w.r.t. to its axis.
on_region = RectangleSkyRegion(center=crab_position,
                               width=0.5 * u.deg,
                               height=0.4 * u.deg,
                               angle=0 * u.deg)

background_estimator = ReflectedRegionsBackgroundEstimator(
    observations=observations, on_region=on_region, min_distance=0.1 * u.rad)

background_estimator.run()

# Let's inspect the data extracted in the first observation
print(background_estimator.result[0])

background_estimator.plot()

# Now we change the ON region, and use a center defined in the galactic frame
on_region_galactic = RectangleSkyRegion(
    center=crab_position.galactic,
    width=0.5 * u.deg,
    height=0.4 * u.deg,
    angle=0 * u.deg,
)
示例#13
0
# TODO: fit a Gaussian to the GC source

# ## Spectrum
#
# We'll run a spectral analysis using the classical reflected regions background estimation method,
# and using the on-off (often called WSTAT) likelihood function.
#
# ### Extraction
#
# The first step is to "extract" the spectrum, i.e. 1-dimensional counts and exposure and background vectors, as well as an energy dispersion matrix from the data and IRFs.

# In[24]:

bkg_estimator = ReflectedRegionsBackgroundEstimator(
    obs_list=obs_list,
    on_region=on_region,
    exclusion_mask=exclusion_mask,
)
bkg_estimator.run()
bkg_estimate = bkg_estimator.result
bkg_estimator.plot()

# In[25]:

extract = SpectrumExtraction(
    obs_list=obs_list,
    bkg_estimate=bkg_estimate,
)
extract.run()

# ### Model fit
示例#14
0
class SpectrumAnalysisIACT:
    """High-level analysis class to perform a full 1D IACT spectral analysis.

    Observation selection must have happened before.

    Config options:

    * outdir : `pathlib.Path`, str
        Output folder, None means no output
    * background : dict
        Forwarded to `~gammapy.background.ReflectedRegionsBackgroundEstimator`
    * extraction : dict
        Forwarded to `~gammapy.spectrum.SpectrumExtraction`
    * fp_binning : `~astropy.units.Quantity`
        Flux points binning

    Parameters
    ----------
    observations : `~gammapy.data.Observations`
        Observations to analyse
    config : dict
        Config dict
    """
    def __init__(self, observations, config):
        self.observations = observations
        self.config = config

    def __str__(self):
        ss = self.__class__.__name__
        ss += "\n{}".format(self.observations)
        ss += "\n{}".format(self.config)
        return ss

    def run(self, optimize_opts=None):
        """Run all steps."""
        log.info("Running {}".format(self.__class__.__name__))
        self.run_extraction()
        self.run_fit(optimize_opts)

    def run_extraction(self):
        """Run all steps for the spectrum extraction."""
        self.background_estimator = ReflectedRegionsBackgroundEstimator(
            observations=self.observations, **self.config["background"])
        self.background_estimator.run()

        self.extraction = SpectrumExtraction(
            observations=self.observations,
            bkg_estimate=self.background_estimator.result,
            **self.config["extraction"])

        self.extraction.run()

    @property
    def _result_dict(self):
        """Convert to dict."""
        val = dict()
        model = self.config["fit"]["model"]
        val["model"] = model.to_dict()

        fit_range = self.config["fit"].get("fit_range")

        if fit_range is not None:
            val["fit_range"] = dict(
                min=fit_range[0].value,
                max=fit_range[1].value,
                unit=fit_range.unit.to_string("fits"),
            )

        val["statval"] = float(self.fit_result.total_stat)
        val["statname"] = "wstat"

        return val

    def write(self, filename, mode="w"):
        """Write to YAML file.

        Parameters
        ----------
        filename : str
            File to write
        mode : str
            Write mode
        """
        d = self._result_dict
        val = yaml.safe_dump(d, default_flow_style=False)

        with open(str(filename), mode) as outfile:
            outfile.write(val)

    def run_fit(self, optimize_opts=None):
        """Run all step for the spectrum fit."""
        fit_range = self.config["fit"].get("fit_range")
        model = self.config["fit"]["model"]

        for obs in self.extraction.spectrum_observations:
            if fit_range is not None:
                obs.mask_fit = obs.counts.energy_mask(fit_range[0],
                                                      fit_range[1])
            obs.model = model

        self.fit = Fit(self.extraction.spectrum_observations)
        self.fit_result = self.fit.run(optimize_opts=optimize_opts)

        model = self.config["fit"]["model"]
        modelname = model.__class__.__name__

        model.parameters.covariance = self.fit_result.parameters.covariance

        filename = make_path(
            self.config["outdir"]) / "fit_result_{}.yaml".format(modelname)

        self.write(filename=filename)

        obs_stacker = SpectrumDatasetOnOffStacker(
            self.extraction.spectrum_observations)
        obs_stacker.run()

        datasets_fp = obs_stacker.stacked_obs
        datasets_fp.model = model
        self.flux_point_estimator = FluxPointsEstimator(
            e_edges=self.config["fp_binning"], datasets=datasets_fp)
        fp = self.flux_point_estimator.run()
        fp.table["is_ul"] = fp.table["ts"] < 4
        self.flux_points = fp

    @property
    def spectrum_result(self):
        """`~gammapy.spectrum.FluxPointsDataset`"""
        return FluxPointsDataset(data=self.flux_points,
                                 model=self.fit.datasets.datasets[0].model)
示例#15
0
                            proj="TAN",
                            coordsys="GAL")

mask = exclusion_mask.geom.region_mask([exclusion_region], inside=False)
exclusion_mask.data = mask
exclusion_mask.plot()

# ## Estimate background
#
# Next we will manually perform a background estimate by placing [reflected regions](https://docs.gammapy.org/dev/background/reflected.html) around the pointing position and looking at the source statistics. This will result in a  [gammapy.background.BackgroundEstimate](https://docs.gammapy.org/dev/api/gammapy.background.BackgroundEstimate.html) that serves as input for other classes in gammapy.

# In[ ]:

background_estimator = ReflectedRegionsBackgroundEstimator(
    observations=observations,
    on_region=on_region,
    exclusion_mask=exclusion_mask,
)

background_estimator.run()

# In[ ]:

plt.figure(figsize=(8, 8))
background_estimator.plot(add_legend=True)

# ## Source statistic
#
# Next we're going to look at the overall source statistics in our signal region. For more info about what debug plots you can create check out the [ObservationSummary](https://docs.gammapy.org/dev/api/gammapy.data.ObservationSummary.html#gammapy.data.ObservationSummary) class.

# In[ ]: