Skip to content
Snippets Groups Projects
Commit f9673310 authored by David Hammer's avatar David Hammer
Browse files

Preview as float32 without nan, improved scenes

parent c0bffab0
No related branches found
No related tags found
1 merge request!12Snapshot: field test deployed version as of end of run 202201
...@@ -5,6 +5,7 @@ import re ...@@ -5,6 +5,7 @@ import re
import numpy as np import numpy as np
from karabo.bound import ( from karabo.bound import (
DOUBLE_ELEMENT, DOUBLE_ELEMENT,
FLOAT_ELEMENT,
IMAGEDATA_ELEMENT, IMAGEDATA_ELEMENT,
NDARRAY_ELEMENT, NDARRAY_ELEMENT,
NODE_ELEMENT, NODE_ELEMENT,
...@@ -131,6 +132,20 @@ class DetectorAssembler(TrainMatcher.TrainMatcher): ...@@ -131,6 +132,20 @@ class DetectorAssembler(TrainMatcher.TrainMatcher):
.reconfigurable() .reconfigurable()
.commit(), .commit(),
FLOAT_ELEMENT(expected)
.key("preview.replaceNanWith")
.description(
"Displaying images in KaraboGUI seems to not go well when there are "
"NaN values in data. And there will be with bad pixel masking or just "
"geometry space between modules. NaN values get replaced with this "
"value to get around this; choose a value which clearly stands out "
"from the image data you want to see."
)
.assignmentOptional()
.defaultValue(-1000)
.reconfigurable()
.commit(),
DOUBLE_ELEMENT(expected) DOUBLE_ELEMENT(expected)
.key("preview.maxRate") .key("preview.maxRate")
.displayedName("Max rate") .displayedName("Max rate")
...@@ -241,7 +256,9 @@ class DetectorAssembler(TrainMatcher.TrainMatcher): ...@@ -241,7 +256,9 @@ class DetectorAssembler(TrainMatcher.TrainMatcher):
return return
self._geometry = geom_utils.deserialize_geometry(serialized_geometry) self._geometry = geom_utils.deserialize_geometry(serialized_geometry)
# TODO: allow multiple memory cells (extra geom notion of extra dimensions) # TODO: allow multiple memory cells (extra geom notion of extra dimensions)
self._stack_input_buffer = np.zeros(self._geometry.expected_data_shape) self._stack_input_buffer = np.zeros(
self._geometry.expected_data_shape, dtype=np.float32
)
def on_matched_data(self, train_id, sources): def on_matched_data(self, train_id, sources):
if self._geometry is None: if self._geometry is None:
...@@ -265,9 +282,9 @@ class DetectorAssembler(TrainMatcher.TrainMatcher): ...@@ -265,9 +282,9 @@ class DetectorAssembler(TrainMatcher.TrainMatcher):
# prepare for assembly # prepare for assembly
# TODO: handle failure to "parse" source, get data out # TODO: handle failure to "parse" source, get data out
module_index = self._source_to_index(source) module_index = self._source_to_index(source)
self._stack_input_buffer[module_index] = np.squeeze( self._stack_input_buffer[module_index] = data.get(
data.get(self._path_to_stack) self._path_to_stack
) ).astype(np.float32, copy=False) # TODO: set dtype based on input?
module_indices_unfilled.discard(module_index) module_indices_unfilled.discard(module_index)
earliest_source_timestamp = min( earliest_source_timestamp = min(
earliest_source_timestamp, source_timestamp.toTimestamp() earliest_source_timestamp, source_timestamp.toTimestamp()
...@@ -308,11 +325,12 @@ class DetectorAssembler(TrainMatcher.TrainMatcher): ...@@ -308,11 +325,12 @@ class DetectorAssembler(TrainMatcher.TrainMatcher):
np, self.unsafe_get("preview.downsamplingFunction") np, self.unsafe_get("preview.downsamplingFunction")
), ),
) )
assembled[np.isnan(assembled)] = self.unsafe_get("preview.replaceNanWith")
output_hash = Hash( output_hash = Hash(
"image.data", "image.data",
ImageData( ImageData(
# TODO: get around this being mirrored... # TODO: get around this being mirrored...
assembled.astype(np.int32)[::-1, ::-1], assembled[::-1, ::-1],
Dims(*assembled.shape), Dims(*assembled.shape),
Encoding.GRAY, Encoding.GRAY,
bitsPerPixel=32, bitsPerPixel=32,
......
...@@ -17,6 +17,7 @@ from karabo.common.scenemodel.api import ( ...@@ -17,6 +17,7 @@ from karabo.common.scenemodel.api import (
IntLineEditModel, IntLineEditModel,
LabelModel, LabelModel,
LineEditModel, LineEditModel,
LineModel,
RectangleModel, RectangleModel,
SceneModel, SceneModel,
SceneTargetWindow, SceneTargetWindow,
...@@ -138,6 +139,23 @@ class Space: ...@@ -138,6 +139,23 @@ class Space:
return [] return []
class Hline:
def __init__(self, width):
self.width = width
self.height = 0
def render(self, x, y):
return [
LineModel(
stroke="#000000",
x1=x,
x2=x+self.width,
y1=y,
y2=y,
)
]
def dummy_wrap(model_class): def dummy_wrap(model_class):
class Wrapper: class Wrapper:
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
...@@ -557,6 +575,16 @@ class AssemblerDeviceStatus(VerticalLayout): ...@@ -557,6 +575,16 @@ class AssemblerDeviceStatus(VerticalLayout):
width=7 * BASE_INC, width=7 * BASE_INC,
height=BASE_INC, height=BASE_INC,
) )
rate = DisplayRoundedFloat(
keys=[f"{device_id}.outProcessing"],
width=7 * BASE_INC,
height=BASE_INC,
)
tof = DisplayRoundedFloat(
keys=[f"{device_id}.timeOfFlight"],
width=7 * BASE_INC,
height=BASE_INC,
)
self.children.extend( self.children.extend(
[ [
name, name,
...@@ -565,37 +593,9 @@ class AssemblerDeviceStatus(VerticalLayout): ...@@ -565,37 +593,9 @@ class AssemblerDeviceStatus(VerticalLayout):
train_id, train_id,
padding=0, padding=0,
), ),
LabelModel(
text="Image downsampling",
width=14 * BASE_INC,
height=BASE_INC,
),
HorizontalLayout(
LabelModel(
text="Factor",
width=7 * BASE_INC,
height=BASE_INC,
),
ComboBoxModel(
keys=[f"{device_id}.preview.downsamplingFactor"],
width=7 * BASE_INC,
height=BASE_INC,
klass="EditableComboBox",
),
padding=0,
),
HorizontalLayout( HorizontalLayout(
LabelModel( rate,
text="Function", tof,
width=7 * BASE_INC,
height=BASE_INC,
),
ComboBoxModel(
keys=[f"{device_id}.preview.downsamplingFunction"],
width=7 * BASE_INC,
height=BASE_INC,
klass="EditableComboBox",
),
padding=0, padding=0,
), ),
DeviceSceneLinkModel( DeviceSceneLinkModel(
...@@ -606,6 +606,16 @@ class AssemblerDeviceStatus(VerticalLayout): ...@@ -606,6 +606,16 @@ class AssemblerDeviceStatus(VerticalLayout):
width=14 * BASE_INC, width=14 * BASE_INC,
height=BASE_INC, height=BASE_INC,
), ),
LabelModel(
text="My geometry device:",
width=14 * BASE_INC,
height=BASE_INC,
),
DisplayLabelModel(
keys=[f"{device_id}.geometryDevice"],
width=14 * BASE_INC,
height=BASE_INC,
), # TODO: some day, get dynamic link to this friend
] ]
) )
...@@ -1131,12 +1141,67 @@ def detector_assembler_overview(device_id): ...@@ -1131,12 +1141,67 @@ def detector_assembler_overview(device_id):
return VerticalLayout( return VerticalLayout(
HorizontalLayout( HorizontalLayout(
AssemblerDeviceStatus(device_id), AssemblerDeviceStatus(device_id),
titled("My geometry device")(boxed(VerticalLayout))( titled("Preview settings")(boxed(VerticalLayout))(
DisplayLabelModel( HorizontalLayout(
keys=[f"{device_id}.geometryDevice"], LabelModel(
width=6 * BASE_INC, text="Display NaN values as:",
width=7 * BASE_INC,
height=BASE_INC,
),
DoubleLineEditModel(
keys=[f"{device_id}.preview.replaceNanWith"],
width=7 * BASE_INC,
height=BASE_INC,
),
padding=0,
),
HorizontalLayout(
LabelModel(
text="Max preview rate",
width=7 * BASE_INC,
height=BASE_INC,
),
DoubleLineEditModel(
keys=[f"{device_id}.preview.maxRate"],
width=7 * BASE_INC,
height=BASE_INC,
),
padding=0,
),
Hline(width=14 * BASE_INC),
LabelModel(
text="Image downsampling",
width=14 * BASE_INC,
height=BASE_INC, height=BASE_INC,
) ),
HorizontalLayout(
LabelModel(
text="Factor",
width=7 * BASE_INC,
height=BASE_INC,
),
ComboBoxModel(
keys=[f"{device_id}.preview.downsamplingFactor"],
width=7 * BASE_INC,
height=BASE_INC,
klass="EditableComboBox",
),
padding=0,
),
HorizontalLayout(
LabelModel(
text="Function",
width=7 * BASE_INC,
height=BASE_INC,
),
ComboBoxModel(
keys=[f"{device_id}.preview.downsamplingFunction"],
width=7 * BASE_INC,
height=BASE_INC,
klass="EditableComboBox",
),
padding=0,
),
), ),
), ),
titled("Preview image")(boxed(dummy_wrap(DetectorGraphModel)))( titled("Preview image")(boxed(dummy_wrap(DetectorGraphModel)))(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment