From d1df365e4e07c67b6b11d4f98fb0d794cafc78e7 Mon Sep 17 00:00:00 2001 From: David Hammer <dhammer@mailbox.org> Date: Fri, 28 Jan 2022 13:50:11 +0100 Subject: [PATCH] Allow downsampling like in FemDataAssembler --- src/calng/SimpleAssembler.py | 56 +++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/calng/SimpleAssembler.py b/src/calng/SimpleAssembler.py index 5081e3ad..3a7708f7 100644 --- a/src/calng/SimpleAssembler.py +++ b/src/calng/SimpleAssembler.py @@ -3,7 +3,6 @@ import pickle import re import numpy as np -from calng import utils from karabo.bound import ( FLOAT_ELEMENT, IMAGEDATA_ELEMENT, @@ -12,6 +11,7 @@ from karabo.bound import ( OUTPUT_CHANNEL, OVERWRITE_ELEMENT, STRING_ELEMENT, + UINT32_ELEMENT, UINT64_ELEMENT, ChannelMetaData, Dims, @@ -42,6 +42,7 @@ preview_schema = Schema() xtdf_source_re = re.compile(r".*\/DET\/(\d+)CH0:xtdf") daq_source_re = re.compile(r".*\/DET\/.*?(\d+):daqOutput") + # TODO: merge scene with TrainMatcher's nice overview @KARABO_CLASSINFO("SimpleAssembler", deviceVersion) class SimpleAssembler(TrainMatcher.TrainMatcher): @@ -81,6 +82,28 @@ class SimpleAssembler(TrainMatcher.TrainMatcher): .defaultValue("image.data") .commit(), + UINT32_ELEMENT(expected) + .key("downsamplingFactor") + .description( + "If greater than 1, the assembled image will be downsampled by this " + "factor in x and y dimensions before sending. This is only to save " + "bandwidth in case GUI updates start lagging." + ) + .assignmentOptional() + .defaultValue(1) + .options("1,2,4,8") + .reconfigurable() + .commit(), + + STRING_ELEMENT(expected) + .key("downsamplingFunction") + .description("Reduction function used during downsampling.") + .assignmentOptional() + .defaultValue("nanmax") + .options("nanmax,nanmean,nanmin,nanmedian") + .reconfigurable() + .commit(), + INPUT_CHANNEL(expected) .key("geometryInput") .displayedName("Geometry input") @@ -157,6 +180,14 @@ class SimpleAssembler(TrainMatcher.TrainMatcher): # TODO: reusable output buffer to save on allocation assembled, _ = self.geometry.position_modules_fast(self.input_buffer) + downsampling_factor = self.get("downsamplingFactor") + if downsampling_factor > 1: + assembled = downsample_2d( + assembled, + downsampling_factor, + reduction_fun=getattr(np, self.get("downsamplingFunction")) + ) + # TODO: optionally include control data out_hash = Hash( "image", @@ -197,3 +228,26 @@ class SimpleAssembler(TrainMatcher.TrainMatcher): self.log.WARN(f"Couldn't figure out index for source {source}") return 0 + + +def downsample_2d(arr, factor, reduction_fun=np.nanmax): + """Generalization of downsampling from FemDataAssembler + + Expects first two dimensions of arr to be multiple of 2 ** factor + Useful if you're sitting at home and ssh connection is slow to get full-resolution + previews.""" + + for i in range(factor // 2): + arr = reduction_fun( + ( + arr[:-1:2], + arr[1::2], + ), axis=0 + ) + arr = reduction_fun( + ( + arr[:, :-1:2], + arr[:, 1::2], + ), axis=0 + ) + return arr -- GitLab