Repository: gammapy/gammapy
Pull request #5362 (2024-07-05 11:54:29)

Backport PR #5342 on branch v1.2.x (Fix evaluation if no edisp is set)
Backport PR #5342: Fix evaluation if no edisp is set


Patch:
diff --git a/gammapy/datasets/evaluator.py b/gammapy/datasets/evaluator.py
index 62a5af847..3631b6a69 100644
--- a/gammapy/datasets/evaluator.py
+++ b/gammapy/datasets/evaluator.py
@@ -72,6 +72,8 @@ class MapEvaluator:
         self.contributes = True
         self.psf_containment = None
 
+        self._geom_reco_axis = None
+
         if evaluation_mode not in {"local", "global"}:
             raise ValueError(f"Invalid evaluation_mode: {evaluation_mode!r}")
 
@@ -117,10 +119,12 @@ class MapEvaluator:
     @property
     def _geom_reco(self):
         if self.edisp is not None:
-            energy_axis = self.edisp.axes["energy"].copy(name="energy")
+            energy_axis = self.edisp.axes["energy"]
+        elif self._geom_reco_axis is not None:
+            energy_axis = self._geom_reco_axis
         else:
-            energy_axis = self.geom.axes["energy_true"].copy(name="energy")
-        geom = self.geom.to_image().to_cube(axes=[energy_axis])
+            energy_axis = self.geom.axes["energy_true"]
+        geom = self.geom.to_image().to_cube(axes=[energy_axis.copy(name="energy")])
         return geom
 
     @property
@@ -192,13 +196,15 @@ class MapEvaluator:
         del self.position
         del self.cutout_width
 
+        self._geom_reco_axis = geom.axes["energy"]
+
         # lookup edisp
+        del self._edisp_diagonal
         if edisp:
             energy_axis = geom.axes["energy"]
             self.edisp = edisp.get_edisp_kernel(
                 position=self.position, energy_axis=energy_axis
             )
-            del self._edisp_diagonal
 
         # lookup psf
         if psf and self.model.spatial_model:
@@ -246,8 +252,8 @@ class MapEvaluator:
     @lazyproperty
     def _edisp_diagonal(self):
         return EDispKernel.from_diagonal_response(
-            energy_axis_true=self.edisp.axes["energy_true"],
-            energy_axis=self.edisp.axes["energy"],
+            energy_axis_true=self.geom.axes["energy_true"],
+            energy_axis=self._geom_reco.axes["energy"],
         )
 
     def update_spatial_oversampling_factor(self, geom):
@@ -388,7 +394,7 @@ class MapEvaluator:
         npred_reco : `~gammapy.maps.Map`
             Predicted counts in reconstructed energy bins.
         """
-        if self.model.apply_irf["edisp"]:
+        if self.model.apply_irf["edisp"] and self.edisp:
             return apply_edisp(npred, self.edisp)
         else:
             if "energy_true" in npred.geom.axes.names:


Test patch:
diff --git a/gammapy/estimators/points/tests/test_sed.py b/gammapy/estimators/points/tests/test_sed.py
index 785946129..17d009948 100644
--- a/gammapy/estimators/points/tests/test_sed.py
+++ b/gammapy/estimators/points/tests/test_sed.py
@@ -400,6 +400,31 @@ def test_run_map_pwl_reoptimize(fpe_map_pwl_reoptimize):
     assert_allclose(actual, [9.788123, 0.486066, 17.603708], rtol=1e-2)
 
 
+def test_run_no_edip(fpe_pwl, tmpdir):
+    datasets, fpe = fpe_pwl
+
+    datasets = datasets.copy()
+
+    datasets[0].models["source"].apply_irf["edisp"] = False
+    fp = fpe.run(datasets)
+    table = fp.to_table()
+    actual = table["norm"].data
+    assert_allclose(actual, [1.081434, 0.91077, 0.922176], rtol=1e-3)
+
+    datasets[0].edisp = None
+
+    fp = fpe.run(datasets)
+    table = fp.to_table()
+    actual = table["norm"].data
+    assert_allclose(actual, [1.081434, 0.91077, 0.922176], rtol=1e-3)
+
+    datasets[0].models["source"].apply_irf["edisp"] = True
+    fp = fpe.run(datasets)
+    table = fp.to_table()
+    actual = table["norm"].data
+    assert_allclose(actual, [1.081434, 0.91077, 0.922176], rtol=1e-3)
+
+
 @requires_dependency("iminuit")
 @requires_data()
 def test_run_template_npred(fpe_map_pwl, tmpdir):