bec-widgets 0.44.4__py3-none-any.whl → 0.45.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.
Files changed (67) hide show
  1. bec_widgets/cli/client.py +105 -5
  2. bec_widgets/cli/client_utils.py +4 -4
  3. bec_widgets/cli/generate_cli.py +6 -4
  4. bec_widgets/cli/server.py +2 -3
  5. bec_widgets/examples/__init__.py +1 -1
  6. bec_widgets/examples/eiger_plot/eiger_plot.py +3 -11
  7. bec_widgets/examples/mca_readout/mca_plot.py +21 -24
  8. bec_widgets/examples/mca_readout/mca_sim.py +7 -12
  9. bec_widgets/examples/motor_movement/__init__.py +1 -1
  10. bec_widgets/examples/motor_movement/motor_control_compilations.py +3 -8
  11. bec_widgets/examples/motor_movement/motor_controller.ui +1 -1
  12. bec_widgets/examples/motor_movement/motor_example.py +13 -14
  13. bec_widgets/examples/stream_plot/stream_plot.py +5 -4
  14. bec_widgets/utils/__init__.py +5 -5
  15. bec_widgets/utils/bec_connector.py +1 -1
  16. bec_widgets/utils/bec_dispatcher.py +1 -2
  17. bec_widgets/utils/bec_table.py +1 -1
  18. bec_widgets/utils/crosshair.py +2 -1
  19. bec_widgets/utils/validator_delegate.py +1 -1
  20. bec_widgets/utils/widget_io.py +6 -6
  21. bec_widgets/utils/yaml_dialog.py +1 -0
  22. bec_widgets/validation/monitor_config_validator.py +6 -6
  23. bec_widgets/widgets/__init__.py +7 -8
  24. bec_widgets/widgets/editor/editor.py +6 -14
  25. bec_widgets/widgets/figure/__init__.py +1 -1
  26. bec_widgets/widgets/figure/figure.py +74 -4
  27. bec_widgets/widgets/monitor/__init__.py +0 -1
  28. bec_widgets/widgets/monitor/config_dialog.py +7 -8
  29. bec_widgets/widgets/monitor/monitor.py +16 -26
  30. bec_widgets/widgets/monitor_scatter_2D/monitor_scatter_2D.py +11 -19
  31. bec_widgets/widgets/motor_control/__init__.py +2 -2
  32. bec_widgets/widgets/motor_control/motor_control.py +11 -10
  33. bec_widgets/widgets/motor_map/motor_map.py +2 -3
  34. bec_widgets/widgets/plots/__init__.py +4 -3
  35. bec_widgets/widgets/plots/image.py +7 -6
  36. bec_widgets/widgets/plots/motor_map.py +423 -0
  37. bec_widgets/widgets/plots/plot_base.py +1 -2
  38. bec_widgets/widgets/plots/waveform1d.py +24 -23
  39. bec_widgets/widgets/scan_control/scan_control.py +12 -12
  40. bec_widgets/widgets/toolbar/toolbar.py +2 -4
  41. {bec_widgets-0.44.4.dist-info → bec_widgets-0.45.0.dist-info}/METADATA +2 -1
  42. bec_widgets-0.45.0.dist-info/RECORD +98 -0
  43. tests/client_mocks.py +76 -30
  44. tests/conftest.py +2 -1
  45. tests/test_bec_connector.py +2 -1
  46. tests/test_bec_dispatcher.py +3 -4
  47. tests/test_bec_figure.py +14 -2
  48. tests/test_bec_monitor.py +7 -76
  49. tests/test_bec_monitor_scatter2D.py +8 -32
  50. tests/test_bec_motor_map.py +125 -0
  51. tests/test_config_dialog.py +4 -66
  52. tests/test_editor.py +2 -4
  53. tests/test_eiger_plot.py +2 -0
  54. tests/test_generate_cli_client.py +4 -2
  55. tests/test_motor_control.py +25 -92
  56. tests/test_motor_map.py +10 -66
  57. tests/test_plot_base.py +1 -0
  58. tests/test_scan_control.py +1 -1
  59. tests/test_stream_plot.py +2 -2
  60. tests/test_validator_errors.py +5 -4
  61. tests/test_waveform1d.py +31 -12
  62. tests/test_widget_io.py +1 -8
  63. tests/test_yaml_dialog.py +2 -1
  64. bec_widgets-0.44.4.dist-info/RECORD +0 -96
  65. {bec_widgets-0.44.4.dist-info → bec_widgets-0.45.0.dist-info}/LICENSE +0 -0
  66. {bec_widgets-0.44.4.dist-info → bec_widgets-0.45.0.dist-info}/WHEEL +0 -0
  67. {bec_widgets-0.44.4.dist-info → bec_widgets-0.45.0.dist-info}/top_level.txt +0 -0
bec_widgets/cli/client.py CHANGED
@@ -1,8 +1,9 @@
1
1
  # This file was automatically generated by generate_cli.py
2
2
 
3
- from bec_widgets.cli.client_utils import rpc_call, RPCBase, BECFigureClientMixin
4
3
  from typing import Literal, Optional, overload
5
4
 
5
+ from bec_widgets.cli.client_utils import BECFigureClientMixin, RPCBase, rpc_call
6
+
6
7
 
7
8
  class BECPlotBase(RPCBase):
8
9
  @rpc_call
@@ -194,12 +195,12 @@ class BECWaveform1D(RPCBase):
194
195
  """
195
196
 
196
197
  @rpc_call
197
- def scan_history(self, scan_index: "int" = None, scanID: "str" = None):
198
+ def scan_history(self, scan_index: "int" = None, scan_id: "str" = None):
198
199
  """
199
200
  Update the scan curves with the data from the scan storage.
200
- Provide only one of scanID or scan_index.
201
+ Provide only one of scan_id or scan_index.
201
202
  Args:
202
- scanID(str, optional): ScanID of the scan to be updated. Defaults to None.
203
+ scan_id(str, optional): ScanID of the scan to be updated. Defaults to None.
203
204
  scan_index(int, optional): Index of the scan to be updated. Defaults to None.
204
205
  """
205
206
 
@@ -449,12 +450,35 @@ class BECFigure(RPCBase, BECFigureClientMixin):
449
450
  row(int): The row coordinate of the widget in the figure. If not provided, the next empty row will be used.
450
451
  col(int): The column coordinate of the widget in the figure. If not provided, the next empty column will be used.
451
452
  config(dict): Additional configuration for the widget.
452
- **axis_kwargs:
453
+ **axis_kwargs: Additional axis properties to set on the widget after creation.
453
454
 
454
455
  Returns:
455
456
  BECImageShow: The image widget.
456
457
  """
457
458
 
459
+ @rpc_call
460
+ def add_motor_map(
461
+ self,
462
+ motor_x: "str" = None,
463
+ motor_y: "str" = None,
464
+ row: "int" = None,
465
+ col: "int" = None,
466
+ config=None,
467
+ **axis_kwargs
468
+ ) -> "BECMotorMap":
469
+ """
470
+ Args:
471
+ motor_x(str): The name of the motor for the X axis.
472
+ motor_y(str): The name of the motor for the Y axis.
473
+ row(int): The row coordinate of the widget in the figure. If not provided, the next empty row will be used.
474
+ col(int): The column coordinate of the widget in the figure. If not provided, the next empty column will be used.
475
+ config(dict): Additional configuration for the widget.
476
+ **axis_kwargs:
477
+
478
+ Returns:
479
+ BECMotorMap: The motor map widget.
480
+ """
481
+
458
482
  @rpc_call
