From cd2dade27988b44ac5ba16ab56cfa2bdf67219d0 Mon Sep 17 00:00:00 2001 From: David Hammer <dhammer@mailbox.org> Date: Thu, 7 Apr 2022 10:02:03 +0200 Subject: [PATCH] Switch preview throttling method for DetectorAssembler --- src/calng/DetectorAssembler.py | 28 ++++++++++++++++------------ src/calng/utils.py | 16 ++++++++++++++++ 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/calng/DetectorAssembler.py b/src/calng/DetectorAssembler.py index 3ec407bf..56178d94 100644 --- a/src/calng/DetectorAssembler.py +++ b/src/calng/DetectorAssembler.py @@ -4,7 +4,7 @@ import re import numpy as np from karabo.bound import ( - FLOAT_ELEMENT, + DOUBLE_ELEMENT, IMAGEDATA_ELEMENT, NDARRAY_ELEMENT, NODE_ELEMENT, @@ -71,7 +71,7 @@ class DetectorAssembler(TrainMatcher.TrainMatcher): .setNewDefaultValue(["overview", "trainMatcherScene"]) .commit(), - FLOAT_ELEMENT(expected) + DOUBLE_ELEMENT(expected) .key("timeOfFlight") .displayedName("Time of flight") .unit(Unit.SECOND) @@ -98,9 +98,8 @@ class DetectorAssembler(TrainMatcher.TrainMatcher): .key("preview") .description( "The preview output is intended for Karabo GUI previews. It differs " - "from the main output in that it is lower rate (controlled by train " - "stride), can be downsampled, and is given the ImageData type for use " - "within Karabo." + "from the main output in that it is rate throttled, can be " + "downsampled, and is given the ImageData type for use within Karabo." ) .commit(), @@ -132,13 +131,17 @@ class DetectorAssembler(TrainMatcher.TrainMatcher): .reconfigurable() .commit(), - UINT32_ELEMENT(expected) - .key("preview.trainStride") - .displayedName("Train stride") - .description("Only trains which are a multiple of this are sent to preview") - .unit(Unit.COUNT) + DOUBLE_ELEMENT(expected) + .key("preview.maxRate") + .displayedName("Max rate") + .description( + "Preview output is throttled to (at most) this speed. New trains " + "matched 'too soon' get dropped here (instead of sending to be dropped " + "by GUI)." + ) + .unit(Unit.HERTZ) .assignmentOptional() - .defaultValue(10) + .defaultValue(2) .reconfigurable() .commit(), @@ -178,6 +181,7 @@ class DetectorAssembler(TrainMatcher.TrainMatcher): # TODO: match inside device, fill multiple independent buffers + self._throttler = utils.SkippingThrottler(1 / self.get("preview.maxRate")) self._path_to_stack = self.get("pathToStack") self._geometry = None self._stack_input_buffer = None @@ -294,7 +298,7 @@ class DetectorAssembler(TrainMatcher.TrainMatcher): self.zmq_output.write(my_source, output_hash, my_timestamp) self.zmq_output.update() - if train_id % self.unsafe_get("preview.trainStride") == 0: + if self._throttler.test_and_set(): downsampling_factor = self.unsafe_get("preview.downsamplingFactor") if downsampling_factor > 1: assembled = downsample_2d( diff --git a/src/calng/utils.py b/src/calng/utils.py index c24502a8..d0f6ceb4 100644 --- a/src/calng/utils.py +++ b/src/calng/utils.py @@ -369,6 +369,22 @@ class ChainHash: raise KeyError() +class SkippingThrottler: + def __init__(self, min_period): + self.min_period = min_period + self.latest_ts = float("-inf") + self.lock = threading.Lock() + + def test_and_set(self): + with self.lock: + now = default_timer() + if (now - self.latest_ts) >= self.min_period: + self.latest_ts = now + return True + else: + return False + + class BadPixelValues(enum.IntFlag): """The European XFEL Bad Pixel Encoding -- GitLab