From 0f507fbd89dda4ff534044c9e10806d5f5c90aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Weber?= Date: Sun, 4 Oct 2026 18:01:30 +0200 Subject: [PATCH 1/3] RoiStuff: emit the cropped data in live mode too - the live branch of grab_data built the cropped DataToExport but emitted the uncropped one - factor the cropping in a crop() method used by both live and single grabs; it returns the data unchanged if 'Use Roi' is off or no ROI select has been made yet (it crashed before) - set the 'sliced' extra attribute on the cropped data (was set on the original one) - remove the extra grab/emission done after the live loop and the useless center_origin - log the crosshair position instead of printing it Related to PyMoDAQ/PyMoDAQ#1237 Co-Authored-By: Claude Opus 5.5 --- .../plugins_2D/daq_2Dviewer_RoiStuff.py | 54 +++++++++---------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/src/pymodaq_plugins_mockexamples/daq_viewer_plugins/plugins_2D/daq_2Dviewer_RoiStuff.py b/src/pymodaq_plugins_mockexamples/daq_viewer_plugins/plugins_2D/daq_2Dviewer_RoiStuff.py index 055181b..735efdc 100644 --- a/src/pymodaq_plugins_mockexamples/daq_viewer_plugins/plugins_2D/daq_2Dviewer_RoiStuff.py +++ b/src/pymodaq_plugins_mockexamples/daq_viewer_plugins/plugins_2D/daq_2Dviewer_RoiStuff.py @@ -4,11 +4,14 @@ from qtpy import QtWidgets import numpy as np from pymodaq.control_modules.viewer_utility_classes import main +from pymodaq_utils.logger import set_logger, get_module_name from pymodaq_gui.plotting.items.roi import RoiInfo from pymodaq_data.data import DataToExport, DataWithAxes, Axis from pymodaq_plugins_mockexamples.daq_viewer_plugins.plugins_2D.daq_2Dviewer_MockCamera import DAQ_2DViewer_MockCamera +logger = set_logger(get_module_name(__file__)) + class DAQ_2DViewer_RoiStuff(DAQ_2DViewer_MockCamera): @@ -41,7 +44,22 @@ def roi_select(self, roi_info: RoiInfo, ind_viewer: int = 0): self.roi_select_viewer_index = ind_viewer def crosshair(self, crosshair_info: Iterable[float], ind_viewer: int = 0): - print(crosshair_info) + logger.info(f'Crosshair position in viewer {ind_viewer}: {crosshair_info}') + + def crop(self, data: DataToExport) -> DataToExport: + """Crop all the data to the ROI select, if 'Use Roi' is checked and a selection has been made + + The RoiInfo is given in the units of the viewer axes (here scaled), so the value-based slicer vsig is used + """ + if not self.settings['use_roi'] or self.roi_select_info is None: + return data + slices = self.roi_select_info.to_slices(False) + dte = DataToExport('cropped') + for dwa in data: + dwa_sliced = dwa.vsig[slices] + dwa_sliced.add_extra_attribute(sliced=True) + dte.append(dwa_sliced) + return dte def grab_data(self, Naverage=1, **kwargs): """Start a grab from the detector @@ -54,42 +72,18 @@ def grab_data(self, Naverage=1, **kwargs): kwargs: dict others optionals arguments """ - - if 'live' in kwargs: - if kwargs['live']: - self.live = True - # self.live = False # don't want to use that for the moment + if kwargs.get('live', False): + self.live = True if self.live: while self.live: - data: DataToExport = self.average_data(Naverage) # hardware averaging + data = self.average_data(Naverage) # hardware averaging QThread.msleep(kwargs.get('wait_time', 100)) - if self.settings['use_roi']: - dte = DataToExport('cropped') - for dwa in data.data: - dwa_sliced = dwa.vsig[self.roi_select_info.to_slices(False)] - dwa.add_extra_attribute(sliced=True) - dte.data.append(dwa_sliced) - self.dte_signal.emit(data) + self.dte_signal.emit(self.crop(data)) QtWidgets.QApplication.processEvents() else: data = self.average_data(Naverage) # hardware averaging - QThread.msleep(000) - - self.live = False # don't want to use that for the moment - - data: DataToExport = self.average_data(Naverage) # hardware averaging - QThread.msleep(kwargs.get('wait_time', 100)) - if self.settings['use_roi']: - self.roi_select_info.center_origin() - dte = DataToExport('cropped') - for dwa in data.data: - dwa_sliced = dwa.vsig[self.roi_select_info.to_slices(False)] - dwa.add_extra_attribute(sliced=True) - dte.data.append(dwa_sliced) - else: - dte = data - self.dte_signal.emit(dte) + self.dte_signal.emit(self.crop(data)) if __name__ == '__main__': From 5d3283704b2f19ce99a3dac2b2e25b69fce5462b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Weber?= Date: Sun, 4 Oct 2026 21:36:24 +0200 Subject: [PATCH 2/3] Fix string formatting in _on_signin method --- json-examples/instrument.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json-examples/instrument.py b/json-examples/instrument.py index d6490c1..e5c5a03 100644 --- a/json-examples/instrument.py +++ b/json-examples/instrument.py @@ -376,7 +376,7 @@ def _stop_move(self): # === transition actions === def _on_signin(self, trame : LECOTrame): - self._communicator.set_fullname(f'{trame.sender.split('.')[0]}.{self._name}') + self._communicator.set_fullname(f"{trame.sender.split('.')[0]}.{self._name}") def _on_signout(self, trame : LECOTrame): pass From 405070910b292949adc2927f472243097d51528c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Weber?= Date: Sun, 4 Oct 2026 21:39:13 +0200 Subject: [PATCH 3/3] Update Python version from 3.11 to 3.12 --- .github/workflows/Test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Test.yml b/.github/workflows/Test.yml index 74d7df2..05bc4e5 100644 --- a/.github/workflows/Test.yml +++ b/.github/workflows/Test.yml @@ -6,5 +6,5 @@ jobs: call_workflow: uses: ./.github/workflows/Testbase.yml with: - python: '3.11' - qt5: 'pyqt6' \ No newline at end of file + python: '3.12' + qt5: 'pyqt6'