From 02aebda935baaf69a850a2ced2416d521f7d7544 Mon Sep 17 00:00:00 2001
From: David Hammer <dhammer@mailbox.org>
Date: Wed, 2 Aug 2023 13:08:15 +0200
Subject: [PATCH] Allow selecting one train from range and adding offset to PPU

---
 src/calng/PickyBoi.py | 61 +++++++++++++++++++++++++++++++++++--------
 1 file changed, 50 insertions(+), 11 deletions(-)

diff --git a/src/calng/PickyBoi.py b/src/calng/PickyBoi.py
index 54c2d63d..e0b87dc4 100644
--- a/src/calng/PickyBoi.py
+++ b/src/calng/PickyBoi.py
@@ -21,6 +21,7 @@ from karabo.bound import (
     ChannelMetaData,
     Epochstamp,
     ImageData,
+    Hash,
     PythonDevice,
     Schema,
     State,
@@ -76,12 +77,35 @@ class PickyBoi(PythonDevice):
             .reconfigurable()
             .commit(),
 
+            INT64_ELEMENT(expected)
+            .key("indexOfTrainToForward")
+            .description(
+                "If this value is negative, all numberOfTrainsToCatch starting from "
+                "nextTrainToCatch are forwarded. If non-negative, this is used as an "
+                "index in this range of trains instead i.e. only the train with ID "
+                "nextTrainToCatch + min(indexOfTrainToForward, numberOfTrainsToCatch-1)"
+                "will be forwarded. This is relevant for previewing in Karabo GUI."
+            )
+            .assignmentOptional()
+            .defaultValue(-1)
+            .commit(),
+
             STRING_ELEMENT(expected)
             .key("ppuDevice")
             .assignmentOptional()
             .defaultValue("")
             .commit(),
 
+            INT64_ELEMENT(expected)
+            .key("ppuTrainOffset")
+            .description(
+                "Offset added to trainTrigger.sequenceStart gotten from watched PPU "
+                "device. Should be 0 unless there are timing issues."
+            )
+            .assignmentOptional()
+            .defaultValue(0)
+            .commit(),
+
             DOUBLE_ELEMENT(expected)
             .key("ratioOfRecentTrainsReceived")
             .description(
@@ -189,7 +213,7 @@ class PickyBoi(PythonDevice):
                 conf.has("trainTrigger.numberOfTrains")
                 or conf.has("trainTrigger.sequenceStart")
         ):
-            self._update_target()
+            self._update_target(offset=self.get("ppuTrainOffset"))
 
     def input_handler(self, data, meta):
         if not self._schema_is_set:
@@ -253,12 +277,23 @@ class PickyBoi(PythonDevice):
                 self.updateState(State.PASSIVE)
         self._previous_tid = current_tid
 
-    def _update_target(self):
-        # assumes nextTrainToCatch and numberOfTrainsToCatch have been set
-        new_target_tid = self.get("nextTrainToCatch")
-        self._trains_to_get = set(
-            range(new_target_tid, new_target_tid + self.get("numberOfTrainsToCatch"))
-        )
+    def _update_target(self, offset=0):
+        # assumes nextTrainToCatch and numberOfTrainsToCatch etc. have been set
+        new_target_tid = self.get("nextTrainToCatch") + offset
+        if (index_to_forward := self.get("indexOfTrainToForward")) < 0:
+            self._trains_to_get = set(
+                range(
+                    new_target_tid, new_target_tid + self.get("numberOfTrainsToCatch")
+                )
+            )
+        else:
+            self._trains_to_get = set(
+                (
+                    new_target_tid + min(
+                        self.get("numberOfTrainsToCatch")-1, index_to_forward
+                    ),
+                )
+            )
         if self._previous_tid >= new_target_tid:
             self.log.INFO(
                 f"Moved target train to {new_target_tid} even though last seen was "
@@ -273,7 +308,6 @@ class PickyBoi(PythonDevice):
                 )
             self.updateState(State.MONITORING)
 
-
     def _update_trackers(self):
         if self.get("trainId") != self._previous_tid:
             self.set(
@@ -297,11 +331,16 @@ class PickyBoi(PythonDevice):
             self.log.WARN("postReconfigure update caching trick failed")
             return
 
-        if (
-                self._cached_update.has("nextTrainToCatch")
-                or self._cached_update.has("numberOfTrainsToCatch")
+        if any(
+            self._cached_update.has(thing)
+            for thing in (
+                "nextTrainToCatch",
+                "numberOfTrainsToCatch",
+                "indexOfTrainToForward",
+            )
         ):
             self._update_target()
+        del self._cached_update
 
 
 def hash_to_schema(h, root=None, prefix=""):
-- 
GitLab