bec-widgets 0.46.3__py3-none-any.whl → 0.46.4__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 (39) hide show
  1. bec_widgets/cli/client.py +72 -73
  2. bec_widgets/cli/server.py +2 -2
  3. bec_widgets/utils/bec_connector.py +19 -1
  4. bec_widgets/utils/bec_dispatcher.py +2 -1
  5. bec_widgets/widgets/figure/figure.py +5 -60
  6. bec_widgets/widgets/plots/image.py +24 -5
  7. bec_widgets/widgets/plots/motor_map.py +14 -1
  8. bec_widgets/widgets/plots/plot_base.py +1 -1
  9. bec_widgets/widgets/plots/waveform.py +2 -2
  10. {bec_widgets-0.46.3.dist-info → bec_widgets-0.46.4.dist-info}/METADATA +1 -1
  11. {bec_widgets-0.46.3.dist-info → bec_widgets-0.46.4.dist-info}/RECORD +38 -37
  12. tests/unit_tests/conftest.py +14 -0
  13. tests/unit_tests/test_msgs/__init__.py +0 -0
  14. tests/{test_scan_control.py → unit_tests/test_scan_control.py} +1 -4
  15. tests/conftest.py +0 -36
  16. {bec_widgets-0.46.3.dist-info → bec_widgets-0.46.4.dist-info}/LICENSE +0 -0
  17. {bec_widgets-0.46.3.dist-info → bec_widgets-0.46.4.dist-info}/WHEEL +0 -0
  18. {bec_widgets-0.46.3.dist-info → bec_widgets-0.46.4.dist-info}/top_level.txt +0 -0
  19. /tests/{test_msgs → unit_tests}/__init__.py +0 -0
  20. /tests/{client_mocks.py → unit_tests/client_mocks.py} +0 -0
  21. /tests/{test_bec_connector.py → unit_tests/test_bec_connector.py} +0 -0
  22. /tests/{test_bec_dispatcher.py → unit_tests/test_bec_dispatcher.py} +0 -0
  23. /tests/{test_bec_figure.py → unit_tests/test_bec_figure.py} +0 -0
  24. /tests/{test_bec_monitor.py → unit_tests/test_bec_monitor.py} +0 -0
  25. /tests/{test_bec_motor_map.py → unit_tests/test_bec_motor_map.py} +0 -0
  26. /tests/{test_config_dialog.py → unit_tests/test_config_dialog.py} +0 -0
  27. /tests/{test_crosshair.py → unit_tests/test_crosshair.py} +0 -0
  28. /tests/{test_editor.py → unit_tests/test_editor.py} +0 -0
  29. /tests/{test_eiger_plot.py → unit_tests/test_eiger_plot.py} +0 -0
  30. /tests/{test_generate_cli_client.py → unit_tests/test_generate_cli_client.py} +0 -0
  31. /tests/{test_motor_control.py → unit_tests/test_motor_control.py} +0 -0
  32. /tests/{test_motor_map.py → unit_tests/test_motor_map.py} +0 -0
  33. /tests/{test_msgs → unit_tests/test_msgs}/available_scans_message.py +0 -0
  34. /tests/{test_plot_base.py → unit_tests/test_plot_base.py} +0 -0
  35. /tests/{test_stream_plot.py → unit_tests/test_stream_plot.py} +0 -0
  36. /tests/{test_validator_errors.py → unit_tests/test_validator_errors.py} +0 -0
  37. /tests/{test_waveform1d.py → unit_tests/test_waveform1d.py} +0 -0
  38. /tests/{test_widget_io.py → unit_tests/test_widget_io.py} +0 -0
  39. /tests/{test_yaml_dialog.py → unit_tests/test_yaml_dialog.py} +0 -0
bec_widgets/cli/client.py CHANGED
@@ -6,14 +6,13 @@ from bec_widgets.cli.client_utils import BECFigureClientMixin, RPCBase, rpc_call
6
6
 
7
7
 
8
8
  class BECPlotBase(RPCBase):
9
+ @property
9
10
  @rpc_call
10
- def get_config(self, dict_output: "bool" = True) -> "dict | BaseModel":
11
+ def config_dict(self) -> "dict":
11
12
  """
12
13
  Get the configuration of the widget.
13
- Args:
14
- dict_output(bool): If True, return the configuration as a dictionary. If False, return the configuration as a pydantic model.
15
14
  Returns:
16
- dict: The configuration of the plot widget.
15
+ dict: The configuration of the widget.
17
16
  """
18
17
 
19
18
  @rpc_call
@@ -137,6 +136,15 @@ class BECPlotBase(RPCBase):
137
136
 
138
137
 
139
138
  class BECWaveform(RPCBase):
139
+ @property
140
+ @rpc_call
141
+ def config_dict(self) -> "dict":
142
+ """
143
+ Get the configuration of the widget.
144
+ Returns:
145
+ dict: The configuration of the widget.
146
+ """
147
+
140
148
  @rpc_call