459
483
  def plot(
460
484
  self,
@@ -511,6 +535,21 @@ class BECFigure(RPCBase, BECFigureClientMixin):
511
535
  BECImageShow: The image widget.
512
536
  """
513
537
 
538
+ @rpc_call
539
+ def motor_map(
540
+ self, motor_x: "str" = None, motor_y: "str" = None, **axis_kwargs
541
+ ) -> "BECMotorMap":
542
+ """
543
+ Add a motor map to the figure. Always access the first motor map widget in the figure.
544
+ Args:
545
+ motor_x(str): The name of the motor for the X axis.
546
+ motor_y(str): The name of the motor for the Y axis.
547
+ **axis_kwargs: Additional axis properties to set on the widget after creation.
548
+
549
+ Returns:
550
+ BECMotorMap: The motor map widget.
551
+ """
552
+
514
553
  @rpc_call
515
554
  def remove(
516
555
  self,
@@ -1090,3 +1129,64 @@ class BECImageItem(RPCBase):
1090
1129
  Returns:
1091
1130
  dict: The configuration of the plot widget.
1092
1131
  """
1132
+
1133
+
1134
+ class BECMotorMap(RPCBase):
1135
+ @rpc_call
1136
+ def change_motors(
1137
+ self,
1138
+ motor_x: "str",
1139
+ motor_y: "str",
1140
+ motor_x_entry: "str" = None,
1141
+ motor_y_entry: "str" = None,
1142
+ validate_bec: "bool" = True,
1143
+ ) -> "None":
1144
+ """
1145
+ Change the active motors for the plot.
1146
+ Args:
1147
+ motor_x(str): Motor name for the X axis.
1148
+ motor_y(str): Motor name for the Y axis.
1149
+ motor_x_entry(str): Motor entry for the X axis.
1150
+ motor_y_entry(str): Motor entry for the Y axis.
1151
+ validate_bec(bool, optional): If True, validate the signal with BEC. Defaults to True.
1152
+ """
1153
+
1154
+ @rpc_call
1155
+ def set_max_points(self, max_points: "int") -> "None":
1156
+ """
1157
+ Set the maximum number of points to display.
1158
+ Args:
1159
+ max_points(int): Maximum number of points to display.
1160
+ """
1161
+
1162
+ @rpc_call
1163
+ def set_precision(self, precision: "int") -> "None":
1164
+ """
1165
+ Set the decimal precision of the motor position.
1166
+ Args:
1167
+ precision(int): Decimal precision of the motor position.
1168
+ """
1169
+
1170
+ @rpc_call
1171
+ def set_num_dim_points(self, num_dim_points: "int") -> "None":
1172
+ """
1173
+ Set the number of dim points for the motor map.
1174
+ Args:
1175
+ num_dim_points(int): Number of dim points.
1176
+ """
1177
+
1178
+ @rpc_call
1179
+ def set_background_value(self, background_value: "int") -> "None":
1180
+ """
1181
+ Set the background value of the motor map.
1182
+ Args:
1183
+ background_value(int): Background value of the motor map.
1184
+ """
1185
+
1186
+ @rpc_call
1187
+ def set_scatter_size(self, scatter_size: "int") -> "None":
1188
+ """
1189
+ Set the scatter size of the motor map plot.
1190
+ Args:
1191
+ scatter_size(int): Size of the scatter points.
1192
+ """
@@ -8,12 +8,12 @@ import uuid
8
8
  from functools import wraps
9
9
  from typing import TYPE_CHECKING
10
10
 
11
- from qtpy.QtCore import QCoreApplication
12
-
13
- import bec_widgets.cli.client as client
14
11
  from bec_lib import MessageEndpoints, messages
15
12
  from bec_lib.connector import MessageObject
16
13
  from bec_lib.device import DeviceBase
14
+ from qtpy.QtCore import QCoreApplication
15
+
16
+ import bec_widgets.cli.client as client
17
17
  from bec_widgets.utils.bec_dispatcher import BECDispatcher
18
18
 
19
19
  if TYPE_CHECKING:
@@ -59,7 +59,7 @@ def update_script(figure: BECFigure, msg):
59
59
  """
60
60
  info = msg.info
61
61
  status = msg.status
62
- scan_id = msg.scanID
62
+ scan_id = msg.scan_id
63
63
  scan_number = info.get("scan_number", 0)
64
64
  scan_name = info.get("scan_name", "Unknown")
65
65
  scan_report_devices = info.get("scan_report_devices", [])
@@ -1,9 +1,10 @@
1
1
  # pylint: disable=missing-module-docstring
2
2
  from __future__ import annotations
3
+
3
4
  import inspect
4
- import black
5
5
  import sys
6
6
 
7
+ import black
7
8
 
8
9
  if sys.version_info >= (3, 11):
9
10
  from typing import get_overloads
@@ -106,11 +107,11 @@ class {class_name}(RPCBase):"""
106
107
  if __name__ == "__main__": # pragma: no cover
107
108
  import os
108
109
 
110
+ from bec_widgets.utils import BECConnector
109
111
  from bec_widgets.widgets.figure import BECFigure
110
- from bec_widgets.widgets.plots import BECPlotBase, BECWaveform1D, BECImageShow
111
- from bec_widgets.widgets.plots.waveform1d import BECCurve
112
+ from bec_widgets.widgets.plots import BECImageShow, BECMotorMap, BECPlotBase, BECWaveform1D
112
113
  from bec_widgets.widgets.plots.image import BECImageItem
113
- from bec_widgets.utils import BECConnector
114
+ from bec_widgets.widgets.plots.waveform1d import BECCurve
114
115
 
115
116
  current_path = os.path.dirname(__file__)
116
117
  client_path = os.path.join(current_path, "client.py")
@@ -122,6 +123,7 @@ if __name__ == "__main__": # pragma: no cover
122
123
  BECImageShow,
123
124
  BECConnector,
124
125
  BECImageItem,
126
+ BECMotorMap,
125
127
  ]
126
128
  generator = ClientGenerator()
127
129
  generator.generate_client(clss)
bec_widgets/cli/server.py CHANGED
@@ -1,8 +1,8 @@
1
1
  import inspect
2
2
 
3
+ from bec_lib import MessageEndpoints, messages
3
4
  from qtpy.QtCore import QTimer
4
5
 
5
- from bec_lib import MessageEndpoints, messages
6
6
  from bec_widgets.utils import BECDispatcher
7
7
  from bec_widgets.utils.bec_connector import BECConnector
8
8
  from bec_widgets.widgets.figure import BECFigure
@@ -115,8 +115,7 @@ if __name__ == "__main__": # pragma: no cover
115
115
  import argparse
116
116
  import sys
117
117
 
118
- from qtpy.QtWidgets import QApplication
119
- from qtpy.QtWidgets import QMainWindow
118
+ from qtpy.QtWidgets import QApplication, QMainWindow
120
119
 
121
120
  app = QApplication(sys.argv)
122
121
  app.setApplicationName("BEC Figure")
@@ -2,8 +2,8 @@ from .motor_movement import (
2
2
  MotorControlApp,
3
3
  MotorControlMap,
4
4
  MotorControlPanel,
5
- MotorControlPanelRelative,
6
5
  MotorControlPanelAbsolute,
6
+ MotorControlPanelRelative,
7
7
  MotorCoordinateTable,
8
8
  MotorThread,
9
9
  )
@@ -6,20 +6,11 @@ import h5py
6
6
  import numpy as np
7
7
  import pyqtgraph as pg
8
8
  import zmq
9
+ from pyqtgraph.Qt import uic
9
10
  from qtpy.QtCore import Signal as pyqtSignal
10
11
  from qtpy.QtCore import Slot as pyqtSlot
11
12
  from qtpy.QtGui import QKeySequence
12
- from qtpy.QtWidgets import (
13
- QWidget,
14
- QFileDialog,
15
- QShortcut,
16
- QDialog,
17
- QVBoxLayout,
18
- QLabel,
19
- QFrame,
20
- )
21
- from pyqtgraph.Qt import uic
22
-
13
+ from qtpy.QtWidgets import QDialog, QFileDialog, QFrame, QLabel, QShortcut, QVBoxLayout, QWidget
23
14
 
24
15
  # from scipy.stats import multivariate_normal
25
16
 
@@ -307,6 +298,7 @@ class EigerPlot(QWidget):
307
298
 
308
299
  if __name__ == "__main__":
309
300
  import sys
301
+
310
302
  from qtpy.QtWidgets import QApplication
311
303
 
312
304
  app = QApplication(sys.argv)
@@ -1,19 +1,15 @@
1
1
  # import simulation_progress as SP
