diff --git a/bliss/controllers/lima/roi.py b/bliss/controllers/lima/roi.py index 2a74aa013f21da705f64f3ad84f6fed8bce99d8f..a52131e9bcab4a3f08b5e9f612f6769f31ea6527 100644 --- a/bliss/controllers/lima/roi.py +++ b/bliss/controllers/lima/roi.py @@ -465,6 +465,9 @@ class RoiProfileCounter(IntegratingCounter): self.roi_name = roi_name super().__init__(roi_name, controller, conversion_function, unit) + def get_metadata(self): + return {self.roi_name: self._counter_controller.get(self.roi_name).to_dict()} + @property def dtype(self): """The data type as used by numpy.""" diff --git a/nexus_writer_service/subscribers/devices.py b/nexus_writer_service/subscribers/devices.py index 891c515432e1924bde5437d80d6c8286f87c52df..f9344f2942d153d3555bbb012e57ac96f5cd2ddf 100644 --- a/nexus_writer_service/subscribers/devices.py +++ b/nexus_writer_service/subscribers/devices.py @@ -190,6 +190,7 @@ def parse_devices(devices, short_names=True, multivalue_positioners=False): elif device["device_type"] == "lima": # 'frelon1:image' # 'frelon1:roi_counters:roi1_min' + # 'frelon1:roi_profiles:roi2' # 'frelon1:bpm:fwhm_x' parts = fullname.split(":") if len(parts) == 3: @@ -199,6 +200,10 @@ def parse_devices(devices, short_names=True, multivalue_positioners=False): device_name = ":".join([parts[0], subparts[0]]) datatype = "_".join(subparts[1:]) device["metadata_keys"] = {subparts[0]: "selection"} + elif parts[1] == "roi_profiles": + device_name = ":".join([parts[0], parts[-1]]) + datatype = "sum" + device["metadata_keys"] = {parts[-1]: "selection"} else: device_name = ":".join(parts[:2]) datatype = parts[2] diff --git a/nexus_writer_service/subscribers/scan_writer_publish.py b/nexus_writer_service/subscribers/scan_writer_publish.py index 2b07e2120ea19eb943c4fcd90f6f295674658eb7..3c8c8186ca6aab9108615b9496e46f9a8d05273b 100644 --- a/nexus_writer_service/subscribers/scan_writer_publish.py +++ b/nexus_writer_service/subscribers/scan_writer_publish.py @@ -24,7 +24,7 @@ from bliss.controllers.mca.base import ( from bliss.controllers.mca.mythen import MythenCounter, RoiMythenCounter from bliss.controllers.lima.bpm import LimaBpmCounter from bliss.controllers.lima.image import ImageCounter -from bliss.controllers.lima.roi import RoiStatCounter +from bliss.controllers.lima.roi import RoiStatCounter, RoiProfileCounter from bliss.common.counter import SamplingCounter from ..utils import config_utils from ..utils import scan_utils @@ -170,7 +170,7 @@ def _device_info_add_ctr(devices, ctr): device_info = {"type": "lima"} device = {"device_info": device_info, "device_type": "lima"} devices[fullname] = device - elif isinstance(ctr, RoiStatCounter): + elif isinstance(ctr, (RoiStatCounter, RoiProfileCounter)): device_info = {"type": "lima"} device = {"device_info": device_info, "device_type": "lima"} devices[fullname] = device diff --git a/tests/nexus_writer/helpers/nxw_test_data.py b/tests/nexus_writer/helpers/nxw_test_data.py index 88c51e7e9944369f330f23486b96e0ccd596174f..9580e18cfc0b0c06c2132d2564c2215e1e142ac5 100644 --- a/tests/nexus_writer/helpers/nxw_test_data.py +++ b/tests/nexus_writer/helpers/nxw_test_data.py @@ -721,12 +721,16 @@ def expected_plots( softtimer=softtimer, ) - def ismca(name): - return "simu" in name or "spectrum" in name + def ismca1d(name): + return ("simu" in name or "spectrum" in name) and "lima" not in name - mca_signals = [name for name in channels[1] if ismca(name)] - non_mca_signals = [name for name in channels[1] if not ismca(name)] - single1Dtype = bool(mca_signals) ^ bool(non_mca_signals) + def islima1d(name): + return "lima" in name or "roi4" in name + + lima_1d_signals = {name for name in channels[1] if islima1d(name)} + mca_1d_signals = {name for name in channels[1] if ismca1d(name)} + other_1d_signals = set(channels[1]) - mca_1d_signals - lima_1d_signals + n_1d_types = bool(mca_1d_signals) + bool(other_1d_signals) + bool(lima_1d_signals) if config: if technique != "none": # All 0D detectors @@ -737,9 +741,10 @@ def expected_plots( "signals": channels[0], } # All 1D detectors - if single1Dtype: + if n_1d_types == 1: signals = {f"simu{i}_det{j}" for i in range(1, 3) for j in range(4)} signals |= {"diode9alias_samples"} + signals |= {"lima_simulator2_roi4", "lima_simulator_roi4"} signals &= channels[1] plots["all_spectra"] = {"ndim": 1, "type": "flat", "signals": signals} plots["all_spectra_grid"] = { @@ -772,6 +777,18 @@ def expected_plots( "type": "grid", "signals": signals, } + signals = {"lima_simulator2_roi4", "lima_simulator_roi4"} + signals &= channels[1] + plots["all_spectra_lima"] = { + "ndim": 1, + "type": "flat", + "signals": signals, + } + plots["all_spectra_grid_lima"] = { + "ndim": 1, + "type": "grid", + "signals": signals, + } # All 2D detectors plots["all_images"] = {"ndim": 2, "type": "flat", "signals": channels[2]} plots["all_images_grid"] = { @@ -814,19 +831,18 @@ def expected_plots( # All 0D detectors plots["plot0D"] = {"ndim": 0, "type": "flat", "signals": channels[0]} # All 1D detectors - if single1Dtype: + if n_1d_types == 1: plots["plot1D"] = {"ndim": 1, "type": "flat", "signals": channels[1]} else: - plots["plot1D_unknown1D1"] = { - "ndim": 1, - "type": "flat", - "signals": non_mca_signals, - } - plots["plot1D_unknown1D2"] = { - "ndim": 1, - "type": "flat", - "signals": mca_signals, - } + i = 1 + for signals in [other_1d_signals, lima_1d_signals, mca_1d_signals]: + if signals: + plots["plot1D_unknown1D" + str(i)] = { + "ndim": 1, + "type": "flat", + "signals": signals, + } + i += 1 # All 2D detectors plots["plot2D"] = {"ndim": 2, "type": "flat", "signals": channels[2]} return plots @@ -976,7 +992,7 @@ def detectors_filter(expected, detectors, removeprefix=False): result, ["^lima_simulator_", "^lima_simulator2_"], ["lima_simulator", "lima_simulator2"], - ["{}_roi_counters_", "{}_bpm_", "{}_"], + ["{}_roi_counters_", "{}_roi_profiles_", "{}_bpm_", "{}_"], ) result = remove_controller_prefix( result, ["^simu1_", "^simu2_"], ["simu1", "simu2"], ["{}_"] @@ -1051,7 +1067,10 @@ def expected_detector_content(name, config=True): } elif name.startswith("lima"): if "roi" in name: - datasets = {"data", "type", "avg", "min", "max", "std", "selection"} + if "roi4" in name: + datasets = {"data", "type", "selection"} + else: + datasets = {"data", "type", "avg", "min", "max", "std", "selection"} elif "bpm" in name: datasets = { "type", @@ -1068,16 +1087,20 @@ def expected_detector_content(name, config=True): datasets = {"data"} else: if name.startswith("lima"): - if "roi" in name: - datasets = {"data", "roi1", "roi2", "roi3", "roi4"} + if "roi_counter" in name: + datasets = {"data", "roi1", "roi2", "roi3"} + elif "roi_profile" in name: + datasets = {"data", "roi4"} elif "bpm" in name: datasets = {"data"} else: datasets = {"data", "acq_parameters", "ctrl_parameters"} elif name == "image": datasets = {"data", "acq_parameters", "ctrl_parameters"} - elif re.match("roi[0-9]_(sum|avg|std|min|max)", name): - datasets = {"data", "roi1", "roi2", "roi3", "roi4"} + elif re.match("roi[1-3]_(sum|avg|std|min|max)", name): + datasets = {"data", "roi1", "roi2", "roi3"} + elif name == "roi4": + datasets = {"data", "roi4"} else: datasets = {"data"} return datasets @@ -1174,27 +1197,23 @@ def expected_channels( if config: for conname in names: datasets[2] |= {conname} + datasets[1] |= {conname + "_roi4"} datasets[0] |= { + conname + "_roi1", conname + "_roi1_min", conname + "_roi1_max", - conname + "_roi1", conname + "_roi1_avg", conname + "_roi1_std", + conname + "_roi2", conname + "_roi2_min", conname + "_roi2_max", - conname + "_roi2", conname + "_roi2_avg", conname + "_roi2_std", + conname + "_roi3", conname + "_roi3_min", conname + "_roi3_max", - conname + "_roi3", conname + "_roi3_avg", conname + "_roi3_std", - conname + "_roi4_min", - conname + "_roi4_max", - conname + "_roi4", - conname + "_roi4_avg", - conname + "_roi4_std", conname + "_bpm_x", conname + "_bpm_y", conname + "_bpm_fwhm_x", @@ -1206,8 +1225,10 @@ def expected_channels( for conname in names: prefix = conname + "_" prefix_roi = conname + "_roi_counters_" + prefix_roi_profile = conname + "_roi_profiles_" prefix_bpm = conname + "_bpm_" datasets[2] |= {prefix + "image"} + datasets[1] |= {prefix_roi_profile + "roi4"} datasets[0] |= { prefix_roi + "roi1_min", prefix_roi + "roi1_max", @@ -1224,11 +1245,6 @@ def expected_channels( prefix_roi + "roi3_sum", prefix_roi + "roi3_avg", prefix_roi + "roi3_std", - prefix_roi + "roi4_min", - prefix_roi + "roi4_max", - prefix_roi + "roi4_sum", - prefix_roi + "roi4_avg", - prefix_roi + "roi4_std", prefix_bpm + "x", prefix_bpm + "y", prefix_bpm + "fwhm_x", diff --git a/tests/test_configuration/sessions/scripts/nexus_writer_session.py b/tests/test_configuration/sessions/scripts/nexus_writer_session.py index 8c7ec63c781fc1a493026616d704c4fda7f7ee39..d2d915792c6e9ce3511ab3d0f3ad2bf2622547bb 100644 --- a/tests/test_configuration/sessions/scripts/nexus_writer_session.py +++ b/tests/test_configuration/sessions/scripts/nexus_writer_session.py @@ -1,5 +1,7 @@ import gevent from bliss.controllers.lima.roi import Roi as LimaRoi +from bliss.controllers.lima.roi import ArcRoi as LimaArcRoi +from bliss.controllers.lima.roi import RoiProfile as LimaLineRoi from bliss.controllers.lima.lima_base import Lima from bliss.controllers.mca.base import BaseMCA from bliss.scanning.toolbox import ChainBuilder @@ -33,12 +35,15 @@ def objects_of_type(*classes): rois = { "roi1": LimaRoi(0, 0, 100, 200), "roi2": LimaRoi(10, 20, 200, 500), - "roi3": LimaRoi(20, 60, 500, 500), - "roi4": LimaRoi(60, 20, 50, 10), + "roi3": LimaArcRoi(500, 500, 10, 100, 0, 135), } for lima in objects_of_type(Lima).values(): lima.roi_counters.update(rois) +rois = {"roi4": LimaLineRoi(100, 200, 100, 300)} +for lima in objects_of_type(Lima).values(): + lima.roi_profiles.update(rois) + # Add mca ROI's rois = {"roi1": (500, 550), "roi2": (600, 650), "roi3": (700, 750)}