From cb43072c5a7b4d3e94704aa268df15303896f4c1 Mon Sep 17 00:00:00 2001
From: ahmedk <karim.ahmed@xfel.eu>
Date: Tue, 10 Oct 2023 10:10:31 +0200
Subject: [PATCH] Separate gain mode validation into validate_gain_modes

---
 .../Characterize_AGIPD_Gain_Darks_NBC.ipynb   |  1 +
 src/cal_tools/agipdlib.py                     | 46 ++++++++++++-------
 tests/test_agipdlib.py                        | 11 +++++
 3 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/notebooks/AGIPD/Characterize_AGIPD_Gain_Darks_NBC.ipynb b/notebooks/AGIPD/Characterize_AGIPD_Gain_Darks_NBC.ipynb
index 2ee182a23..cdf00a228 100644
--- a/notebooks/AGIPD/Characterize_AGIPD_Gain_Darks_NBC.ipynb
+++ b/notebooks/AGIPD/Characterize_AGIPD_Gain_Darks_NBC.ipynb
@@ -284,6 +284,7 @@
     "    bias_voltage = agipd_ctrl_dark.get_bias_voltage(karabo_id_control)\n",
     "\n",
     "fixed_gain_mode = False\n",
+    "agipd_ctrl_dark.validate_gain_modes()\n",
     "if gain_mode == -1:\n",
     "    gain_mode = agipd_ctrl_dark.gain_modes\n",
     "    fixed_gain_mode = agipd_ctrl_dark.fixed_gain_mode()\n",
diff --git a/src/cal_tools/agipdlib.py b/src/cal_tools/agipdlib.py
index dbca752e3..d8b78d524 100644
--- a/src/cal_tools/agipdlib.py
+++ b/src/cal_tools/agipdlib.py
@@ -309,7 +309,14 @@ class AgipdCtrl:
 @dataclass
 class AgipdCtrlRuns:
     run_ctrls: List[AgipdCtrl]
-    runs: list = field(init=False)
+    adaptive_gain_modes: List[AgipdGainMode] = field(
+        default_factory=lambda: [AgipdGainMode.ADAPTIVE_GAIN] * 3)
+    fixed_gain_modes: List[AgipdGainMode] = field(
+        default_factory=lambda: [
+            AgipdGainMode.FIXED_HIGH_GAIN,
+            AgipdGainMode.FIXED_MEDIUM_GAIN,
+            AgipdGainMode.FIXED_LOW_GAIN,
+        ])
 
     def __post_init__(self):
         self.runs = [c.run for c in self.run_ctrls]
@@ -326,33 +333,40 @@ class AgipdCtrlRuns:
         assert len(self.run_ctrls) == 3, f"AGIPD dark runs are expected to be 3. {len(self.run_ctrls)} runs are given."
         # TODO: complete sorting
 
+    def validate_gain_modes(self):
+        """Validate the runs' gain modes arrangement.
+        
+        Raises:
+            ValueError: Runs are a mix of adaptive and fixed gains
+            ValueError: Unexpected gain modes for the dark runs"""
+        if self.gain_modes in [
+            self.adaptive_gain_modes, self.fixed_gain_modes]:
+            return  # all good.
+        # Check if a mix of adaptive and fixed gain runs.
+        if any(gm == AgipdGainMode.ADAPTIVE_GAIN for gm in self.gain_modes):
+            raise ValueError(
+                f"Given runs {self.runs} have a mix of ADAPTIVE and "
+                f"FIXED gain modes: {self.gain_modes}.")
+        else:  # Unsorted fixed gain runs.
+            raise ValueError(
+            "Wrong arrangement of given dark runs. Given runs' "
+            f"gain_modes are {self.gain_modes} for runs: {self.runs}.")
+
     def fixed_gain_mode(self):
         """Check if runs are in fixed gain mode.
 
         Raises:
-            ValueError: Runs are a mix of adaptive and fixed gains
             ValueError: Unexpected gain modes for the dark runs
 
         Returns:
             bool: runs are in fixed gain mode.
         """
-        if all(gm == AgipdGainMode.ADAPTIVE_GAIN for gm in self.gain_modes):
+        if self.gain_modes == self.adaptive_gain_modes:
             return False
-        # Some runs are adaptive by mistake.
-        elif any(gm == AgipdGainMode.ADAPTIVE_GAIN for gm in self.gain_modes):
-            raise ValueError(
-                f"Given runs {self.runs} have a mix of ADAPTIVE and "
-                f"FIXED gain modes: {self.gain_modes}.")
-        elif list(self.gain_modes) == [
-            AgipdGainMode.FIXED_HIGH_GAIN,
-            AgipdGainMode.FIXED_MEDIUM_GAIN,
-            AgipdGainMode.FIXED_LOW_GAIN
-        ]:
+        elif self.gain_modes == self.fixed_gain_modes:
             return True
         else:
-            raise ValueError(
-            "Wrong arrangement of given dark runs. Given runs' "
-            f"gain_modes are {self.gain_modes} for runs: {self.runs}.")
+            raise ValueError(f"Unexpected runs' gain modes: {self.gain_modes}")
 
     def get_gain_modes(self):
         """Get runs' gain modes.
diff --git a/tests/test_agipdlib.py b/tests/test_agipdlib.py
index 4e0d79125..566045698 100644
--- a/tests/test_agipdlib.py
+++ b/tests/test_agipdlib.py
@@ -307,3 +307,14 @@ def test_raise_fixed_gain_mode():
     with pytest.raises(ValueError) as e:
         ctrl_runs = AgipdCtrlRuns(run_ctrls=adaptive_fixed)
         ctrl_runs.fixed_gain_mode()
+
+@pytest.mark.requires_gpfs
+def test_raise_validate_gain_modes():
+    adaptive_fixed = _initialize_agipd_ctrls([9011, 9016, 9017])
+    ctrl_runs = AgipdCtrlRuns(run_ctrls=adaptive_fixed)
+    with pytest.raises(ValueError) as e:
+        ctrl_runs.validate_gain_modes()
+    unsorted_fixed_gais = _initialize_agipd_ctrls([9013, 9011, 9012])
+    ctrl_runs = AgipdCtrlRuns(run_ctrls=unsorted_fixed_gais)
+    with pytest.raises(ValueError) as e:
+        ctrl_runs.validate_gain_modes()
-- 
GitLab