141
149
  def add_curve_scan(
142
150
  self,
@@ -258,16 +266,6 @@ class BECWaveform(RPCBase):
258
266
  dict | pd.DataFrame: Data of all curves in the specified format.
259
267
  """
260
268
 
261
- @rpc_call
262
- def get_config(self, dict_output: "bool" = True) -> "dict | BaseModel":
263
- """
264
- Get the configuration of the widget.
265
- Args:
266
- dict_output(bool): If True, return the configuration as a dictionary. If False, return the configuration as a pydantic model.
267
- Returns:
268
- dict: The configuration of the plot widget.
269
- """
270
-
271
269
  @rpc_call
272
270
  def set(self, **kwargs) -> "None":
273
271
  """
@@ -389,6 +387,15 @@ class BECWaveform(RPCBase):
389
387
 
390
388
 
391
389
  class BECFigure(RPCBase, BECFigureClientMixin):
390
+ @property
391
+ @rpc_call
392
+ def config_dict(self) -> "dict":
393
+ """
394
+ Get the configuration of the widget.
395
+ Returns:
396
+ dict: The configuration of the widget.
397
+ """
398
+
392
399
  @property
393
400
  @rpc_call
394
401
  def axes(self) -> "list[BECPlotBase]":
@@ -607,18 +614,17 @@ class BECFigure(RPCBase, BECFigureClientMixin):
607
614
  Clear all widgets from the figure and reset to default state
608
615
  """
609
616
 
617
+
618
+ class BECCurve(RPCBase):
619
+ @property
610
620
  @rpc_call
611
- def get_config(self, dict_output: "bool" = True) -> "dict | BaseModel":
621
+ def config_dict(self) -> "dict":
612
622
  """
613
623
  Get the configuration of the widget.
614
- Args:
615
- dict_output(bool): If True, return the configuration as a dictionary. If False, return the configuration as a pydantic model.
616
624
  Returns:
617
- dict: The configuration of the plot widget.
625
+ dict: The configuration of the widget.
618
626
  """
619
627
 
620
-
621
- class BECCurve(RPCBase):
622
628
  @rpc_call
623
629
  def set(self, **kwargs):
624
630
  """
@@ -705,18 +711,17 @@ class BECCurve(RPCBase):
705
711
  tuple[np.ndarray,np.ndarray]: X and Y data of the curve.
706
712
  """
707
713
 
714
+
715
+ class BECImageShow(RPCBase):
716
+ @property
708
717
  @rpc_call
709
- def get_config(self, dict_output: "bool" = True) -> "dict | BaseModel":
718
+ def config_dict(self) -> "dict":
710
719
  """
711
720
  Get the configuration of the widget.
712
- Args:
713
- dict_output(bool): If True, return the configuration as a dictionary. If False, return the configuration as a pydantic model.
714
721
  Returns:
715
- dict: The configuration of the plot widget.
722
+ dict: The configuration of the widget.
716
723
  """
717
724
 
718
-
719
- class BECImageShow(RPCBase):
720
725
  @rpc_call
721
726
  def add_image_by_config(self, config: "ImageItemConfig | dict") -> "BECImageItem":
722
727
  """
@@ -740,14 +745,6 @@ class BECImageShow(RPCBase):
740
745
  ImageItemConfig|dict: The configuration of the image.
741
746
  """
742
747
 
743
- @rpc_call
744
- def get_image_list(self) -> "list[BECImageItem]":
745
- """
746
- Get the list of images.
747
- Returns:
748
- list[BECImageItem]: The list of images.
749
- """
750
-
751
748
  @rpc_call
752
749
  def get_image_dict(self) -> "dict[str, dict[str, BECImageItem]]":
753
750
  """
@@ -756,16 +753,6 @@ class BECImageShow(RPCBase):
756
753
  dict[str, dict[str, BECImageItem]]: The dictionary of images.
757
754
  """
758
755
 
759
- @rpc_call
760
- def get_config(self, dict_output: "bool" = True) -> "dict | BaseModel":
761
- """
762
- Get the configuration of the widget.
763
- Args:
764
- dict_output(bool): If True, return the configuration as a dictionary. If False, return the configuration as a pydantic model.
765
- Returns:
766
- dict: The configuration of the plot widget.
767
- """
768
-
769
756
  @rpc_call
770
757
  def add_monitor_image(
771
758
  self,
@@ -919,16 +906,6 @@ class BECImageShow(RPCBase):
919
906
  use_threading(bool): Whether to use threading.
920
907
  """
921
908
 
922
- @rpc_call
923
- def get_config(self, dict_output: "bool" = True) -> "dict | BaseModel":
924
- """
925
- Get the configuration of the widget.
926
- Args:
927
- dict_output(bool): If True, return the configuration as a dictionary. If False, return the configuration as a pydantic model.
928
- Returns:
929
- dict: The configuration of the plot widget.
930
- """
931
-
932
909
  @rpc_call
933
910
  def set(self, **kwargs) -> "None":
934
911
  """
@@ -1048,20 +1025,37 @@ class BECImageShow(RPCBase):
1048
1025
  Remove the plot widget from the figure.
1049
1026
  """
1050
1027
 
1028
+ @property
1029
+ @rpc_call
1030
+ def images(self) -> "list[BECImageItem]":
1031
+ """
1032
+ Get the list of images.
1033
+ Returns:
1034
+ list[BECImageItem]: The list of images.
1035
+ """
1036
+
1051
1037
 
1052
1038
  class BECConnector(RPCBase):
1039
+ @property
1053
1040
  @rpc_call
1054
- def get_config(self, dict_output: "bool" = True) -> "dict | BaseModel":
1041
+ def config_dict(self) -> "dict":
1055
1042
  """
1056
1043
  Get the configuration of the widget.
1057
- Args:
1058
- dict_output(bool): If True, return the configuration as a dictionary. If False, return the configuration as a pydantic model.
1059
1044
  Returns:
1060
- dict: The configuration of the plot widget.
1045
+ dict: The configuration of the widget.
1061
1046
  """
1062
1047
 
1063
1048
 
1064
1049
  class BECImageItem(RPCBase):
1050
+ @property
1051
+ @rpc_call
1052
+ def config_dict(self) -> "dict":
1053
+ """
1054
+ Get the configuration of the widget.
1055
+ Returns:
1056
+ dict: The configuration of the widget.
1057
+ """
1058
+
1065
1059
  @rpc_call
1066
1060
  def set(self, **kwargs):
1067
1061
  """
@@ -1164,17 +1158,24 @@ class BECImageItem(RPCBase):
1164
1158
  """
1165
1159
 
1166
1160
  @rpc_call
1167
- def get_config(self, dict_output: "bool" = True) -> "dict | BaseModel":
1161
+ def get_data(self) -> "np.ndarray":
1168
1162
  """
1169
- Get the configuration of the widget.
1170
- Args:
1171
- dict_output(bool): If True, return the configuration as a dictionary. If False, return the configuration as a pydantic model.
1163
+ Get the data of the image.
1172
1164
  Returns:
1173
- dict: The configuration of the plot widget.
1165
+ np.ndarray: The data of the image.
1174
1166
  """
1175
1167
 
1176
1168
 
1177
1169
  class BECMotorMap(RPCBase):
1170
+ @property
1171
+ @rpc_call
1172
+ def config_dict(self) -> "dict":
1173
+ """
1174
+ Get the configuration of the widget.
1175
+ Returns:
1176
+ dict: The configuration of the widget.
1177
+ """
1178
+
1178
1179
  @rpc_call
1179
1180
  def change_motors(
1180
1181
  self,
@@ -1194,16 +1195,6 @@ class BECMotorMap(RPCBase):
1194
1195
  validate_bec(bool, optional): If True, validate the signal with BEC. Defaults to True.
1195
1196
  """
1196
1197
 
1197
- @rpc_call
1198
- def get_config(self, dict_output: "bool" = True) -> "dict | BaseModel":
1199
- """
1200
- Get the configuration of the widget.
1201
- Args:
1202
- dict_output(bool): If True, return the configuration as a dictionary. If False, return the configuration as a pydantic model.
1203
- Returns:
1204
- dict: The configuration of the plot widget.
1205
- """
1206
-
1207
1198
  @rpc_call
1208
1199
  def set_max_points(self, max_points: "int") -> "None":
1209
1200
  """
@@ -1243,3 +1234,11 @@ class BECMotorMap(RPCBase):
1243
1234
  Args:
1244
1235
  scatter_size(int): Size of the scatter points.
1245
1236
  """
1237
+
1238
+ @rpc_call
1239
+ def get_data(self) -> "dict":
1240
+ """
1241
+ Get the data of the motor map.
1242
+ Returns:
1243
+ dict: Data of the motor map.
1244
+ """
bec_widgets/cli/server.py CHANGED
@@ -12,9 +12,9 @@ from bec_widgets.widgets.plots import BECCurve, BECImageShow, BECWaveform
12
12
  class BECWidgetsCLIServer:
13
13
  WIDGETS = [BECWaveform, BECFigure, BECCurve, BECImageShow]
14
14
 
15
- def __init__(self, gui_id: str = None, dispatcher: BECDispatcher = None) -> None:
15
+ def __init__(self, gui_id: str = None, dispatcher: BECDispatcher = None, client=None) -> None:
16
16
  self.dispatcher = BECDispatcher() if dispatcher is None else dispatcher
17
- self.client = self.dispatcher.client
17
+ self.client = self.dispatcher.client if client is None else client
18
18
  self.client.start()
19
19
  self.gui_id = gui_id
20
20
  self.fig = BECFigure(gui_id=self.gui_id)
@@ -31,7 +31,7 @@ class ConnectionConfig(BaseModel):
31
31
  class BECConnector:
32
32
  """Connection mixin class for all BEC widgets, to handle BEC client and device manager"""
33
33
 
34
- USER_ACCESS = ["get_config"]
34
+ USER_ACCESS = ["config_dict"]
35
35
 
36
36
  def __init__(self, client=None, config: ConnectionConfig = None, gui_id: str = None):
37
37
  # BEC related connections
@@ -54,6 +54,24 @@ class BECConnector:
54
54
  else:
55
55
  self.gui_id = self.config.gui_id
56
56
 
57
+ @property
58
+ def config_dict(self) -> dict:
59
+ """
60
+ Get the configuration of the widget.
61
+ Returns:
62
+ dict: The configuration of the widget.
63
+ """
64
+ return self.config.model_dump()
65
+
66
+ @config_dict.setter
67
+ def config_dict(self, config: BaseModel) -> None:
68
+ """
69
+ Get the configuration of the widget.
70
+ Returns:
71
+ dict: The configuration of the widget.
72
+ """
73
+ self.config = config
74
+
57
75
  @pyqtSlot(str)
58
76
  def set_gui_id(self, gui_id: str) -> None:
59
77
  """
@@ -82,8 +82,9 @@ class BECDispatcher:
82
82
  return
83
83
 
84
84
  self._slots = collections.defaultdict(set)
85
+ self.client = client
85
86
 
86
- if client is None:
87
+ if self.client is None:
87
88
  self.client = BECClient(connector_cls=QtRedisConnector, forced=True)
88
89
  else:
89
90
  if self.client.started:
@@ -97,6 +97,7 @@ class WidgetHandler:
97
97
 
98
98
  class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
99
99
  USER_ACCESS = [
100
+ "config_dict",
100
101
  "axes",
101
102
  "widgets",
102
103
  "add_plot",
@@ -109,7 +110,6 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
109
110
  "change_layout",
110
111
  "change_theme",
111
112
  "clear_all",
112
- "get_config",
113
113
  ]
114
114
 
115
115
  clean_signal = pyqtSignal()
@@ -847,7 +847,6 @@ class DebugWindow(QWidget): # pragma: no cover:
847
847
  "w1": self.w1,
848
848
  "w2": self.w2,
849
849
  "w3": self.w3,
850
- "w4": self.w4,
851
850
  "bec": self.figure.client,
852
851
  "scans": self.figure.client.scans,
853
852
  "dev": self.figure.client.device_manager.devices,
@@ -869,75 +868,21 @@ class DebugWindow(QWidget): # pragma: no cover:
869
868
  self.console.set_default_style("linux")
870
869
 
871
870
  def _init_figure(self):
872
- # self.figure.add_widget(widget_type="Waveform1D", row=0, col=0, title="Widget 1")
873
871
  self.figure.plot("samx", "bpm4d")
874
- self.figure.add_widget(widget_type="Waveform1D", row=0, col=1, title="Widget 2")
875
- self.figure.add_image(
876
- title="Image", row=1, col=0, color_map="viridis", color_bar="simple", vrange=(0, 100)
877
- )
878
- self.figure.add_image(title="Image", row=1, col=1, vrange=(0, 100))
872
+ self.figure.motor_map("samx", "samy")
873
+ self.figure.image("eiger", color_map="viridis", vrange=(0, 100))
874
+
875
+ self.figure.change_layout(2, 2)
879
876
 
880
877
  self.w1 = self.figure[0, 0]
881
878
  self.w2 = self.figure[0, 1]
882
879
  self.w3 = self.figure[1, 0]
883
- self.w4 = self.figure[1, 1]
884
880
 
885
881
  # curves for w1
886
882
  self.w1.add_curve_scan("samx", "samy", "bpm4i", pen_style="dash")
887
883
  self.w1.add_curve_scan("samx", "samy", "bpm3a", pen_style="dash")
888
-
889
- # self.w1.add_curve_custom(
890
- # x=[1, 2, 3, 4, 5],
891
- # y=[1, 2, 3, 4, 5],
892
- # label="curve-custom",
893
- # color="blue",
894
- # pen_style="dashdot",
895
- # )
896
884
  self.c1 = self.w1.get_config()
897
885
 
898
- # curves for w2
899
- self.w2.add_curve_scan("samx", "bpm3a", pen_style="solid")
900
- self.w2.add_curve_scan("samx", "bpm4d", pen_style="dot")
901
- self.w2.add_curve_custom(
902
- x=[1, 2, 3, 4, 5], y=[5, 4, 3, 2, 1], color="red", pen_style="dashdot"
903
- )
904
-
905
- # curves for w3
906
- # self.w3.add_curve_scan("samx", "bpm4i", pen_style="dash")
907
- # self.w3.add_curve_custom(
908
- # x=[1, 2, 3, 4, 5],
909
- # y=[1, 2, 3, 4, 5],
910
- # label="curve-custom",
911
- # color="blue",
912
- # pen_style="dashdot",
913
- # )
914
-
915
- # curves for w4
916
- # self.w4.add_curve_scan("samx", "bpm4i", pen_style="dash")
917
- # self.w4.add_curve_custom(
918
- # x=[1, 2, 3, 4, 5],
919
- # y=[1, 2, 3, 4, 5],
920
- # label="curve-custom",
921
- # color="blue",
922
- # pen_style="dashdot",
923
- # )
924
-
925
- # Image setting for w3
926
-
927
- self.w3.add_monitor_image("eiger", vrange=(0, 100), color_bar="full")
928
-
929
- # Image setting for w4
930
- self.w4.add_monitor_image("eiger", vrange=(0, 100), color_map="viridis")
931
-
932
- # def confirm_close(self):
933
- # self.safe_close = True
934
- #
935
- # def closeEvent(self, event):
936
- # self.figure.cleanup()
937
- # if self.safe_close == True:
938
- # print("Safe close")
939
- # event.accept()
940
-
941
886
 
942
887
  if __name__ == "__main__": # pragma: no cover
943
888
  import sys
@@ -59,6 +59,7 @@ class ImageConfig(WidgetConfig):
59
59
 
60
60
  class BECImageItem(BECConnector, pg.ImageItem):
61
61
  USER_ACCESS = [
62
+ "config_dict",
62
63
  "set",
63
64
  "set_fft",
64
65
  "set_log",
@@ -70,7 +71,7 @@ class BECImageItem(BECConnector, pg.ImageItem):
70
71
  "set_auto_downsample",
71
72
  "set_monitor",
72
73
  "set_vrange",
73
- "get_config",
74
+ "get_data",
74
75
  ]
75
76
 
76
77
  def __init__(
@@ -243,6 +244,14 @@ class BECImageItem(BECConnector, pg.ImageItem):
243
244
  self.color_bar.setLevels(min=vmin, max=vmax)
244
245
  self.color_bar.setHistogramRange(vmin - 0.1 * vmin, vmax + 0.1 * vmax)
245
246
 
247
+ def get_data(self) -> np.ndarray:
248
+ """
249
+ Get the data of the image.
250
+ Returns:
251
+ np.ndarray: The data of the image.
252
+ """
253
+ return self.image
254
+
246
255
  def _add_color_bar(
247
256
  self, color_bar_style: str = "simple", vrange: Optional[tuple[int, int]] = None
248
257
  ):
@@ -281,11 +290,10 @@ class BECImageItem(BECConnector, pg.ImageItem):
281
290
 
282
291
  class BECImageShow(BECPlotBase):
283
292
  USER_ACCESS = [
293
+ "config_dict",
284
294
  "add_image_by_config",
285
295
  "get_image_config",
286
- "get_image_list",
287
296
  "get_image_dict",
288
- "get_config",
289
297
  "add_monitor_image",
290
298
  "add_custom_image",
291
299
  "set_vrange",
@@ -299,7 +307,6 @@ class BECImageShow(BECPlotBase):
299
307
  "set_rotation",
300
308
  "set_transpose",
301
309
  "toggle_threading",
302
- "get_config",
303
310
  "set",
304
311
  "set_title",
305
312
  "set_x_label",
@@ -312,6 +319,7 @@ class BECImageShow(BECPlotBase):
312
319
  "lock_aspect_ratio",
313
320
  "plot",
314
321
  "remove",
322
+ "images",
315
323
  ]
316
324
 
317
325
  def __init__(
@@ -449,7 +457,8 @@ class BECImageShow(BECPlotBase):
449
457
  else:
450
458
  return image.config # TODO check if this works
451
459
 
452
- def get_image_list(self) -> list[BECImageItem]:
460
+ @property
461
+ def images(self) -> list[BECImageItem]:
453
462
  """
454
463
  Get the list of images.
455
464
  Returns:
@@ -461,6 +470,16 @@ class BECImageShow(BECPlotBase):
461
470
  images.append(image)
462
471
  return images
463
472
 
473
+ @images.setter
474
+ def images(self, value: dict[str, dict[str, BECImageItem]]):
475
+ """
476
+ Set the images from a dictionary.
477
+
478
+ Args:
479
+ value (dict[str, dict[str, BECImageItem]]): The images to set, organized by source and id.
480
+ """
481
+ self._images = value
482
+
464
483
  def get_image_dict(self) -> dict[str, dict[str, BECImageItem]]:
465
484
  """
466
485
  Get all images.
@@ -36,13 +36,14 @@ class MotorMapConfig(WidgetConfig):
36
36
 
37
37
  class BECMotorMap(BECPlotBase):
38
38
  USER_ACCESS = [
39
+ "config_dict",
39
40
  "change_motors",
40
- "get_config",
41
41
  "set_max_points",
42
42
  "set_precision",
43
43
  "set_num_dim_points",
44
44
  "set_background_value",
45
45
  "set_scatter_size",
46
+ "get_data",
46
47
  ]
47
48
 
48
49
  # QT Signals
@@ -128,6 +129,18 @@ class BECMotorMap(BECPlotBase):
128
129
  # Redraw the motor map
129
130
  self._make_motor_map()
130
131
 
132
+ def get_data(self) -> dict:
133
+ """
134
+ Get the data of the motor map.
135
+ Returns:
136
+ dict: Data of the motor map.
137
+ """
138
+ data = {
139
+ "x": self.database_buffer["x"],
140
+ "y": self.database_buffer["y"],
141
+ }
142
+ return data
143
+
131
144
  # TODO setup all visual properties
132
145
  def set_max_points(self, max_points: int) -> None:
133
146
  """
@@ -37,7 +37,7 @@ class WidgetConfig(ConnectionConfig):
37
37
 
38
38
  class BECPlotBase(BECConnector, pg.GraphicsLayout):
39
39
  USER_ACCESS = [
40
- "get_config",
40
+ "config_dict",
41
41
  "set",
42
42
  "set_title",
43
43
  "set_x_label",
@@ -64,6 +64,7 @@ class Waveform1DConfig(WidgetConfig):
64
64
 
65
65
  class BECCurve(BECConnector, pg.PlotDataItem):
66
66
  USER_ACCESS = [
67
+ "config_dict",
67
68
  "set",
68
69
  "set_data",
69
70
  "set_color",
@@ -74,7 +75,6 @@ class BECCurve(BECConnector, pg.PlotDataItem):
74
75
  "set_pen_width",
75
76
  "set_pen_style",
76
77
  "get_data",
77
- "get_config",
78
78
  ]
79
79
 
80
80
  def __init__(
@@ -228,6 +228,7 @@ class BECCurve(BECConnector, pg.PlotDataItem):
228
228
 
229
229
  class BECWaveform(BECPlotBase):
230
230
  USER_ACCESS = [
231
+ "config_dict",
231
232
  "add_curve_scan",
232
233
  "add_curve_custom",
233
234
  "remove_curve",
@@ -237,7 +238,6 @@ class BECWaveform(BECPlotBase):
237
238
  "get_curve_config",
238
239
  "apply_config",
239
240
  "get_all_data",
240
- "get_config",
241
241
  "set",
242
242
  "set_title",
243
243
  "set_x_label",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bec-widgets
3
- Version: 0.46.3
3
+ Version: 0.46.4
4
4
  Summary: BEC Widgets
5
5
  Home-page: https://gitlab.psi.ch/bec/bec-widgets
6
6
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec-widgets/issues
@@ -1,9 +1,9 @@
1
1
  bec_widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  bec_widgets/cli/__init__.py,sha256=yFyAmDteCcndbReunhnrfDib6JujQ7-BKWeVvuU0Ylw,30
3
- bec_widgets/cli/client.py,sha256=MC4j-IthGZmeoimuHSOrqsvc2ad81vFbqcPGaVNe3Cw,39369
3
+ bec_widgets/cli/client.py,sha256=4QedDVBgkCOnRQFYQcAabyAsl5UQ0aRwwLwk1OR5M1k,37882
4
4
  bec_widgets/cli/client_utils.py,sha256=KpC9rSwXO3gQMTTxtuvnFPSOq3IvLw-sryqxVGt7Xqw,10437
5
5
  bec_widgets/cli/generate_cli.py,sha256=JLqUlUgfz_f_4KHPRUAN-Xli-K7uNOc8-F-LkAC7Scw,4004
6
- bec_widgets/cli/server.py,sha256=IqpFG7FnsTejnq-4reAqk5mBpynk1jZgoTn7O43N_6I,4717
6
+ bec_widgets/cli/server.py,sha256=OMWnl99RrSTKK1EVEyu3MFjkJ54bWfh_fpg38b-bres,4760
7
7
  bec_widgets/examples/__init__.py,sha256=WWQ0cu7m8sA4Ehy-DWdTIqSISjaHsbxhsNmNrMnhDZU,202
8
8
  bec_widgets/examples/eiger_plot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  bec_widgets/examples/eiger_plot/eiger_plot.py,sha256=Uxl2Usf8jEzaX7AT8zVqa1x8ZIEgI1HmazSlb-tRFWE,10359
@@ -23,8 +23,8 @@ bec_widgets/examples/stream_plot/line_plot.ui,sha256=rgNfhOXu1AcWF0P6wnOlmJKDjS-
23
23
  bec_widgets/examples/stream_plot/stream_plot.py,sha256=vHii1p9JxSyGQ_VcCjnk9SHJ41Q6Oi1GGd6swVVHLRM,12177
24
24
  bec_widgets/simulations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  bec_widgets/utils/__init__.py,sha256=-szVMxtb6Aoz5_e6Py652ExbGnmSVjd0w6ULBvumguk,353
26
- bec_widgets/utils/bec_connector.py,sha256=Dclw55JjBi4eJ4oacgGvG6XeEE9BkVbDWCojTXTVWM4,3665
27
- bec_widgets/utils/bec_dispatcher.py,sha256=SecPHfYLR6sJE1ELzCQJaR9tbDfsdqCQ07GgKNeYdN8,4806
26
+ bec_widgets/utils/bec_connector.py,sha256=QHVjgGRGEpojvZ04absLnUNiXEtZu3tvrHsW52MPWOk,4138
27
+ bec_widgets/utils/bec_dispatcher.py,sha256=sLv9CmJ3GKGDhvCXCDmuKtNRlI4w1oWxuQu_Mq2mDDY,4840
28
28
  bec_widgets/utils/bec_table.py,sha256=Xy5qM343K8EvEpB4g_129b63yo1wdEvEY3wqxB_p_Iw,716
29
29
  bec_widgets/utils/colors.py,sha256=JsLxzkxbw-I8GIuvnIKyiM83n0edhyMG2Fa4Ffm62ww,2392
30
30
  bec_widgets/utils/crosshair.py,sha256=5gG4G6jjtp6Bd1Y5EySHP2EkmtR4mYdxLCgVtx9fokE,9406
@@ -40,7 +40,7 @@ bec_widgets/widgets/__init__.py,sha256=GptryTiWJ4yWZZVBG_03guISJabSOzVpOMRkgW0Ld
40
40
  bec_widgets/widgets/editor/__init__.py,sha256=5mBdFYi_IpygCz81kbLEZUWhd1b6oqiO3nASejuV_ug,30
41
41
  bec_widgets/widgets/editor/editor.py,sha256=pIIYLPqqqhXqT11Xj10cyGEiy-ieNGE4ZujN5lf0e68,15110
42
42
  bec_widgets/widgets/figure/__init__.py,sha256=3hGx_KOV7QHCYAV06aNuUgKq4QIYCjUTad-DrwkUaBM,44
43
- bec_widgets/widgets/figure/figure.py,sha256=7kcHjkml3roJCVqMvlrDI3h_b4gSt2GNHm-JcTWHnDk,34361
43
+ bec_widgets/widgets/figure/figure.py,sha256=wG4nSl_SPezpKuLKFLTF-Ucmm9zsFru6X9g--9ivE7M,32487
44
44
  bec_widgets/widgets/figure/figure_debug_minimal.ui,sha256=GodXBvBvs5QAUsHbo3pcxR4o51Tvce4DTqpTluk3hOs,742
45
45
  bec_widgets/widgets/monitor/__init__.py,sha256=afXuZcBOxNAuYdCkIQXX5J60R5A3Q_86lNEW2vpFtPI,32
46
46
  bec_widgets/widgets/monitor/config_dialog.py,sha256=Z1a4WRIVlfEGdwC-QG25kba2EHCZWi5J843tBVZlWiI,20275
@@ -56,40 +56,41 @@ bec_widgets/widgets/motor_control/motor_control_table.ui,sha256=t6aRKiSmutMfp0Ay
56
56
  bec_widgets/widgets/motor_map/__init__.py,sha256=K3c-3A_LbxK0UJ0_bV3opL-wGLTwBLendsJXsg8GAqE,32
57
57
  bec_widgets/widgets/motor_map/motor_map.py,sha256=vJlLWa0BXv5KMZ7UVT0q3I1I5CXgsDiXoM_ptsAsG3c,21860
58
58
  bec_widgets/widgets/plots/__init__.py,sha256=kGQTORTr-2M9vmVCK-T7AFre4bY5LVVzGxcIzT81-ZU,237
59
- bec_widgets/widgets/plots/image.py,sha256=plmVd_VYxmQiUoqegcUr2ka6wLnHh5LB26VY5fUnu6U,31770
60
- bec_widgets/widgets/plots/motor_map.py,sha256=Q3x4RiwZogzGf64LRUn_2fQyIY1_Kt8KiCUekF6jocc,15076
61
- bec_widgets/widgets/plots/plot_base.py,sha256=tF0oamgCVIXFrfD8jnMVTltkzYLLSQ0Dq9HAG57Ji3E,8446
62
- bec_widgets/widgets/plots/waveform.py,sha256=RK31yRjtX9P7FS3KNCodi0U7E_IoaYl0Zo1iJiLHVqU,28526
59
+ bec_widgets/widgets/plots/image.py,sha256=GvtVVmtgaytuBIlLOzyE54BPQ8H2yRqRYrnDEy6n1rY,32254
60
+ bec_widgets/widgets/plots/motor_map.py,sha256=Uitx080FEyCDCTYHfBt0Ah-98QD4J5nSNZ628lu7EOg,15386
61
+ bec_widgets/widgets/plots/plot_base.py,sha256=xuNA4S5lwWiYXHT60XklWX09KiwqbrRiDr4J_iDXkes,8447
62
+ bec_widgets/widgets/plots/waveform.py,sha256=aUaWPg5NL0HoGqEs3Yo5nXEg_qy31C5ZwaOAwIoiqcs,28528
63
63
  bec_widgets/widgets/scan_control/__init__.py,sha256=IOfHl15vxb_uC6KN62-PeUzbBha_vQyqkkXbJ2HU674,38
64
64
  bec_widgets/widgets/scan_control/scan_control.py,sha256=tbO9tbVynRvs4VCxTZ4ZFBDTVAojIr-zkl70vuHbWgw,17116
65
65
  bec_widgets/widgets/toolbar/__init__.py,sha256=d-TP4_cr_VbpwreMM4ePnfZ5YXsEPQ45ibEf75nuGoE,36
66
66
  bec_widgets/widgets/toolbar/toolbar.py,sha256=sxz7rbc8XNPS6n2WMObF4-2PqdYfPxVtsOZEGV6mqa0,5124
67
67
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
- tests/client_mocks.py,sha256=Hga61hUk6FRz4yp2XLRe_3ZTM42aaDyISrXLsXcMmEY,4103
69
- tests/conftest.py,sha256=DFnQElTWgXhC7ii7NWIsnzlvnOUTQEzzMbgyFMt2L3o,1064
70
- tests/test_bec_connector.py,sha256=f2XXGGw3NoZLIUrDuZuEWwF_ttOYmmquCgUrV5XkIOY,1951
71
- tests/test_bec_dispatcher.py,sha256=MtNyfC7-Y4na-Fwf1ny9raHBqE45eSnQNWSqqAx79FU,1857
72
- tests/test_bec_figure.py,sha256=T4k-E1D3sjTTDTFZGdTFDQv0EYNQ_R-QbWOM7pQwFw4,7926
73
- tests/test_bec_monitor.py,sha256=mN7gBY7oXY6j65zzihpy8r-FvwVoCQlie3F6SoVq0mo,7042
74
- tests/test_bec_motor_map.py,sha256=IXSfitUGxOPqmngwVNPK5nwi2QDcXWjBkGNb0dBZDxQ,4611
75
- tests/test_config_dialog.py,sha256=5uNGcpvrx8qDdMwFCTXr8HMzFZF4rFi-ZHoDpMxGMf8,6955
76
- tests/test_crosshair.py,sha256=d7fX-ymboZPALNqqiAj86PZ96llmGZ_3jf0yjVP0S94,5039
77
- tests/test_editor.py,sha256=TED5k1xFJHRZ4KDAg2VxSRu_hMJnra-lbAmVwsDicsM,6784
78
- tests/test_eiger_plot.py,sha256=bWnKBQid0YcLMQeBLy6ojb4ZpwTG-rFVT0kMg9Y08p8,4427
79
- tests/test_generate_cli_client.py,sha256=BdpTZMNUFOBJa2e-rme9AJUoXfueYyLiUCOpGi3SNvc,2400
80
- tests/test_motor_control.py,sha256=jdTG35z3jOL9XCAIDNIGfdv60vcwGLHa3KJjKqJkoZw,20322
81
- tests/test_motor_map.py,sha256=UEjmtIYI2mxq9BUeopqoqNNy7UiPJEts9h45ufsFcrA,5979
82
- tests/test_plot_base.py,sha256=bOdlgAxh9oKk5PwiQ_MSFmzr44uJ61Tlg242RCIhl5c,2610
83
- tests/test_scan_control.py,sha256=e6_YpyxcayK35jXBSfxinGNL_8G-jcrWap25eg3z4QI,7560
84
- tests/test_stream_plot.py,sha256=LNCYIj9CafremGaz-DwDktCRJRrjgfOdVewCUwwZE5s,5843
85
- tests/test_validator_errors.py,sha256=NFxyv0TIOXeZKZRRUBfVQ7bpunwY4KkG95yTUdQmvns,3532
86
- tests/test_waveform1d.py,sha256=-YfBi_m91sR_v4oj8rshARk4G6AOxqQB_gbVqJ3iXvY,15003
87
- tests/test_widget_io.py,sha256=FeL3ZYSBQnRt6jxj8VGYw1cmcicRQyHKleahw7XIyR0,3475
88
- tests/test_yaml_dialog.py,sha256=HNrqferkdg02-9ieOhhI2mr2Qvt7GrYgXmQ061YCTbg,5794
89
- tests/test_msgs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
90
- tests/test_msgs/available_scans_message.py,sha256=m_z97hIrjHXXMa2Ex-UvsPmTxOYXfjxyJaGkIY6StTY,46532
91
- bec_widgets-0.46.3.dist-info/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
92
- bec_widgets-0.46.3.dist-info/METADATA,sha256=481-sA8FdWAmUJWk1pXB-VhwQ9QjGMez66IG79_nuJA,3714
93
- bec_widgets-0.46.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
94
- bec_widgets-0.46.3.dist-info/top_level.txt,sha256=EXCwhJYmXmd1DjYYL3hrGsddX-97IwYSiIHrf27FFVk,18
95
- bec_widgets-0.46.3.dist-info/RECORD,,
68
+ tests/unit_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
+ tests/unit_tests/client_mocks.py,sha256=Hga61hUk6FRz4yp2XLRe_3ZTM42aaDyISrXLsXcMmEY,4103
70
+ tests/unit_tests/conftest.py,sha256=roLbKZ1thm2Bd-5zEtL-eRBB5TTs36sAqXTUdHYYqSw,433
71
+ tests/unit_tests/test_bec_connector.py,sha256=f2XXGGw3NoZLIUrDuZuEWwF_ttOYmmquCgUrV5XkIOY,1951
72
+ tests/unit_tests/test_bec_dispatcher.py,sha256=MtNyfC7-Y4na-Fwf1ny9raHBqE45eSnQNWSqqAx79FU,1857
73
+ tests/unit_tests/test_bec_figure.py,sha256=T4k-E1D3sjTTDTFZGdTFDQv0EYNQ_R-QbWOM7pQwFw4,7926
74
+ tests/unit_tests/test_bec_monitor.py,sha256=mN7gBY7oXY6j65zzihpy8r-FvwVoCQlie3F6SoVq0mo,7042
75
+ tests/unit_tests/test_bec_motor_map.py,sha256=IXSfitUGxOPqmngwVNPK5nwi2QDcXWjBkGNb0dBZDxQ,4611
76
+ tests/unit_tests/test_config_dialog.py,sha256=5uNGcpvrx8qDdMwFCTXr8HMzFZF4rFi-ZHoDpMxGMf8,6955
77
+ tests/unit_tests/test_crosshair.py,sha256=d7fX-ymboZPALNqqiAj86PZ96llmGZ_3jf0yjVP0S94,5039
78
+ tests/unit_tests/test_editor.py,sha256=TED5k1xFJHRZ4KDAg2VxSRu_hMJnra-lbAmVwsDicsM,6784
79
+ tests/unit_tests/test_eiger_plot.py,sha256=bWnKBQid0YcLMQeBLy6ojb4ZpwTG-rFVT0kMg9Y08p8,4427
80
+ tests/unit_tests/test_generate_cli_client.py,sha256=BdpTZMNUFOBJa2e-rme9AJUoXfueYyLiUCOpGi3SNvc,2400
81
+ tests/unit_tests/test_motor_control.py,sha256=jdTG35z3jOL9XCAIDNIGfdv60vcwGLHa3KJjKqJkoZw,20322
82
+ tests/unit_tests/test_motor_map.py,sha256=UEjmtIYI2mxq9BUeopqoqNNy7UiPJEts9h45ufsFcrA,5979
83
+ tests/unit_tests/test_plot_base.py,sha256=bOdlgAxh9oKk5PwiQ_MSFmzr44uJ61Tlg242RCIhl5c,2610
84
+ tests/unit_tests/test_scan_control.py,sha256=7dtGpE0g4FqUhhQeCkyJl-9o7NH3DFZJgEaqDmBYbBc,7551
85
+ tests/unit_tests/test_stream_plot.py,sha256=LNCYIj9CafremGaz-DwDktCRJRrjgfOdVewCUwwZE5s,5843
86
+ tests/unit_tests/test_validator_errors.py,sha256=NFxyv0TIOXeZKZRRUBfVQ7bpunwY4KkG95yTUdQmvns,3532
87
+ tests/unit_tests/test_waveform1d.py,sha256=-YfBi_m91sR_v4oj8rshARk4G6AOxqQB_gbVqJ3iXvY,15003
88
+ tests/unit_tests/test_widget_io.py,sha256=FeL3ZYSBQnRt6jxj8VGYw1cmcicRQyHKleahw7XIyR0,3475
89
+ tests/unit_tests/test_yaml_dialog.py,sha256=HNrqferkdg02-9ieOhhI2mr2Qvt7GrYgXmQ061YCTbg,5794
90
+ tests/unit_tests/test_msgs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
91
+ tests/unit_tests/test_msgs/available_scans_message.py,sha256=m_z97hIrjHXXMa2Ex-UvsPmTxOYXfjxyJaGkIY6StTY,46532
92
+ bec_widgets-0.46.4.dist-info/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
93
+ bec_widgets-0.46.4.dist-info/METADATA,sha256=uahRMbNnY6SHjDVtXPrrsxICHZdsTayTZLeyUUu1u9w,3714
94
+ bec_widgets-0.46.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
95
+ bec_widgets-0.46.4.dist-info/top_level.txt,sha256=EXCwhJYmXmd1DjYYL3hrGsddX-97IwYSiIHrf27FFVk,18
96
+ bec_widgets-0.46.4.dist-info/RECORD,,
@@ -0,0 +1,14 @@
1
+ import pytest
2
+
3
+ from bec_widgets.utils import bec_dispatcher as bec_dispatcher_module
4
+
5
+
6
+ @pytest.fixture(autouse=True)
7
+ def bec_dispatcher(threads_check):
8
+ bec_dispatcher = bec_dispatcher_module.BECDispatcher()
9
+ yield bec_dispatcher
10
+ bec_dispatcher.disconnect_all()
11
+ # clean BEC client
12
+ bec_dispatcher.client.shutdown()
13
+ # reinitialize singleton for next test
14
+ bec_dispatcher_module.BECDispatcher.reset_singleton()
File without changes
@@ -1,6 +1,4 @@
1
1
  # pylint: disable = no-name-in-module,missing-class-docstring, missing-module-docstring
2
- import os
3
- import pickle
4
2
  from unittest.mock import MagicMock
5
3
 
6
4
  import pytest
@@ -8,8 +6,7 @@ from qtpy.QtWidgets import QLineEdit
8
6
 
9
7
  from bec_widgets.utils.widget_io import WidgetIO
10
8
  from bec_widgets.widgets import ScanControl
11
-
12
- from .test_msgs.available_scans_message import available_scans_message
9
+ from tests.unit_tests.test_msgs.available_scans_message import available_scans_message
13
10
 
14
11
 
15
12
  class FakePositioner:
tests/conftest.py DELETED
@@ -1,36 +0,0 @@
1
- import threading
2
-
3
- import pytest
4
- from bec_lib.bec_service import BECService
5
-
6
- from bec_widgets.utils import bec_dispatcher as bec_dispatcher_module
7
-
8
-
9
- @pytest.fixture()
10
- def threads_check():
11
- current_threads = set(
12
- th
13
- for th in threading.enumerate()
14
- if "loguru" not in th.name and th is not threading.main_thread()
15
- )
16
- yield
17
- threads_after = set(
18
- th
19
- for th in threading.enumerate()
20
- if "loguru" not in th.name and th is not threading.main_thread()
21
- )
22
- additional_threads = threads_after - current_threads
23
- assert (
24
- len(additional_threads) == 0
25
- ), f"Test creates {len(additional_threads)} threads that are not cleaned: {additional_threads}"
26
-
27
-
28
- @pytest.fixture(autouse=True)
29
- def bec_dispatcher(threads_check):
30
- bec_dispatcher = bec_dispatcher_module.BECDispatcher()
31
- yield bec_dispatcher
32
- bec_dispatcher.disconnect_all()
33
- # clean BEC client
34
- bec_dispatcher.client.shutdown()
35
- # reinitialize singleton for next test
36
- bec_dispatcher_module.BECDispatcher.reset_singleton()
File without changes
File without changes
File without changes