2
2
  import numpy as np
3
3
  import pyqtgraph as pg
4
- from qtpy.QtCore import Signal as pyqtSignal, Slot as pyqtSlot
5
- from qtpy.QtWidgets import (
6
- QApplication,
7
- QVBoxLayout,
8
- QWidget,
9
- )
10
-
11
4
  from bec_lib import MessageEndpoints, messages
5
+ from qtpy.QtCore import Signal as pyqtSignal
6
+ from qtpy.QtCore import Slot as pyqtSlot
7
+ from qtpy.QtWidgets import QApplication, QVBoxLayout, QWidget
12
8
 
13
9
 
14
10
  class StreamApp(QWidget):
15
11
  update_signal = pyqtSignal()
16
- new_scanID = pyqtSignal(str)
12
+ new_scan_id = pyqtSignal(str)
17
13
 
18
14
  def __init__(self, device, sub_device):
19
15
  super().__init__()
@@ -23,7 +19,7 @@ class StreamApp(QWidget):
23
19
  self.setWindowTitle("MCA readout")
24
20
 
25
21
  self.data = None
26
- self.scanID = None
22
+ self.scan_id = None
27
23
  self.stream_consumer = None
28
24
 
29
25
  self.device = device
@@ -33,7 +29,7 @@ class StreamApp(QWidget):
33
29
 
34
30
  # self.start_device_consumer(self.device) # for simulation
35
31
 
36
- self.new_scanID.connect(self.create_new_stream_consumer)
32
+ self.new_scan_id.connect(self.create_new_stream_consumer)
37
33
  self.update_signal.connect(self.plot_new)
38
34
 
39
35
  def init_ui(self):
@@ -64,17 +60,17 @@ class StreamApp(QWidget):
64
60
  # self.glw.addItem(self.hist)
65
61
 
66
62
  @pyqtSlot(str)
67
- def create_new_stream_consumer(self, scanID: str):
68
- print(f"Creating new stream consumer for scanID: {scanID}")
63
+ def create_new_stream_consumer(self, scan_id: str):
64
+ print(f"Creating new stream consumer for scan_id: {scan_id}")
69
65
 
70
- self.connect_stream_consumer(scanID, self.device)
66
+ self.connect_stream_consumer(scan_id, self.device)
71
67
 
72
- def connect_stream_consumer(self, scanID, device):
68
+ def connect_stream_consumer(self, scan_id, device):
73
69
  if self.stream_consumer is not None:
74
70
  self.stream_consumer.shutdown()
75
71
 
76
72
  self.stream_consumer = connector.stream_consumer(
77
- topics=MessageEndpoints.device_async_readback(scanID=scanID, device=device),
73
+ topics=MessageEndpoints.device_async_readback(scan_id=scan_id, device=device),
78
74
  cb=self._streamer_cb,
79
75
  parent=self,
80
76
  )
@@ -125,24 +121,25 @@ class StreamApp(QWidget):
125
121
 
126
122
  msgDEV = msg.value
127
123
 
128
- current_scanID = msgDEV.content["scanID"]
124
+ current_scan_id = msgDEV.content["scan_id"]
129
125
 
130
- if parent.scanID is None:
131
- parent.scanID = current_scanID
132
- parent.new_scanID.emit(current_scanID)
133
- print(f"New scanID: {current_scanID}")
126
+ if parent.scan_id is None:
127
+ parent.scan_id = current_scan_id
128
+ parent.new_scan_id.emit(current_scan_id)
129
+ print(f"New scan_id: {current_scan_id}")
134
130
 
135
- if current_scanID != parent.scanID:
136
- parent.scanID = current_scanID
131
+ if current_scan_id != parent.scan_id:
132
+ parent.scan_id = current_scan_id
137
133
  # parent.data = None
138
134
  # parent.imageItem.clear()
139
- parent.new_scanID.emit(current_scanID)
135
+ parent.new_scan_id.emit(current_scan_id)
140
136
 
141
- print(f"New scanID: {current_scanID}")
137
+ print(f"New scan_id: {current_scan_id}")
142
138
 
143
139
 
144
140
  if __name__ == "__main__":
