pymodaq 4.1.4__py3-none-any.whl → 4.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pymodaq might be problematic. Click here for more details.
- pymodaq/__init__.py +41 -4
- pymodaq/control_modules/daq_move.py +33 -74
- pymodaq/control_modules/daq_viewer.py +73 -98
- pymodaq/control_modules/daq_viewer_ui.py +2 -1
- pymodaq/control_modules/move_utility_classes.py +17 -7
- pymodaq/control_modules/utils.py +153 -5
- pymodaq/control_modules/viewer_utility_classes.py +31 -20
- pymodaq/dashboard.py +23 -5
- pymodaq/examples/tcp_client.py +97 -0
- pymodaq/extensions/__init__.py +4 -0
- pymodaq/extensions/bayesian/__init__.py +2 -0
- pymodaq/extensions/bayesian/bayesian_optimisation.py +673 -0
- pymodaq/extensions/bayesian/utils.py +403 -0
- pymodaq/extensions/daq_scan.py +4 -4
- pymodaq/extensions/daq_scan_ui.py +2 -1
- pymodaq/extensions/pid/pid_controller.py +12 -7
- pymodaq/extensions/pid/utils.py +9 -26
- pymodaq/extensions/utils.py +3 -0
- pymodaq/post_treatment/load_and_plot.py +42 -19
- pymodaq/resources/VERSION +1 -1
- pymodaq/resources/config_template.toml +9 -24
- pymodaq/resources/setup_plugin.py +1 -1
- pymodaq/utils/config.py +103 -5
- pymodaq/utils/daq_utils.py +37 -138
- pymodaq/utils/data.py +614 -95
- pymodaq/utils/enums.py +17 -1
- pymodaq/utils/factory.py +2 -2
- pymodaq/utils/gui_utils/custom_app.py +5 -2
- pymodaq/utils/gui_utils/dock.py +33 -4
- pymodaq/utils/gui_utils/file_io.py +3 -2
- pymodaq/utils/gui_utils/utils.py +14 -1
- pymodaq/utils/h5modules/backends.py +9 -1
- pymodaq/utils/h5modules/data_saving.py +254 -57
- pymodaq/utils/h5modules/saving.py +1 -0
- pymodaq/utils/leco/daq_move_LECODirector.py +172 -0
- pymodaq/utils/leco/daq_xDviewer_LECODirector.py +170 -0
- pymodaq/utils/leco/desktop.ini +2 -0
- pymodaq/utils/leco/director_utils.py +58 -0
- pymodaq/utils/leco/leco_director.py +88 -0
- pymodaq/utils/leco/pymodaq_listener.py +279 -0
- pymodaq/utils/leco/utils.py +41 -0
- pymodaq/utils/managers/action_manager.py +20 -6
- pymodaq/utils/managers/parameter_manager.py +6 -4
- pymodaq/utils/managers/roi_manager.py +64 -55
- pymodaq/utils/math_utils.py +1 -1
- pymodaq/utils/plotting/data_viewers/__init__.py +3 -1
- pymodaq/utils/plotting/data_viewers/base.py +286 -0
- pymodaq/utils/plotting/data_viewers/viewer.py +29 -202
- pymodaq/utils/plotting/data_viewers/viewer0D.py +94 -47
- pymodaq/utils/plotting/data_viewers/viewer1D.py +341 -174
- pymodaq/utils/plotting/data_viewers/viewer1Dbasic.py +1 -1
- pymodaq/utils/plotting/data_viewers/viewer2D.py +271 -181
- pymodaq/utils/plotting/data_viewers/viewerND.py +26 -22
- pymodaq/utils/plotting/items/crosshair.py +3 -3
- pymodaq/utils/plotting/items/image.py +2 -1
- pymodaq/utils/plotting/plotter/plotter.py +94 -0
- pymodaq/utils/plotting/plotter/plotters/__init__.py +0 -0
- pymodaq/utils/plotting/plotter/plotters/matplotlib_plotters.py +134 -0
- pymodaq/utils/plotting/plotter/plotters/qt_plotters.py +78 -0
- pymodaq/utils/plotting/utils/axes_viewer.py +1 -1
- pymodaq/utils/plotting/utils/filter.py +194 -147
- pymodaq/utils/plotting/utils/lineout.py +13 -11
- pymodaq/utils/plotting/utils/plot_utils.py +89 -12
- pymodaq/utils/scanner/__init__.py +0 -3
- pymodaq/utils/scanner/scan_config.py +1 -9
- pymodaq/utils/scanner/scan_factory.py +10 -36
- pymodaq/utils/scanner/scanner.py +3 -2
- pymodaq/utils/scanner/scanners/_1d_scanners.py +7 -5
- pymodaq/utils/scanner/scanners/_2d_scanners.py +36 -49
- pymodaq/utils/scanner/scanners/sequential.py +10 -4
- pymodaq/utils/scanner/scanners/tabular.py +10 -5
- pymodaq/utils/slicing.py +1 -1
- pymodaq/utils/tcp_ip/serializer.py +38 -5
- pymodaq/utils/tcp_ip/tcp_server_client.py +25 -17
- {pymodaq-4.1.4.dist-info → pymodaq-4.2.0.dist-info}/METADATA +4 -2
- {pymodaq-4.1.4.dist-info → pymodaq-4.2.0.dist-info}/RECORD +79 -64
- {pymodaq-4.1.4.dist-info → pymodaq-4.2.0.dist-info}/WHEEL +1 -1
- pymodaq/resources/config_scan_template.toml +0 -42
- {pymodaq-4.1.4.dist-info → pymodaq-4.2.0.dist-info}/entry_points.txt +0 -0
- {pymodaq-4.1.4.dist-info → pymodaq-4.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -3,28 +3,31 @@ import copy
|
|
|
3
3
|
import datetime
|
|
4
4
|
import numpy as np
|
|
5
5
|
import sys
|
|
6
|
-
from typing import Union, Iterable
|
|
6
|
+
from typing import Union, Iterable, List, Dict
|
|
7
7
|
|
|
8
8
|
import pymodaq.utils.messenger
|
|
9
9
|
from qtpy import QtCore, QtGui, QtWidgets
|
|
10
|
-
from qtpy.QtCore import QObject, Slot, Signal
|
|
10
|
+
from qtpy.QtCore import QObject, Slot, Signal, Qt
|
|
11
11
|
import pyqtgraph as pg
|
|
12
12
|
from pyqtgraph.graphicsItems.GradientEditorItem import Gradients
|
|
13
13
|
from pyqtgraph import ROI as pgROI
|
|
14
14
|
|
|
15
|
-
from pymodaq.utils.data import Axis, DataToExport, DataFromRoi, DataFromPlugins, DataRaw,
|
|
15
|
+
from pymodaq.utils.data import (Axis, DataToExport, DataFromRoi, DataFromPlugins, DataRaw,
|
|
16
|
+
DataDistribution, DataWithAxes)
|
|
16
17
|
from pymodaq.utils.logger import set_logger, get_module_name
|
|
17
18
|
from pymodaq.utils.managers.roi_manager import ROIManager, SimpleRectROI
|
|
18
19
|
from pymodaq.utils.managers.action_manager import ActionManager
|
|
19
20
|
from pymodaq.utils.plotting.widgets import ImageWidget
|
|
20
21
|
|
|
21
22
|
from pymodaq.utils.plotting.data_viewers.viewer import ViewerBase
|
|
23
|
+
from pymodaq.utils.plotting.data_viewers.viewer1D import Viewer1D
|
|
24
|
+
from pymodaq.utils.plotting.data_viewers.viewer0D import Viewer0D
|
|
22
25
|
from pymodaq.utils.plotting.items.image import UniformImageItem, SpreadImageItem
|
|
23
26
|
from pymodaq.utils.plotting.items.axis_scaled import AXIS_POSITIONS, AxisItem_Scaled
|
|
24
27
|
from pymodaq.utils.plotting.items.crosshair import Crosshair
|
|
25
28
|
from pymodaq.utils.plotting.utils.filter import Filter2DFromCrosshair, Filter2DFromRois
|
|
26
29
|
import pymodaq.utils.daq_utils as utils
|
|
27
|
-
from pymodaq.utils.plotting.utils.
|
|
30
|
+
from pymodaq.utils.plotting.utils.plot_utils import make_dashed_pens, RoiInfo
|
|
28
31
|
|
|
29
32
|
|
|
30
33
|
logger = set_logger(get_module_name(__file__))
|
|
@@ -36,17 +39,20 @@ Gradients.update(OrderedDict([
|
|
|
36
39
|
('spread', {'ticks': [(0.0, (0, 0, 0, 255)), (1.0, (255, 255, 255, 255))], 'mode': 'rgb'}),]))
|
|
37
40
|
|
|
38
41
|
COLORS_DICT = dict(red=(255, 0, 0), green=(0, 255, 0), blue=(0, 0, 255), spread=(128, 128, 128))
|
|
39
|
-
IMAGE_TYPES = ['red', 'green', 'blue']
|
|
40
42
|
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
IMAGE_TYPES = ['red', 'green', 'blue']
|
|
41
46
|
COLOR_LIST = utils.plot_colors
|
|
47
|
+
crosshair_pens = make_dashed_pens(color=(255, 255, 0))
|
|
42
48
|
|
|
43
49
|
|
|
44
|
-
def image_item_factory(item_type='uniform', axisOrder='row-major'):
|
|
50
|
+
def image_item_factory(item_type='uniform', axisOrder='row-major', pen='r'):
|
|
45
51
|
if item_type == 'uniform':
|
|
46
|
-
image = UniformImageItem()
|
|
52
|
+
image = UniformImageItem(pen=pen)
|
|
47
53
|
image.setOpts(axisOrder=axisOrder)
|
|
48
54
|
elif item_type == 'spread':
|
|
49
|
-
image = SpreadImageItem()
|
|
55
|
+
image = SpreadImageItem(pen=pen)
|
|
50
56
|
image.setCompositionMode(QtGui.QPainter.CompositionMode_Plus)
|
|
51
57
|
return image
|
|
52
58
|
|
|
@@ -85,12 +91,22 @@ class ImageDisplayer(QObject):
|
|
|
85
91
|
def __init__(self, plotitem, data_distribution: DataDistribution):
|
|
86
92
|
super().__init__()
|
|
87
93
|
self._plotitem = plotitem
|
|
94
|
+
self._plotitem.addLegend()
|
|
95
|
+
self.show_legend(False)
|
|
88
96
|
self.display_type = data_distribution
|
|
89
97
|
self._image_items = dict([])
|
|
90
98
|
self._autolevels = False
|
|
99
|
+
self._data: DataWithAxes = None
|
|
91
100
|
|
|
92
101
|
self.update_display_items()
|
|
93
102
|
|
|
103
|
+
def show_legend(self, show=True):
|
|
104
|
+
self.legend.setVisible(show)
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def legend(self):
|
|
108
|
+
return self._plotitem.legend
|
|
109
|
+
|
|
94
110
|
def get_images(self):
|
|
95
111
|
return self._image_items
|
|
96
112
|
|
|
@@ -100,6 +116,13 @@ class ImageDisplayer(QObject):
|
|
|
100
116
|
else:
|
|
101
117
|
return self._image_items[name]
|
|
102
118
|
|
|
119
|
+
@property
|
|
120
|
+
def labels(self):
|
|
121
|
+
if self._data is None:
|
|
122
|
+
return []
|
|
123
|
+
else:
|
|
124
|
+
return self._data.labels
|
|
125
|
+
|
|
103
126
|
@property
|
|
104
127
|
def autolevels(self):
|
|
105
128
|
return self._autolevels
|
|
@@ -108,26 +131,36 @@ class ImageDisplayer(QObject):
|
|
|
108
131
|
def set_autolevels(self, isautolevel):
|
|
109
132
|
self._autolevels = isautolevel
|
|
110
133
|
|
|
111
|
-
def update_data(self,
|
|
112
|
-
if
|
|
113
|
-
self.
|
|
114
|
-
|
|
115
|
-
|
|
134
|
+
def update_data(self, dwa: DataWithAxes):
|
|
135
|
+
if dwa.labels != self.labels:
|
|
136
|
+
self.update_display_items(dwa.labels)
|
|
137
|
+
if dwa.distribution != self.display_type:
|
|
138
|
+
self.display_type = dwa.distribution
|
|
139
|
+
self._data = dwa
|
|
140
|
+
for ind_data, data_array in enumerate(dwa.data):
|
|
116
141
|
if data_array.size > 0:
|
|
117
142
|
if self.display_type == 'uniform':
|
|
118
143
|
self._image_items[IMAGE_TYPES[ind_data]].setImage(data_array, self.autolevels)
|
|
119
144
|
else:
|
|
120
|
-
nav_axes =
|
|
121
|
-
data_array = np.stack((nav_axes[0].
|
|
145
|
+
nav_axes = dwa.get_nav_axes()
|
|
146
|
+
data_array = np.stack((nav_axes[0].get_data(),
|
|
147
|
+
nav_axes[1].get_data(),
|
|
148
|
+
data_array), axis=0).T
|
|
122
149
|
self._image_items[IMAGE_TYPES[ind_data]].setImage(data_array, self.autolevels)
|
|
123
150
|
|
|
124
|
-
def update_display_items(self):
|
|
151
|
+
def update_display_items(self, labels: List[str] = None):
|
|
125
152
|
while len(self._image_items) > 0:
|
|
126
153
|
self._plotitem.removeItem(self._image_items.pop(next(iter(self._image_items))))
|
|
154
|
+
if labels is None:
|
|
155
|
+
labels = []
|
|
156
|
+
while len(labels) != len(IMAGE_TYPES):
|
|
157
|
+
labels.append(IMAGE_TYPES[len(labels)])
|
|
127
158
|
|
|
128
|
-
for img_key in IMAGE_TYPES:
|
|
129
|
-
self._image_items[img_key] = image_item_factory(self.display_type)
|
|
159
|
+
for ind, img_key in enumerate(IMAGE_TYPES):
|
|
160
|
+
self._image_items[img_key] = image_item_factory(self.display_type, pen=img_key[0])
|
|
130
161
|
self._plotitem.addItem(self._image_items[img_key])
|
|
162
|
+
if ind < len(labels):
|
|
163
|
+
self.legend.addItem(self._image_items[img_key], labels[ind])
|
|
131
164
|
self.updated_item.emit(self._image_items)
|
|
132
165
|
|
|
133
166
|
def update_image_visibility(self, are_items_visible):
|
|
@@ -257,56 +290,22 @@ class IsoCurver(QObject):
|
|
|
257
290
|
self._isoLine.hide()
|
|
258
291
|
|
|
259
292
|
|
|
260
|
-
class LineoutPlotter(LineoutPlotter):
|
|
261
|
-
"""class to manage and display data filtered out into lineouts (1D, 0D)
|
|
262
|
-
|
|
263
|
-
Should be inherited and subclass some methods as appropriate
|
|
264
|
-
|
|
265
|
-
Parameters
|
|
266
|
-
----------
|
|
267
|
-
graph_widgets: OrderedDict
|
|
268
|
-
Includes plotwidgets to display data
|
|
269
|
-
roi_manager:
|
|
270
|
-
The ROIManager to create ROIs and manage their properties
|
|
271
|
-
crosshair:
|
|
272
|
-
The Crosshair object
|
|
273
|
-
"""
|
|
274
|
-
lineout_widgets = ['hor', 'ver', 'int']
|
|
275
|
-
|
|
276
|
-
def __init__(self, graph_widgets: OrderedDict, roi_manager: ROIManager, crosshair: Crosshair):
|
|
277
|
-
super().__init__(graph_widgets, roi_manager, crosshair)
|
|
278
|
-
|
|
279
|
-
def plot_other_lineouts(self, roi_dicts):
|
|
280
|
-
for roi_key, lineout_data in roi_dicts.items():
|
|
281
|
-
if roi_key in self._roi_curves:
|
|
282
|
-
if lineout_data.hor_data.size > 0:
|
|
283
|
-
self._roi_curves[roi_key]['hor'].setData(lineout_data.hor_axis, lineout_data.hor_data)
|
|
284
|
-
self._roi_curves[roi_key]['ver'].setData(lineout_data.ver_data, lineout_data.ver_axis)
|
|
285
|
-
|
|
286
|
-
def plot_other_crosshair_lineouts(self, crosshair_dict):
|
|
287
|
-
for data_key, lineout_data in crosshair_dict.items():
|
|
288
|
-
if data_key in self._crosshair_curves:
|
|
289
|
-
self._crosshair_curves[data_key]['hor'].setData(lineout_data.hor_axis, lineout_data.hor_data)
|
|
290
|
-
self._crosshair_curves[data_key]['ver'].setData(lineout_data.ver_data, lineout_data.ver_axis)
|
|
291
|
-
|
|
292
|
-
def setup_crosshair(self):
|
|
293
|
-
for image_key in IMAGE_TYPES:
|
|
294
|
-
self._crosshair_curves[image_key] = \
|
|
295
|
-
{curv_key: curve_item_factory(image_key) for curv_key in self.lineout_widgets}
|
|
296
|
-
self.add_lineout_items(self._crosshair_curves[image_key]['hor'], self._crosshair_curves[image_key]['ver'])
|
|
297
|
-
|
|
298
|
-
def show_crosshair_curves(self, curve_key, show=True):
|
|
299
|
-
for curve in self._crosshair_curves[curve_key].values():
|
|
300
|
-
curve.setVisible(show)
|
|
301
|
-
|
|
302
|
-
|
|
303
293
|
class View2D(ActionManager, QtCore.QObject):
|
|
304
294
|
|
|
295
|
+
lineout_types = ['hor', 'ver', 'int']
|
|
296
|
+
|
|
305
297
|
def __init__(self, parent_widget=None):
|
|
306
298
|
QtCore.QObject.__init__(self)
|
|
307
299
|
ActionManager.__init__(self, toolbar=QtWidgets.QToolBar())
|
|
300
|
+
|
|
308
301
|
self.ROIselect = SimpleRectROI([0, 0], [10, 10], centered=True, sideScalers=True)
|
|
309
302
|
|
|
303
|
+
self._lineout_widgets = {widg_key: QtWidgets.QWidget() for widg_key in self.lineout_types}
|
|
304
|
+
self.lineout_viewers: Dict[str, Viewer1D] = dict(hor=Viewer1D(self._lineout_widgets['hor'], show_toolbar=False, no_margins=True),
|
|
305
|
+
ver=Viewer1D(self._lineout_widgets['ver'], show_toolbar=False, no_margins=True,
|
|
306
|
+
flip_axes=True),
|
|
307
|
+
int=Viewer0D(self._lineout_widgets['int'], show_toolbar=False, no_margins=True))
|
|
308
|
+
|
|
310
309
|
self.setup_actions()
|
|
311
310
|
|
|
312
311
|
self.parent_widget = parent_widget
|
|
@@ -317,8 +316,7 @@ class View2D(ActionManager, QtCore.QObject):
|
|
|
317
316
|
self.image_widget = ImageWidget()
|
|
318
317
|
self.roi_manager = ROIManager(self.image_widget, '2D')
|
|
319
318
|
|
|
320
|
-
self.roi_target
|
|
321
|
-
self.roi_target.setVisible(False)
|
|
319
|
+
self.roi_target: Union[pgROI, Crosshair] = None
|
|
322
320
|
|
|
323
321
|
self.setup_widgets()
|
|
324
322
|
|
|
@@ -327,7 +325,6 @@ class View2D(ActionManager, QtCore.QObject):
|
|
|
327
325
|
self.isocurver: IsoCurver = None
|
|
328
326
|
|
|
329
327
|
self.crosshair = Crosshair(self.image_widget)
|
|
330
|
-
self.lineout_plotter = LineoutPlotter(self.graphical_widgets, self.roi_manager, self.crosshair)
|
|
331
328
|
|
|
332
329
|
self.connect_things()
|
|
333
330
|
self.prepare_ui()
|
|
@@ -346,36 +343,51 @@ class View2D(ActionManager, QtCore.QObject):
|
|
|
346
343
|
self.clear_plot_item()
|
|
347
344
|
self.data_displayer = ImageDisplayer(self.plotitem, data_distribution)
|
|
348
345
|
self.isocurver = IsoCurver(self.data_displayer.get_image('red'), self.histogrammer.get_histogram('red'))
|
|
346
|
+
self.connect_action('isocurve', self.isocurver.show_hide_iso)
|
|
349
347
|
self.data_displayer.updated_item.connect(self.histogrammer.affect_histo_to_imageitems)
|
|
350
348
|
self.connect_action('autolevels', self.data_displayer.set_autolevels)
|
|
351
349
|
for key in IMAGE_TYPES:
|
|
352
350
|
self.connect_action(key, self.notify_visibility_data_displayer)
|
|
353
|
-
|
|
351
|
+
|
|
354
352
|
self.histogrammer.affect_histo_to_imageitems(self.data_displayer.get_images())
|
|
355
353
|
|
|
354
|
+
if data_distribution.name == 'uniform':
|
|
355
|
+
self.roi_target = pgROI(pos=(0, 0), size=(20, 20), movable=False, rotatable=False,
|
|
356
|
+
resizable=False)
|
|
357
|
+
self.plotitem.addItem(self.roi_target)
|
|
358
|
+
|
|
359
|
+
elif data_distribution.name == 'spread':
|
|
360
|
+
self.roi_target = Crosshair(self.image_widget, pen=(255, 255, 255))
|
|
361
|
+
self.roi_target.setVisible(False)
|
|
362
|
+
|
|
356
363
|
def show_roi_target(self, show=True):
|
|
357
364
|
self.roi_target.setVisible(show)
|
|
358
365
|
|
|
359
366
|
def move_scale_roi_target(self, pos=None, size=None):
|
|
360
367
|
"""
|
|
361
|
-
Move and scale the target ROI (used to display a particular area,
|
|
368
|
+
Move and scale the target ROI (used to display a particular area,
|
|
369
|
+
for instance the currently scanned points
|
|
362
370
|
during a scan
|
|
363
371
|
Parameters
|
|
364
372
|
----------
|
|
365
|
-
pos: (iterable)
|
|
366
|
-
size: (iterable)
|
|
373
|
+
pos: (iterable) setting the central position of the ROI in the view
|
|
374
|
+
size: (iterable) setting the size of the ROI
|
|
367
375
|
"""
|
|
368
|
-
if
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
self.roi_target.
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
pos
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
self.roi_target.
|
|
376
|
+
if isinstance(self.roi_target, pgROI):
|
|
377
|
+
if size is not None:
|
|
378
|
+
x_offset, x_scaling, y_offset, y_scaling = self._get_axis_scaling_offset()
|
|
379
|
+
size = list(np.divide(list(size), [x_scaling, y_scaling]))
|
|
380
|
+
if list(self.roi_target.size()) != size:
|
|
381
|
+
self.roi_target.setSize(size, center=(0.5, 0.5))
|
|
382
|
+
|
|
383
|
+
if pos is not None:
|
|
384
|
+
pos = self.unscale_axis(*list(pos))
|
|
385
|
+
pos = list(pos)
|
|
386
|
+
if list(self.roi_target.pos()) != pos:
|
|
387
|
+
self.roi_target.setPos(pos)
|
|
388
|
+
|
|
389
|
+
else:
|
|
390
|
+
self.roi_target.set_crosshair_position(*list(pos))
|
|
379
391
|
|
|
380
392
|
def setup_widgets(self):
|
|
381
393
|
vertical_layout = QtWidgets.QVBoxLayout()
|
|
@@ -392,11 +404,13 @@ class View2D(ActionManager, QtCore.QObject):
|
|
|
392
404
|
splitter_vertical.addWidget(self.graphs_widget)
|
|
393
405
|
|
|
394
406
|
self.plotitem.addItem(self.ROIselect)
|
|
395
|
-
self.plotitem.addItem(self.roi_target)
|
|
396
407
|
|
|
397
408
|
self.splitter_VLeft.splitterMoved[int, int].connect(self.move_right_splitter)
|
|
398
409
|
self.splitter_VRight.splitterMoved[int, int].connect(self.move_left_splitter)
|
|
399
410
|
|
|
411
|
+
self.splitter_VLeft.setSizes([1, 0])
|
|
412
|
+
self.splitter_VRight.setSizes([1, 0])
|
|
413
|
+
|
|
400
414
|
def setup_graphs(self, graphs_layout):
|
|
401
415
|
self.splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
|
|
402
416
|
graphs_layout.addWidget(self.splitter)
|
|
@@ -411,8 +425,6 @@ class View2D(ActionManager, QtCore.QObject):
|
|
|
411
425
|
self.splitter.addWidget(self.splitter_VLeft)
|
|
412
426
|
self.splitter.addWidget(self.splitter_VRight)
|
|
413
427
|
|
|
414
|
-
self._lineout_widgets = {widg_key: pg.PlotWidget() for widg_key in LineoutPlotter.lineout_widgets}
|
|
415
|
-
self.graphical_widgets = dict(lineouts=self._lineout_widgets, image=self.image_widget)
|
|
416
428
|
self.splitter_VLeft.addWidget(self.image_widget)
|
|
417
429
|
self.splitter_VLeft.addWidget(self._lineout_widgets['hor'])
|
|
418
430
|
self.splitter_VRight.addWidget(self._lineout_widgets['ver'])
|
|
@@ -431,6 +443,10 @@ class View2D(ActionManager, QtCore.QObject):
|
|
|
431
443
|
self.add_action('red', 'Red Channel', 'r_icon', tip='Show/Hide Red Channel', checkable=True)
|
|
432
444
|
self.add_action('green', 'Green Channel', 'g_icon', tip='Show/Hide Green Channel', checkable=True)
|
|
433
445
|
self.add_action('blue', 'Blue Channel', 'b_icon', tip='Show/Hide Blue Channel', checkable=True)
|
|
446
|
+
self.get_action('red').setChecked(True)
|
|
447
|
+
self.get_action('green').setChecked(True)
|
|
448
|
+
self.get_action('blue').setChecked(True)
|
|
449
|
+
|
|
434
450
|
self.add_action('autolevels', 'AutoLevels', 'autoscale',
|
|
435
451
|
tip='Scale Histogram to Min/Max intensity', checkable=True)
|
|
436
452
|
self.add_action('auto_levels_sym', 'AutoLevels Sym.', 'autoscale',
|
|
@@ -449,25 +465,54 @@ class View2D(ActionManager, QtCore.QObject):
|
|
|
449
465
|
tip='Flip the image left/right', checkable=True)
|
|
450
466
|
self.add_action('rotate', 'Rotate', 'rotation2',
|
|
451
467
|
tip='Rotate the image', checkable=True)
|
|
468
|
+
self.add_action('legend', 'Legend', 'RGB',
|
|
469
|
+
tip='Show the legend', checkable=True)
|
|
452
470
|
|
|
453
|
-
def
|
|
454
|
-
|
|
455
|
-
|
|
471
|
+
def update_colors(self, colors: list):
|
|
472
|
+
for ind, roi_name in enumerate(self.roi_manager.ROIs):
|
|
473
|
+
self.lineout_viewers['hor'].update_colors(make_dashed_pens(colors[ind]), displayer=roi_name)
|
|
474
|
+
self.lineout_viewers['ver'].update_colors(make_dashed_pens(colors[ind]), displayer=roi_name)
|
|
475
|
+
self.lineout_viewers['int'].update_colors(make_dashed_pens(colors[ind]), displayer=roi_name)
|
|
456
476
|
|
|
477
|
+
def connect_things(self):
|
|
457
478
|
self.connect_action('histo', self.histogrammer.activated)
|
|
458
479
|
self.connect_action('autolevels', self.histogrammer.set_autolevels)
|
|
459
|
-
|
|
480
|
+
self.roi_manager.new_ROI_signal.connect(self.update_roi_channels)
|
|
481
|
+
self.roi_manager.new_ROI_signal.connect(self.add_roi_displayer)
|
|
482
|
+
self.roi_manager.new_ROI_signal.connect(self.lineout_viewers['int'].get_action('clear').click)
|
|
483
|
+
self.roi_manager.remove_ROI_signal.connect(self.remove_roi_displayer)
|
|
484
|
+
self.roi_manager.color_signal.connect(self.update_colors)
|
|
460
485
|
self.connect_action('isocurve', self.get_action('histo').trigger)
|
|
461
486
|
|
|
462
487
|
self.connect_action('aspect_ratio', self.lock_aspect_ratio)
|
|
463
488
|
self.connect_action('histo', self.show_hide_histogram)
|
|
464
|
-
self.connect_action('roi', self.lineout_plotter.roi_clicked)
|
|
465
489
|
self.connect_action('roi', self.show_lineout_widgets)
|
|
490
|
+
self.connect_action('roi', self.roi_clicked)
|
|
466
491
|
self.connect_action('ROIselect', self.show_ROI_select)
|
|
467
492
|
self.connect_action('crosshair', self.show_hide_crosshair)
|
|
468
493
|
self.connect_action('crosshair', self.show_lineout_widgets)
|
|
469
|
-
self.connect_action('
|
|
494
|
+
self.connect_action('legend', self.show_legend)
|
|
470
495
|
|
|
496
|
+
def show_legend(self, show=True):
|
|
497
|
+
self.data_displayer.show_legend(show)
|
|
498
|
+
|
|
499
|
+
@Slot(int, str, str)
|
|
500
|
+
def add_roi_displayer(self, index, roi_type='', roi_name=''):
|
|
501
|
+
color = self.roi_manager.ROIs[roi_name].color
|
|
502
|
+
self.lineout_viewers['hor'].view.add_data_displayer(roi_name, make_dashed_pens(color))
|
|
503
|
+
self.lineout_viewers['ver'].view.add_data_displayer(roi_name, make_dashed_pens(color))
|
|
504
|
+
self.lineout_viewers['int'].view.add_data_displayer(roi_name, make_dashed_pens(color))
|
|
505
|
+
|
|
506
|
+
@Slot(str)
|
|
507
|
+
def remove_roi_displayer(self, roi_name=''):
|
|
508
|
+
self.lineout_viewers['hor'].view.remove_data_displayer(roi_name)
|
|
509
|
+
self.lineout_viewers['ver'].view.remove_data_displayer(roi_name)
|
|
510
|
+
self.lineout_viewers['int'].view.remove_data_displayer(roi_name)
|
|
511
|
+
|
|
512
|
+
@Slot(int, str, str)
|
|
513
|
+
def update_roi_channels(self, index, roi_type=''):
|
|
514
|
+
"""Update the use_channel setting each time a ROI is added"""
|
|
515
|
+
self.roi_manager.update_use_channel(self.data_displayer.labels.copy())
|
|
471
516
|
|
|
472
517
|
def prepare_ui(self):
|
|
473
518
|
self.ROIselect.setVisible(False)
|
|
@@ -480,26 +525,39 @@ class View2D(ActionManager, QtCore.QObject):
|
|
|
480
525
|
if self.is_action_checked('isocurve'):
|
|
481
526
|
self.isocurver.set_isocurve_data(datas.data[0])
|
|
482
527
|
|
|
483
|
-
def display_roi_lineouts(self,
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
528
|
+
def display_roi_lineouts(self, roi_dte: DataToExport):
|
|
529
|
+
if len(roi_dte) > 0:
|
|
530
|
+
for lineout_type in self.lineout_types:
|
|
531
|
+
for displayer_name in self.lineout_viewers[lineout_type].view.other_data_displayers:
|
|
532
|
+
dwa = roi_dte.get_data_from_name_origin(lineout_type, displayer_name)
|
|
533
|
+
if dwa is not None:
|
|
534
|
+
self.lineout_viewers[lineout_type].view.display_data(dwa.deepcopy(),
|
|
535
|
+
displayer=displayer_name)
|
|
536
|
+
|
|
537
|
+
def display_crosshair_lineouts(self, crosshair_dte: DataToExport):
|
|
538
|
+
for lineout_type in self.lineout_types:
|
|
539
|
+
dwa = crosshair_dte.get_data_from_name(lineout_type)
|
|
540
|
+
if dwa is not None:
|
|
541
|
+
self.lineout_viewers[lineout_type].view.display_data(dwa, displayer='crosshair')
|
|
488
542
|
|
|
489
543
|
def show_lineout_widgets(self):
|
|
490
544
|
state = self.is_action_checked('roi') or self.is_action_checked('crosshair')
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
545
|
+
if state:
|
|
546
|
+
self.prepare_image_widget_for_lineouts()
|
|
547
|
+
else:
|
|
548
|
+
self.prepare_image_widget_for_lineouts(1)
|
|
549
|
+
|
|
550
|
+
@Slot(bool)
|
|
551
|
+
def roi_clicked(self, isroichecked=True):
|
|
552
|
+
self.roi_manager.roiwidget.setVisible(isroichecked)
|
|
553
|
+
|
|
554
|
+
for k, roi in self.roi_manager.ROIs.items():
|
|
555
|
+
roi.setVisible(isroichecked)
|
|
498
556
|
|
|
499
557
|
def get_visible_images(self):
|
|
500
558
|
are_items_visible = []
|
|
501
559
|
for key in IMAGE_TYPES:
|
|
502
|
-
are_items_visible.append(self.is_action_checked(key))
|
|
560
|
+
are_items_visible.append(self.is_action_visible(key) and self.is_action_checked(key))
|
|
503
561
|
return are_items_visible
|
|
504
562
|
|
|
505
563
|
def notify_visibility_data_displayer(self):
|
|
@@ -519,6 +577,9 @@ class View2D(ActionManager, QtCore.QObject):
|
|
|
519
577
|
self.splitter_VLeft.splitterMoved[int, int].emit(int(ratio * self.parent_widget.height()), 1)
|
|
520
578
|
QtGui.QGuiApplication.processEvents()
|
|
521
579
|
|
|
580
|
+
def collapse_lineout_widgets(self):
|
|
581
|
+
self.prepare_image_widget_for_lineouts(ratio=1)
|
|
582
|
+
|
|
522
583
|
def get_view_range(self):
|
|
523
584
|
return self.image_widget.view.viewRange()
|
|
524
585
|
|
|
@@ -571,8 +632,15 @@ class View2D(ActionManager, QtCore.QObject):
|
|
|
571
632
|
self.set_action_visible('position', show)
|
|
572
633
|
self.crosshair.setVisible(show)
|
|
573
634
|
if show:
|
|
635
|
+
self.lineout_viewers['hor'].view.add_data_displayer('crosshair', plot_colors=crosshair_pens)
|
|
636
|
+
self.lineout_viewers['ver'].view.add_data_displayer('crosshair', plot_colors=crosshair_pens)
|
|
637
|
+
self.lineout_viewers['int'].view.add_data_displayer('crosshair', plot_colors=crosshair_pens)
|
|
574
638
|
range = self.get_view_range()
|
|
575
639
|
self.set_crosshair_position(np.mean(np.array(range[0])), np.mean(np.array(range[0])))
|
|
640
|
+
else:
|
|
641
|
+
self.lineout_viewers['hor'].view.remove_data_displayer('crosshair')
|
|
642
|
+
self.lineout_viewers['ver'].view.remove_data_displayer('crosshair')
|
|
643
|
+
self.lineout_viewers['int'].view.remove_data_displayer('crosshair')
|
|
576
644
|
logger.debug(f'Crosshair visible?: {self.crosshair.isVisible()}')
|
|
577
645
|
|
|
578
646
|
def show_ROI_select(self):
|
|
@@ -581,6 +649,13 @@ class View2D(ActionManager, QtCore.QObject):
|
|
|
581
649
|
self.ROIselect.setPos(rect.center()-QtCore.QPointF(rect.width() * 2 / 3, rect.height() * 2 / 3)/2)
|
|
582
650
|
self.ROIselect.setSize(rect.size() * 2 / 3)
|
|
583
651
|
|
|
652
|
+
def set_image_labels(self, labels: List[str]):
|
|
653
|
+
action_names =['red', 'green', 'blue']
|
|
654
|
+
for action_name, label in zip(action_names[:len(labels)], labels):
|
|
655
|
+
self.get_action(action_name).setToolTip(f'{self.get_action(action_name).toolTip()}'
|
|
656
|
+
f' - '
|
|
657
|
+
f'{label}')
|
|
658
|
+
|
|
584
659
|
def set_axis_label(self, position, label='', units=''):
|
|
585
660
|
"""
|
|
586
661
|
Convenience method to set label and unit of any view axes
|
|
@@ -637,12 +712,11 @@ class View2D(ActionManager, QtCore.QObject):
|
|
|
637
712
|
class Viewer2D(ViewerBase):
|
|
638
713
|
"""Object managing plotting and manipulation of 2D data using a View2D"""
|
|
639
714
|
|
|
640
|
-
crosshair_clicked = Signal(bool)
|
|
641
|
-
ROI_select_signal = Signal(QtCore.QRectF)
|
|
642
|
-
|
|
643
715
|
def __init__(self, parent: QtWidgets.QWidget = None, title=''):
|
|
644
716
|
super().__init__(parent, title)
|
|
645
717
|
|
|
718
|
+
self.just_init = True
|
|
719
|
+
|
|
646
720
|
self._datas = None
|
|
647
721
|
self.isdata = dict([])
|
|
648
722
|
self._is_gradient_manually_set = False
|
|
@@ -696,8 +770,7 @@ class Viewer2D(ViewerBase):
|
|
|
696
770
|
self.view.set_action_checked('roi', activate)
|
|
697
771
|
self.view.get_action('roi').triggered.emit(activate)
|
|
698
772
|
|
|
699
|
-
|
|
700
|
-
def roi_changed(self):
|
|
773
|
+
def roi_changed(self, *args, **kwargs):
|
|
701
774
|
self.filter_from_rois.filter_data(self._datas)
|
|
702
775
|
|
|
703
776
|
def crosshair_changed(self):
|
|
@@ -721,6 +794,7 @@ class Viewer2D(ViewerBase):
|
|
|
721
794
|
if len(data) > 3:
|
|
722
795
|
logger.warning('Cannot plot on 2D plot more than 3 channels')
|
|
723
796
|
data.data = data.data[:3]
|
|
797
|
+
self.view.set_image_labels(data.labels)
|
|
724
798
|
if data.distribution != self.view.data_displayer.display_type:
|
|
725
799
|
self.view.set_image_displayer(data.distribution)
|
|
726
800
|
self.filter_from_crosshair.set_graph_items(self.view.data_displayer.get_images())
|
|
@@ -731,11 +805,21 @@ class Viewer2D(ViewerBase):
|
|
|
731
805
|
self.isdata['green'] = len(data) > 1
|
|
732
806
|
self.isdata['blue'] = len(data) > 2
|
|
733
807
|
|
|
734
|
-
self.set_visible_items()
|
|
735
808
|
self.update_data()
|
|
809
|
+
|
|
810
|
+
self.set_visible_items()
|
|
736
811
|
if not self.view.is_action_checked('roi'):
|
|
737
812
|
self.data_to_export_signal.emit(self.data_to_export)
|
|
738
813
|
|
|
814
|
+
self.autolevels_first()
|
|
815
|
+
|
|
816
|
+
def autolevels_first(self):
|
|
817
|
+
if self.just_init and not self.is_action_checked('autolevels'):
|
|
818
|
+
self.get_action('autolevels').trigger()
|
|
819
|
+
self.update_data()
|
|
820
|
+
self.get_action('autolevels').trigger()
|
|
821
|
+
self.just_init = False
|
|
822
|
+
|
|
739
823
|
def get_axes_from_view(self, data: DataWithAxes):
|
|
740
824
|
"""Obtain axes info from the view
|
|
741
825
|
|
|
@@ -796,15 +880,9 @@ class Viewer2D(ViewerBase):
|
|
|
796
880
|
|
|
797
881
|
def set_visible_items(self):
|
|
798
882
|
for key in IMAGE_TYPES:
|
|
799
|
-
|
|
800
|
-
self.view.set_action_checked(key, False)
|
|
801
|
-
self.view.set_action_visible(key, False)
|
|
883
|
+
self.view.set_action_visible(key, self.isdata[key])
|
|
802
884
|
|
|
803
|
-
|
|
804
|
-
self.view.set_action_checked(key, True)
|
|
805
|
-
self.view.set_action_visible(key, True)
|
|
806
|
-
|
|
807
|
-
self.view.notify_visibility_data_displayer()
|
|
885
|
+
self.view.notify_visibility_data_displayer()
|
|
808
886
|
|
|
809
887
|
def show_roi(self, show=True, show_roi_widget=True):
|
|
810
888
|
"""convenience function to control roi"""
|
|
@@ -813,24 +891,28 @@ class Viewer2D(ViewerBase):
|
|
|
813
891
|
|
|
814
892
|
self.view.roi_manager.roiwidget.setVisible(show_roi_widget)
|
|
815
893
|
|
|
816
|
-
def update_crosshair_data(self,
|
|
894
|
+
def update_crosshair_data(self, crosshair_dte: DataToExport):
|
|
817
895
|
try:
|
|
818
896
|
posx, posy = self.view.get_crosshair_position()
|
|
819
897
|
(posx_scaled, posy_scaled) = self.view.scale_axis(posx, posy)
|
|
820
898
|
|
|
821
899
|
dat = f'({posx_scaled:.1e}{posy_scaled:.1e})\n'
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
900
|
+
dwa_int = crosshair_dte.get_data_from_name('int')
|
|
901
|
+
if dwa_int is not None:
|
|
902
|
+
for ind_data in range(len(dwa_int)):
|
|
903
|
+
dat += f' {dwa_int.labels[ind_data]}:{float(dwa_int[ind_data][0]):.1e}\n'
|
|
825
904
|
|
|
826
|
-
|
|
905
|
+
self.view.set_action_text('position', dat)
|
|
827
906
|
|
|
828
907
|
except Exception as e:
|
|
829
|
-
|
|
908
|
+
logger.warning(str(e))
|
|
830
909
|
|
|
831
910
|
def prepare_connect_ui(self):
|
|
832
911
|
self.view.ROIselect.sigRegionChangeFinished.connect(self.selected_region_changed)
|
|
833
912
|
|
|
913
|
+
self.roi_manager.roi_changed.connect(self.roi_changed)
|
|
914
|
+
self.roi_manager.roi_value_changed.connect(self.roi_changed)
|
|
915
|
+
|
|
834
916
|
self.view.connect_action('flip_ud', slot=self.update_data)
|
|
835
917
|
self.view.connect_action('flip_lr', slot=self.update_data)
|
|
836
918
|
self.view.connect_action('rotate', slot=self.update_data)
|
|
@@ -838,7 +920,7 @@ class Viewer2D(ViewerBase):
|
|
|
838
920
|
self.view.connect_action('isocurve', slot=self.update_data)
|
|
839
921
|
self.view.histogrammer.gradient_changed.connect(lambda: setattr(self, '_is_gradient_manually_set', True))
|
|
840
922
|
|
|
841
|
-
self.view.lineout_plotter.roi_changed.connect(self.roi_changed)
|
|
923
|
+
# todo : self.view.lineout_plotter.roi_changed.connect(self.roi_changed)
|
|
842
924
|
self.view.get_crosshair_signal().connect(self.crosshair_changed)
|
|
843
925
|
|
|
844
926
|
self.view.get_double_clicked().connect(self.double_clicked)
|
|
@@ -847,7 +929,8 @@ class Viewer2D(ViewerBase):
|
|
|
847
929
|
if self.view.is_action_checked('ROIselect'):
|
|
848
930
|
pos = self.view.ROIselect.pos()
|
|
849
931
|
size = self.view.ROIselect.size()
|
|
850
|
-
self.ROI_select_signal.emit(QtCore.QRectF(pos[0], pos[1], size[0], size[1]))
|
|
932
|
+
# self.ROI_select_signal.emit(QtCore.QRectF(pos[0], pos[1], size[0], size[1]))
|
|
933
|
+
self.roi_select_signal.emit(RoiInfo.info_from_rect_roi(self.view.ROIselect))
|
|
851
934
|
|
|
852
935
|
@Slot(float, float)
|
|
853
936
|
def double_clicked(self, posx, posy):
|
|
@@ -879,55 +962,38 @@ class Viewer2D(ViewerBase):
|
|
|
879
962
|
self.view.set_axis_scaling('right', scaling=axis.scaling, offset=axis.offset,
|
|
880
963
|
label=axis.label, units=axis.units)
|
|
881
964
|
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
return lineout_dicts
|
|
887
|
-
|
|
888
|
-
@Slot(dict)
|
|
889
|
-
def process_crosshair_lineouts(self, crosshair_dict):
|
|
890
|
-
self.view.display_crosshair_lineouts(self.scale_lineout_dicts(crosshair_dict))
|
|
891
|
-
self.update_crosshair_data(crosshair_dict)
|
|
965
|
+
@Slot(DataToExport)
|
|
966
|
+
def process_crosshair_lineouts(self, dte):
|
|
967
|
+
self.view.display_crosshair_lineouts(dte)
|
|
968
|
+
self.update_crosshair_data(dte)
|
|
892
969
|
self.crosshair_dragged.emit(*self.view.scale_axis(*self.view.crosshair.get_positions()))
|
|
893
970
|
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
units=self.x_axis.axis_units,
|
|
907
|
-
label=self.x_axis.axis_label)]))
|
|
908
|
-
|
|
909
|
-
self.data_to_export.append(
|
|
910
|
-
DataFromRoi(name=f'Vlineout_{roi_key}', data=[lineout_data.ver_data],
|
|
911
|
-
origin=self.title,
|
|
912
|
-
axes=[Axis(data=lineout_data.ver_axis,
|
|
913
|
-
units=self.y_axis.axis_units,
|
|
914
|
-
label=self.y_axis.axis_label)]))
|
|
915
|
-
|
|
916
|
-
self.data_to_export.append(DataFromRoi(name=f'Integrated_{roi_key}', data=[lineout_data.int_data],
|
|
917
|
-
origin=self.title))
|
|
918
|
-
|
|
919
|
-
if not isinstance(lineout_data.math_data, list):
|
|
920
|
-
self.measure_data_dict[f'{roi_key}:'] = lineout_data.math_data
|
|
921
|
-
else:
|
|
922
|
-
for ind, dat in enumerate(lineout_data.math_data):
|
|
923
|
-
self.measure_data_dict[f'{roi_key}/{ind:02d}:'] = dat
|
|
971
|
+
def process_roi_lineouts(self, roi_dte: DataToExport):
|
|
972
|
+
if len(roi_dte) > 0:
|
|
973
|
+
self.view.display_roi_lineouts(roi_dte)
|
|
974
|
+
roi_dte_bis = roi_dte.deepcopy()
|
|
975
|
+
for dwa in roi_dte_bis.data:
|
|
976
|
+
if dwa.name == 'hor':
|
|
977
|
+
dwa.name = f'Hlineout_{dwa.origin}'
|
|
978
|
+
elif dwa.name == 'ver':
|
|
979
|
+
dwa.name = f'Vlineout_{dwa.origin}'
|
|
980
|
+
elif dwa.name == 'int':
|
|
981
|
+
dwa.name = f'Integrated_{dwa.origin}'
|
|
982
|
+
self.data_to_export.append(roi_dte_bis)
|
|
924
983
|
|
|
925
|
-
|
|
984
|
+
self.measure_data_dict = dict([])
|
|
926
985
|
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
986
|
+
for roi_name in roi_dte_bis.get_origins():
|
|
987
|
+
dwa = roi_dte_bis.get_data_from_name_origin(f'Integrated_{roi_name}', roi_name)
|
|
988
|
+
for ind, data_array in enumerate(dwa.data):
|
|
989
|
+
self.measure_data_dict[f'{dwa.labels[ind]}:'] = float(data_array[0])
|
|
990
|
+
|
|
991
|
+
QtWidgets.QApplication.processEvents()
|
|
992
|
+
|
|
993
|
+
self.view.roi_manager.settings.child('measurements').setValue(self.measure_data_dict)
|
|
994
|
+
if not self._display_temporary:
|
|
995
|
+
self.data_to_export_signal.emit(self.data_to_export)
|
|
996
|
+
self.ROI_changed.emit()
|
|
931
997
|
|
|
932
998
|
|
|
933
999
|
def main_spread():
|
|
@@ -961,29 +1027,24 @@ def main_spread():
|
|
|
961
1027
|
|
|
962
1028
|
def main(data_distribution='uniform'):
|
|
963
1029
|
"""either 'uniform' or 'spread'"""
|
|
964
|
-
from pymodaq.utils.math_utils import gauss2D
|
|
965
1030
|
|
|
966
1031
|
app = QtWidgets.QApplication(sys.argv)
|
|
967
1032
|
widget = QtWidgets.QWidget()
|
|
968
1033
|
|
|
1034
|
+
widget_button = QtWidgets.QWidget()
|
|
1035
|
+
widget_button.setLayout(QtWidgets.QHBoxLayout())
|
|
1036
|
+
button = QtWidgets.QPushButton('New Data')
|
|
1037
|
+
ndata = QtWidgets.QSpinBox()
|
|
1038
|
+
widget_button.layout().addWidget(button)
|
|
1039
|
+
widget_button.layout().addWidget(ndata)
|
|
1040
|
+
|
|
969
1041
|
def print_data(data: DataToExport):
|
|
970
1042
|
print(data)
|
|
971
1043
|
print('******')
|
|
972
1044
|
print(data.get_data_from_dim('Data1D'))
|
|
973
1045
|
|
|
974
1046
|
if data_distribution == 'uniform':
|
|
975
|
-
|
|
976
|
-
Ny = 2 * Nx
|
|
977
|
-
data_random = np.random.normal(size=(Ny, Nx))
|
|
978
|
-
x = 0.5 * np.linspace(-Nx / 2, Nx / 2 - 1, Nx)
|
|
979
|
-
y = 0.2 * np.linspace(-Ny / 2, Ny / 2 - 1, Ny)
|
|
980
|
-
data_red = 3 * np.sin(x/5)**2 * gauss2D(x, 5, Nx / 10, y, -1, Ny / 10, 1, 90) + 0.1 * data_random
|
|
981
|
-
data_green = 10 * gauss2D(x, -20, Nx / 10, y, -10, Ny / 20, 1, 0)
|
|
982
|
-
data_green[70:80, 7:12] = np.nan
|
|
983
|
-
|
|
984
|
-
data_to_plot = DataFromPlugins(name='mydata', distribution='uniform', data=[data_red, data_green],
|
|
985
|
-
axes=[Axis('xaxis', units='xpxl', data=x, index=1),
|
|
986
|
-
Axis('yaxis', units='ypxl', data=y, index=0), ])
|
|
1047
|
+
data_to_plot = generate_uniform_data()
|
|
987
1048
|
|
|
988
1049
|
elif data_distribution == 'spread':
|
|
989
1050
|
data_spread = np.load('../../../resources/triangulation_data.npy')
|
|
@@ -1004,16 +1065,45 @@ def main(data_distribution='uniform'):
|
|
|
1004
1065
|
prog.view.show_roi_target(True)
|
|
1005
1066
|
prog.view.move_scale_roi_target((50, 40), (10, 20))
|
|
1006
1067
|
|
|
1068
|
+
button.clicked.connect(lambda: plot_data(prog, ndata.value()))
|
|
1069
|
+
widget_button.show()
|
|
1007
1070
|
QtWidgets.QApplication.processEvents()
|
|
1008
1071
|
sys.exit(app.exec_())
|
|
1009
1072
|
|
|
1010
1073
|
|
|
1074
|
+
def generate_uniform_data() -> DataFromPlugins:
|
|
1075
|
+
from pymodaq.utils.math_utils import gauss2D
|
|
1076
|
+
Nx = 100
|
|
1077
|
+
Ny = 2 * Nx
|
|
1078
|
+
data_random = np.random.normal(size=(Ny, Nx))
|
|
1079
|
+
x = 0.5 * np.linspace(-Nx / 2, Nx / 2 - 1, Nx)
|
|
1080
|
+
y = 0.2 * np.linspace(-Ny / 2, Ny / 2 - 1, Ny)
|
|
1081
|
+
data_red = 3 * np.sin(x / 5) ** 2 * gauss2D(x, 5, Nx / 10, y, -1, Ny / 10, 1, 90) + 0.2 * data_random
|
|
1082
|
+
data_green = 10 * gauss2D(x, -20, Nx / 10, y, -10, Ny / 20, 1, 0)
|
|
1083
|
+
data_green[70:80, 7:12] = np.nan
|
|
1084
|
+
|
|
1085
|
+
data_to_plot = DataFromPlugins(name='mydata', distribution='uniform',
|
|
1086
|
+
data=[data_red, data_green, data_red-data_green],
|
|
1087
|
+
labels = ['myreddata', 'mygreendata'],
|
|
1088
|
+
axes=[Axis('xaxis', units='xpxl', data=x, index=1),
|
|
1089
|
+
Axis('yaxis', units='ypxl', data=y, index=0), ])
|
|
1090
|
+
return data_to_plot
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
def plot_data(viewer2D: Viewer2D, ndata: int = 2):
|
|
1094
|
+
if ndata > 0:
|
|
1095
|
+
dwa = generate_uniform_data()
|
|
1096
|
+
dwa.data = dwa.data[0:ndata]
|
|
1097
|
+
viewer2D.show_data(dwa)
|
|
1098
|
+
|
|
1099
|
+
|
|
1011
1100
|
def print_roi_select(rect):
|
|
1012
1101
|
print(rect)
|
|
1013
1102
|
|
|
1014
1103
|
|
|
1015
1104
|
def main_view():
|
|
1016
1105
|
app = QtWidgets.QApplication(sys.argv)
|
|
1106
|
+
|
|
1017
1107
|
form = QtWidgets.QWidget()
|
|
1018
1108
|
prog = View2D(form)
|
|
1019
1109
|
form.show()
|