bec-widgets 0.106.0__py3-none-any.whl → 0.107.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.
CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v0.107.0 (2024-09-06)
4
+
5
+ ### Documentation
6
+
7
+ * docs: extend waveform docs ([`e6976dc`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e6976dc15105209852090a00a97b7cda723142e9))
8
+
9
+ ### Feature
10
+
11
+ * feat: add roi select for dap, allow automatic clear curves on plot request ([`7bdca84`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/7bdca8431496fe6562d2c28f5a6af869d1a2e654))
12
+
13
+ ### Refactor
14
+
15
+ * refactor: change style to bec_accent_colors ([`bd126dd`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/bd126dddbbec3e6c448cce263433d328d577c5c0))
16
+
17
+ ### Test
18
+
19
+ * test: add tests, including extension to end-2-end test ([`b1aff6d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b1aff6d791ff847eb2f628e66ccaa4672fdeea08))
20
+
3
21
  ## v0.106.0 (2024-09-05)
4
22
 
5
23
  ### Feature
@@ -140,20 +158,6 @@
140
158
 
141
159
  ## v0.99.13 (2024-08-30)
142
160
 
143
- ### Documentation
144
-
145
- * docs: minor updates to the widget tutorial ([`ec9c8f2`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/ec9c8f29633364c45ebd998a5411d428c1ce488d))
146
-
147
- * docs(widget tutorial): step by step guide added ([`b32ced8`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b32ced85fff628a9e1303a781630cdae3865238e))
148
-
149
161
  ### Fix
150
162
 
151
163
  * fix(dark mode button): fixed dark mode button state for external updates, including auto ([`a3110d9`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a3110d98147295dcb1f9353f9aaf5461cba9232a))
152
-
153
- ## v0.99.12 (2024-08-29)
154
-
155
- ### Fix
156
-
157
- * fix(toolbar): widget action added ([`2efd487`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/2efd48736cbe04e84533f7933c552ea8274e2162))
158
-
159
- * fix(reset_button): reset button added ([`6ed1efc`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6ed1efc6af193908f70aa37fb73157d2ca6a62f4))
PKG-INFO CHANGED
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.106.0
3
+ Version: 0.107.0
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
bec_widgets/cli/client.py CHANGED
@@ -1887,7 +1887,7 @@ class BECWaveform(RPCBase):
1887
1887
  """
1888
1888
 
1889
1889
  @rpc_call
1890
- def get_all_data(self, output: "Literal['dict', 'pandas']" = "dict") -> "dict | pd.DataFrame":
1890
+ def get_all_data(self, output: "Literal['dict', 'pandas']" = "dict") -> "dict":
1891
1891
  """
1892
1892
  Extract all curve data into a dictionary or a pandas DataFrame.
1893
1893
 
@@ -2050,6 +2050,25 @@ class BECWaveform(RPCBase):
2050
2050
  size(int): Font size of the legend.
2051
2051
  """
2052
2052
 
2053
+ @rpc_call
2054
+ def toggle_roi(self, toggled: "bool") -> "None":
2055
+ """
2056
+ Toggle the linear region selector on the plot.
2057
+
2058
+ Args:
2059
+ toggled(bool): If True, enable the linear region selector.
2060
+ """
2061
+
2062
+ @rpc_call
2063
+ def select_roi(self, region: "tuple[float, float]"):
2064
+ """
2065
+ Set the fit region of the plot widget. At the moment only a single region is supported.
2066
+ To remove the roi region again, use toggle_roi_region
2067
+
2068
+ Args:
2069
+ region(tuple[float, float]): The fit region.
2070
+ """
2071
+
2053
2072
 
2054
2073
  class BECWaveformWidget(RPCBase):
2055
2074
  @property
@@ -2321,6 +2340,24 @@ class BECWaveformWidget(RPCBase):
2321
2340
  Export the plot widget to Matplotlib.
2322
2341
  """
2323
2342
 
2343
+ @rpc_call
2344
+ def toggle_roi(self, checked: "bool"):
2345
+ """
2346
+ Toggle the linear region selector.
2347
+
2348
+ Args:
2349
+ checked(bool): If True, enable the linear region selector.
2350
+ """
2351
+
2352
+ @rpc_call
2353
+ def select_roi(self, region: "tuple"):
2354
+ """
2355
+ Set the region of interest of the plot widget.
2356
+
2357
+ Args:
2358
+ region(tuple): Region of interest.
2359
+ """
2360
+
2324
2361
 
2325
2362
  class DapComboBox(RPCBase):
2326
2363
  @rpc_call
@@ -0,0 +1,72 @@
1
+ """ Module for a thin wrapper (LinearRegionWrapper) around the LinearRegionItem in pyqtgraph.
2
+ The class is mainly designed for usage with the BECWaveform and 1D plots. """
3
+
4
+ import pyqtgraph as pg
5
+ from qtpy.QtCore import QObject, Signal, Slot
6
+ from qtpy.QtGui import QColor
7
+
8
+
9
+ class LinearRegionWrapper(QObject):
10
+ """Wrapper class for the LinearRegionItem in pyqtgraph for 1D plots (BECWaveform)
11
+
12
+ Args:
13
+ plot_item (pg.PlotItem): The plot item to add the region selector to.
14
+ parent (QObject): The parent object.
15
+ color (QColor): The color of the region selector.
16
+ hover_color (QColor): The color of the region selector when the mouse is over it.
17
+ """
18
+
19
+ # Signal with the region tuble (start, end)
20
+ region_changed = Signal(tuple)
21
+
22
+ def __init__(
23
+ self, plot_item: pg.PlotItem, color: QColor = None, hover_color: QColor = None, parent=None
24
+ ):
25
+ super().__init__(parent)
26
+ self._edge_width = 2
27
+ self.plot_item = plot_item
28
+ self.linear_region_selector = pg.LinearRegionItem()
29
+ self.proxy = None
30
+ self.change_roi_color((color, hover_color))
31
+
32
+ # Slot for changing the color of the region selector (edge and fill)
33
+ @Slot(tuple)
34
+ def change_roi_color(self, colors: tuple[QColor | str | tuple, QColor | str | tuple]):
35
+ """Change the color and hover color of the region selector.
36
+ Hover color means the color when the mouse is over the region.
37
+
38
+ Args:
39
+ colors (tuple): Tuple with the color and hover color
40
+ """
41
+ color, hover_color = colors
42
+ if color is not None:
43
+ self.linear_region_selector.setBrush(pg.mkBrush(color))
44
+ if hover_color is not None:
45
+ self.linear_region_selector.setHoverBrush(pg.mkBrush(hover_color))
46
+
47
+ @Slot()
48
+ def add_region_selector(self):
49
+ """Add the region selector to the plot item"""
50
+ self.plot_item.addItem(self.linear_region_selector)
51
+ # Use proxy to limit the update rate of the region change signal to 10Hz
52
+ self.proxy = pg.SignalProxy(
53
+ self.linear_region_selector.sigRegionChanged,
54
+ rateLimit=10,
55
+ slot=self._region_change_proxy,
56
+ )
57
+
58
+ @Slot()
59
+ def remove_region_selector(self):
60
+ """Remove the region selector from the plot item"""
61
+ self.proxy.disconnect()
62
+ self.proxy = None
63
+ self.plot_item.removeItem(self.linear_region_selector)
64
+
65
+ def _region_change_proxy(self):
66
+ """Emit the region change signal"""
67
+ region = self.linear_region_selector.getRegion()
68
+ self.region_changed.emit(region)
69
+
70
+ def cleanup(self):
71
+ """Cleanup the widget."""
72
+ self.remove_region_selector()
@@ -12,10 +12,11 @@ from bec_lib.logger import bec_logger
12
12
  from pydantic import Field, ValidationError, field_validator
13
13
  from pyqtgraph.exporters import MatplotlibExporter
14
14
  from qtpy.QtCore import Signal as pyqtSignal
15
- from qtpy.QtWidgets import QWidget
15
+ from qtpy.QtWidgets import QApplication, QWidget
16
16
 
17
17
  from bec_widgets.qt_utils.error_popups import SafeSlot as Slot
18
18
  from bec_widgets.utils import Colors, EntryValidator
19
+ from bec_widgets.utils.linear_region_selector import LinearRegionWrapper
19
20
  from bec_widgets.widgets.figure.plots.plot_base import BECPlotBase, SubplotConfig
20
21
  from bec_widgets.widgets.figure.plots.waveform.waveform_curve import (
21
22
  BECCurve,
@@ -74,6 +75,8 @@ class BECWaveform(BECPlotBase):
74
75
  "remove",
75
76
  "clear_all",
76
77
  "set_legend_label_size",
78
+ "toggle_roi",
79
+ "select_roi",
77
80
  ]
78
81
  scan_signal_update = pyqtSignal()
79
82
  async_signal_update = pyqtSignal()
@@ -81,6 +84,9 @@ class BECWaveform(BECPlotBase):
81
84
  dap_summary_update = pyqtSignal(dict, dict)
82
85
  autorange_signal = pyqtSignal()
83
86
  new_scan = pyqtSignal()
87
+ roi_changed = pyqtSignal(tuple)
88
+ roi_active = pyqtSignal(bool)
89
+ request_dap_refresh = pyqtSignal()
84
90
 
85
91
  def __init__(
86
92
  self,
@@ -100,6 +106,9 @@ class BECWaveform(BECPlotBase):
100
106
  self.old_scan_id = None
101
107
  self.scan_id = None
102
108
  self.scan_item = None
109
+ self._roi_region = None
110
+ self.roi_select = None
111
+ self._accent_colors = QApplication.instance().theme.accent_colors
103
112
  self._x_axis_mode = {
104
113
  "name": None,
105
114
  "entry": None,
@@ -130,6 +139,63 @@ class BECWaveform(BECPlotBase):
130
139
  self.add_legend()
131
140
  self.apply_config(self.config)
132
141
 
142
+ @Slot(bool)
143
+ def toggle_roi(self, toggled: bool) -> None:
144
+ """Toggle the linear region selector on the plot.
145
+
146
+ Args:
147
+ toggled(bool): If True, enable the linear region selector.
148
+ """
149
+ if toggled:
150
+ return self._hook_roi()
151
+ return self._unhook_roi()
152
+
153
+ @Slot(tuple)
154
+ def select_roi(self, region: tuple[float, float]):
155
+ """Set the fit region of the plot widget. At the moment only a single region is supported.
156
+ To remove the roi region again, use toggle_roi_region
157
+
158
+ Args:
159
+ region(tuple[float, float]): The fit region.
160
+ """
161
+ if self.roi_region == (None, None):
162
+ self.toggle_roi(True)
163
+ try:
164
+ self.roi_select.linear_region_selector.setRegion(region)
165
+ except Exception as e:
166
+ logger.error(f"Error setting region {tuple}; Exception raised: {e}")
167
+ raise ValueError(f"Error setting region {tuple}; Exception raised: {e}")
168
+
169
+ def _hook_roi(self):
170
+ """Hook the linear region selector to the plot."""
171
+ color = self._accent_colors.default
172
+ color.setAlpha(int(0.2 * 255))
173
+ hover_color = self._accent_colors.default
174
+ hover_color.setAlpha(int(0.35 * 255))
175
+ if self.roi_select is None:
176
+ self.roi_select = LinearRegionWrapper(
177
+ self.plot_item, color=color, hover_color=hover_color, parent=self
178
+ )
179
+ self.roi_select.add_region_selector()
180
+ self.roi_select.region_changed.connect(self.roi_changed)
181
+ self.roi_select.region_changed.connect(self.set_roi_region)
182
+ self.request_dap_refresh.connect(self.refresh_dap)
183
+ self._emit_roi_region()
184
+ self.roi_active.emit(True)
185
+
186
+ def _unhook_roi(self):
187
+ """Unhook the linear region selector from the plot."""
188
+ if self.roi_select is not None:
189
+ self.roi_select.region_changed.disconnect(self.roi_changed)
190
+ self.roi_select.region_changed.disconnect(self.set_roi_region)
191
+ self.request_dap_refresh.disconnect(self.refresh_dap)
192
+ self.roi_active.emit(False)
193
+ self.roi_region = None
194
+ self.refresh_dap()
195
+ self.roi_select.cleanup()
196
+ self.roi_select.deleteLater()
197
+ self.roi_select = None
198
+
133
199
  def apply_config(self, config: dict | SubplotConfig, replot_last_scan: bool = False):
134
200
  """
135
201
  Apply the configuration to the 1D waveform widget.
@@ -171,6 +237,48 @@ class BECWaveform(BECPlotBase):
171
237
  for curve in self.curves:
172
238
  curve.config.parent_id = new_gui_id
173
239
 
240
+ ###################################
241
+ # Fit Range Properties
242
+ ###################################
243
+
244
+ @property
245
+ def roi_region(self) -> tuple[float, float] | None:
246
+ """
247
+ Get the fit region of the plot widget.
248
+
249
+ Returns:
250
+ tuple: The fit region.
251
+ """
252
+ if self._roi_region is not None:
253
+ return self._roi_region
254
+ return None, None
255
+
256
+ @roi_region.setter
257
+ def roi_region(self, value: tuple[float, float] | None):
258
+ """Set the fit region of the plot widget.
259
+
260
+ Args:
261
+ value(tuple[float, float]|None): The fit region.
262
+ """
263
+ self._roi_region = value
264
+ if value is not None:
265
+ self.request_dap_refresh.emit()
266
+
267
+ @Slot(tuple)
268
+ def set_roi_region(self, region: tuple[float, float]):
269
+ """
270
+ Set the fit region of the plot widget.
271
+
272
+ Args:
273
+ region(tuple[float, float]): The fit region.
274
+ """
275
+ self.roi_region = region
276
+
277
+ def _emit_roi_region(self):
278
+ """Emit the current ROI from selector the plot widget."""
279
+ if self.roi_select is not None:
280
+ self.set_roi_region(self.roi_select.linear_region_selector.getRegion())
281
+
174
282
  ###################################
175
283
  # Waveform Properties
176
284
  ###################################
@@ -1058,13 +1166,14 @@ class BECWaveform(BECPlotBase):
1058
1166
  y_entry = curve.config.signals.y.entry
1059
1167
  model_name = curve.config.signals.dap
1060
1168
  model = getattr(self.dap, model_name)
1169
+ x_min, x_max = self.roi_region
1061
1170
 
1062
1171
  msg = messages.DAPRequestMessage(
1063
1172
  dap_cls="LmfitService1D",
1064
1173
  dap_type="on_demand",
1065
1174
  config={
1066
1175
  "args": [self.scan_id, x_name, x_entry, y_name, y_entry],
1067
- "kwargs": {},
1176
+ "kwargs": {"x_min": x_min, "x_max": x_max},
1068
1177
  "class_args": model._plugin_info["class_args"],
1069
1178
  "class_kwargs": model._plugin_info["class_kwargs"],
1070
1179
  },
@@ -1304,7 +1413,8 @@ class BECWaveform(BECPlotBase):
1304
1413
  self.scan_signal_update.emit()
1305
1414
  self.async_signal_update.emit()
1306
1415
 
1307
- def get_all_data(self, output: Literal["dict", "pandas"] = "dict") -> dict | pd.DataFrame:
1416
+ # pylint: ignore: undefined-variable
1417
+ def get_all_data(self, output: Literal["dict", "pandas"] = "dict") -> dict: # | pd.DataFrame:
1308
1418
  """
1309
1419
  Extract all curve data into a dictionary or a pandas DataFrame.
1310
1420
 
@@ -1351,13 +1461,21 @@ class BECWaveform(BECPlotBase):
1351
1461
  """
1352
1462
  MatplotlibExporter(self.plot_item).export()
1353
1463
 
1354
- def clear_all(self):
1464
+ def clear_source(self, source: Literal["DAP", "async", "scan_segment", "custom"]):
1465
+ """Clear speicific source from self._curves_data.
1466
+
1467
+ Args:
1468
+ source (Literal["DAP", "async", "scan_segment", "custom"]): Source to be cleared.
1469
+ """
1355
1470
  curves_data = self._curves_data
1356
- sources = list(curves_data.keys())
1471
+ curve_ids_to_remove = list(curves_data[source].keys())
1472
+ for curve_id in curve_ids_to_remove:
1473
+ self.remove_curve(curve_id)
1474
+
1475
+ def clear_all(self):
1476
+ sources = list(self._curves_data.keys())
1357
1477
  for source in sources:
1358
- curve_ids_to_remove = list(curves_data[source].keys())
1359
- for curve_id in curve_ids_to_remove:
1360
- self.remove_curve(curve_id)
1478
+ self.clear_source(source)
1361
1479
 
1362
1480
  def cleanup(self):
1363
1481
  """Cleanup the widget connection from BECDispatcher."""
@@ -6,7 +6,7 @@ from typing import Literal
6
6
  import numpy as np
7
7
  import pyqtgraph as pg
8
8
  from bec_lib.logger import bec_logger
9
- from qtpy.QtCore import Signal
9
+ from qtpy.QtCore import Property, Signal, Slot
10
10
  from qtpy.QtWidgets import QVBoxLayout, QWidget
11
11
 
12
12
  from bec_widgets.qt_utils.error_popups import SafeSlot, WarningPopupUtility
@@ -55,6 +55,8 @@ class BECWaveformWidget(BECWidget, QWidget):
55
55
  "lock_aspect_ratio",
56
56
  "export",
57
57
  "export_to_matplotlib",
58
+ "toggle_roi",
59
+ "select_roi",
58
60
  ]
59
61
  scan_signal_update = Signal()
60
62
  async_signal_update = Signal()
@@ -70,6 +72,8 @@ class BECWaveformWidget(BECWidget, QWidget):
70
72
  crosshair_coordinates_changed_string = Signal(str)
71
73
  crosshair_coordinates_clicked = Signal(tuple)
72
74
  crosshair_coordinates_clicked_string = Signal(str)
75
+ roi_changed = Signal(tuple)
76
+ roi_active = Signal(bool)
73
77
 
74
78
  def __init__(
75
79
  self,
@@ -120,6 +124,11 @@ class BECWaveformWidget(BECWidget, QWidget):
120
124
  "crosshair": MaterialIconAction(
121
125
  icon_name="point_scan", tooltip="Show Crosshair", checkable=True
122
126
  ),
127
+ "roi_select": MaterialIconAction(
128
+ icon_name="align_justify_space_between",
129
+ tooltip="Add ROI region for DAP",
130
+ checkable=True,
131
+ ),
123
132
  },
124
133
  target_widget=self,
125
134
  )
@@ -133,6 +142,7 @@ class BECWaveformWidget(BECWidget, QWidget):
133
142
  self.waveform.apply_config(config)
134
143
 
135
144
  self.config = config
145
+ self._clear_curves_on_plot_update = False
136
146
 
137
147
  self.hook_waveform_signals()
138
148
  self._hook_actions()
@@ -160,6 +170,8 @@ class BECWaveformWidget(BECWidget, QWidget):
160
170
  self.waveform.crosshair_position_clicked.connect(
161
171
  self._emit_crosshair_position_clicked_string
162
172
  )
173
+ self.waveform.roi_changed.connect(self.roi_changed)
174
+ self.waveform.roi_active.connect(self.roi_active)
163
175
 
164
176
  def _hook_actions(self):
165
177
  self.toolbar.widgets["save"].action.triggered.connect(self.export)
@@ -173,6 +185,7 @@ class BECWaveformWidget(BECWidget, QWidget):
173
185
  self.toolbar.widgets["fit_params"].action.triggered.connect(self.show_fit_summary_dialog)
174
186
  self.toolbar.widgets["axis_settings"].action.triggered.connect(self.show_axis_settings)
175
187
  self.toolbar.widgets["crosshair"].action.triggered.connect(self.waveform.toggle_crosshair)
188
+ self.toolbar.widgets["roi_select"].action.toggled.connect(self.waveform.toggle_roi)
176
189
  # self.toolbar.widgets["import"].action.triggered.connect(
177
190
  # lambda: self.load_config(path=None, gui=True)
178
191
  # )
@@ -180,6 +193,29 @@ class BECWaveformWidget(BECWidget, QWidget):
180
193
  # lambda: self.save_config(path=None, gui=True)
181
194
  # )
182
195
 
196
+ @Slot(bool)
197
+ def toogle_roi_select(self, checked: bool):
198
+ """Toggle the linear region selector.
199
+
200
+ Args:
201
+ checked(bool): If True, enable the linear region selector.
202
+ """
203
+ self.toolbar.widgets["roi_select"].action.setChecked(checked)
204
+
205
+ @Property(bool)
206
+ def clear_curves_on_plot_update(self) -> bool:
207
+ """If True, clear curves on plot update."""
208
+ return self._clear_curves_on_plot_update
209
+
210
+ @clear_curves_on_plot_update.setter
211
+ def clear_curves_on_plot_update(self, value: bool):
212
+ """Set the clear curves on plot update property.
213
+
214
+ Args:
215
+ value(bool): If True, clear curves on plot update.
216
+ """
217
+ self._clear_curves_on_plot_update = value
218
+
183
219
  @SafeSlot(tuple)
184
220
  def _emit_crosshair_coordinates_changed_string(self, coordinates):
185
221
  self.crosshair_coordinates_changed_string.emit(str(coordinates))
@@ -260,7 +296,8 @@ class BECWaveformWidget(BECWidget, QWidget):
260
296
  """
261
297
  self.waveform.set_colormap(colormap)
262
298
 
263
- @SafeSlot(str, popup_error=True)
299
+ @Slot(str, str) # Slot for x_name, x_entry
300
+ @SafeSlot(str, popup_error=True) # Slot for x_name and
264
301
  def set_x(self, x_name: str, x_entry: str | None = None):
265
302
  """
266
303
  Change the x axis of the plot widget.
@@ -275,7 +312,8 @@ class BECWaveformWidget(BECWidget, QWidget):
275
312
  """
276
313
  self.waveform.set_x(x_name, x_entry)
277
314
 
278
- @SafeSlot(str, popup_error=True)
315
+ @Slot(str) # Slot for y_name
316
+ @SafeSlot(popup_error=True)
279
317
  def plot(
280
318
  self,
281
319
  arg1: list | np.ndarray | str | None = None,
@@ -315,7 +353,8 @@ class BECWaveformWidget(BECWidget, QWidget):
315
353
  Returns:
316
354
  BECCurve: The curve object.
317
355
  """
318
- # self._check_if_scans_have_same_x(enabled=True, x_name_to_check=x_name)
356
+ if self.clear_curves_on_plot_update is True:
357
+ self.waveform.clear_source(source="scan_segment")
319
358
  return self.waveform.plot(
320
359
  arg1=arg1,
321
360
  x=x,
@@ -334,6 +373,9 @@ class BECWaveformWidget(BECWidget, QWidget):
334
373
  **kwargs,
335
374
  )
336
375
 
376
+ @Slot(
377
+ str, str, str, str, str, str, bool
378
+ ) # Slot for x_name, y_name, x_entry, y_entry, color, validate_bec
337
379
  @SafeSlot(str, str, str, popup_error=True)
338
380
  def add_dap(
339
381
  self,
@@ -362,6 +404,8 @@ class BECWaveformWidget(BECWidget, QWidget):
362
404
  Returns:
363
405
  BECCurve: The curve object.
364
406
  """
407
+ if self.clear_curves_on_plot_update is True:
408
+ self.waveform.clear_source(source="DAP")
365
409
  return self.waveform.add_dap(
366
410
  x_name=x_name,
367
411
  y_name=y_name,
@@ -543,6 +587,23 @@ class BECWaveformWidget(BECWidget, QWidget):
543
587
  """
544
588
  self.waveform.set_auto_range(enabled, axis)
545
589
 
590
+ def toggle_roi(self, checked: bool):
591
+ """Toggle the linear region selector.
592
+
593
+ Args:
594
+ checked(bool): If True, enable the linear region selector.
595
+ """
596
+ self.waveform.toggle_roi(checked)
597
+
598
+ def select_roi(self, region: tuple):
599
+ """
600
+ Set the region of interest of the plot widget.
601
+
602
+ Args:
603
+ region(tuple): Region of interest.
604
+ """
605
+ self.waveform.select_roi(region)
606
+
546
607
  @SafeSlot()
547
608
  def _auto_range_from_toolbar(self):
548
609
  """
@@ -644,6 +705,10 @@ def main(): # pragma: no cover
644
705
 
645
706
  app = QApplication(sys.argv)
646
707
  widget = BECWaveformWidget()
708
+ widget.plot(x_name="samx", y_name="bpm4i")
709
+ widget.plot(y_name="bpm3i")
710
+ widget.plot(y_name="bpm4a")
711
+ widget.plot(y_name="bpm5i")
647
712
  widget.show()
648
713
  sys.exit(app.exec_())
649
714
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.106.0
3
+ Version: 0.107.0
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
@@ -2,11 +2,11 @@
2
2
  .gitlab-ci.yml,sha256=Dc1iDjsc72UxdUtihx4uSZU0lrTQeR8hZwGx1MQBfKE,8432
3
3
  .pylintrc,sha256=eeY8YwSI74oFfq6IYIbCqnx3Vk8ZncKaatv96n_Y8Rs,18544
4
4
  .readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
5
- CHANGELOG.md,sha256=VgvcwmknCXjX8mxzyJp2yygmsjtJtbaHfD8KQU5RpE0,7261
5
+ CHANGELOG.md,sha256=YNuBSx-46LZDVFz6S9ZO_AgMDViB7SgjvT34zLnn8Eo,7327
6
6
  LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
7
- PKG-INFO,sha256=ffhpXp786ojh7YAGYizUsBPGvONAJlGKSpSvSaTL804,1334
7
+ PKG-INFO,sha256=0qltRqNV0ASskefdamUg6Xo_9_k7dFyiQunWQPSddsA,1334
8
8
  README.md,sha256=Od69x-RS85Hph0-WwWACwal4yUd67XkEn4APEfHhHFw,2649
9
- pyproject.toml,sha256=tFMA5VaEZprfuybgIv-mHOCvtaC1VMWruKRtKHyqI5M,2544
9
+ pyproject.toml,sha256=eykDu2JzexvTUnaRXjMpDyLp5t1uX9TWNMX3omeC2Ng,2544
10
10
  .git_hooks/pre-commit,sha256=n3RofIZHJl8zfJJIUomcMyYGFi_rwq4CC19z0snz3FI,286
11
11
  .gitlab/issue_templates/bug_report_template.md,sha256=gAuyEwl7XlnebBrkiJ9AqffSNOywmr8vygUFWKTuQeI,386
12
12
  .gitlab/issue_templates/documentation_update_template.md,sha256=FHLdb3TS_D9aL4CYZCjyXSulbaW5mrN2CmwTaeLPbNw,860
@@ -22,7 +22,7 @@ bec_widgets/assets/status_icons/running.svg,sha256=nlc6rKh_f-uOxQSk0BkBNyWnPAJU5
22
22
  bec_widgets/assets/status_icons/warning.svg,sha256=CNx88p9kbDG51s9ztKf-cfYan4JdDBbk3-IFKfOOFlI,364
23
23
  bec_widgets/cli/__init__.py,sha256=d0Q6Fn44e7wFfLabDOBxpcJ1DPKWlFunGYDUBmO-4hA,22
24
24
  bec_widgets/cli/auto_updates.py,sha256=DwzRChcFIWPH2kCYvp8H7dXvyYSKGYv6LwCmK2sDR2E,5676
25
- bec_widgets/cli/client.py,sha256=DCFTDwMNjLQwQe3mhg7eWoECYqaQJmvFvOrNhVZmmJ4,79251
25
+ bec_widgets/cli/client.py,sha256=oJO_3IQZ2EGgB0Z2td0nqv9Wj6iijilN6SP4UrlZDkQ,80205
26
26
  bec_widgets/cli/client_utils.py,sha256=EdDfo3uuYAWtZiDGGu3_GPnl94FSLkNG2N_4I9FNfMc,11809
27
27
  bec_widgets/cli/generate_cli.py,sha256=Ea5px9KblUlcGg-1JbJBTIU7laGg2n8PM7Efw9WVVzM,5889
28
28
  bec_widgets/cli/rpc_register.py,sha256=QxXUZu5XNg00Yf5O3UHWOXg3-f_pzKjjoZYMOa-MOJc,2216
@@ -59,6 +59,7 @@ bec_widgets/utils/crosshair.py,sha256=8lik9k69WI2WMj5FGLbrKtny9duxqXUJAhpX8tHoyp
59
59
  bec_widgets/utils/entry_validator.py,sha256=3skJIsUwTYicT76AMHm_M78RiWtUgyD2zb-Rxo2HdHQ,1313
60
60
  bec_widgets/utils/generate_designer_plugin.py,sha256=eidqauS8YLgoxkPntPL0oSG_lYqI2D7fSyOZvOtCU_U,5891
61
61
  bec_widgets/utils/layout_manager.py,sha256=H0nKsIMaPxRkof1MEXlSmW6w1dFxA6astaGzf4stI84,4727
62
+ bec_widgets/utils/linear_region_selector.py,sha256=kRLoZ0P0FttcsFvDBN8NGPm3swCIBv7Ax9AuqmjkRjE,2719
62
63
  bec_widgets/utils/plugin_utils.py,sha256=njvVdvF-AR47Yn80ntpvFldEvLuFx9GV-qEX4p_n4AI,5263
63
64
  bec_widgets/utils/reference_utils.py,sha256=8pq06TOvZBZdim0G6hvPJXzVDib7ve4o-Ptvfp563nk,2859
64
65
  bec_widgets/utils/rpc_decorator.py,sha256=pIvtqySQLnuS7l2Ti_UAe4WX7CRivZnsE5ZdKAihxh0,479
@@ -156,7 +157,7 @@ bec_widgets/widgets/figure/plots/image/image_processor.py,sha256=GeTtWjbldy6VejM
156
157
  bec_widgets/widgets/figure/plots/motor_map/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
157
158
  bec_widgets/widgets/figure/plots/motor_map/motor_map.py,sha256=AiDq4bmcEoj9PlkRQtHCk-5cwvOFGPBcfxPNNr8E53Y,18399
158
159
  bec_widgets/widgets/figure/plots/waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
159
- bec_widgets/widgets/figure/plots/waveform/waveform.py,sha256=52yf5wba5JtX5MM-KoKWSdx6Ltv_n4xHyI2yvm2euhs,51936
160
+ bec_widgets/widgets/figure/plots/waveform/waveform.py,sha256=aU_anZcC6Z17ZHsBPxPeC_0x5YRyJMP4BN7pWk0nG3E,56270
160
161
  bec_widgets/widgets/figure/plots/waveform/waveform_curve.py,sha256=RUo4GfXwlaCei8BBvWBQF3IEB8h-KgpvaHur6JUvT6s,8682
161
162
  bec_widgets/widgets/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
162
163
  bec_widgets/widgets/image/bec_image_widget.pyproject,sha256=PHisdBo5_5UCApd27GkizzqgfdjsDx2bFZa_p9LiSW8,30
@@ -237,7 +238,7 @@ bec_widgets/widgets/waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
237
238
  bec_widgets/widgets/waveform/bec_waveform_widget.pyproject,sha256=GLD8GN9dXx9wNbtnevrxqqcwk7vKV-Uv8QYSycdaoaI,33
238
239
  bec_widgets/widgets/waveform/bec_waveform_widget_plugin.py,sha256=qSQTeCzIUn8rgDkjIM47Rr3-fqg1uk8rDf_lCoY9gZw,1402
239
240
  bec_widgets/widgets/waveform/register_bec_waveform_widget.py,sha256=qZHVZH_lP2hvzkG1Ra0EyrXlMeLkRCy0aceH-bfJ1cs,490
240
- bec_widgets/widgets/waveform/waveform_widget.py,sha256=nEIRz6mnBpVl2BTauQHMI_DJHXO7aO5HyuAsf8OrMag,22427
241
+ bec_widgets/widgets/waveform/waveform_widget.py,sha256=jUyeGZCKKqtyk219Xkj_IMca-nvPELW23FqjMn-SMhc,24736
241
242
  bec_widgets/widgets/waveform/waveform_popups/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
242
243
  bec_widgets/widgets/waveform/waveform_popups/curve_dialog/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
243
244
  bec_widgets/widgets/waveform/waveform_popups/curve_dialog/curve_dialog.py,sha256=VxbAtI_ZLfkrkTXqImQcNPwKDqFRWEj-vI8v6mmVMJ8,13025
@@ -249,8 +250,8 @@ bec_widgets/widgets/website/register_website_widget.py,sha256=LIQJpV9uqcBiPR9cEA
249
250
  bec_widgets/widgets/website/website.py,sha256=42pncCc_zI2eqeMArIurVmPUukRo5bTxa2h1Skah-io,3012
250
251
  bec_widgets/widgets/website/website_widget.pyproject,sha256=scOiV3cV1_BjbzpPzy2N8rIJL5P2qIZz8ObTJ-Uvdtg,25
251
252
  bec_widgets/widgets/website/website_widget_plugin.py,sha256=pz38_C2cZ0yvPPS02wdIPcmhFo_yiwUhflsASocAPQQ,1341
252
- bec_widgets-0.106.0.dist-info/METADATA,sha256=ffhpXp786ojh7YAGYizUsBPGvONAJlGKSpSvSaTL804,1334
253
- bec_widgets-0.106.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
254
- bec_widgets-0.106.0.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
255
- bec_widgets-0.106.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
256
- bec_widgets-0.106.0.dist-info/RECORD,,
253
+ bec_widgets-0.107.0.dist-info/METADATA,sha256=0qltRqNV0ASskefdamUg6Xo_9_k7dFyiQunWQPSddsA,1334
254
+ bec_widgets-0.107.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
255
+ bec_widgets-0.107.0.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
256
+ bec_widgets-0.107.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
257
+ bec_widgets-0.107.0.dist-info/RECORD,,
pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bec_widgets"
7
- version = "0.106.0"
7
+ version = "0.107.0"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [