bapsf-motion 0.2.1__tar.gz → 0.2.2__tar.gz

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 (154) hide show
  1. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/PKG-INFO +3 -1
  2. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/actors/axis_.py +2 -2
  3. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/actors/drive_.py +9 -3
  4. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/actors/motion_group_.py +2 -2
  5. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/actors/motor_.py +65 -4
  6. bapsf_motion-0.2.2/bapsf_motion/gui/__init__.py +14 -0
  7. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/gui/configure/__init__.py +11 -5
  8. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/gui/configure/bases.py +14 -24
  9. bapsf_motion-0.2.2/bapsf_motion/gui/configure/configure.qss +11 -0
  10. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/gui/configure/configure_.py +76 -59
  11. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/gui/configure/drive_overlay.py +33 -48
  12. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/gui/configure/motion_builder_overlay.py +265 -102
  13. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/gui/configure/motion_group_widget.py +1235 -329
  14. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/gui/configure/transform_overlay.py +75 -32
  15. bapsf_motion-0.2.2/bapsf_motion/gui/helpers.py +41 -0
  16. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/gui/widgets/__init__.py +14 -0
  17. bapsf_motion-0.2.2/bapsf_motion/gui/widgets/buttons.py +555 -0
  18. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/gui/widgets/logging.py +60 -53
  19. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/gui/widgets/misc.py +40 -2
  20. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/motion_builder/exclusions/divider.py +1 -1
  21. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/utils/__init__.py +11 -6
  22. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion.egg-info/PKG-INFO +3 -1
  23. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion.egg-info/SOURCES.txt +2 -0
  24. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion.egg-info/requires.txt +2 -0
  25. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/requirements/gui.txt +1 -0
  26. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/setup.cfg +1 -0
  27. bapsf_motion-0.2.1/bapsf_motion/gui/__init__.py +0 -4
  28. bapsf_motion-0.2.1/bapsf_motion/gui/widgets/buttons.py +0 -290
  29. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/.gitattributes +0 -0
  30. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/.github/dependabot.yml +0 -0
  31. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/.github/workflows/python-publish.yml +0 -0
  32. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/.github/workflows/test.yml +0 -0
  33. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/.gitignore +0 -0
  34. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/.readthedocs.yml +0 -0
  35. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/README.md +0 -0
  36. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/__init__.py +0 -0
  37. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/actors/__init__.py +0 -0
  38. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/actors/base.py +0 -0
  39. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/actors/demos/__init__.py +0 -0
  40. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/actors/demos/drive_timed_run_1D.py +0 -0
  41. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/actors/demos/drive_timed_run_2D.py +0 -0
  42. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/actors/demos/mgroup_timed_run_2D.py +0 -0
  43. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/actors/manager_.py +0 -0
  44. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/actors/tests/__init__.py +0 -0
  45. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/examples/20240627_2D_test_setup.toml +0 -0
  46. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/examples/20241004_2D_test_setup.toml +0 -0
  47. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/examples/bapsf_motion.toml +0 -0
  48. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/examples/benchtop_motion_group.toml +0 -0
  49. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/examples/benchtop_run.toml +0 -0
  50. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/examples/mg_1d.toml +0 -0
  51. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/examples/mg_2d_strb_test_setup.toml +0 -0
  52. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/examples/motion_group.toml +0 -0
  53. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/gui/configure/helpers.py +0 -0
  54. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/gui/motor.py +0 -0
  55. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/motion_builder/__init__.py +0 -0
  56. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/motion_builder/core.py +0 -0
  57. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/motion_builder/exclusions/__init__.py +0 -0
  58. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/motion_builder/exclusions/base.py +0 -0
  59. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/motion_builder/exclusions/circular.py +0 -0
  60. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/motion_builder/exclusions/helpers.py +0 -0
  61. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/motion_builder/exclusions/lapd.py +0 -0
  62. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/motion_builder/exclusions/shadow.py +0 -0
  63. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/motion_builder/item.py +0 -0
  64. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/motion_builder/layers/__init__.py +0 -0
  65. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/motion_builder/layers/base.py +0 -0
  66. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/motion_builder/layers/helpers.py +0 -0
  67. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/motion_builder/layers/regular_grid.py +0 -0
  68. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/transform/__init__.py +0 -0
  69. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/transform/base.py +0 -0
  70. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/transform/helpers.py +0 -0
  71. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/transform/identity.py +0 -0
  72. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/transform/lapd.py +0 -0
  73. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/transform/lapd_droop.py +0 -0
  74. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/utils/exceptions.py +0 -0
  75. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/utils/toml.py +0 -0
  76. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion/utils/units_.py +0 -0
  77. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion.egg-info/dependency_links.txt +0 -0
  78. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/bapsf_motion.egg-info/top_level.txt +0 -0
  79. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/Makefile +0 -0
  80. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/_static/BaPSF_Logo_Color_RGB.png +0 -0
  81. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/_static/BaPSF_Logo_Color_yellow_background_RGB_32px.ico +0 -0
  82. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/_static/BaPSF_Logo_White_RGB.png +0 -0
  83. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/_static/BaPSF_Logo_White_RGB_150px.png +0 -0
  84. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/_static/css/overrides.css +0 -0
  85. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.actors.axis_.rst +0 -0
  86. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.actors.base.rst +0 -0
  87. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.actors.drive_.rst +0 -0
  88. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.actors.manager_.rst +0 -0
  89. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.actors.motion_group_.rst +0 -0
  90. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.actors.motor_.rst +0 -0
  91. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.actors.rst +0 -0
  92. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.gui.configure.rst +0 -0
  93. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.gui.motor.rst +0 -0
  94. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.gui.rst +0 -0
  95. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.gui.widgets.buttons.rst +0 -0
  96. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.gui.widgets.logging.rst +0 -0
  97. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.gui.widgets.misc.rst +0 -0
  98. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.gui.widgets.rst +0 -0
  99. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.motion_builder.core.rst +0 -0
  100. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.motion_builder.exclusions.base.rst +0 -0
  101. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.motion_builder.exclusions.circular.rst +0 -0
  102. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.motion_builder.exclusions.divider.rst +0 -0
  103. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.motion_builder.exclusions.helpers.rst +0 -0
  104. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.motion_builder.exclusions.lapd.rst +0 -0
  105. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.motion_builder.exclusions.rst +0 -0
  106. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.motion_builder.exclusions.shadow.rst +0 -0
  107. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.motion_builder.item.rst +0 -0
  108. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.motion_builder.layers.base.rst +0 -0
  109. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.motion_builder.layers.helpers.rst +0 -0
  110. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.motion_builder.layers.regular_grid.rst +0 -0
  111. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.motion_builder.layers.rst +0 -0
  112. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.motion_builder.rst +0 -0
  113. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.rst +0 -0
  114. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.transform.base.rst +0 -0
  115. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.transform.helpers.rst +0 -0
  116. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.transform.identity.rst +0 -0
  117. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.transform.lapd.rst +0 -0
  118. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.transform.lapd_droop.rst +0 -0
  119. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.transform.rst +0 -0
  120. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.utils.exceptions.rst +0 -0
  121. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.utils.rst +0 -0
  122. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.utils.toml.rst +0 -0
  123. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/api_static/bapsf_motion.utils.units_.rst +0 -0
  124. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/available_transformers.rst +0 -0
  125. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/bibliography.bib +0 -0
  126. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/bibliography.rst +0 -0
  127. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/common_links.rst +0 -0
  128. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/conf.py +0 -0
  129. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/glossary.rst +0 -0
  130. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/index.rst +0 -0
  131. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/make.bat +0 -0
  132. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/motion_builder/index.rst +0 -0
  133. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/notebooks/motion_list/CircularExclusion.ipynb +0 -0
  134. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/notebooks/motion_list/LaPDXYExclusion.ipynb +0 -0
  135. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/notebooks/motion_list/Shadow2DExclusion.ipynb +0 -0
  136. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/notebooks/motion_list/motionlist.ipynb +0 -0
  137. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/notebooks/prototypes/README.md +0 -0
  138. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/notebooks/transform/identity_transform.ipynb +0 -0
  139. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/notebooks/transform/lapd_xy_droop_correction.ipynb +0 -0
  140. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/notebooks/transform/lapd_xy_transform.ipynb +0 -0
  141. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/notebooks_.rst +0 -0
  142. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/robots.txt +0 -0
  143. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/docs/toml/index.rst +0 -0
  144. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/pyproject.toml +0 -0
  145. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/requirements/build.txt +0 -0
  146. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/requirements/docs.txt +0 -0
  147. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/requirements/extras.txt +0 -0
  148. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/requirements/install.txt +0 -0
  149. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/requirements/readthedocs.txt +0 -0
  150. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/requirements/tests.txt +0 -0
  151. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/requirements.txt +0 -0
  152. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/resources/README.md +0 -0
  153. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/resources/Remote module installation guide.pdf +0 -0
  154. {bapsf_motion-0.2.1 → bapsf_motion-0.2.2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: bapsf_motion
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Package for controlling motion devices in a BaPSF DAQ system
5
5
  Author: Basic Plasma Science Facility
6
6
  Keywords: plasma physics,plasma,science,bapsf,motion
@@ -30,6 +30,7 @@ Requires-Dist: tomli_w
30
30
  Requires-Dist: tqdm
31
31
  Requires-Dist: xarray
32
32
  Provides-Extra: gui
33
+ Requires-Dist: pygame; extra == "gui"
33
34
  Requires-Dist: PySide6; python_version >= "3.10" and extra == "gui"
34
35
  Requires-Dist: PySide6<=6.3.1; python_version < "3.10" and extra == "gui"
35
36
  Requires-Dist: qtawesome; extra == "gui"
@@ -62,6 +63,7 @@ Provides-Extra: extras
62
63
  Requires-Dist: black; extra == "extras"
63
64
  Requires-Dist: isort; extra == "extras"
64
65
  Provides-Extra: developer
66
+ Requires-Dist: pygame; extra == "developer"
65
67
  Requires-Dist: PySide6; python_version >= "3.10" and extra == "developer"
66
68
  Requires-Dist: PySide6<=6.3.1; python_version < "3.10" and extra == "developer"
67
69
  Requires-Dist: qtawesome; extra == "developer"
@@ -354,10 +354,10 @@ class Axis(EventActor):
354
354
  """
355
355
  return self.send_command("move_to", *args)
356
356
 
357
- def stop(self):
357
+ def stop(self, soft=False):
358
358
  """
359
359
  Quick access command for ``send_command("stop")``.
360
360
  """
361
361
  # not sending STOP command through send_command() since using
362
362
  # motor.stop() should result in faster execution
363
- return self.motor.stop()
363
+ return self.motor.stop(soft=soft)
@@ -292,7 +292,7 @@ class Drive(EventActor):
292
292
  Any arguments to the ``command`` that will be sent with the
293
293
  motor command.
294
294
  axis: int, optional
295
- Axis index the comment is directed to. If `None`, then the
295
+ Axis index the command is directed to. If `None`, then the
296
296
  command is sent to all axes. (DEFAULT: `NONE`)
297
297
  """
298
298
  if axis is None:
@@ -365,14 +365,20 @@ class Drive(EventActor):
365
365
 
366
366
  return rtn
367
367
 
368
- def stop(self):
368
+ def stop(self, soft=False):
369
369
  """Stop all axes from moving."""
370
370
  # TODO: should I really be construct a return here?
371
371
  # TODO: is there a quicker/more efficient way of stopping the motors?
372
372
 
373
373
  rtn = []
374
374
  for ax in self.axes:
375
- _rtn = ax.stop()
375
+ if ax.motor.terminated:
376
+ self.logger.warning(
377
+ f"Motor for axis {ax.name} has been terminated, can NOT "
378
+ f"perform STOP command."
379
+ )
380
+ continue
381
+ _rtn = ax.stop(soft=soft)
376
382
  rtn.append(_rtn)
377
383
 
378
384
  return rtn
@@ -924,9 +924,9 @@ class MotionGroup(EventActor):
924
924
  ).squeeze()