145
141
  import argparse
142
+
146
143
  from bec_lib import RedisConnector
147
144
 
148
145
  parser = argparse.ArgumentParser(description="Stream App.")
@@ -1,31 +1,26 @@
1
- from bec_lib import messages, MessageEndpoints, RedisConnector
2
1
  import time
3
2
 
3
+ from bec_lib import MessageEndpoints, RedisConnector, messages
4
+
4
5
  connector = RedisConnector("localhost:6379")
5
6
  producer = connector.producer()
6
7
  metadata = {}
7
8
 
8
- scanID = "ScanID1"
9
+ scan_id = "ScanID1"
9
10
 
10
11
  metadata.update(
11
- {
12
- "scanID": scanID, # this will be different for each scan
13
- "async_update": "append",
14
- }
12
+ {"scan_id": scan_id, "async_update": "append"} # this will be different for each scan
15
13
  )
16
14
  for ii in range(20):
17
15
  data = {"mca1": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "mca2": [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]}
18
- msg = messages.DeviceMessage(
19
- signals=data,
20
- metadata=metadata,
21
- ).dumps()
16
+ msg = messages.DeviceMessage(signals=data, metadata=metadata).dumps()
22
17
 
23
18
  # producer.send(topic=MessageEndpoints.device_status(device="mca"), msg=msg)
24
19
 
25
20
  producer.xadd(
26
21
  topic=MessageEndpoints.device_async_readback(
27
- scanID=scanID, device="mca"
28
- ), # scanID will be different for each scan
22
+ scan_id=scan_id, device="mca"
23
+ ), # scan_id will be different for each scan
29
24
  msg={"data": msg}, # TODO should be msg_dict
30
25
  expire=1800,
31
26
  )
@@ -2,8 +2,8 @@ from .motor_control_compilations import (
2
2
  MotorControlApp,
3
3
  MotorControlMap,
4
4
  MotorControlPanel,
5
- MotorControlPanelRelative,
6
5
  MotorControlPanelAbsolute,
6
+ MotorControlPanelRelative,
7
7
  MotorCoordinateTable,
8
8
  MotorThread,
9
9
  )
@@ -1,22 +1,17 @@
1
1
  # pylint: disable = no-name-in-module,missing-class-docstring, missing-module-docstring
2
2
 
3
3
  import qdarktheme
4
- from qtpy.QtWidgets import QApplication
5
- from qtpy.QtWidgets import QVBoxLayout
6
- from qtpy.QtWidgets import (
7
- QWidget,
8
- QSplitter,
9
- )
10
4
  from qtpy.QtCore import Qt
5
+ from qtpy.QtWidgets import QApplication, QSplitter, QVBoxLayout, QWidget
11
6
 
12
7
  from bec_widgets.utils.bec_dispatcher import BECDispatcher
13
8
  from bec_widgets.widgets import (
14
9
  MotorControlAbsolute,
15
10
  MotorControlRelative,
16
11
  MotorControlSelection,
17
- MotorThread,
18
- MotorMap,
19
12
  MotorCoordinateTable,
13
+ MotorMap,
14
+ MotorThread,
20
15
  )
21
16
 
