Repository: gammapy/gammapy

Issue:
Setting background_model to none on a dataset
I am not sure if this is expected behaviour or it is a bug, but I find this very confusing:
Suppose I have a `dataset`  with a background_model and one sky model.
`dataset.models`  returns both these model, as expected. 
Now, I do `dataset.background_model=None` .

`dataset.models` now gives me:

```
ModelsModels
Component 0: BackgroundModel
  Name                      : stacked-bkg
  Datasets names            : ['stacked']
  Parameters:
    norm                    :   1.300              
    tilt         (frozen)   :   0.000              
    reference    (frozen)   :   1.000  TeV         
Component 1: SkyModel
  Name                      : gc-source
  Datasets names            : None
  Spectral model type       : ExpCutoffPowerLawSpectralModel
  Spatial  model type       : PointSpatialModel
  Temporal model type       : None
  Parameters:
    index                   :   2.300              
    amplitude               :   2.80e-12  1 / (cm2 s TeV)
    reference    (frozen)   :   1.000  TeV         
    lambda_                 :   0.020  1 / TeV     
    alpha        (frozen)   :   1.000              
    lon_0                   :  -0.050  deg         
    lat_0                   :  -0.050  deg         
```
I would expect Component 0 to have vanished now...

comments @registerrier @QRemy @adonath ?


Discussion:
Not sure that should be allowed maybe dataset.background_model should be a property. Why do you want to set it to None ?
Thanks @AtreyeeS, these inconsistencies are still a result of the unsolved question of background and global model handling in Gammapy. In this specific case I’m pretty sure the `background_model` attribute will be removed soon and the only way to interact with the model will be `MapDataset.models`. The minimal action here could be to make the `background_model` attribute read only...
@QRemy : Indeed I do not have a reasonable science case for it, but this in done in the tests 
eg:  https://github.com/gammapy/gammapy/blob/5f8eaf2d4c3c89a2705e6897c2ecc9f04b5c38b1/gammapy/datasets/tests/test_map.py#L254
which I realised while implementing #2870 .

Thanks for the clarification @adonath ! I keep this issue open till we sort this out.

Resolving patch:
diff --git a/gammapy/datasets/map.py b/gammapy/datasets/map.py
--- a/gammapy/datasets/map.py
+++ b/gammapy/datasets/map.py
@@ -87,7 +87,7 @@ def __init__(
             raise ValueError("mask data must have dtype bool")
 
         self._name = make_name(name)
-        self.background_model = None
+        self._background_model = None
         self.evaluation_mode = evaluation_mode
         self.counts = counts
         self.exposure = exposure
@@ -186,6 +186,10 @@ def models(self):
         """Models (`~gammapy.modeling.models.Models`)."""
         return self._models
 
+    @property
+    def background_model(self):
+        return self._background_model
+
     @models.setter
     def models(self, models):
         if models is None:
@@ -199,7 +203,7 @@ def models(self, models):
                 if isinstance(model, BackgroundModel):
                     if model.datasets_names is not None:
                         if self.name in model.datasets_names:
-                            self.background_model = model
+                            self._background_model = model
                             break
             else:
                 log.warning(f"No background model defined for dataset {self.name}")
@@ -411,8 +415,8 @@ def stack(self, other):
             background_model = other.background_model
 
         if self.background_model and background_model:
-            self.background_model.map *= self.mask_safe
-            self.background_model.stack(background_model, other.mask_safe)
+            self._background_model.map *= self.mask_safe
+            self._background_model.stack(background_model, other.mask_safe)
 
         if self.mask_safe is not None and other.mask_safe is not None:
             self.mask_safe.stack(other.mask_safe)
@@ -1053,7 +1057,7 @@ def __init__(
         self.acceptance = acceptance
         self.acceptance_off = acceptance_off
         self.exposure = exposure
-        self.background_model = None
+        self._background_model = None
         self.mask_fit = mask_fit
         self.psf = psf
         self.edisp = edisp


Test patch:
diff --git a/gammapy/datasets/tests/test_io.py b/gammapy/datasets/tests/test_io.py
--- a/gammapy/datasets/tests/test_io.py
+++ b/gammapy/datasets/tests/test_io.py
@@ -70,4 +70,4 @@ def test_datasets_to_io(tmp_path):
     assert_allclose(
         datasets.models["background_irf_g09"].covariance,
         datasets.models["background_irf_gc"].covariance,
-    )
\ No newline at end of file
+    )
diff --git a/gammapy/datasets/tests/test_map.py b/gammapy/datasets/tests/test_map.py
--- a/gammapy/datasets/tests/test_map.py
+++ b/gammapy/datasets/tests/test_map.py
@@ -251,10 +251,10 @@ def test_to_image(geom):
     # Check that missing entries in the dataset do not break
     dataset_copy = dataset.copy()
     dataset_copy.exposure = None
-    dataset_copy.background_model = None
+    dataset_copy._background_model = None
     dataset_im = dataset_copy.to_image()
     assert dataset_im.exposure is None
-    assert dataset_im.background_model is None
+    assert dataset_im.background_model == None
 
     dataset_copy = dataset.copy()
     dataset_copy.counts = None
@@ -734,7 +734,7 @@ def test_map_dataset_on_off_cutout(images):
     assert cutout_dataset.counts_off.data.shape == (1, 50, 50)
     assert cutout_dataset.acceptance.data.shape == (1, 50, 50)
     assert cutout_dataset.acceptance_off.data.shape == (1, 50, 50)
-    assert cutout_dataset.background_model is None
+    assert cutout_dataset.background_model == None
     assert cutout_dataset.name != dataset.name
 
 
@@ -779,7 +779,9 @@ def test_map_dataset_geom(geom, sky_model):
     e_true = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=5, name="energy_true")
     dataset = MapDataset.create(geom, energy_axis_true=e_true)
     dataset.counts = None
-    dataset.background_model = None
+    dataset._background_model = None
+    with pytest.raises(AttributeError):
+        dataset.background_model = None
 
     dataset.models = sky_model
 
diff --git a/gammapy/datasets/tests/test_simulate.py b/gammapy/datasets/tests/test_simulate.py
--- a/gammapy/datasets/tests/test_simulate.py
+++ b/gammapy/datasets/tests/test_simulate.py
@@ -279,7 +279,7 @@ def test_mde_run_switchoff(dataset):
 
     dataset.psf = None
     dataset.edisp = None
-    dataset.background_model = None
+    dataset._background_model = None
 
     sampler = MapDatasetEventSampler(random_state=0)
     events = sampler.run(dataset=dataset, observation=obs)