925
925
  return pos * dr_pos.unit
926
926
 
927
- def stop(self):
927
+ def stop(self, soft=False):
928
928
  """Immediately stop the probe drive motion."""
929
- self.drive.stop()
929
+ self.drive.stop(soft=soft)
930
930
 
931
931
  def move_to(self, pos, axis: Optional[int] = None):
932
932
  """
@@ -275,6 +275,12 @@ class Motor(EventActor):
275
275
  recv=re.compile(r"BS=(?P<return>[0-9]\.?[0-9]?)"),
276
276
  recv_processor=int,
277
277
  ),
278
+ "commence_jogging": CommandEntry("commence_jogging", send="CJ"),
279
+ "continuous_jog": CommandEntry(
280
+ "continuous_jog",
281
+ send="",
282
+ method_command=True,
283
+ ),
278
284
  "current": CommandEntry(
279
285
  "change_current",
280
286
  send="CC",
@@ -341,6 +347,33 @@ class Motor(EventActor):
341
347
  recv_processor=float,
342
348
  two_way=True,
343
349
  ),
350
+ "jog_acceleration": CommandEntry(
351
+ "jog_acceleration",
352
+ send="JA",
353
+ send_processor=lambda value: f"{float(value):.3f}",
354
+ recv=re.compile(r"JA=(?P<return>[0-9]+\.?[0-9]*)"),
355
+ recv_processor=float,
356
+ two_way=True,
357
+ units=u.rev / u.s / u.s,
358
+ ),
359
+ "jog_deceleration": CommandEntry(
360
+ "jog_deceleration",
361
+ send="JL",
362
+ send_processor=lambda value: f"{float(value):.3f}",
363
+ recv=re.compile(r"JL=(?P<return>[0-9]+\.?[0-9]*)"),
364
+ recv_processor=float,
365
+ two_way=True,
366
+ units=u.rev / u.s / u.s,
367
+ ),
368
+ "jog_speed": CommandEntry(
369
+ "jog_speed",
370
+ send="JS",
371
+ send_processor=lambda value: f"{float(value):.4f}",
372
+ recv=re.compile(r"JS=(?P<return>[0-9]+\.?[0-9]*)"),
373
+ recv_processor=float,
374
+ two_way=True,
375
+ units=u.rev / u.s,
376
+ ),
344
377
  "kill": CommandEntry(
345
378
  "stop_and_kill", # immediately stop moving and erase queue
346
379
  send="SK",
@@ -418,7 +451,11 @@ class Motor(EventActor):
418
451
  two_way=True,
419
452
  units=u.rev / u.s,
420
453
  ),
421
- "stop": CommandEntry("stop", send="SK"),
454
+ "stop": CommandEntry(
455
+ "stop",
456
+ send="SK",
457
+ send_processor=lambda soft: "D" if bool(soft) else "",
458
+ ),
422
459
  "target_distance": CommandEntry(
423
460
  "target_distance",
424
461
  send="DI",
@@ -699,7 +736,7 @@ class Motor(EventActor):
699
736
 
700
737
  def _lost_connection(self, rtn: Any = None):
701
738
  """