22
17
  CONFIG_DEFAULT = {
@@ -883,7 +883,7 @@
883
883
  </column>
884
884
  <column>
885
885
  <property name="text">
886
- <string>scanID</string>
886
+ <string>scan_id</string>
887
887
  </property>
888
888
  </column>
889
889
  <column>
@@ -5,29 +5,28 @@ from functools import partial
5
5
 
6
6
  import numpy as np
7
7
  import pyqtgraph as pg
8
+ from bec_lib import MessageEndpoints, messages
9
+ from pyqtgraph.Qt import QtCore, QtWidgets, uic
8
10
  from qtpy import QtGui
9
- from qtpy.QtCore import QThread, Slot as pyqtSlot
10
- from qtpy.QtCore import Signal as pyqtSignal, Qt
11
- from qtpy.QtGui import QDoubleValidator
12
- from qtpy.QtGui import QKeySequence
11
+ from qtpy.QtCore import Qt, QThread
12
+ from qtpy.QtCore import Signal as pyqtSignal
13
+ from qtpy.QtCore import Slot as pyqtSlot
14
+ from qtpy.QtGui import QDoubleValidator, QKeySequence
13
15
  from qtpy.QtWidgets import (
14
16
  QApplication,
15
- QWidget,
16
- QFileDialog,
17
17
  QDialog,
18
- QVBoxLayout,
18
+ QFileDialog,
19
+ QFrame,
19
20
  QLabel,
21
+ QMessageBox,
20
22
  QPushButton,
21
- QFrame,
23
+ QShortcut,
24
+ QVBoxLayout,
25
+ QWidget,
22
26
  )
23
- from qtpy.QtWidgets import QMessageBox
24
- from qtpy.QtWidgets import QShortcut
25
- from pyqtgraph.Qt import QtWidgets, uic, QtCore
26
27
 
27
- from bec_lib import MessageEndpoints, messages
28
28
  from bec_widgets.utils import DoubleValidationDelegate
29
29
 
30
-
31
30
  # TODO - General features
32
31
  # - put motor status (moving, stopped, etc)
33
32
  # - add mouse interactions with the plot -> click to select coordinates, double click to move?
@@ -1306,9 +1305,9 @@ class MotorControl(QThread):
1306
1305
 
1307
1306
 
1308
1307
  if __name__ == "__main__":
1309
- import yaml
1310
1308
  import argparse
1311
1309
 
1310
+ import yaml
1312
1311
  from bec_lib import BECClient, ServiceConfig
1313
1312
 
1314
1313
  parser = argparse.ArgumentParser(description="Motor App")
@@ -5,14 +5,15 @@ import time
5
5
  import numpy as np
6
6
  import pyqtgraph
7
7
  import pyqtgraph as pg
8
- from bec_lib import messages, MessageEndpoints
8
+ from bec_lib import MessageEndpoints, messages
9
9
  from bec_lib.redis_connector import RedisConnector
10
- from qtpy.QtCore import Slot as pyqtSlot
11
- from qtpy.QtWidgets import QTableWidgetItem
12
10
  from pyqtgraph import mkBrush, mkPen
13
11
  from pyqtgraph.Qt import QtCore, QtWidgets, uic
14
12
  from pyqtgraph.Qt.QtCore import pyqtSignal
15
- from bec_widgets.utils import Crosshair, Colors
13
+ from qtpy.QtCore import Slot as pyqtSlot
14
+ from qtpy.QtWidgets import QTableWidgetItem
15
+
16
+ from bec_widgets.utils import Colors, Crosshair
16
17
  from bec_widgets.utils.bec_dispatcher import BECDispatcher
17
18
 
18
19
 
@@ -1,8 +1,8 @@
1
- from .crosshair import Crosshair
2
- from .colors import Colors
3
- from .validator_delegate import DoubleValidationDelegate
4
- from .bec_table import BECTable
5
1
  from .bec_connector import BECConnector, ConnectionConfig
6
2
  from .bec_dispatcher import BECDispatcher
7
- from .rpc_decorator import rpc_public, register_rpc_methods
3
+ from .bec_table import BECTable
4
+ from .colors import Colors
5
+ from .crosshair import Crosshair
8
6
  from .entry_validator import EntryValidator
7
+ from .rpc_decorator import register_rpc_methods, rpc_public
8
+ from .validator_delegate import DoubleValidationDelegate
@@ -2,7 +2,7 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  import time
5
- from typing import Type, Optional
5
+ from typing import Optional, Type
6
6
 
7
7
  from pydantic import BaseModel, Field, field_validator
8
8
  from qtpy.QtCore import Slot as pyqtSlot
@@ -8,11 +8,10 @@ from typing import Union
8
8
 
9
9
  import redis
10
10
  from bec_lib import BECClient, ServiceConfig
11
+ from bec_lib.endpoints import EndpointInfo
11
12
  from qtpy.QtCore import QObject
12
13
  from qtpy.QtCore import Signal as pyqtSignal
13
14
 
14
- from bec_lib.endpoints import EndpointInfo
15
-
16
15
  # Adding a new pyqt signal requires a class factory, as they must be part of the class definition
17
16
  # and cannot be dynamically added as class attributes after the class has been defined.
18
17
  _signal_class_factory = (
@@ -1,5 +1,5 @@
1
- from qtpy.QtWidgets import QTableWidget
2
1
  from qtpy.QtCore import Qt
2
+ from qtpy.QtWidgets import QTableWidget
3
3
 
4
4
 
5
5
  class BECTable(QTableWidget):
@@ -2,7 +2,8 @@ import numpy as np
2
2
  import pyqtgraph as pg
3
3
 
4
4
  # from qtpy.QtCore import QObject, pyqtSignal
5
- from qtpy.QtCore import QObject, Signal as pyqtSignal
5
+ from qtpy.QtCore import QObject
6
+ from qtpy.QtCore import Signal as pyqtSignal
6
7
 
7
8
 
8
9
  class Crosshair(QObject):
@@ -2,7 +2,7 @@
2
2
  # from qtpy.QtWidgets import QStyledItemDelegate, QLineEdit
3
3
 
4
4
  from qtpy.QtGui import QDoubleValidator
5
- from qtpy.QtWidgets import QStyledItemDelegate, QLineEdit
5
+ from qtpy.QtWidgets import QLineEdit, QStyledItemDelegate
6
6
 
7
7
 
8
8
  class DoubleValidationDelegate(QStyledItemDelegate):
@@ -3,16 +3,16 @@ from abc import ABC, abstractmethod
3
3
 
4
4
  from qtpy.QtWidgets import (
5
5
  QApplication,
6
- QWidget,
7
- QLineEdit,
6
+ QCheckBox,
8
7
  QComboBox,
9
- QTableWidget,
10
- QSpinBox,
11
8
  QDoubleSpinBox,
9
+ QLabel,
10
+ QLineEdit,
11
+ QSpinBox,
12
+ QTableWidget,
12
13
  QTableWidgetItem,
13
14
  QVBoxLayout,
14
- QCheckBox,
15
- QLabel,
15
+ QWidget,
16
16
  )
17
17
 
18
18
 
@@ -1,6 +1,7 @@
1
1
  # pylint: disable=no-name-in-module
2
2
 
3
3
  from typing import Union
4
+
4
5
  import yaml
5
6
  from qtpy.QtWidgets import QFileDialog
6
7
 
@@ -1,6 +1,6 @@
1
- from typing import Optional, Union, Literal
1
+ from typing import Literal, Optional, Union
2
2
 
3
- from pydantic import BaseModel, Field, field_validator, model_validator, ValidationError
3
+ from pydantic import BaseModel, Field, ValidationError, field_validator, model_validator
4
4
  from pydantic_core import PydanticCustomError
5
5
 
6
6
 
@@ -92,12 +92,12 @@ class SourceHistoryValidator(BaseModel):
92
92
  """History source validator
93
93
  Attributes:
94
94
  type (str): type of source - history
95
- scanID (str): Scan ID for history source.
95
+ scan_id (str): Scan ID for history source.
96
96
  signals (list): Signal for the source.
97
97
  """
98
98
 
99
99
  type: Literal["history"]
100
- scanID: str # TODO can be validated if it is a valid scanID
100
+ scan_id: str # TODO can be validated if it is a valid scan_id
101
101
  signals: AxisSignal
102
102
 
103
103
 
@@ -131,12 +131,12 @@ class Source(BaseModel): # TODO decide if it should stay for general Source val
131
131
  General source validation, includes all Optional arguments of all other sources.
132
132
  Attributes:
133
133
  type (list): type of source (scan_segment, history)
134
- scanID (Optional[str]): Scan ID for history source.
134
+ scan_id (Optional[str]): Scan ID for history source.
135
135
  signals (Optional[AxisSignal]): Signal for the source.
136
136
  """
137
137
 
138
138
  type: Literal["scan_segment", "history", "redis"]
139
- scanID: Optional[str] = None
139
+ scan_id: Optional[str] = None
140
140
  signals: Optional[dict] = None
141
141
 
142
142