Repository: cta-observatory/ctapipe (python)

Issue:
NSBImageCleaner tries to reach the tel attribute from the MonitoringCameraContainer
'NSBImageCleaner' tries to reach the 'tel' attribute from the 'MonitoringCameraContainer' here
https://github.com/cta-observatory/ctapipe/blob/f9108ac61728eeb4c35899e5b49035aee00288ee/src/ctapipe/image/cleaning.py#L802

which results in an AttributeError when e.g. using the 'ImageProcessor' in ctapipe-process.

Thanks to @BastienLacave for noticing!

Pull request description:
Delete tel attribute from MonitoringCameraContainer in NSBImageCleaner
Fixes #2601 
Adding `MonitoringCameraContainer` to tests

Patch:
diff --git a/docs/changes/2602.bugfix.rst b/docs/changes/2602.bugfix.rst
new file mode 100644
index 00000000..34275815
--- /dev/null
+++ b/docs/changes/2602.bugfix.rst
@@ -0,0 +1,3 @@
+Fix ``NSBImageCleaner`` that tries to reach the tel attribute
+from a MonitoringCameraContainer which results in an AttributeError
+when using the ``ImageProcessor``.
diff --git a/src/ctapipe/image/cleaning.py b/src/ctapipe/image/cleaning.py
index e96b2bef..328fb4be 100644
--- a/src/ctapipe/image/cleaning.py
+++ b/src/ctapipe/image/cleaning.py
@@ -799,7 +799,7 @@ class NSBImageCleaner(TailcutsImageCleaner):
         """
         pedestal_std = None
         if monitoring is not None:
-            pedestal_std = monitoring.tel[tel_id].pedestal.charge_std
+            pedestal_std = monitoring.pedestal.charge_std
 
         return nsb_image_cleaning(
             self.subarray.tel[tel_id].camera.geometry,


Test patch:
diff --git a/src/ctapipe/image/tests/test_image_cleaner_component.py b/src/ctapipe/image/tests/test_image_cleaner_component.py
index e0f34829..6bfe4379 100644
--- a/src/ctapipe/image/tests/test_image_cleaner_component.py
+++ b/src/ctapipe/image/tests/test_image_cleaner_component.py
@@ -2,6 +2,7 @@ import numpy as np
 import pytest
 from traitlets.config import Config
 
+from ctapipe.containers import MonitoringCameraContainer
 from ctapipe.image import ImageCleaner
 from ctapipe.instrument import SubarrayDescription
 
@@ -41,6 +42,11 @@ def test_image_cleaner(method, prod5_mst_nectarcam, reference_location):
         reference_location=reference_location,
     )
 
+    monitoring = MonitoringCameraContainer()
+    monitoring.pedestal.charge_std = np.ones(
+        prod5_mst_nectarcam.camera.geometry.n_pixels
+    )
+
     clean = ImageCleaner.from_name(method, config=config, subarray=subarray)
 
     image = np.zeros_like(
@@ -51,7 +57,7 @@ def test_image_cleaner(method, prod5_mst_nectarcam, reference_location):
     image[31:40] = 8.0
     times = np.linspace(-5, 10, image.shape[0])
 
-    mask = clean(tel_id=1, image=image, arrival_times=times)
+    mask = clean(tel_id=1, image=image, arrival_times=times, monitoring=monitoring)
 
     # we're not testing the algorithm here, just that it does something (for the
     # algorithm tests, see test_cleaning.py