702
- Check if the motor connection as lost by examining the return
739
+ Check if the motor connection was lost by examining the return
703
740
  value from send_command.
704
741
  """
705
742
  if rtn is None:
@@ -732,6 +769,7 @@ class Motor(EventActor):
732
769
 
733
770
  # set a slower speed
734
771
  self.send_command("speed", 4.0)
772
+ self.send_command("jog_speed", 4.0)
735
773
 
736
774
  def _read_and_set_protocol(self):
737
775
  """
@@ -1627,9 +1665,32 @@ class Motor(EventActor):
1627
1665
  except AttributeError:
1628
1666
  pass
1629
1667
 
1630
- def stop(self):
1668
+ def continuous_jog(self, direction="forward"):
1669
+ """
1670
+ Start a continuous jog. The motor will not stop until
1671
+ commanded to.
1672
+ """
1673
+ if self.status["alarm"]:
1674
+ self.send_command("alarm_reset")
1675
+ alarm_msg = self.retrieve_motor_alarm(defer_status_update=True)
1676
+
1677
+ if self._lost_connection(alarm_msg) or alarm_msg["alarm_message"]:
1678
+ self.logger.error(
1679
+ f"Motor alarm could not be reset. -- {alarm_msg}"
1680
+ )
1681
+ return None
1682
+
1683
+ self.enable()
1684
+
1685
+ # The direction of the commence_jogging is defined by the side
1686
+ # of the target_distance (DI) command
1687
+ direction = -1 if direction == "backward" else 1
1688
+ self.send_command("target_distance", direction)
1689
+ self.send_command("commence_jogging")
1690
+
1691
+ def stop(self, soft=False):
1631
1692
  """Stop motor movement."""
