Repository: gammapy/gammapy
Pull request #5999 (2025-07-21 14:02:15)

Handling non-backward compatible format of the covariance matrix

**Description**

This pull request is associated to the issue #5549. It correctly catches the problem.

**Dear reviewer**
For the 2.1, one should read correctly the Gammapy version in the metadata of the correlation matrix, and treat correctly non-backward compatible formats.
We have no available version of an old model of the TemplateSpatialModel with a such correlation matrix. So, this is hard to make a test...


Patch:
diff --git a/gammapy/modeling/models/core.py b/gammapy/modeling/models/core.py
index 881d9df79..e69dae39d 100644
--- a/gammapy/modeling/models/core.py
+++ b/gammapy/modeling/models/core.py
@@ -571,7 +571,14 @@ class DatasetModels(collections.abc.Sequence, CovarianceMixin):
             filename = data["covariance"]
             if not (path / filename).exists():
                 path, filename = split(filename)
-            models.read_covariance(path, filename, format="ascii.fixed_width")
+            try:
+                models.read_covariance(path, filename, format="ascii.fixed_width")
+            except ValueError as exception:
+                log.warning(
+                    "Impossible to read the covariance correctly: \n"
+                    f"{exception} \n "
+                    "Covariance will be created from errors and non-diagonal terms ignored."
+                )
 
         _set_models_link(models)
 


Test patch:
diff --git a/gammapy/modeling/models/tests/test_core.py b/gammapy/modeling/models/tests/test_core.py
index 83b2a9e00..4f62cf270 100644
--- a/gammapy/modeling/models/tests/test_core.py
+++ b/gammapy/modeling/models/tests/test_core.py
@@ -1,6 +1,8 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 import sys
 import pytest
+import logging
+import numpy as np
 from numpy.testing import assert_allclose
 import astropy.units as u
 from astropy.coordinates import SkyCoord
@@ -293,7 +295,6 @@ def test_select_models():
 
 
 def test_to_template():
-
     energy_bounds = [1, 100] * u.TeV
     energy_axis = MapAxis.from_energy_bounds(
         energy_bounds[0], energy_bounds[1], nbin=2, per_decade=True, name="energy_true"
@@ -360,3 +361,30 @@ def test_two_fov_bkg_models_single_dataset():
         match="Only one FoVBackgroundModel per Dataset is permitted - already got one for ds1",
     ):
         Models([fov1, fov2])
+
+
+def test_bad_covariance(caplog, tmp_path):
+    # Step 1: Create a simple spectral model
+    spectral_model = PowerLawSpectralModel()
+    model = SkyModel(spectral_model=spectral_model, name="test-model")
+    models = Models([model])
+
+    # Step 2: Assign a valid 3x3 identity covariance matrix
+    models.covariance = np.identity(3)
+
+    # Step 3: Write models.yaml and covariance.dat
+    models_file = tmp_path / "models.yaml"
+    models.write(models_file, write_covariance=True, overwrite=True)
+
+    # Step 4: Overwrite covariance.dat with an invalid 1x1 matrix
+    covariance_file = tmp_path / "models_covariance.dat"
+    with open(covariance_file, "w") as f:
+        f.write("|                    Parameters |   0 |\n")
+        f.write("|     test-model.spectral.index | 1.0 |\n")
+
+    # Step 5: Attempt to read the model and catch the expected error
+    with caplog.at_level(logging.WARNING):
+        Models.read(models_file)
+        assert (
+            "Impossible to read the covariance correctly" in caplog.records[0].message
+        )