bec-widgets 0.73.2__py3-none-any.whl → 0.74.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 +14 -16
- PKG-INFO +1 -1
- bec_widgets/cli/client.py +57 -0
- bec_widgets/examples/jupyter_console/jupyter_console_window.py +3 -16
- bec_widgets/utils/bec_connector.py +1 -0
- bec_widgets/widgets/figure/figure.py +14 -5
- bec_widgets/widgets/figure/plots/waveform/waveform.py +153 -5
- bec_widgets/widgets/figure/plots/waveform/waveform_curve.py +14 -1
- {bec_widgets-0.73.2.dist-info → bec_widgets-0.74.0.dist-info}/METADATA +1 -1
- {bec_widgets-0.73.2.dist-info → bec_widgets-0.74.0.dist-info}/RECORD +19 -18
- docs/user/widgets/bec_figure.md +45 -3
- docs/user/widgets/bec_figure_dap.gif +0 -0
- pyproject.toml +1 -1
- tests/end-2-end/test_bec_dock_rpc_e2e.py +2 -0
- tests/end-2-end/test_bec_figure_rpc_e2e.py +34 -0
- tests/unit_tests/test_waveform1d.py +4 -0
- {bec_widgets-0.73.2.dist-info → bec_widgets-0.74.0.dist-info}/WHEEL +0 -0
- {bec_widgets-0.73.2.dist-info → bec_widgets-0.74.0.dist-info}/entry_points.txt +0 -0
- {bec_widgets-0.73.2.dist-info → bec_widgets-0.74.0.dist-info}/licenses/LICENSE +0 -0
CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## v0.74.0 (2024-06-25)
|
4
|
+
|
5
|
+
### Documentation
|
6
|
+
|
7
|
+
* docs(becfigure): docs added ([`a51b15d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a51b15da3f5e83e0c897a0342bdb05b9c677a179))
|
8
|
+
|
9
|
+
### Feature
|
10
|
+
|
11
|
+
* feat(waveform1d): dap LMFit model can be added to plot ([`1866ba6`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/1866ba66c8e3526661beb13fff3e13af6a0ae562))
|
12
|
+
|
13
|
+
### Test
|
14
|
+
|
15
|
+
* test(waveform1d): dap e2e test added ([`7271b42`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/7271b422f98ef9264970d708811c414b69a644db))
|
16
|
+
|
3
17
|
## v0.73.2 (2024-06-25)
|
4
18
|
|
5
19
|
### Fix
|
@@ -133,19 +147,3 @@
|
|
133
147
|
* fix(generate_cli): fixed rpc generate for classes without user access; closes #226 ([`925c893`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/925c893f3ff4337fc8b4d237c8ffc19a597b0996))
|
134
148
|
|
135
149
|
## v0.68.0 (2024-06-21)
|
136
|
-
|
137
|
-
### Feature
|
138
|
-
|
139
|
-
* feat: properly handle SIGINT (ctrl-c) in BEC GUI server -> calls qapplication.quit() ([`3644f34`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/3644f344da2df674bc0d5740c376a86b9d0dfe95))
|
140
|
-
|
141
|
-
* feat: bec-gui-server: redirect stdout and stderr (if any) as proper debug and error log entries ([`d1266a1`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/d1266a1ce148ff89557a039e3a182a87a3948f49))
|
142
|
-
|
143
|
-
### Fix
|
144
|
-
|
145
|
-
* fix: ignore GUI server output (any output will go to log file)
|
146
|
-
|
147
|
-
If a logger is given to log `_start_log_process`, the server stdout and
|
148
|
-
stderr streams will be redirected as log entries with levels DEBUG or ERROR
|
149
|
-
in their parent process ([`ce37416`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/ce374163cab87a92847409051739777bc505a77b))
|
150
|
-
|
151
|
-
* fix: do not create 'BECClient' logger when instantiating BECDispatcher ([`f7d0b07`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f7d0b0768ace42a33e2556bb33611d4f02e5a6d9))
|
PKG-INFO
CHANGED
bec_widgets/cli/client.py
CHANGED
@@ -31,6 +31,13 @@ class BECCurve(RPCBase):
|
|
31
31
|
Remove the curve from the plot.
|
32
32
|
"""
|
33
33
|
|
34
|
+
@property
|
35
|
+
@rpc_call
|
36
|
+
def dap_params(self):
|
37
|
+
"""
|
38
|
+
None
|
39
|
+
"""
|
40
|
+
|
34
41
|
@property
|
35
42
|
@rpc_call
|
36
43
|
def rpc_id(self) -> "str":
|
@@ -143,6 +150,13 @@ class BECCurve(RPCBase):
|
|
143
150
|
tuple[np.ndarray,np.ndarray]: X and Y data of the curve.
|
144
151
|
"""
|
145
152
|
|
153
|
+
@property
|
154
|
+
@rpc_call
|
155
|
+
def dap_params(self):
|
156
|
+
"""
|
157
|
+
None
|
158
|
+
"""
|
159
|
+
|
146
160
|
|
147
161
|
class BECDock(RPCBase):
|
148
162
|
@property
|
@@ -457,6 +471,7 @@ class BECFigure(RPCBase):
|
|
457
471
|
row: "int" = None,
|
458
472
|
col: "int" = None,
|
459
473
|
config=None,
|
474
|
+
dap: "str | None" = None,
|
460
475
|
**axis_kwargs,
|
461
476
|
) -> "BECWaveform":
|
462
477
|
"""
|
@@ -550,6 +565,7 @@ class BECFigure(RPCBase):
|
|
550
565
|
color_map_z: "str | None" = "plasma",
|
551
566
|
label: "str | None" = None,
|
552
567
|
validate: "bool" = True,
|
568
|
+
dap: "str | None" = None,
|
553
569
|
**axis_kwargs,
|
554
570
|
) -> "BECWaveform":
|
555
571
|
"""
|
@@ -568,6 +584,7 @@ class BECFigure(RPCBase):
|
|
568
584
|
color_map_z(str): The color map to use for the z-axis.
|
569
585
|
label(str): The label of the curve.
|
570
586
|
validate(bool): If True, validate the device names and entries.
|
587
|
+
dap(str): The DAP model to use for the curve.
|
571
588
|
**axis_kwargs: Additional axis properties to set on the widget after creation.
|
572
589
|
|
573
590
|
Returns:
|
@@ -1467,6 +1484,7 @@ class BECWaveform(RPCBase):
|
|
1467
1484
|
color_map_z: "str | None" = "plasma",
|
1468
1485
|
label: "str | None" = None,
|
1469
1486
|
validate: "bool" = True,
|
1487
|
+
dap: "str | None" = None,
|
1470
1488
|
) -> "BECCurve":
|
1471
1489
|
"""
|
1472
1490
|
Plot a curve to the plot widget.
|
@@ -1483,11 +1501,50 @@ class BECWaveform(RPCBase):
|
|
1483
1501
|
color_map_z(str): The color map to use for the z-axis.
|
1484
1502
|
label(str): The label of the curve.
|
1485
1503
|
validate(bool): If True, validate the device names and entries.
|
1504
|
+
dap(str): The dap model to use for the curve. If not specified, none will be added.
|
1505
|
+
|
1506
|
+
Returns:
|
1507
|
+
BECCurve: The curve object.
|
1508
|
+
"""
|
1509
|
+
|
1510
|
+
@rpc_call
|
1511
|
+
def add_dap(
|
1512
|
+
self,
|
1513
|
+
x_name: "str",
|
1514
|
+
y_name: "str",
|
1515
|
+
x_entry: "Optional[str]" = None,
|
1516
|
+
y_entry: "Optional[str]" = None,
|
1517
|
+
color: "Optional[str]" = None,
|
1518
|
+
dap: "str" = "GaussianModel",
|
1519
|
+
**kwargs,
|
1520
|
+
) -> "BECCurve":
|
1521
|
+
"""
|
1522
|
+
Add LMFIT dap model curve to the plot widget.
|
1523
|
+
|
1524
|
+
Args:
|
1525
|
+
x_name(str): Name of the x signal.
|
1526
|
+
x_entry(str): Entry of the x signal.
|
1527
|
+
y_name(str): Name of the y signal.
|
1528
|
+
y_entry(str): Entry of the y signal.
|
1529
|
+
color(str, optional): Color of the curve. Defaults to None.
|
1530
|
+
color_map_z(str): The color map to use for the z-axis.
|
1531
|
+
label(str, optional): Label of the curve. Defaults to None.
|
1532
|
+
dap(str): The dap model to use for the curve.
|
1533
|
+
**kwargs: Additional keyword arguments for the curve configuration.
|
1486
1534
|
|
1487
1535
|
Returns:
|
1488
1536
|
BECCurve: The curve object.
|
1489
1537
|
"""
|
1490
1538
|
|
1539
|
+
@rpc_call
|
1540
|
+
def get_dap_params(self) -> "dict":
|
1541
|
+
"""
|
1542
|
+
Get the DAP parameters of all DAP curves.
|
1543
|
+
|
1544
|
+
Returns:
|
1545
|
+
dict: DAP parameters of all DAP curves.
|
1546
|
+
"""
|
1547
|
+
|
1491
1548
|
@rpc_call
|
1492
1549
|
def remove_curve(self, *identifiers):
|
1493
1550
|
"""
|
@@ -14,21 +14,6 @@ from bec_widgets.widgets.dock.dock_area import BECDockArea
|
|
14
14
|
from bec_widgets.widgets.figure import BECFigure
|
15
15
|
from bec_widgets.widgets.jupyter_console.jupyter_console import BECJupyterConsole
|
16
16
|
|
17
|
-
# class JupyterConsoleWidget(RichJupyterWidget): # pragma: no cover:
|
18
|
-
# def __init__(self):
|
19
|
-
# super().__init__()
|
20
|
-
#
|
21
|
-
# self.kernel_manager = QtInProcessKernelManager()
|
22
|
-
# self.kernel_manager.start_kernel(show_banner=False)
|
23
|
-
# self.kernel_client = self.kernel_manager.client()
|
24
|
-
# self.kernel_client.start_channels()
|
25
|
-
#
|
26
|
-
# self.kernel_manager.kernel.shell.push({"np": np, "pg": pg})
|
27
|
-
#
|
28
|
-
# def shutdown_kernel(self):
|
29
|
-
# self.kernel_client.stop_channels()
|
30
|
-
# self.kernel_manager.shutdown_kernel()
|
31
|
-
|
32
17
|
|
33
18
|
class JupyterConsoleWindow(QWidget): # pragma: no cover:
|
34
19
|
"""A widget that contains a Jupyter console linked to BEC Widgets with full API access (contains Qt and pyqtgraph API)."""
|
@@ -61,6 +46,7 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
|
|
61
46
|
"fig0": self.fig0,
|
62
47
|
"fig1": self.fig1,
|
63
48
|
"fig2": self.fig2,
|
49
|
+
"plt": self.plt,
|
64
50
|
"bar": self.bar,
|
65
51
|
}
|
66
52
|
)
|
@@ -115,7 +101,8 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
|
|
115
101
|
|
116
102
|
self.d2 = self.dock.add_dock(name="dock_2", position="bottom")
|
117
103
|
self.fig2 = self.d2.add_widget("BECFigure", row=0, col=0)
|
118
|
-
self.fig2.plot(x_name="samx", y_name="
|
104
|
+
self.plt = self.fig2.plot(x_name="samx", y_name="bpm3a")
|
105
|
+
self.plt.plot(x_name="samx", y_name="bpm4i", dap="GaussianModel")
|
119
106
|
self.bar = self.d2.add_widget("RingProgressBar", row=0, col=1)
|
120
107
|
self.bar.set_diameter(200)
|
121
108
|
|
@@ -228,6 +228,7 @@ class BECConnector:
|
|
228
228
|
all_connections = self.rpc_register.list_all_connections()
|
229
229
|
if len(all_connections) == 0:
|
230
230
|
print("No more connections. Shutting down GUI BEC client.")
|
231
|
+
self.bec_dispatcher.disconnect_all()
|
231
232
|
self.client.shutdown()
|
232
233
|
|
233
234
|
# def closeEvent(self, event):
|
@@ -195,10 +195,11 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
|
|
195
195
|
z_entry: str = None,
|
196
196
|
x: list | np.ndarray = None,
|
197
197
|
y: list | np.ndarray = None,
|
198
|
-
color:
|
199
|
-
color_map_z:
|
200
|
-
label:
|
198
|
+
color: str | None = None,
|
199
|
+
color_map_z: str | None = "plasma",
|
200
|
+
label: str | None = None,
|
201
201
|
validate: bool = True,
|
202
|
+
dap: str | None = None,
|
202
203
|
):
|
203
204
|
"""
|
204
205
|
Configure the waveform based on the provided parameters.
|
@@ -217,6 +218,7 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
|
|
217
218
|
color_map_z (str): The color map to use for the z-axis.
|
218
219
|
label (str): The label of the curve.
|
219
220
|
validate (bool): If True, validate the device names and entries.
|
221
|
+
dap (str): The DAP model to use for the curve.
|
220
222
|
"""
|
221
223
|
if x is not None and y is None:
|
222
224
|
if isinstance(x, np.ndarray):
|
@@ -240,7 +242,7 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
|
|
240
242
|
return waveform
|
241
243
|
# User wants to add scan curve -> 1D Waveform
|
242
244
|
if x_name is not None and y_name is not None and z_name is None and x is None and y is None:
|
243
|
-
waveform.
|
245
|
+
waveform.plot(
|
244
246
|
x_name=x_name,
|
245
247
|
y_name=y_name,
|
246
248
|
x_entry=x_entry,
|
@@ -248,6 +250,7 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
|
|
248
250
|
validate=validate,
|
249
251
|
color=color,
|
250
252
|
label=label,
|
253
|
+
dap=dap,
|
251
254
|
)
|
252
255
|
# User wants to add scan curve -> 2D Waveform Scatter
|
253
256
|
if (
|
@@ -257,7 +260,7 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
|
|
257
260
|
and x is None
|
258
261
|
and y is None
|
259
262
|
):
|
260
|
-
waveform.
|
263
|
+
waveform.plot(
|
261
264
|
x_name=x_name,
|
262
265
|
y_name=y_name,
|
263
266
|
z_name=z_name,
|
@@ -268,6 +271,7 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
|
|
268
271
|
color_map_z=color_map_z,
|
269
272
|
label=label,
|
270
273
|
validate=validate,
|
274
|
+
dap=dap,
|
271
275
|
)
|
272
276
|
# User wants to add custom curve
|
273
277
|
elif x is not None and y is not None and x_name is None and y_name is None:
|
@@ -292,6 +296,7 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
|
|
292
296
|
row: int = None,
|
293
297
|
col: int = None,
|
294
298
|
config=None,
|
299
|
+
dap: str | None = None,
|
295
300
|
**axis_kwargs,
|
296
301
|
) -> BECWaveform:
|
297
302
|
"""
|
@@ -339,6 +344,7 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
|
|
339
344
|
color_map_z=color_map_z,
|
340
345
|
label=label,
|
341
346
|
validate=validate,
|
347
|
+
dap=dap,
|
342
348
|
)
|
343
349
|
return waveform
|
344
350
|
|
@@ -357,6 +363,7 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
|
|
357
363
|
color_map_z: str | None = "plasma",
|
358
364
|
label: str | None = None,
|
359
365
|
validate: bool = True,
|
366
|
+
dap: str | None = None,
|
360
367
|
**axis_kwargs,
|
361
368
|
) -> BECWaveform:
|
362
369
|
"""
|
@@ -375,6 +382,7 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
|
|
375
382
|
color_map_z(str): The color map to use for the z-axis.
|
376
383
|
label(str): The label of the curve.
|
377
384
|
validate(bool): If True, validate the device names and entries.
|
385
|
+
dap(str): The DAP model to use for the curve.
|
378
386
|
**axis_kwargs: Additional axis properties to set on the widget after creation.
|
379
387
|
|
380
388
|
Returns:
|
@@ -403,6 +411,7 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
|
|
403
411
|
color_map_z=color_map_z,
|
404
412
|
label=label,
|
405
413
|
validate=validate,
|
414
|
+
dap=dap,
|
406
415
|
)
|
407
416
|
# TODO remove repetition from .plot method
|
408
417
|
return waveform
|
@@ -1,10 +1,12 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
import time
|
3
4
|
from collections import defaultdict
|
4
5
|
from typing import Any, Literal, Optional
|
5
6
|
|
6
7
|
import numpy as np
|
7
8
|
import pyqtgraph as pg
|
9
|
+
from bec_lib import messages
|
8
10
|
from bec_lib.endpoints import MessageEndpoints
|
9
11
|
from bec_lib.scan_data import ScanData
|
10
12
|
from pydantic import Field, ValidationError
|
@@ -36,6 +38,8 @@ class BECWaveform(BECPlotBase):
|
|
36
38
|
"rpc_id",
|
37
39
|
"config_dict",
|
38
40
|
"plot",
|
41
|
+
"add_dap",
|
42
|
+
"get_dap_params",
|
39
43
|
"remove_curve",
|
40
44
|
"scan_history",
|
41
45
|
"curves",
|
@@ -57,6 +61,7 @@ class BECWaveform(BECPlotBase):
|
|
57
61
|
"set_legend_label_size",
|
58
62
|
]
|
59
63
|
scan_signal_update = pyqtSignal()
|
64
|
+
dap_params_update = pyqtSignal(dict)
|
60
65
|
|
61
66
|
def __init__(
|
62
67
|
self,
|
@@ -73,6 +78,7 @@ class BECWaveform(BECPlotBase):
|
|
73
78
|
)
|
74
79
|
|
75
80
|
self._curves_data = defaultdict(dict)
|
81
|
+
self.old_scan_id = None
|
76
82
|
self.scan_id = None
|
77
83
|
|
78
84
|
# Scan segment update proxy
|
@@ -80,6 +86,9 @@ class BECWaveform(BECPlotBase):
|
|
80
86
|
self.scan_signal_update, rateLimit=25, slot=self._update_scan_segment_plot
|
81
87
|
)
|
82
88
|
|
89
|
+
self.proxy_update_dap = pg.SignalProxy(
|
90
|
+
self.scan_signal_update, rateLimit=25, slot=self.refresh_dap
|
91
|
+
)
|
83
92
|
# Get bec shortcuts dev, scans, queue, scan_storage, dap
|
84
93
|
self.get_bec_shortcuts()
|
85
94
|
|
@@ -213,6 +222,7 @@ class BECWaveform(BECPlotBase):
|
|
213
222
|
color_map_z: str | None = "plasma",
|
214
223
|
label: str | None = None,
|
215
224
|
validate: bool = True,
|
225
|
+
dap: str | None = None, # TODO add dap custom curve wrapper
|
216
226
|
) -> BECCurve:
|
217
227
|
"""
|
218
228
|
Plot a curve to the plot widget.
|
@@ -229,6 +239,7 @@ class BECWaveform(BECPlotBase):
|
|
229
239
|
color_map_z(str): The color map to use for the z-axis.
|
230
240
|
label(str): The label of the curve.
|
231
241
|
validate(bool): If True, validate the device names and entries.
|
242
|
+
dap(str): The dap model to use for the curve. If not specified, none will be added.
|
232
243
|
|
233
244
|
Returns:
|
234
245
|
BECCurve: The curve object.
|
@@ -237,6 +248,8 @@ class BECWaveform(BECPlotBase):
|
|
237
248
|
if x is not None and y is not None:
|
238
249
|
return self.add_curve_custom(x=x, y=y, label=label, color=color)
|
239
250
|
else:
|
251
|
+
if dap:
|
252
|
+
self.add_dap(x_name=x_name, y_name=y_name, dap=dap)
|
240
253
|
return self.add_curve_scan(
|
241
254
|
x_name=x_name,
|
242
255
|
y_name=y_name,
|
@@ -256,6 +269,7 @@ class BECWaveform(BECPlotBase):
|
|
256
269
|
y: list | np.ndarray,
|
257
270
|
label: str = None,
|
258
271
|
color: str = None,
|
272
|
+
curve_source: str = "custom",
|
259
273
|
**kwargs,
|
260
274
|
) -> BECCurve:
|
261
275
|
"""
|
@@ -266,12 +280,13 @@ class BECWaveform(BECPlotBase):
|
|
266
280
|
y(list|np.ndarray): Y data of the curve.
|
267
281
|
label(str, optional): Label of the curve. Defaults to None.
|
268
282
|
color(str, optional): Color of the curve. Defaults to None.
|
283
|
+
curve_source(str, optional): Tag for source of the curve. Defaults to "custom".
|
269
284
|
**kwargs: Additional keyword arguments for the curve configuration.
|
270
285
|
|
271
286
|
Returns:
|
272
287
|
BECCurve: The curve object.
|
273
288
|
"""
|
274
|
-
curve_source =
|
289
|
+
curve_source = curve_source
|
275
290
|
curve_id = label or f"Curve {len(self.plot_item.curves) + 1}"
|
276
291
|
|
277
292
|
curve_exits = self._check_curve_id(curve_id, self._curves_data)
|
@@ -314,10 +329,12 @@ class BECWaveform(BECPlotBase):
|
|
314
329
|
color_map_z: Optional[str] = "plasma",
|
315
330
|
label: Optional[str] = None,
|
316
331
|
validate_bec: bool = True,
|
332
|
+
source: str = "scan_segment",
|
333
|
+
dap: Optional[str] = None,
|
317
334
|
**kwargs,
|
318
335
|
) -> BECCurve:
|
319
336
|
"""
|
320
|
-
Add a curve to the plot widget from the scan segment.
|
337
|
+
Add a curve to the plot widget from the scan segment. #TODO adapt docs to DAP
|
321
338
|
|
322
339
|
Args:
|
323
340
|
x_name(str): Name of the x signal.
|
@@ -335,7 +352,7 @@ class BECWaveform(BECPlotBase):
|
|
335
352
|
BECCurve: The curve object.
|
336
353
|
"""
|
337
354
|
# Check if curve already exists
|
338
|
-
curve_source =
|
355
|
+
curve_source = source
|
339
356
|
|
340
357
|
# Get entry if not provided and validate
|
341
358
|
x_entry, y_entry, z_entry = self._validate_signal_entries(
|
@@ -371,12 +388,74 @@ class BECWaveform(BECPlotBase):
|
|
371
388
|
x=SignalData(name=x_name, entry=x_entry),
|
372
389
|
y=SignalData(name=y_name, entry=y_entry),
|
373
390
|
z=SignalData(name=z_name, entry=z_entry) if z_name else None,
|
391
|
+
dap=dap,
|
374
392
|
),
|
375
393
|
**kwargs,
|
376
394
|
)
|
377
395
|
curve = self._add_curve_object(name=label, source=curve_source, config=curve_config)
|
378
396
|
return curve
|
379
397
|
|
398
|
+
def add_dap(
|
399
|
+
self,
|
400
|
+
x_name: str,
|
401
|
+
y_name: str,
|
402
|
+
x_entry: Optional[str] = None,
|
403
|
+
y_entry: Optional[str] = None,
|
404
|
+
color: Optional[str] = None,
|
405
|
+
dap: str = "GaussianModel",
|
406
|
+
**kwargs,
|
407
|
+
) -> BECCurve:
|
408
|
+
"""
|
409
|
+
Add LMFIT dap model curve to the plot widget.
|
410
|
+
|
411
|
+
Args:
|
412
|
+
x_name(str): Name of the x signal.
|
413
|
+
x_entry(str): Entry of the x signal.
|
414
|
+
y_name(str): Name of the y signal.
|
415
|
+
y_entry(str): Entry of the y signal.
|
416
|
+
color(str, optional): Color of the curve. Defaults to None.
|
417
|
+
color_map_z(str): The color map to use for the z-axis.
|
418
|
+
label(str, optional): Label of the curve. Defaults to None.
|
419
|
+
dap(str): The dap model to use for the curve.
|
420
|
+
**kwargs: Additional keyword arguments for the curve configuration.
|
421
|
+
|
422
|
+
Returns:
|
423
|
+
BECCurve: The curve object.
|
424
|
+
"""
|
425
|
+
x_entry, y_entry, _ = self._validate_signal_entries(
|
426
|
+
x_name, y_name, None, x_entry, y_entry, None
|
427
|
+
)
|
428
|
+
label = f"{y_name}-{y_entry}-{dap}"
|
429
|
+
curve = self.add_curve_scan(
|
430
|
+
x_name=x_name,
|
431
|
+
y_name=y_name,
|
432
|
+
x_entry=x_entry,
|
433
|
+
y_entry=y_entry,
|
434
|
+
color=color,
|
435
|
+
label=label,
|
436
|
+
source="DAP",
|
437
|
+
dap=dap,
|
438
|
+
pen_style="dash",
|
439
|
+
symbol="star",
|
440
|
+
**kwargs,
|
441
|
+
)
|
442
|
+
|
443
|
+
self.setup_dap(self.old_scan_id, self.scan_id)
|
444
|
+
self.refresh_dap()
|
445
|
+
return curve
|
446
|
+
|
447
|
+
def get_dap_params(self) -> dict:
|
448
|
+
"""
|
449
|
+
Get the DAP parameters of all DAP curves.
|
450
|
+
|
451
|
+
Returns:
|
452
|
+
dict: DAP parameters of all DAP curves.
|
453
|
+
"""
|
454
|
+
params = {}
|
455
|
+
for curve_id, curve in self._curves_data["DAP"].items():
|
456
|
+
params[curve_id] = curve.dap_params
|
457
|
+
return params
|
458
|
+
|
380
459
|
def _add_curve_object(
|
381
460
|
self,
|
382
461
|
name: str,
|
@@ -528,13 +607,75 @@ class BECWaveform(BECPlotBase):
|
|
528
607
|
return
|
529
608
|
|
530
609
|
if current_scan_id != self.scan_id:
|
610
|
+
self.old_scan_id = self.scan_id
|
531
611
|
self.scan_id = current_scan_id
|
532
612
|
self.scan_segment_data = self.queue.scan_storage.find_scan_by_ID(
|
533
613
|
self.scan_id
|
534
614
|
) # TODO do scan access through BECFigure
|
615
|
+
self.setup_dap(self.old_scan_id, self.scan_id)
|
535
616
|
|
536
617
|
self.scan_signal_update.emit()
|
537
618
|
|
619
|
+
def setup_dap(self, old_scan_id, new_scan_id):
|
620
|
+
"""
|
621
|
+
Setup DAP for the new scan.
|
622
|
+
|
623
|
+
Args:
|
624
|
+
old_scan_id(str): old_scan_id, used to disconnect the previous dispatcher connection.
|
625
|
+
new_scan_id(str): new_scan_id, used to connect the new dispatcher connection.
|
626
|
+
|
627
|
+
"""
|
628
|
+
self.bec_dispatcher.disconnect_slot(
|
629
|
+
self.update_dap, MessageEndpoints.dap_response(old_scan_id)
|
630
|
+
)
|
631
|
+
if len(self._curves_data["DAP"]) > 0:
|
632
|
+
self.bec_dispatcher.connect_slot(
|
633
|
+
self.update_dap, MessageEndpoints.dap_response(new_scan_id)
|
634
|
+
)
|
635
|
+
|
636
|
+
def refresh_dap(self):
|
637
|
+
"""
|
638
|
+
Refresh the DAP curves with the latest data from the DAP model MessageEndpoints.dap_response().
|
639
|
+
"""
|
640
|
+
for curve_id, curve in self._curves_data["DAP"].items():
|
641
|
+
x_name = curve.config.signals.x.name
|
642
|
+
y_name = curve.config.signals.y.name
|
643
|
+
x_entry = curve.config.signals.x.entry
|
644
|
+
y_entry = curve.config.signals.y.entry
|
645
|
+
model_name = curve.config.signals.dap
|
646
|
+
model = getattr(self.dap, model_name)
|
647
|
+
|
648
|
+
msg = messages.DAPRequestMessage(
|
649
|
+
dap_cls="LmfitService1D",
|
650
|
+
dap_type="on_demand",
|
651
|
+
config={
|
652
|
+
"args": [self.scan_id, x_name, x_entry, y_name, y_entry],
|
653
|
+
"kwargs": {},
|
654
|
+
"class_args": model._plugin_info["class_args"],
|
655
|
+
"class_kwargs": model._plugin_info["class_kwargs"],
|
656
|
+
},
|
657
|
+
metadata={"RID": self.scan_id},
|
658
|
+
)
|
659
|
+
self.client.connector.set_and_publish(MessageEndpoints.dap_request(), msg)
|
660
|
+
|
661
|
+
@pyqtSlot(dict, dict)
|
662
|
+
def update_dap(self, msg, metadata):
|
663
|
+
self.msg = msg
|
664
|
+
scan_id, x_name, x_entry, y_name, y_entry = msg["dap_request"].content["config"]["args"]
|
665
|
+
model = msg["dap_request"].content["config"]["class_kwargs"]["model"]
|
666
|
+
|
667
|
+
curve_id_request = f"{y_name}-{y_entry}-{model}"
|
668
|
+
|
669
|
+
for curve_id, curve in self._curves_data["DAP"].items():
|
670
|
+
if curve_id == curve_id_request:
|
671
|
+
if msg["data"] is not None:
|
672
|
+
x = msg["data"][0]["x"]
|
673
|
+
y = msg["data"][0]["y"]
|
674
|
+
curve.setData(x, y)
|
675
|
+
curve.dap_params = msg["data"][1]["fit_parameters"]
|
676
|
+
self.dap_params_update.emit(curve.dap_params)
|
677
|
+
break
|
678
|
+
|
538
679
|
def _update_scan_segment_plot(self):
|
539
680
|
"""Update the plot with the data from the scan segment."""
|
540
681
|
data = self.scan_segment_data.data
|
@@ -609,13 +750,17 @@ class BECWaveform(BECPlotBase):
|
|
609
750
|
if scan_index is not None and scan_id is not None:
|
610
751
|
raise ValueError("Only one of scan_id or scan_index can be provided.")
|
611
752
|
|
753
|
+
# Reset DAP connector
|
754
|
+
self.bec_dispatcher.disconnect_slot(
|
755
|
+
self.update_dap, MessageEndpoints.dap_response(self.scan_id)
|
756
|
+
)
|
612
757
|
if scan_index is not None:
|
613
758
|
self.scan_id = self.queue.scan_storage.storage[scan_index].scan_id
|
614
|
-
data = self.queue.scan_storage.find_scan_by_ID(self.scan_id).data
|
615
759
|
elif scan_id is not None:
|
616
760
|
self.scan_id = scan_id
|
617
|
-
data = self.queue.scan_storage.find_scan_by_ID(self.scan_id).data
|
618
761
|
|
762
|
+
self.setup_dap(self.old_scan_id, self.scan_id)
|
763
|
+
data = self.queue.scan_storage.find_scan_by_ID(self.scan_id).data
|
619
764
|
self._update_scan_curves(data)
|
620
765
|
|
621
766
|
def get_all_data(self, output: Literal["dict", "pandas"] = "dict") -> dict | pd.DataFrame:
|
@@ -661,6 +806,9 @@ class BECWaveform(BECPlotBase):
|
|
661
806
|
def cleanup(self):
|
662
807
|
"""Cleanup the widget connection from BECDispatcher."""
|
663
808
|
self.bec_dispatcher.disconnect_slot(self.on_scan_segment, MessageEndpoints.scan_segment())
|
809
|
+
self.bec_dispatcher.disconnect_slot(
|
810
|
+
self.update_dap, MessageEndpoints.dap_response(self.scan_id)
|
811
|
+
)
|
664
812
|
for curve in self.curves:
|
665
813
|
curve.cleanup()
|
666
814
|
super().cleanup()
|
@@ -31,6 +31,7 @@ class Signal(BaseModel):
|
|
31
31
|
x: SignalData # TODO maybe add metadata for config gui later
|
32
32
|
y: SignalData
|
33
33
|
z: Optional[SignalData] = None
|
34
|
+
dap: Optional[str] = None
|
34
35
|
model_config: dict = {"validate_assignment": True}
|
35
36
|
|
36
37
|
|
@@ -63,6 +64,7 @@ class CurveConfig(ConnectionConfig):
|
|
63
64
|
class BECCurve(BECConnector, pg.PlotDataItem):
|
64
65
|
USER_ACCESS = [
|
65
66
|
"remove",
|
67
|
+
"dap_params",
|
66
68
|
"rpc_id",
|
67
69
|
"config_dict",
|
68
70
|
"set",
|
@@ -75,6 +77,7 @@ class BECCurve(BECConnector, pg.PlotDataItem):
|
|
75
77
|
"set_pen_width",
|
76
78
|
"set_pen_style",
|
77
79
|
"get_data",
|
80
|
+
"dap_params",
|
78
81
|
]
|
79
82
|
|
80
83
|
def __init__(
|
@@ -96,6 +99,7 @@ class BECCurve(BECConnector, pg.PlotDataItem):
|
|
96
99
|
|
97
100
|
self.parent_item = parent_item
|
98
101
|
self.apply_config()
|
102
|
+
self.dap_params = None
|
99
103
|
if kwargs:
|
100
104
|
self.set(**kwargs)
|
101
105
|
|
@@ -119,6 +123,14 @@ class BECCurve(BECConnector, pg.PlotDataItem):
|
|
119
123
|
self.setSymbolSize(self.config.symbol_size)
|
120
124
|
self.setSymbol(self.config.symbol)
|
121
125
|
|
126
|
+
@property
|
127
|
+
def dap_params(self):
|
128
|
+
return self._dap_params
|
129
|
+
|
130
|
+
@dap_params.setter
|
131
|
+
def dap_params(self, value):
|
132
|
+
self._dap_params = value
|
133
|
+
|
122
134
|
def set_data(self, x, y):
|
123
135
|
if self.config.source == "custom":
|
124
136
|
self.setData(x, y)
|
@@ -241,5 +253,6 @@ class BECCurve(BECConnector, pg.PlotDataItem):
|
|
241
253
|
|
242
254
|
def remove(self):
|
243
255
|
"""Remove the curve from the plot."""
|
244
|
-
self.parent_item.removeItem(self)
|
256
|
+
# self.parent_item.removeItem(self)
|
257
|
+
self.parent_item.remove_curve(self.name())
|
245
258
|
self.cleanup()
|
@@ -2,11 +2,11 @@
|
|
2
2
|
.gitlab-ci.yml,sha256=RnYDz4zKXjlqltTryprlB1s5vLXxI2-seW-Vb70NNF0,8162
|
3
3
|
.pylintrc,sha256=OstrgmEyP0smNFBKoIN5_26-UmNZgMHnbjvAWX0UrLs,18535
|
4
4
|
.readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
|
5
|
-
CHANGELOG.md,sha256=
|
5
|
+
CHANGELOG.md,sha256=3OR7elUbZdoiPcldtqGY44VNZH4TSuz0svsMYCGuLUA,6941
|
6
6
|
LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
|
7
|
-
PKG-INFO,sha256=
|
7
|
+
PKG-INFO,sha256=plkqu38RzQ_wzukLGmT6Em8xZ2dnAFx-2GQHqzkfiBQ,1302
|
8
8
|
README.md,sha256=y4jB6wvArS7N8_iTbKWnSM_oRAqLA2GqgzUR-FMh5sU,2645
|
9
|
-
pyproject.toml,sha256=
|
9
|
+
pyproject.toml,sha256=g7vJWYDj3s2pBA-9wQjQnACLoeiCC8Vv-GMnNT5t2H0,2215
|
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
|
@@ -17,7 +17,7 @@ bec_widgets/assets/bec_widgets_icon.png,sha256=K8dgGwIjalDh9PRHUsSQBqgdX7a00nM3i
|
|
17
17
|
bec_widgets/assets/terminal_icon.png,sha256=bJl7Tft4Fi2uxvuXI8o14uMHnI9eAWKSU2uftXCH9ws,3889
|
18
18
|
bec_widgets/cli/__init__.py,sha256=d0Q6Fn44e7wFfLabDOBxpcJ1DPKWlFunGYDUBmO-4hA,22
|
19
19
|
bec_widgets/cli/auto_updates.py,sha256=DyBV3HnjMSH-cvVkYNcDiYKVf0Xut4Qy2qGQqkW47Bw,4833
|
20
|
-
bec_widgets/cli/client.py,sha256=
|
20
|
+
bec_widgets/cli/client.py,sha256=dXno8pOJ3sP6fAA_nEkAyX2XfJ75GUDVqAkHcYYxCjU,60979
|
21
21
|
bec_widgets/cli/client_utils.py,sha256=zq1gPW7t4n9Nsn4MLkdUeKwwl-9nUcf5UjuN8lZr9iY,12281
|
22
22
|
bec_widgets/cli/generate_cli.py,sha256=InKBVYM7DRfAVLNJhRJbWWSSPBQBHI8Ek6v7NCsK0ME,4997
|
23
23
|
bec_widgets/cli/rpc_register.py,sha256=QxXUZu5XNg00Yf5O3UHWOXg3-f_pzKjjoZYMOa-MOJc,2216
|
@@ -25,7 +25,7 @@ bec_widgets/cli/rpc_wigdet_handler.py,sha256=1qQOGrM8rozaWLkoxAW8DTVLv_L_DZdZgUM
|
|
25
25
|
bec_widgets/cli/server.py,sha256=2EJvkQDzrDTsZjRPs7g2v_iPTspGqxzY34tRAnvjxjY,7281
|
26
26
|
bec_widgets/examples/__init__.py,sha256=WWQ0cu7m8sA4Ehy-DWdTIqSISjaHsbxhsNmNrMnhDZU,202
|
27
27
|
bec_widgets/examples/jupyter_console/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
28
|
-
bec_widgets/examples/jupyter_console/jupyter_console_window.py,sha256=
|
28
|
+
bec_widgets/examples/jupyter_console/jupyter_console_window.py,sha256=tyvV9ZW5QHgF7Q2AqaUPO0cdz3eldZnIlVCqwd9CkGA,4910
|
29
29
|
bec_widgets/examples/jupyter_console/jupyter_console_window.ui,sha256=2A2mNTUMZBYygz8K4qWzrcjnNqZBMVyeHm26iLZVRWI,1473
|
30
30
|
bec_widgets/examples/motor_movement/__init__.py,sha256=LzPJkxLAxOsZCbXR-fRCPmeYobp7Yqds6tDxW4W1gSw,214
|
31
31
|
bec_widgets/examples/motor_movement/motor_control_compilations.py,sha256=8rpA7a2xVZTDMrx7YQIj3IJew78J1gcVMkHvloS0U_Q,9055
|
@@ -38,7 +38,7 @@ bec_widgets/examples/plugin_example_pyside/tictactoe.py,sha256=s3rCurXloVcmMdzZi
|
|
38
38
|
bec_widgets/examples/plugin_example_pyside/tictactoeplugin.py,sha256=BBt3MD8oDLUMCCY3mioJa1QRR0WQdW6DuvVmK1Taovk,1734
|
39
39
|
bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py,sha256=LNwplI6deUdKY6FOhUuWBanotxk9asF2G-6k7lFfA8Y,2301
|
40
40
|
bec_widgets/utils/__init__.py,sha256=1930ji1Jj6dVuY81Wd2kYBhHYNV-2R0bN_L4o9zBj1U,533
|
41
|
-
bec_widgets/utils/bec_connector.py,sha256=
|
41
|
+
bec_widgets/utils/bec_connector.py,sha256=t59482Tu30eiQ2YNHJZFEE-wQFt4qf85OmBfPkl-3N4,7335
|
42
42
|
bec_widgets/utils/bec_designer.py,sha256=2ay6c7dLozV06vsJcceoMRe78ePxQf_7pxnrEZjOrB8,4386
|
43
43
|
bec_widgets/utils/bec_dispatcher.py,sha256=yM9PG04O7ABhiA9Nzk38Rv9Qbjc5O93wi2xfSbOlOxc,6202
|
44
44
|
bec_widgets/utils/bec_table.py,sha256=nA2b8ukSeUfquFMAxGrUVOqdrzMoDYD6O_4EYbOG2zk,717
|
@@ -79,7 +79,7 @@ bec_widgets/widgets/dock/__init__.py,sha256=B7foHt02gnhM7mFksa7GJVwT7n0j_JvYDCt6
|
|
79
79
|
bec_widgets/widgets/dock/dock.py,sha256=lEl6ppy0v-8X5bVX7EQIYka8rAakjkZyh6ufgr7YxKs,7595
|
80
80
|
bec_widgets/widgets/dock/dock_area.py,sha256=9c_tLzyBRllLfc4H5o9-4bvasWp5hWe1NWg4mupXVtU,7911
|
81
81
|
bec_widgets/widgets/figure/__init__.py,sha256=3hGx_KOV7QHCYAV06aNuUgKq4QIYCjUTad-DrwkUaBM,44
|
82
|
-
bec_widgets/widgets/figure/figure.py,sha256=
|
82
|
+
bec_widgets/widgets/figure/figure.py,sha256=3lmx93RLrXfLp07NYcUujD-O79ATmVQUzkEyowJPOzQ,32097
|
83
83
|
bec_widgets/widgets/figure/plots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
84
84
|
bec_widgets/widgets/figure/plots/plot_base.py,sha256=QdDMMuWwTK0f6kNN8aAPBM7jah7TpUbYrMrRTdb2EZY,10419
|
85
85
|
bec_widgets/widgets/figure/plots/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -89,8 +89,8 @@ bec_widgets/widgets/figure/plots/image/image_processor.py,sha256=GeTtWjbldy6VejM
|
|
89
89
|
bec_widgets/widgets/figure/plots/motor_map/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
90
90
|
bec_widgets/widgets/figure/plots/motor_map/motor_map.py,sha256=Ff2WoNHxO_A3ggsbSd_AVUP1JeOWMuJs-0GLskxn-94,15267
|
91
91
|
bec_widgets/widgets/figure/plots/waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
92
|
-
bec_widgets/widgets/figure/plots/waveform/waveform.py,sha256=
|
93
|
-
bec_widgets/widgets/figure/plots/waveform/waveform_curve.py,sha256=
|
92
|
+
bec_widgets/widgets/figure/plots/waveform/waveform.py,sha256=j_Lb3ovxKzNKgssNTR9HJ-L4MP-SmesRcdyxIcbqnO0,29101
|
93
|
+
bec_widgets/widgets/figure/plots/waveform/waveform_curve.py,sha256=mSBzqQNpLhol1_2_9k7s2b-Y0ICGU242T39md0LxTSA,8291
|
94
94
|
bec_widgets/widgets/jupyter_console/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
95
95
|
bec_widgets/widgets/jupyter_console/jupyter_console.py,sha256=ioLYJL31RdBoAOGFSS8PVSnUhkWPWmLC3tiKp7CouO8,2251
|
96
96
|
bec_widgets/widgets/motor_control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -153,7 +153,8 @@ docs/user/getting_started/gui_complex_gui.gif,sha256=ovv9u371BGG5GqhzyBMl4mvqMHL
|
|
153
153
|
docs/user/getting_started/installation.md,sha256=5_fPbmUqLGtwOskFHTlytd4PJKrMcHqHShzM9ymM0oI,1149
|
154
154
|
docs/user/getting_started/quick_start.md,sha256=ABDRRB8DM8dFYdsWUfzQV0eaffRFAlcn2HIfw7yiUGs,9401
|
155
155
|
docs/user/widgets/BECFigure.png,sha256=8dQr4u0uk_y0VV-R1Jh9yTR3Vidd9HDEno_07R0swaE,1605920
|
156
|
-
docs/user/widgets/bec_figure.md,sha256=
|
156
|
+
docs/user/widgets/bec_figure.md,sha256=tNT-5QP3DekY_iC9jOMULzdxmUU8wMkkX5Ru9yq0Txo,6671
|
157
|
+
docs/user/widgets/bec_figure_dap.gif,sha256=8EBRKcB7828M7w429c7djTZG2AbfJ-Zsy1epPvyYoII,4058735
|
157
158
|
docs/user/widgets/bec_status_box.gif,sha256=kLxf40HbS6fjdUIQ2b9SiduBEXdBd4DDWGEnQDOFMcY,1259044
|
158
159
|
docs/user/widgets/bec_status_box.md,sha256=YJ7uHuaHRsvP7tkC65O7siJOzm1LRtsrvH1ikeOH9xo,1156
|
159
160
|
docs/user/widgets/buttons.md,sha256=Yci21PmxlRvfKcrvY7mVI7JkECPmE6j9WyWyH3j7Y2o,1221
|
@@ -171,8 +172,8 @@ docs/user/widgets/widgets.md,sha256=ZeRNmP7GUOu8kEoGu9XHsyF8Hb1foqZKEbwpgFP7ITk,
|
|
171
172
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
172
173
|
tests/end-2-end/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
173
174
|
tests/end-2-end/conftest.py,sha256=-BLnFE-NeCerf6xahGCkbZ4Ktactowi6RkBnboIzRvg,1767
|
174
|
-
tests/end-2-end/test_bec_dock_rpc_e2e.py,sha256=
|
175
|
-
tests/end-2-end/test_bec_figure_rpc_e2e.py,sha256=
|
175
|
+
tests/end-2-end/test_bec_dock_rpc_e2e.py,sha256=59nrcbEB0NK7ttXdOizN9kjUaqhMImVGaf4aciT4Jcs,9099
|
176
|
+
tests/end-2-end/test_bec_figure_rpc_e2e.py,sha256=rAVA7aLP7dhQNK_BQK9wD-1whhy-MIyeIgknY5xwSAU,5980
|
176
177
|
tests/end-2-end/test_rpc_register_e2e.py,sha256=3dfCnSvdcRO92pzHt9WlCTK0vzTKAvPtliEoEKrtuzQ,1604
|
177
178
|
tests/end-2-end/test_scan_control_e2e.py,sha256=u7oLgFyltkMW2apSZKDukMIXvYrbhHrU32p4mBdn8VE,2276
|
178
179
|
tests/unit_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -202,7 +203,7 @@ tests/unit_tests/test_scan_control_group_box.py,sha256=HNqjP10B_NonikspNwKz9upJU
|
|
202
203
|
tests/unit_tests/test_stop_button.py,sha256=2OH9dhs_-S5QovPPgU-5hJoViE1YKZa0gxisb4vOY28,712
|
203
204
|
tests/unit_tests/test_text_box_widget.py,sha256=cT0uEHt_6d-FwST0A_wE9sFW9E3F_nJbKhuBAeU4yHg,1862
|
204
205
|
tests/unit_tests/test_vscode_widget.py,sha256=NVB23ppLqIj-Opd8QnapqUJzDMz6mIZfm3wGPnFXyUE,2788
|
205
|
-
tests/unit_tests/test_waveform1d.py,sha256=
|
206
|
+
tests/unit_tests/test_waveform1d.py,sha256=bADYGc7COoDnYxaAM0fX6SUASOVirlZEOnXIOlyajNw,15993
|
206
207
|
tests/unit_tests/test_website_widget.py,sha256=fBADIJJBAHU4Ro7u95kdemFVNv196UOcuO9oLHuHt8A,761
|
207
208
|
tests/unit_tests/test_widget_io.py,sha256=FeL3ZYSBQnRt6jxj8VGYw1cmcicRQyHKleahw7XIyR0,3475
|
208
209
|
tests/unit_tests/test_yaml_dialog.py,sha256=HNrqferkdg02-9ieOhhI2mr2Qvt7GrYgXmQ061YCTbg,5794
|
@@ -211,8 +212,8 @@ tests/unit_tests/test_configs/config_device_no_entry.yaml,sha256=hdvue9KLc_kfNzG
|
|
211
212
|
tests/unit_tests/test_configs/config_scan.yaml,sha256=vo484BbWOjA_e-h6bTjSV9k7QaQHrlAvx-z8wtY-P4E,1915
|
212
213
|
tests/unit_tests/test_msgs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
213
214
|
tests/unit_tests/test_msgs/available_scans_message.py,sha256=m_z97hIrjHXXMa2Ex-UvsPmTxOYXfjxyJaGkIY6StTY,46532
|
214
|
-
bec_widgets-0.
|
215
|
-
bec_widgets-0.
|
216
|
-
bec_widgets-0.
|
217
|
-
bec_widgets-0.
|
218
|
-
bec_widgets-0.
|
215
|
+
bec_widgets-0.74.0.dist-info/METADATA,sha256=plkqu38RzQ_wzukLGmT6Em8xZ2dnAFx-2GQHqzkfiBQ,1302
|
216
|
+
bec_widgets-0.74.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
217
|
+
bec_widgets-0.74.0.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
|
218
|
+
bec_widgets-0.74.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
|
219
|
+
bec_widgets-0.74.0.dist-info/RECORD,,
|
docs/user/widgets/bec_figure.md
CHANGED
@@ -7,7 +7,6 @@ In the following, we describe 4 different type of widgets thaat are available in
|
|
7
7
|
|
8
8
|

|
9
9
|
|
10
|
-
(user.widgets.waveform_1d)=
|
11
10
|
## [1D Waveform Widget](/api_reference/_autosummary/bec_widgets.cli.client.BECWaveform)
|
12
11
|
|
13
12
|
**Purpose:** This widget provides a straightforward visualization of 1D data. It is particularly useful for plotting positioner movements against detector readings, enabling users to observe correlations and patterns in a simple, linear format.
|
@@ -20,11 +19,12 @@ In the following, we describe 4 different type of widgets thaat are available in
|
|
20
19
|
**Example of Use:**
|
21
20
|

|
22
21
|
|
23
|
-
**Code example**
|
22
|
+
**Code example 1 - adding curves**
|
23
|
+
|
24
24
|
The following code snipped demonstrates how to create a 1D waveform plot using BEC Widgets within BEC. More details about BEC Widgets in BEC can be found in the getting started section within the [introduction to the command line.](user.command_line_introduction)
|
25
25
|
```python
|
26
26
|
# adds a new dock, a new BECFigure and a BECWaveForm to the dock
|
27
|
-
plt = gui.add_dock().add_widget('BECFigure').plot('samx', 'bpm4i')
|
27
|
+
plt = gui.add_dock().add_widget('BECFigure').plot(x_name='samx', y_name='bpm4i')
|
28
28
|
# add a second curve to the same plot
|
29
29
|
plt.plot(x_name='samx', y_name='bpm3i')
|
30
30
|
plt.set_title("Gauss plots vs. samx")
|
@@ -39,6 +39,48 @@ dev.bpm4i.sim.select_sim_model("GaussianModel")
|
|
39
39
|
dev.bpm3i.sim.select_sim_model("StepModel")
|
40
40
|
```
|
41
41
|
|
42
|
+
**Code example 2 - Adding Data Processing Pipeline Curve with LMFit Models**
|
43
|
+
|
44
|
+
Together with the scan curve, one can also add a second curve that fits the signal using a specified model
|
45
|
+
from [LMFit](https://lmfit.github.io/lmfit-py/builtin_models.html). The following code snippet demonstrates how to
|
46
|
+
create a 1D waveform curve with an attached DAP process, or how to add a DAP process to an existing curve using the BEC
|
47
|
+
CLI. Please note that for this example, both devices were set as Gaussian signals.
|
48
|
+
|
49
|
+
```python
|
50
|
+
# Add a new dock, a new BECFigure, and a BECWaveForm to the dock with a GaussianModel DAP
|
51
|
+
plt = gui.add_dock().add_widget('BECFigure').plot(x_name='samx', y_name='bpm4i', dap="GaussianModel")
|
52
|
+
|
53
|
+
# Add a second curve to the same plot without DAP
|
54
|
+
plt.plot(x_name='samx', y_name='bpm3a')
|
55
|
+
|
56
|
+
# Add DAP to the second curve
|
57
|
+
plt.add_dap(x_name='samx', y_name='bpm3a', dap="GaussianModel")
|
58
|
+
|
59
|
+
```
|
60
|
+
|
61
|
+
To get the parameters of the fit, one has to retrieve the curve objects and call the dap_params property.
|
62
|
+
|
63
|
+
```python
|
64
|
+
# Get the curve object by name from the legend
|
65
|
+
dap_bpm4i = plt.get_curve("bpm4i-bpm4i-GaussianModel")
|
66
|
+
dap_bpm3a = plt.get_curve("bpm3a-bpm3a-GaussianModel")
|
67
|
+
|
68
|
+
# Get the parameters of the fit
|
69
|
+
print(dap_bpm4i.dap_params)
|
70
|
+
# Output
|
71
|
+
{'amplitude': 197.399639720862,
|
72
|
+
'center': 5.013486095404885,
|
73
|
+
'sigma': 0.9820868875739888}
|
74
|
+
|
75
|
+
print(dap_bpm3a.dap_params)
|
76
|
+
# Output
|
77
|
+
{'amplitude': 698.3072786185278,
|
78
|
+
'center': 0.9702840866173836,
|
79
|
+
'sigma': 1.97139754785518}
|
80
|
+
```
|
81
|
+
|
82
|
+

|
83
|
+
|
42
84
|
(user.widgets.scatter_2d)=
|
43
85
|
## [2D Scatter Plot](/api_reference/_autosummary/bec_widgets.cli.client.BECWaveform)
|
44
86
|
|
Binary file
|
pyproject.toml
CHANGED
@@ -53,6 +53,7 @@ def test_rpc_add_dock_with_figure_e2e(bec_client_lib, rpc_server_dock):
|
|
53
53
|
assert im.__class__ == BECImageShow
|
54
54
|
|
55
55
|
assert mm.config_dict["signals"] == {
|
56
|
+
"dap": None,
|
56
57
|
"source": "device_readback",
|
57
58
|
"x": {
|
58
59
|
"name": "samx",
|
@@ -71,6 +72,7 @@ def test_rpc_add_dock_with_figure_e2e(bec_client_lib, rpc_server_dock):
|
|
71
72
|
"z": None,
|
72
73
|
}
|
73
74
|
assert plt.config_dict["curves"]["bpm4i-bpm4i"]["signals"] == {
|
75
|
+
"dap": None,
|
74
76
|
"source": "scan_segment",
|
75
77
|
"x": {"name": "samx", "entry": "samx", "unit": None, "modifier": None, "limits": None},
|
76
78
|
"y": {"name": "bpm4i", "entry": "bpm4i", "unit": None, "modifier": None, "limits": None},
|
@@ -1,3 +1,5 @@
|
|
1
|
+
import time
|
2
|
+
|
1
3
|
import numpy as np
|
2
4
|
import pytest
|
3
5
|
from bec_lib.endpoints import MessageEndpoints
|
@@ -38,6 +40,7 @@ def test_rpc_plotting_shortcuts_init_configs(rpc_server_figure, qtbot):
|
|
38
40
|
# check if the correct devices are set
|
39
41
|
# plot
|
40
42
|
assert plt.config_dict["curves"]["bpm4i-bpm4i"]["signals"] == {
|
43
|
+
"dap": None,
|
41
44
|
"source": "scan_segment",
|
42
45
|
"x": {"name": "samx", "entry": "samx", "unit": None, "modifier": None, "limits": None},
|
43
46
|
"y": {"name": "bpm4i", "entry": "bpm4i", "unit": None, "modifier": None, "limits": None},
|
@@ -47,6 +50,7 @@ def test_rpc_plotting_shortcuts_init_configs(rpc_server_figure, qtbot):
|
|
47
50
|
assert im.config_dict["images"]["eiger"]["monitor"] == "eiger"
|
48
51
|
# motor map
|
49
52
|
assert motor_map.config_dict["signals"] == {
|
53
|
+
"dap": None,
|
50
54
|
"source": "device_readback",
|
51
55
|
"x": {
|
52
56
|
"name": "samx",
|
@@ -66,6 +70,7 @@ def test_rpc_plotting_shortcuts_init_configs(rpc_server_figure, qtbot):
|
|
66
70
|
}
|
67
71
|
# plot with z scatter
|
68
72
|
assert plt_z.config_dict["curves"]["bpm4i-bpm4i"]["signals"] == {
|
73
|
+
"dap": None,
|
69
74
|
"source": "scan_segment",
|
70
75
|
"x": {"name": "samx", "entry": "samx", "unit": None, "modifier": None, "limits": None},
|
71
76
|
"y": {"name": "samy", "entry": "samy", "unit": None, "modifier": None, "limits": None},
|
@@ -151,3 +156,32 @@ def test_rpc_motor_map(rpc_server_figure, bec_client_lib):
|
|
151
156
|
np.testing.assert_equal(
|
152
157
|
[motor_map_data["x"][-1], motor_map_data["y"][-1]], [final_pos_x, final_pos_y]
|
153
158
|
)
|
159
|
+
|
160
|
+
|
161
|
+
def test_dap_rpc(rpc_server_figure, bec_client_lib):
|
162
|
+
|
163
|
+
fig = BECFigure(rpc_server_figure)
|
164
|
+
plt = fig.plot(x_name="samx", y_name="bpm4i", dap="GaussianModel")
|
165
|
+
|
166
|
+
client = bec_client_lib
|
167
|
+
dev = client.device_manager.devices
|
168
|
+
scans = client.scans
|
169
|
+
|
170
|
+
dev.bpm4i.sim.sim_select_model("GaussianModel")
|
171
|
+
params = dev.bpm4i.sim.sim_params
|
172
|
+
params.update(
|
173
|
+
{"noise": "uniform", "noise_multiplier": 10, "center": 5, "sigma": 1, "amplitude": 200}
|
174
|
+
)
|
175
|
+
dev.bpm4i.sim.sim_params = params
|
176
|
+
time.sleep(1)
|
177
|
+
|
178
|
+
res = scans.line_scan(dev.samx, 0, 8, steps=50, relative=False)
|
179
|
+
res.wait()
|
180
|
+
|
181
|
+
time.sleep(2)
|
182
|
+
|
183
|
+
dap_curve = plt.get_curve("bpm4i-bpm4i-GaussianModel")
|
184
|
+
fit_params = dap_curve.dap_params
|
185
|
+
print(fit_params)
|
186
|
+
|
187
|
+
assert np.isclose(fit_params["center"], 5, atol=0.5)
|
@@ -85,6 +85,7 @@ def test_create_waveform1D_by_config(bec_figure):
|
|
85
85
|
"pen_style": "dash",
|
86
86
|
"source": "scan_segment",
|
87
87
|
"signals": {
|
88
|
+
"dap": None,
|
88
89
|
"source": "scan_segment",
|
89
90
|
"x": {
|
90
91
|
"name": "samx",
|
@@ -248,6 +249,7 @@ def test_change_curve_appearance_methods(bec_figure, qtbot):
|
|
248
249
|
assert c1.config.pen_style == "dashdot"
|
249
250
|
assert c1.config.source == "scan_segment"
|
250
251
|
assert c1.config.signals.model_dump() == {
|
252
|
+
"dap": None,
|
251
253
|
"source": "scan_segment",
|
252
254
|
"x": {"name": "samx", "entry": "samx", "unit": None, "modifier": None, "limits": None},
|
253
255
|
"y": {"name": "bpm4i", "entry": "bpm4i", "unit": None, "modifier": None, "limits": None},
|
@@ -277,6 +279,7 @@ def test_change_curve_appearance_args(bec_figure):
|
|
277
279
|
assert c1.config.pen_style == "dashdot"
|
278
280
|
assert c1.config.source == "scan_segment"
|
279
281
|
assert c1.config.signals.model_dump() == {
|
282
|
+
"dap": None,
|
280
283
|
"source": "scan_segment",
|
281
284
|
"x": {"name": "samx", "entry": "samx", "unit": None, "modifier": None, "limits": None},
|
282
285
|
"y": {"name": "bpm4i", "entry": "bpm4i", "unit": None, "modifier": None, "limits": None},
|
@@ -384,6 +387,7 @@ def test_curve_add_by_config(bec_figure):
|
|
384
387
|
"pen_style": "dash",
|
385
388
|
"source": "scan_segment",
|
386
389
|
"signals": {
|
390
|
+
"dap": None,
|
387
391
|
"source": "scan_segment",
|
388
392
|
"x": {"name": "samx", "entry": "samx", "unit": None, "modifier": None, "limits": None},
|
389
393
|
"y": {
|
File without changes
|
File without changes
|
File without changes
|