1632
- self.send_command("stop")
1693
+ self.send_command("stop", soft)
1633
1694
 
1634
1695
  def move_to(self, pos: int):
1635
1696
  """
@@ -0,0 +1,14 @@
1
+ """Subpackage containing GUI's for `bapsf_motion`."""
2
+ __all__ = [
3
+ "ConfigureApp",
4
+ "get_qapplication",
5
+ "get_color_scheme",
6
+ "cast_color_to_rgba_string",
7
+ ]
8
+
9
+ from bapsf_motion.gui.configure.configure_ import ConfigureApp
10
+ from bapsf_motion.gui.helpers import (
11
+ get_qapplication,
12
+ get_color_scheme,
13
+ cast_color_to_rgba_string,
14
+ )
@@ -5,7 +5,8 @@ if __name__ == "__main__":
5
5
  import argparse
6
6
  import pathlib
7
7
 
8
- from PySide6.QtWidgets import QApplication
8
+ # from PySide6.QtWidgets import QApplication
9
+ from bapsf_motion.gui.configure.configure_ import ConfigureApp
9
10
 
10
11
  parser = argparse.ArgumentParser(
11
12
  description="Launch the bapsf_motion Configuration GUI (ConfigureGUI)",
@@ -36,12 +37,17 @@ if __name__ == "__main__":
36
37
  elif args.config_file is not None:
37
38
  args.config_file = args.config_file.resolve()
38
39
 
39
- app = QApplication([])
40
+ # app = QApplication([])
41
+ #
42
+ # window = ConfigureGUI(
43
+ # config=args.config_file,
44
+ # defaults=args.defaults_file,
45
+ # )
46
+ # window.show()
40
47
 
41
- window = ConfigureGUI(
48
+ app = ConfigureApp(
49
+ [],
42
50
  config=args.config_file,
43
51
  defaults=args.defaults_file,
44
52
  )
45
- window.show()
46
-
47
53
  app.exec()
@@ -4,13 +4,13 @@ import logging
4
4
 
5
5
  from abc import abstractmethod
6
6
  from PySide6.QtCore import Qt, Signal
7
- from PySide6.QtGui import QColor, QPainter
7
+ from PySide6.QtGui import QColor, QPainter, QPen
8
8
  from PySide6.QtWidgets import QWidget, QSizePolicy
9
9
  from typing import Union
10
10
 
11
11
  from bapsf_motion.actors import MotionGroup
12
12
  from bapsf_motion.gui.configure.helpers import gui_logger
13
- from bapsf_motion.gui.widgets import StyleButton
13
+ from bapsf_motion.gui.widgets import DiscardButton, DoneButton
14
14
  from bapsf_motion.gui.configure import motion_group_widget as mgw
15
15
 
16
16
 
@@ -24,13 +24,15 @@ class _OverlayWidget(QWidget):
24
24
  # self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
25
25
  self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
26
26
  self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
27
- self.setStyleSheet("_OverlayWidget{ border: 2px solid black }")
28
27
 
29
- self.background_fill_color = QColor(30, 30, 30, 120)
30
- self.background_pen_color = QColor(30, 30, 30, 120)
28
+ self.background_fill_color = QColor(30, 30, 30, 100)
29
+ self.background_pen_color = QColor(30, 30, 30, 200)
31
30
 
32
- self.overlay_fill_color = QColor(50, 50, 50)
33
- self.overlay_pen_color = QColor(90, 90, 90)
31
+ _palette = self.style().standardPalette()
32
+ self.overlay_fill_color = _palette.color(_palette.ColorRole.Window)
33
+
34
+ self.overlay_pen = QPen(QColor(60, 60, 60))
35
+ self.overlay_pen.setWidth(3)
34
36
 
35
37
  self._margins = [0.01, 0.01] # [ w_margin / width, h_margin / height]
36
38
  self._set_contents_margins(*self._margins)
@@ -55,7 +57,9 @@ class _OverlayWidget(QWidget):
55
57
  qp.drawRoundedRect(0, 0, s.width(), s.height(), 3, 3)
56
58
 
57
59
  # draw overlay
58
- qp.setPen(self.overlay_pen_color)
60
+ _pen = QPen(self.overlay_pen)
61
+ _pen.setWidth(3)
62
+ qp.setPen(_pen)
59
63
  qp.setBrush(self.overlay_fill_color)
60
64
 
61
65
  self.contentsRect().width()
@@ -89,25 +93,11 @@ class _ConfigOverlay(_OverlayWidget):
89
93
 
90
94
  # Define BUTTONS
91
95
 
92
- _btn = StyleButton("Add / Update", parent=self)
93
- _btn.setFixedWidth(200)
94
- _btn.setFixedHeight(48)
95
- font = _btn.font()
96
- font.setPointSize(24)
97
- _btn.setFont(font)
96
+ _btn = DoneButton("Add / Update", parent=self)
98
97
  _btn.setEnabled(False)
99
98
  self.done_btn = _btn
100
99
 
101
- _btn = StyleButton("Discard", parent=self)
102
- _btn.setFixedWidth(250)
103
- _btn.setFixedHeight(48)
104
- font = _btn.font()
105
- font.setPointSize(24)
106
- font.setBold(True)
107
- _btn.setFont(font)
108
- _btn.update_style_sheet(
109
- {"background-color": "rgb(255, 110, 110)"}
110
- )
100
+ _btn = DiscardButton(parent=self)
111
101
  self.discard_btn = _btn
112
102
 
113
103
  def _connect_signals(self):
@@ -0,0 +1,11 @@
1
+ /* This is the QSS (similar to CSS) Style Sheet for the ConfigureGUI
2
+ *
3
+ * Useful links:
4
+ *
5
+ * - Qt Style Sheets
6
+ * https://doc.qt.io/qt-6/stylesheet.html
7
+ * - Style Sheet Syntax
8
+ * https://doc.qt.io/qt-6/stylesheet-syntax.html
9
+ * - Style Sheet Reference
10
+ * https://doc.qt.io/qt-6/stylesheet-reference.html
11
+ */
@@ -1,7 +1,7 @@
1
1
  """
2
2
  This module defines the configuration GUI for construction data runs.
3
3
  """
4
- __all__ = ["ConfigureGUI"]
4
+ __all__ = ["ConfigureGUI", "ConfigureApp"]
5
5
 
6
6
  import logging
7
7
  import logging.config
@@ -16,6 +16,7 @@ from PySide6.QtCore import (
16
16
  )
17
17
  from PySide6.QtGui import QCloseEvent, QIcon
18
18
  from PySide6.QtWidgets import (
19
+ QApplication,
19
20
  QMainWindow,
20
21
  QHBoxLayout,
21
22
  QLabel,
@@ -30,7 +31,7 @@ from PySide6.QtWidgets import (
30
31
  QStackedWidget,
31
32
  QListWidgetItem,
32
33
  )
33
- from typing import Any, Dict, Optional, Union
34
+ from typing import Any, Dict, Union
34
35
 
35
36
  # noqa
36
37
  # import of qtawesome must happen after the PySide6 imports
@@ -39,10 +40,19 @@ import qtawesome as qta
39
40
  from bapsf_motion.actors import RunManager, RunManagerConfig, MotionGroup
40
41
  from bapsf_motion.gui.configure.helpers import gui_logger, gui_logger_config_dict
41
42
  from bapsf_motion.gui.configure.motion_group_widget import MGWidget
42
- from bapsf_motion.gui.widgets import QLogger, StyleButton, VLinePlain
43
+ from bapsf_motion.gui.widgets import (
44
+ DiscardButton,
45
+ DoneButton,
46
+ QLogger,
47
+ StyleButton,
48
+ VLinePlain,
49
+ )
43
50
  from bapsf_motion.utils import toml, _deepcopy_dict
44
51
 
45
52
 
53
+ _HERE = Path(__file__).parent
54
+
55
+
46
56
  class RunWidget(QWidget):
47
57
  def __init__(self, parent: "ConfigureGUI"):
48
58
  super().__init__(parent=parent)
@@ -51,68 +61,47 @@ class RunWidget(QWidget):
51
61
 
52
62
  # Define BUTTONS
53
63
 
54
- _btn = StyleButton("DONE")
55
- _btn.setFixedWidth(200)
56
- _btn.setFixedHeight(48)
57
- font = _btn.font()
58
- font.setPointSize(24)
59
- _btn.setFont(font)
60
- self.done_btn = _btn
64
+ self.done_btn = DoneButton(parent=self)
65
+ self.quit_btn = DiscardButton("Discard && Quit", parent=self)
61
66
 
62
- _btn = StyleButton("Discard && Quit")
63
- _btn.setFixedWidth(200)
67
+ _btn = StyleButton("IMPORT", parent=self)
64
68
  _btn.setFixedHeight(48)
65
- font = _btn.font()
66
- font.setPointSize(24)
67
- font.setBold(True)
68
- _btn.setFont(font)
69
- _btn.update_style_sheet({"background-color": "rgb(255, 110, 110)"})
70
- self.quit_btn = _btn
71
-
72
- _btn = StyleButton("IMPORT")
73
- _btn.setFixedHeight(28)
74
- font = _btn.font()
75
- font.setPointSize(16)
76
- _btn.setFont(font)
69
+ _btn.setPointSize(16)
70
+ _btn.setEnabled(False)
77
71
  self.import_btn = _btn
78
72
 
79
- _btn = StyleButton("EXPORT")
80
- _btn.setFixedHeight(28)
81
- font = _btn.font()
82
- font.setPointSize(16)
83
- _btn.setFont(font)
73
+ _btn = StyleButton("EXPORT", parent=self)
74
+ _btn.setFixedHeight(48)
75
+ _btn.setPointSize(16)
76
+ _btn.setEnabled(False)
84
77
  self.export_btn = _btn
85
78
 
86
- _btn = StyleButton("ADD")
87
- _btn.setFixedHeight(32)
88
- font = _btn.font()
89
- font.setPointSize(16)
90
- _btn.setFont(font)
91
- _btn.setEnabled(True)
79
+ _btn = StyleButton("ADD", parent=self)
80
+ _btn.setFixedHeight(38)
81
+ _btn.setPointSize(16)
92
82
  self.add_mg_btn = _btn
93
83
 
94
- _btn = StyleButton("REMOVE")
95
- _btn.setFixedHeight(32)
96
- font = _btn.font()
97
- font.setPointSize(16)
98
- _btn.setFont(font)
84
+ _btn = StyleButton("REMOVE", parent=self)
85
+ _btn.setFixedHeight(38)
86
+ _btn.setPointSize(16)
99
87
  _btn.setEnabled(False)
100
88
  self.remove_mg_btn = _btn
101
89
 
102
- _btn = StyleButton("Edit / Control")
103
- _btn.setFixedHeight(32)
104
- font = _btn.font()
105
- font.setPointSize(16)
106
- _btn.setFont(font)
90
+ _btn = StyleButton("Edit / Control", parent=self)
91
+ _btn.setFixedHeight(38)
92
+ _btn.setPointSize(16)
107
93
  _btn.setEnabled(False)
108
94
  self.modify_mg_btn = _btn
109
95
 
110
96
  # Define TEXT WIDGETS
111
97
 
112
- self.config_widget = QTextEdit()
113
- self.mg_list_widget = QListWidget()
98
+ self.config_widget = QTextEdit(parent=self)
99
+ self.mg_list_widget = QListWidget(parent=self)
100
+ _font = self.mg_list_widget.font()
101
+ _font.setPointSize(14)
102
+ self.mg_list_widget.setFont(_font)
114
103
 
115
- _txt_widget = QLineEdit()
104
+ _txt_widget = QLineEdit(parent=self)
116
105
  font = _txt_widget.font()
117
106
  font.setPointSize(16)
118
107
  _txt_widget.setFont(font)
@@ -128,14 +117,14 @@ class RunWidget(QWidget):
128
117
  banner_layout = self._define_banner_layout()
129
118
 
130
119
  # Create layout for toml window
131
- toml_widget = QWidget()
120
+ toml_widget = QWidget(parent=self)
132
121
  toml_widget.setLayout(self._define_toml_layout())
133
122
  toml_widget.setMinimumWidth(400)
134
123
  toml_widget.setMinimumWidth(500)
135
124
  toml_widget.sizeHint().setWidth(450)
136
125
 
137
126
  # Create layout for controls
138
- control_widget = QWidget()
127
+ control_widget = QWidget(parent=self)
139
128
  control_widget.setLayout(self._define_control_layout())
140
129
 
141
130
  # Construct layout below top banner
@@ -153,7 +142,7 @@ class RunWidget(QWidget):
153
142
 
154
143
  def _define_toml_layout(self):
155
144
  layout = QGridLayout()
156
- label = QLabel("Run Configuration")
145
+ label = QLabel("Run Configuration", parent=self)
157
146
  label.setAlignment(
158
147
  Qt.AlignmentFlag.AlignCenter | Qt.AlignmentFlag.AlignBottom
159
148
  )
@@ -171,8 +160,8 @@ class RunWidget(QWidget):
171
160
 
172
161
  layout.addWidget(label, 0, 0, 1, 2)
173
162
  layout.addWidget(self.config_widget, 1, 0, 1, 2)
174
- layout.addWidget(self.import_btn, 2, 0, 1, 1)
175
- layout.addWidget(self.export_btn, 2, 1, 1, 1)
163
+ layout.addWidget(self.import_btn, 2, 0)
164
+ layout.addWidget(self.export_btn, 2, 1)
176
165
 
177
166
  return layout
178
167
 
@@ -188,7 +177,7 @@ class RunWidget(QWidget):
188
177
  def _define_control_layout(self):
189
178
  layout = QVBoxLayout()
190
179
 
191
- run_label = QLabel("Run Name: ")
180
+ run_label = QLabel("Run Name: ", parent=self)
192
181
  run_label.setAlignment(
193
182
  Qt.AlignmentFlag.AlignVCenter | Qt. AlignmentFlag.AlignLeft
194
183
  )
@@ -197,7 +186,7 @@ class RunWidget(QWidget):
197
186
  font.setPointSize(16)
198
187
  run_label.setFont(font)
199
188
 
200
- mg_label = QLabel("Defined Motion Groups")
189
+ mg_label = QLabel("Defined Motion Groups", parent=self)
201
190
  mg_label.setAlignment(
202
191
  Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignCenter
203
192
  )
@@ -237,7 +226,7 @@ class RunWidget(QWidget):
237
226
 
238
227
  @property
239
228
  def rm(self) -> Union[RunManager, None]:
240
- parent = self.parent() # type: "ConfigureGUI"
229
+ parent = self.parentWidget() # type: "ConfigureGUI"
241
230
  try:
242
231
  return parent.rm
243
232
  except AttributeError:
@@ -277,7 +266,7 @@ class ConfigureGUI(QMainWindow):
277
266
 
278
267
  # define "important" qt widgets
279
268
  self._log_widget = QLogger(self._logger, parent=self)
280
- self._run_widget = RunWidget(self)
269
+ self._run_widget = RunWidget(parent=self)
281
270
  self._mg_widget = None # type: Union[MGWidget, None]
282
271
 
283
272
  self._stacked_widget = QStackedWidget(parent=self)
@@ -324,7 +313,8 @@ class ConfigureGUI(QMainWindow):
324
313
  def _define_main_window(self):
325
314
  self.setWindowTitle("Run Configuration")
326
315
  self.resize(1760, 990)
327
- self.setMinimumHeight(600)
316
+ self.setMinimumHeight(990)
317
+ self.setMinimumWidth(1760)
328
318
 
329
319
  def _define_layout(self):
330
320
 
@@ -368,7 +358,7 @@ class ConfigureGUI(QMainWindow):
368
358
  return self._logging_config_dict
369
359
 
370
360
  def replace_rm(self, config):
371
- if isinstance(self.rm, RunManager) and not self.rm.terminate():
361
+ if isinstance(self.rm, RunManager) and not self.rm.terminated:
372
362
  self.rm.terminate()
373
363
 
374
364
  self.logger.info(f"Replacing the run manager with new config: {config}.")
@@ -603,3 +593,30 @@ class ConfigureGUI(QMainWindow):
603
593
  self._run_widget.close()
604
594
 
605
595
  event.accept()
596
+
597
+
598
+ class ConfigureApp(QApplication):
599
+ qss_file_path = (_HERE / "configure.qss").resolve()
600
+
601
+ def __init__(
602
+ self,
603
+ *args,
604
+ config: Union[Path, str, Dict[str, Any], RunManagerConfig] = None,
605
+ defaults: Union[Path, str, Dict[str, Any], None] = None,
606
+ **kwargs,
607
+ ) -> None:
608
+ super().__init__(*args, **kwargs)
609
+
610
+ self.setStyle("Fusion")
611
+ self.styleHints().setColorScheme(Qt.ColorScheme.Light)
612
+ self.reload_style_sheet()
613
+
614
+ self._window = ConfigureGUI(config=config, defaults=defaults)
615
+ self._window.show()
616
+ self._window.activateWindow()
617
+
618
+ def reload_style_sheet(self):
619
+ with open(self.qss_file_path, "r") as f:
620
+ qss_style = f.read()
621
+
622
+ self.setStyleSheet(qss_style)