bec-server 4.2.1__tar.gz → 4.3.1__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 (213) hide show
  1. {bec_server-4.2.1 → bec_server-4.3.1}/PKG-INFO +1 -1
  2. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/actors/worker.py +5 -15
  3. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/procedures/container_utils.py +3 -2
  4. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/procedures/container_worker.py +1 -1
  5. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/procedures/manager.py +32 -7
  6. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/procedures/oop_worker_base.py +22 -4
  7. bec_server-4.3.1/bec_server/procedures/subprocess_worker.py +144 -0
  8. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/procedures/worker_base.py +17 -6
  9. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scan_manager.py +4 -0
  10. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/fermat_scan.py +12 -2
  11. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/grid_scan.py +4 -1
  12. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/hexagonal_scan.py +10 -1
  13. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/line_scan.py +4 -1
  14. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/log_scan.py +4 -1
  15. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/multi_region_grid_scan.py +4 -1
  16. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/multi_region_line_scan.py +4 -1
  17. bec_server-4.3.1/bec_server/scan_server/scans/path_optimization.py +5 -0
  18. bec_server-4.3.1/bec_server/scan_server/scans/position_generators.py +33 -0
  19. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/round_roi_scan.py +13 -1
  20. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/round_scan.py +11 -1
  21. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/scan_base.py +12 -1
  22. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/scan_components.py +2 -2
  23. {bec_server-4.2.1 → bec_server-4.3.1}/pyproject.toml +1 -1
  24. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_actors/test_actors.py +27 -2
  25. bec_server-4.3.1/tests/tests_scan_server/scans/test_position_preview.py +61 -0
  26. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_container_utils.py +35 -0
  27. bec_server-4.3.1/tests/tests_scan_server/test_path_optimization.py +14 -0
  28. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_procedure_container_worker.py +119 -2
  29. bec_server-4.3.1/tests/tests_scan_server/test_procedure_subprocess_worker.py +121 -0
  30. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_procedures.py +95 -1
  31. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_scan_server_scan_manager.py +11 -0
  32. bec_server-4.2.1/bec_server/procedures/subprocess_worker.py +0 -73
  33. bec_server-4.2.1/bec_server/scan_server/scans/path_optimization.py +0 -503
  34. bec_server-4.2.1/bec_server/scan_server/scans/position_generators.py +0 -565
  35. bec_server-4.2.1/tests/tests_scan_server/scans/test_position_generators.py +0 -212
  36. bec_server-4.2.1/tests/tests_scan_server/test_path_optimization.py +0 -276
  37. {bec_server-4.2.1 → bec_server-4.3.1}/.gitignore +0 -0
  38. {bec_server-4.2.1 → bec_server-4.3.1}/.zed/debug.json +0 -0
  39. {bec_server-4.2.1 → bec_server-4.3.1}/README.md +0 -0
  40. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/__init__.py +0 -0
  41. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/actors/__init__.py +0 -0
  42. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/actors/actor.py +0 -0
  43. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/actors/builtin_actor_manager.py +0 -0
  44. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/actors/manager.py +0 -0
  45. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/actors/scan_interlock.py +0 -0
  46. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/bec_server_utils/__init__.py +0 -0
  47. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/bec_server_utils/launch.py +0 -0
  48. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/bec_server_utils/service_handler.py +0 -0
  49. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/bec_server_utils/subprocess_launch.py +0 -0
  50. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/bec_server_utils/tmux_launch.py +0 -0
  51. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/data_processing/__init__.py +0 -0
  52. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/data_processing/cli/__init__.py +0 -0
  53. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/data_processing/cli/launch.py +0 -0
  54. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/data_processing/dap_server.py +0 -0
  55. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/data_processing/dap_service.py +0 -0
  56. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/data_processing/dap_service_manager.py +0 -0
  57. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/data_processing/lmfit1d_service.py +0 -0
  58. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/device_server/__init__.py +0 -0
  59. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/device_server/bec_message_handler.py +0 -0
  60. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/device_server/cli/__init__.py +0 -0
  61. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/device_server/cli/launch.py +0 -0
  62. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/device_server/device_server.py +0 -0
  63. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/device_server/devices/__init__.py +0 -0
  64. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/device_server/devices/config_update_handler.py +0 -0
  65. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/device_server/devices/device_serializer.py +0 -0
  66. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/device_server/devices/devicemanager.py +0 -0
  67. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/device_server/friendly_device_exceptions.py +0 -0
  68. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/device_server/ophyd_callback_monitor.py +0 -0
  69. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/device_server/rpc_handler.py +0 -0
  70. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/device_server/tests/__init__.py +0 -0
  71. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/device_server/tests/utils.py +0 -0
  72. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/file_writer/__init__.py +0 -0
  73. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/file_writer/async_writer.py +0 -0
  74. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/file_writer/cli/__init__.py +0 -0
  75. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/file_writer/cli/launch.py +0 -0
  76. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/file_writer/default_writer.py +0 -0
  77. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/file_writer/file_writer.py +0 -0
  78. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/file_writer/file_writer_manager.py +0 -0
  79. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/file_writer/merged_dicts.py +0 -0
  80. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/procedures/Containerfile.bec_linux_base +0 -0
  81. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/procedures/Containerfile.requirements +0 -0
  82. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/procedures/Containerfile.worker +0 -0
  83. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/procedures/__init__.py +0 -0
  84. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/procedures/_dev_runner.py +0 -0
  85. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/procedures/builtin_procedures.py +0 -0
  86. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/procedures/constants.py +0 -0
  87. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/procedures/procedure_registry.py +0 -0
  88. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/procedures/protocol.py +0 -0
  89. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_bundler/__init__.py +0 -0
  90. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_bundler/bec_emitter.py +0 -0
  91. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_bundler/cli/__init__.py +0 -0
  92. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_bundler/cli/launch.py +0 -0
  93. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_bundler/emitter.py +0 -0
  94. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_bundler/scan_bundler.py +0 -0
  95. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/__init__.py +0 -0
  96. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/beamline_state_manager.py +0 -0
  97. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/cli/__init__.py +0 -0
  98. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/cli/launch.py +0 -0
  99. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/device_lock_registry.py +0 -0
  100. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/direct_scan_worker.py +0 -0
  101. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/errors.py +0 -0
  102. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/instruction_handler.py +0 -0
  103. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scan_assembler.py +0 -0
  104. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scan_guard.py +0 -0
  105. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scan_queue.py +0 -0
  106. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scan_server.py +0 -0
  107. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scan_worker.py +0 -0
  108. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/__init__.py +0 -0
  109. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/acquire.py +0 -0
  110. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/cont_line_scan.py +0 -0
  111. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/device_rpc.py +0 -0
  112. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/line_sweep_scan.py +0 -0
  113. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/list_scan.py +0 -0
  114. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/move.py +0 -0
  115. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/scan_actions.py +0 -0
  116. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/scan_argument_modifier.py +0 -0
  117. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/scan_modifier.py +0 -0
  118. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/scan_status.py +0 -0
  119. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/time_scan.py +0 -0
  120. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/scans/updated_move.py +0 -0
  121. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/tests/__init__.py +0 -0
  122. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/tests/fixtures.py +0 -0
  123. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/tests/scan_fixtures.py +0 -0
  124. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/tests/scan_hook_tests.py +0 -0
  125. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scan_server/tests/utils.py +0 -0
  126. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scihub/__init__.py +0 -0
  127. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scihub/atlas/__init__.py +0 -0
  128. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scihub/atlas/atlas_active_client_emitter.py +0 -0
  129. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scihub/atlas/atlas_connector.py +0 -0
  130. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scihub/atlas/atlas_forwarder.py +0 -0
  131. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scihub/atlas/atlas_metadata_handler.py +0 -0
  132. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scihub/atlas/atlas_plugin_repo_emitter.py +0 -0
  133. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scihub/atlas/config_handler.py +0 -0
  134. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scihub/cli/__init__.py +0 -0
  135. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scihub/cli/launch.py +0 -0
  136. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scihub/scihub.py +0 -0
  137. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scihub/service_handler/__init__.py +0 -0
  138. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/scihub/service_handler/service_handler.py +0 -0
  139. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/test/__init__.py +0 -0
  140. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/test/actor_test_utils.py +0 -0
  141. {bec_server-4.2.1 → bec_server-4.3.1}/bec_server/test/helpers.py +0 -0
  142. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_bec_server_utils/test_main.py +0 -0
  143. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_bec_server_utils/test_service_handler.py +0 -0
  144. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_bec_server_utils/test_subprocess_launch.py +0 -0
  145. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_bec_server_utils/test_tmux_launch.py +0 -0
  146. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_data_processing/conftest.py +0 -0
  147. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_data_processing/test_dap_cli_launch.py +0 -0
  148. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_data_processing/test_dap_server.py +0 -0
  149. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_data_processing/test_dap_service_manager.py +0 -0
  150. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_data_processing/test_lmfit1d_service.py +0 -0
  151. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_device_server/conftest.py +0 -0
  152. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_device_server/test_config_handler.py +0 -0
  153. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_device_server/test_device_instructions.py +0 -0
  154. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_device_server/test_device_manager_ds.py +0 -0
  155. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_device_server/test_device_serializer.py +0 -0
  156. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_device_server/test_device_server.py +0 -0
  157. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_device_server/test_device_server_cli_launch.py +0 -0
  158. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_device_server/test_ophyd_callback_monitor.py +0 -0
  159. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_device_server/test_rpc_handler.py +0 -0
  160. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_file_writer/conftest.py +0 -0
  161. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_file_writer/test_async_file_writer.py +0 -0
  162. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_file_writer/test_file_writer.py +0 -0
  163. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_file_writer/test_file_writer_cli_launch.py +0 -0
  164. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_file_writer/test_file_writer_manager.py +0 -0
  165. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_bundler/conftest.py +0 -0
  166. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_bundler/test_bec_emitter.py +0 -0
  167. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_bundler/test_scan_bundler.py +0 -0
  168. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_bundler/test_scan_bundler_cli_launch.py +0 -0
  169. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/conftest.py +0 -0
  170. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/__init__.py +0 -0
  171. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_acquire.py +0 -0
  172. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_cont_line_scan.py +0 -0
  173. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_device_rpc_scan.py +0 -0
  174. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_fermat_scan.py +0 -0
  175. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_grid_scan.py +0 -0
  176. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_hexagonal_scan.py +0 -0
  177. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_line_scan.py +0 -0
  178. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_line_sweep_scan.py +0 -0
  179. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_list_scan.py +0 -0
  180. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_log_scan.py +0 -0
  181. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_move_scan.py +0 -0
  182. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_multi_region_grid_scan.py +0 -0
  183. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_multi_region_line_scan.py +0 -0
  184. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_relative_scan_return_to_start.py +0 -0
  185. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_round_roi_scan.py +0 -0
  186. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_round_scan.py +0 -0
  187. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_scan_actions.py +0 -0
  188. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_scan_components.py +0 -0
  189. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_scan_status.py +0 -0
  190. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_time_scan.py +0 -0
  191. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/scans/test_updated_move_scan.py +0 -0
  192. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_beamline_state_manager.py +0 -0
  193. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_builtin_actor_manager.py +0 -0
  194. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_device_lock_registry.py +0 -0
  195. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_direct_scan_worker.py +0 -0
  196. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_instruction_handler.py +0 -0
  197. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_scan_argument_modifier.py +0 -0
  198. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_scan_assembler.py +0 -0
  199. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_scan_fixture_imports.py +0 -0
  200. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_scan_guard.py +0 -0
  201. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_scan_interlock.py +0 -0
  202. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_scan_modifier.py +0 -0
  203. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_scan_server_cli_launch.py +0 -0
  204. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_scan_server_queue.py +0 -0
  205. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scan_server/test_scan_worker.py +0 -0
  206. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scihub/conftest.py +0 -0
  207. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scihub/test_atlas_active_client_emitter.py +0 -0
  208. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scihub/test_atlas_config_handler.py +0 -0
  209. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scihub/test_atlas_connector.py +0 -0
  210. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scihub/test_atlas_forwarder.py +0 -0
  211. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scihub/test_atlas_metadata_handler.py +0 -0
  212. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scihub/test_atlas_plugin_repo_emitter.py +0 -0
  213. {bec_server-4.2.1 → bec_server-4.3.1}/tests/tests_scihub/test_scihub_cli_launch.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: bec-server
3
- Version: 4.2.1
3
+ Version: 4.3.1
4
4
  Summary: BEC server
5
5
  Project-URL: Bug Tracker, https://github.com/bec-project/bec/issues
6
6
  Project-URL: Homepage, https://github.com/bec-project/bec
@@ -1,14 +1,12 @@
1
1
  import importlib
2
2
  import os
3
- from contextlib import redirect_stdout
4
3
  from inspect import isclass
5
4
 
6
5
  from bec_lib.client import BECClient
7
- from bec_lib.logger import LogLevel, bec_logger
6
+ from bec_lib.logger import bec_logger
8
7
  from bec_lib.messages import ProcedureWorkerStatus
9
- from bec_lib.redis_connector import RedisConnector
10
8
  from bec_server.actors.actor import ActorBase
11
- from bec_server.procedures.oop_worker_base import RedisOutputDiverter, get_env, push_status, setup
9
+ from bec_server.procedures.oop_worker_base import get_env, push_status, setup
12
10
  from bec_server.procedures.subprocess_worker import SubProcessWorker
13
11
 
14
12
  logger = bec_logger.logger
@@ -53,20 +51,12 @@ def get_actor_env():
53
51
  def main():
54
52
  env, helper, client, conn = setup(get_env())
55
53
  actor_env = get_actor_env()
56
- logger_connector = RedisConnector(env["redis_server"])
57
- output_diverter = RedisOutputDiverter(logger_connector, env["queue"])
58
- with redirect_stdout(output_diverter):
59
- logger.add(
60
- output_diverter,
61
- level=LogLevel.SUCCESS,
62
- format=bec_logger.formatting(is_container=True),
63
- filter=bec_logger.filter(),
64
- )
65
- logger.success(f"Starting ActorProcedureWorker with env: {actor_env}")
54
+ # The parent SubProcessWorker streams stdout and stderr to Redis.
55
+ logger.success(f"Starting ActorProcedureWorker with env: {actor_env}")
66
56
  push_status(conn, env["queue"], ProcedureWorkerStatus.IDLE)
67
57
  actor_procedure(bec=client, **actor_env)
58
+ push_status(conn, env["queue"], ProcedureWorkerStatus.FINISHED)
68
59
  conn.shutdown()
69
- logger_connector.shutdown()
70
60
 
71
61
 
72
62
  if __name__ == "__main__":
@@ -220,7 +220,7 @@ class PodmanCliUtils(_PodmanUtilsBase):
220
220
  _name_arg = ["--replace", "--name", container_name] if container_name else []
221
221
  if container_name:
222
222
  # in case of incomplete cleanup previously, even with --replace it is possible to get an error
223
- _run_and_capture_error("podman", "rm", "-f", container_name)
223
+ _run_and_capture_error("podman", "rm", "-f", "--ignore", container_name)
224
224
  return (
225
225
  _run_and_capture_error(
226
226
  "podman",
@@ -251,7 +251,8 @@ class PodmanCliUtils(_PodmanUtilsBase):
251
251
 
252
252
  def logs(self, id: str) -> list[str]:
253
253
  try:
254
- return _run_and_capture_error("podman", "logs", id).stderr.decode().splitlines()
254
+ output = _run_and_capture_error("podman", "logs", id)
255
+ return (output.stdout + output.stderr).decode(errors="replace").splitlines()
255
256
  except ProcedureWorkerError as e:
256
257
  logger.error(e)
257
258
  return [f"No logs found for container {id}\n"]
@@ -28,7 +28,7 @@ class ContainerProcedureWorker(OutOfProcessWorkerBase):
28
28
  self._backend.build_worker_image()
29
29
  self._container_id = self._backend.run(
30
30
  image_tag,
31
- self._worker_environment(),
31
+ self._worker_environment() | self._additional_env,
32
32
  [
33
33
  {
34
34
  "source": str(PROCEDURE.CONTAINER.DEPLOYMENT_PATH),
@@ -46,6 +46,8 @@ class RedisCredentials(TypedDict):
46
46
 
47
47
  def _log_on_end(future: Future):
48
48
  """Use as a callback so that future is always done."""
49
+ if future.cancelled():
50
+ return
49
51
  if e := future.exception():
50
52
  logger.error(f"Worker failed with exception: {e}")
51
53
  else:
@@ -141,9 +143,9 @@ class ProcedureManagerBase(ABC, Generic[_ReqMsgT, _ExecMsgT]):
141
143
  with self.lock:
142
144
  if exec_msg.queue not in self._active_workers:
143
145
  new_worker = self.executor.submit(self.spawn, queue=queue, env=env)
146
+ self._active_workers[queue] = {"worker": None, "future": new_worker}
144
147
  new_worker.add_done_callback(_log_on_end)
145
148
  new_worker.add_done_callback(self._cleanup_worker_function(queue))
146
- self._active_workers[queue] = {"worker": None, "future": new_worker}
147
149
  return exec_msg
148
150
 
149
151
  def spawn(self, queue: str, env: dict[str, str]):
@@ -156,11 +158,20 @@ class ProcedureManagerBase(ABC, Generic[_ReqMsgT, _ExecMsgT]):
156
158
  raise WorkerAlreadyExists(
157
159
  f"Queue {queue} already has an active worker in {self._active_workers}!"
158
160
  )
159
- with self._worker_cls(self._server, queue, PROCEDURE.WORKER.QUEUE_TIMEOUT_S, env) as worker:
160
- with self.lock:
161
- self._active_workers[queue]["worker"] = worker
162
- worker.work()
163
- self._logs.extend(worker.logs())
161
+ worker = None
162
+ try:
163
+ with self._worker_cls(
164
+ self._server, queue, PROCEDURE.WORKER.QUEUE_TIMEOUT_S, env
165
+ ) as worker:
166
+ with self.lock:
167
+ self._active_workers[queue]["worker"] = worker
168
+ worker.work()
169
+ finally:
170
+ if worker is not None:
171
+ logs = worker.logs()
172
+ self._logs.extend(logs)
173
+ for line in logs:
174
+ logger.info(f"Procedure worker '{queue}': {line}")
164
175
 
165
176
  def _wait_for_all_futures(self):
166
177
  with self.lock:
@@ -195,7 +206,7 @@ class ProcedureManagerBase(ABC, Generic[_ReqMsgT, _ExecMsgT]):
195
206
  self._conn.shutdown()
196
207
  # cancel futures by hand to give us the opportunity to detach them from redis if they have started
197
208
  with self.lock:
198
- for entry in self._active_workers.values():
209
+ for entry in list(self._active_workers.values()):
199
210
  cancelled = entry["future"].cancel()
200
211
  if not cancelled:
201
212
  # unblock any waiting workers and let them shutdown
@@ -292,6 +303,20 @@ class ProcedureManager(ProcedureManagerBase[ProcedureRequestMessage, ProcedureEx
292
303
  def cleanup_worker(fut):
293
304
  with self.lock:
294
305
  logger.debug(f"cleaning up worker {fut} for queue {queue}...")
306
+ error = None if fut.cancelled() else fut.exception()
307
+ if error is not None:
308
+ pending = self._helper.get.exec_queue(queue)
309
+ running = [
310
+ msg for msg in self._helper.get.running_procedures() if msg.queue == queue
311
+ ]
312
+ self._helper.move.execution_queue_to_unhandled(queue)
313
+ for msg in running:
314
+ self._helper.push.unhandled(queue, msg)
315
+ for msg in pending + running:
316
+ self._helper.status_update(
317
+ msg.execution_id, "Finished", error=f"Procedure worker failed: {error}"
318
+ )
319
+ self._helper.notify_watchers(queue, "unhandled")
295
320
  self._helper.remove_from_active.by_queue(queue)
296
321
  self._run_callbacks(queue)
297
322
  self._helper.notify_watchers(queue, "execution")
@@ -59,7 +59,7 @@ class OutOfProcessWorkerBase(ProcedureWorker):
59
59
  minimum necessary, or things which are only necessary for the functioning of the worker,
60
60
  and other information should be passed through redis"""
61
61
  return {
62
- "redis_server": f"{PROCEDURE.REDIS_HOST}:{self._conn.port}",
62
+ "redis_server": self._redis_server,
63
63
  "queue": self._queue,
64
64
  "timeout_s": str(self._lifetime_s),
65
65
  }
@@ -70,7 +70,7 @@ class OutOfProcessWorkerBase(ProcedureWorker):
70
70
  # on timeout check if container is still running
71
71
 
72
72
  status_update = None
73
- while not self._ending_or_ended():
73
+ while not self._aborted.is_set():
74
74
  status_update = self._conn.blocking_list_pop(
75
75
  MessageEndpoints.procedure_worker_status_update(self._queue), timeout_s=0.2
76
76
  )
@@ -82,10 +82,17 @@ class OutOfProcessWorkerBase(ProcedureWorker):
82
82
  logger.info(
83
83
  f"Procedure worker '{self._queue}' status update: {status_update.status.name}"
84
84
  )
85
+ elif self._ending_or_ended():
86
+ break
85
87
  # TODO: we probably do want to handle some kind of timeout here but we don't know how
86
88
  # long a running procedure should actually take - it could theoretically be infinite
87
89
  if self.status != ProcedureWorkerStatus.FINISHED:
88
90
  self.status = ProcedureWorkerStatus.DEAD
91
+ if not self._aborted.is_set():
92
+ logs = "\n".join(self.logs())
93
+ raise ProcedureWorkerError(
94
+ f"Procedure worker for queue {self._queue} exited unexpectedly.\n{logs}"
95
+ )
89
96
 
90
97
 
91
98
  def _default_env() -> dict[str, str]:
@@ -230,10 +237,21 @@ def _main(
230
237
  helper.remove_from_active.by_exec_id(item.execution_id)
231
238
 
232
239
 
233
- def main():
234
- """Replaces the main contents of Worker.work() - should be called as the container entrypoint or command"""
240
+ def main(*, output_to_redis: bool = True) -> None:
241
+ """Run the worker entry point.
242
+
243
+ Args:
244
+ output_to_redis (bool): Redirect procedure output to Redis in this process. Subprocess
245
+ workers disable this because their parent streams both output pipes instead.
246
+ """
235
247
 
236
248
  env, helper, client, conn = setup(get_env())
249
+ if not output_to_redis:
250
+ try:
251
+ _main(env, helper, client, conn)
252
+ finally:
253
+ conn.shutdown()
254
+ return
237
255
  logger_connector = RedisConnector(env["redis_server"])
238
256
  output_diverter = RedisOutputDiverter(logger_connector, env["queue"])
239
257
  with redirect_stdout(output_diverter):
@@ -0,0 +1,144 @@
1
+ import os
2
+ import subprocess
3
+ import sys
4
+ from codecs import getincrementaldecoder
5
+ from collections import deque
6
+ from signal import SIGINT
7
+ from threading import Lock, Thread
8
+
9
+ from bec_lib.endpoints import MessageEndpoints
10
+ from bec_lib.logger import bec_logger
11
+ from bec_lib.messages import RawMessage
12
+ from bec_lib.redis_connector import RedisConnector
13
+ from bec_server.procedures.constants import ProcedureWorkerError
14
+ from bec_server.procedures.oop_worker_base import PROCESS_TIMEOUT, OutOfProcessWorkerBase, main
15
+
16
+ logger = bec_logger.logger
17
+
18
+
19
+ class SubProcessWorker(OutOfProcessWorkerBase):
20
+ """Run procedures in a subprocess, streaming stdout and stderr to Redis."""
21
+
22
+ WORKER_FILE = __file__
23
+
24
+ def _setup_execution_environment(self):
25
+ # Match the UTF-8 decoder in the parent even when the host uses another encoding.
26
+ env: dict[str, str] = {"PYTHONIOENCODING": "utf-8"} | self._worker_environment()
27
+ first_start = not hasattr(self, "_output_logs")
28
+ self._output_error_logged = False
29
+ if first_start:
30
+ self._output_logs: deque[str] = deque(maxlen=10000)
31
+ self._output_lock = Lock()
32
+ output_conn = RedisConnector(
33
+ [self._redis_server], name=f"ProcedureWorker-{self._queue} output"
34
+ )
35
+ try:
36
+ if first_start:
37
+ output_conn.delete(MessageEndpoints.procedure_logs(self._queue))
38
+ self._process = subprocess.Popen(
39
+ [sys.executable, "-u", self.WORKER_FILE],
40
+ stdout=subprocess.PIPE,
41
+ stderr=subprocess.STDOUT,
42
+ bufsize=0,
43
+ env=os.environ | env | self._additional_env,
44
+ )
45
+ except BaseException:
46
+ output_conn.shutdown()
47
+ raise
48
+ self._output_thread = Thread(
49
+ target=self._capture_output,
50
+ args=(self._process, output_conn),
51
+ name=f"ProcedureWorker-{self._queue} output",
52
+ daemon=True,
53
+ )
54
+ self._output_thread.start()
55
+ logger.success("Subprocess Procedure Worker started.")
56
+ self._ending: bool = False
57
+
58
+ def _capture_output(self, process: subprocess.Popen, conn: RedisConnector) -> None:
59
+ """Drain both streams even if Redis rejects an output write."""
60
+ decoder = getincrementaldecoder("utf-8")(errors="replace")
61
+ try:
62
+ with process.stdout as output:
63
+ while True:
64
+ chunk = output.read(4096)
65
+ if not chunk:
66
+ self._publish_output(decoder.decode(b"", final=True), conn)
67
+ break
68
+ self._publish_output(decoder.decode(chunk), conn)
69
+ finally:
70
+ conn.shutdown()
71
+
72
+ def _publish_output(self, text: str, conn: RedisConnector) -> None:
73
+ if not text:
74
+ return
75
+ with self._output_lock:
76
+ self._output_logs.append(text)
77
+ try:
78
+ conn.xadd(
79
+ MessageEndpoints.procedure_logs(self._queue),
80
+ {"data": RawMessage(data=text)},
81
+ max_size=10000,
82
+ expire=3600,
83
+ )
84
+ except Exception as exc:
85
+ if not self._output_error_logged:
86
+ logger.error(f"Failed to publish procedure output: {exc}")
87
+ self._output_error_logged = True
88
+
89
+ def _join_output(self) -> None:
90
+ if hasattr(self, "_output_thread"):
91
+ self._output_thread.join(timeout=PROCESS_TIMEOUT)
92
+ if self._output_thread.is_alive():
93
+ raise ProcedureWorkerError("Subprocess output reader failed to stop")
94
+
95
+ def _cleanup_execution_environment(self) -> None:
96
+ try:
97
+ super()._cleanup_execution_environment()
98
+ finally:
99
+ self._join_output()
100
+
101
+ def _ending_or_ended(self):
102
+ return self._ending or (self._process.poll() is not None)
103
+
104
+ def _kill_process(self):
105
+ """Attempts to end the process gently by first sending SIGINT, which is handled by the BECIpythonClient to
106
+ gracefully shut down, and end any scans it has started. See:
107
+ bec_ipython_client/main.py#L125 and bec_ipython_client/signals.py#L103
108
+ If the process fails to shut down naturally, kills it unceremoniously. This will leave the running scan running
109
+ on the ScanServer.
110
+ """
111
+ if not self._ending_or_ended():
112
+ self._ending = True
113
+ self._process.send_signal(SIGINT)
114
+ self._process.send_signal(SIGINT)
115
+ try:
116
+ self._process.wait(PROCESS_TIMEOUT)
117
+ except subprocess.TimeoutExpired:
118
+ logger.warning(
119
+ f"Subprocess Procedure Worker failed to exit in {PROCESS_TIMEOUT} s. Killing."
120
+ )
121
+ self._process.kill()
122
+ self._process.wait(PROCESS_TIMEOUT)
123
+
124
+ def abort_execution(self, execution_id: str):
125
+ """Abort the execution with the given id. Has no effect if the given ID is not the current job"""
126
+ if execution_id == self._current_execution_id:
127
+ self._kill_process()
128
+ self._helper.remove_from_active.by_exec_id(execution_id)
129
+ logger.info(
130
+ f"Aborting execution {execution_id}, restarting worker for queue: {self._queue}"
131
+ )
132
+ self._join_output()
133
+ self._setup_execution_environment()
134
+
135
+ def logs(self) -> list[str]:
136
+ """Return captured output without consuming it or waiting for a live process."""
137
+ if self._process.poll() is not None:
138
+ self._join_output()
139
+ with self._output_lock:
140
+ return "".join(self._output_logs).splitlines()
141
+
142
+
143
+ if __name__ == "__main__":
144
+ main(output_to_redis=False)
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from abc import ABC, abstractmethod
4
- from threading import Event
4
+ from threading import Event, Lock
5
5
 
6
6
  from bec_lib.endpoints import MessageEndpoints
7
7
  from bec_lib.logger import bec_logger
@@ -52,15 +52,27 @@ class ProcedureWorker(ABC):
52
52
  self.client_id = self._conn.client_id()
53
53
  self._current_execution_id: str | None = None
54
54
  self._aborted = Event()
55
+ self._shutdown_lock = Lock()
55
56
 
56
- self._setup_execution_environment()
57
+ try:
58
+ self._setup_execution_environment()
59
+ except BaseException:
60
+ self._conn.shutdown()
61
+ raise
57
62
 
58
63
  def __enter__(self):
59
64
  return self
60
65
 
61
66
  def __exit__(self, exc_type, exc_val, exc_tb):
62
- self._conn.shutdown()
63
- self._kill_process()
67
+ self._cleanup_execution_environment()
68
+
69
+ def _cleanup_execution_environment(self) -> None:
70
+ """Serialize abort and context teardown, always stopping the external process."""
71
+ with self._shutdown_lock:
72
+ try:
73
+ self._conn.shutdown()
74
+ finally:
75
+ self._kill_process()
64
76
 
65
77
  @abstractmethod
66
78
  def _kill_process(self):
@@ -86,8 +98,7 @@ class ProcedureWorker(ABC):
86
98
  def abort(self):
87
99
  """Abort the entire worker"""
88
100
  self._aborted.set()
89
- self._conn.shutdown()
90
- self._kill_process()
101
+ self._cleanup_execution_environment()
91
102
 
92
103
  @abstractmethod
93
104
  def abort_execution(self, execution_id: str):
@@ -164,6 +164,10 @@ class ScanManager:
164
164
  "doc": scan_doc_with_modifiers(scan_cls),
165
165
  "signature": scan_signature_with_modifiers(scan_cls),
166
166
  "gui_visibility": gui_visibility,
167
+ "position_preview": getattr(scan_cls, "position_preview", None),
168
+ "position_preview_parameter_mapping": getattr(
169
+ scan_cls, "position_preview_parameter_mapping", {}
170
+ ),
167
171
  }
168
172
 
169
173
  @staticmethod
@@ -20,11 +20,11 @@ from typing import Annotated
20
20
 
21
21
  import numpy as np
22
22
 
23
+ from bec_lib import position_generators
23
24
  from bec_lib.device import DeviceBase
24
25
  from bec_lib.logger import bec_logger
26
+ from bec_lib.position_generators import Direction
25
27
  from bec_lib.scan_args import DefaultArgType, ScanArgument, Units
26
- from bec_server.scan_server.scans import position_generators
27
- from bec_server.scan_server.scans.position_generators import Direction
28
28
  from bec_server.scan_server.scans.scan_base import ScanBase, ScanType
29
29
  from bec_server.scan_server.scans.scan_modifier import scan_hook
30
30
 
@@ -59,6 +59,16 @@ class FermatSpiralScan(ScanBase):
59
59
  ],
60
60
  }
61
61
 
62
+ position_preview = "bec_lib.position_generators.fermat_spiral_pos"
63
+ position_preview_parameter_mapping = {
64
+ "m1_start": "start_motor1",
65
+ "m1_stop": "stop_motor1",
66
+ "m2_start": "start_motor2",
67
+ "m2_stop": "stop_motor2",
68
+ "step": "step",
69
+ "spiral_type": "spiral_type",
70
+ }
71
+
62
72
  def __init__(
63
73
  self,
64
74
  motor1: DeviceBase,
@@ -20,10 +20,10 @@ from typing import Annotated
20
20
 
21
21
  import numpy as np
22
22
 
23
+ from bec_lib import position_generators
23
24
  from bec_lib.device import DeviceBase
24
25
  from bec_lib.logger import bec_logger
25
26
  from bec_lib.scan_args import DefaultArgType, ScanArgument
26
- from bec_server.scan_server.scans import position_generators
27
27
  from bec_server.scan_server.scans.scan_base import ScanBase, ScanType, bundle_args
28
28
  from bec_server.scan_server.scans.scan_modifier import scan_hook
29
29
 
@@ -69,6 +69,9 @@ class GridScan(ScanBase):
69
69
  ],
70
70
  }
71
71
 
72
+ position_preview = "bec_lib.position_generators.nd_grid_positions"
73
+ position_preview_parameter_mapping = {"axes": {"bundle": [1, 2, 3]}, "snaked": "snaked"}
74
+
72
75
  def __init__(
73
76
  self,
74
77
  *args,
@@ -20,9 +20,9 @@ from typing import Annotated
20
20
 
21
21
  import numpy as np
22
22
 
23
+ from bec_lib import position_generators
23
24
  from bec_lib.device import DeviceBase
24
25
  from bec_lib.scan_args import DefaultArgType, ScanArgument
25
- from bec_server.scan_server.scans import position_generators
26
26
  from bec_server.scan_server.scans.scan_base import ScanBase, ScanType
27
27
  from bec_server.scan_server.scans.scan_modifier import scan_hook
28
28
 
@@ -53,6 +53,15 @@ class HexagonalScan(ScanBase):
53
53
  ],
54
54
  }
55
55
 
56
+ position_preview = "bec_lib.position_generators.hex_grid_2d"
57
+ position_preview_parameter_mapping = {
58
+ "axes": [
59
+ ["start_motor1", "stop_motor1", "step_motor1"],
60
+ ["start_motor2", "stop_motor2", "step_motor2"],
61
+ ],
62
+ "snaked": "snaked",
63
+ }
64
+
56
65
  def __init__(
57
66
  self,
58
67
  motor1: DeviceBase,
@@ -20,9 +20,9 @@ from typing import Annotated
20
20
 
21
21
  import numpy as np
22
22
 
23
+ from bec_lib import position_generators
23
24
  from bec_lib.device import DeviceBase
24
25
  from bec_lib.scan_args import DefaultArgType, ScanArgument
25
- from bec_server.scan_server.scans import position_generators
26
26
  from bec_server.scan_server.scans.scan_base import ScanBase, ScanType, bundle_args
27
27
  from bec_server.scan_server.scans.scan_modifier import scan_hook
28
28
 
@@ -64,6 +64,9 @@ class LineScan(ScanBase):
64
64
  ],
65
65
  }
66
66
 
67
+ position_preview = "bec_lib.position_generators.line_scan_positions"
68
+ position_preview_parameter_mapping = {"axes": {"bundle": [1, 2]}, "steps": "steps"}
69
+
67
70
  def __init__(
68
71
  self,
69
72
  *args,
@@ -20,9 +20,9 @@ from typing import Annotated
20
20
 
21
21
  import numpy as np
22
22
 
23
+ from bec_lib import position_generators
23
24
  from bec_lib.device import DeviceBase
24
25
  from bec_lib.scan_args import DefaultArgType, ScanArgument
25
- from bec_server.scan_server.scans import position_generators
26
26
  from bec_server.scan_server.scans.scan_base import ScanBase, ScanType, bundle_args
27
27
  from bec_server.scan_server.scans.scan_modifier import scan_hook
28
28
 
@@ -64,6 +64,9 @@ class LogScan(ScanBase):
64
64
  ],
65
65
  }
66
66
 
67
+ position_preview = "bec_lib.position_generators.log_scan_positions"
68
+ position_preview_parameter_mapping = {"axes": {"bundle": [1, 2]}, "steps": "steps"}
69
+
67
70
  def __init__(
68
71
  self,
69
72
  *args,
@@ -18,9 +18,9 @@ from __future__ import annotations
18
18
 
19
19
  import numpy as np
20
20
 
21
+ from bec_lib import position_generators
21
22
  from bec_lib.device import DeviceBase
22
23
  from bec_lib.scan_args import DefaultArgType
23
- from bec_server.scan_server.scans import position_generators
24
24
  from bec_server.scan_server.scans.scan_base import ScanBase, ScanType
25
25
  from bec_server.scan_server.scans.scan_modifier import scan_hook
26
26
 
@@ -44,6 +44,9 @@ class MultiRegionGridScan(ScanBase):
44
44
  "Acquisition Parameters": ["exp_time", "settling_time", "burst_at_each_point"],
45
45
  }
46
46
 
47
+ position_preview = "bec_lib.position_generators.multi_region_grid_positions"
48
+ position_preview_parameter_mapping = {"regions": "regions", "snaked": "snaked"}
49
+
47
50
  def __init__(
48
51
  self,
49
52
  motor1: DeviceBase,
@@ -18,9 +18,9 @@ from __future__ import annotations
18
18
 
19
19
  import numpy as np
20
20
 
21
+ from bec_lib import position_generators
21
22
  from bec_lib.device import DeviceBase
22
23
  from bec_lib.scan_args import DefaultArgType
23
- from bec_server.scan_server.scans import position_generators
24
24
  from bec_server.scan_server.scans.scan_base import ScanBase, ScanType
25
25
  from bec_server.scan_server.scans.scan_modifier import scan_hook
26
26
 
@@ -50,6 +50,9 @@ class MultiRegionLineScan(ScanBase):
50
50
  ],
51
51
  }
52
52
 
53
+ position_preview = "bec_lib.position_generators.multi_region_line_positions"
54
+ position_preview_parameter_mapping = {"regions": "regions"}
55
+
53
56
  def __init__(
54
57
  self,
55
58
  motor: DeviceBase,
@@ -0,0 +1,5 @@
1
+ """Compatibility imports; use :mod:`bec_lib.path_optimization` for new code."""
2
+
3
+ from bec_lib.path_optimization import PathOptimizerMixin, PathQualityStats
4
+
5
+ __all__ = ["PathOptimizerMixin", "PathQualityStats"]
@@ -0,0 +1,33 @@
1
+ """Compatibility imports; use :mod:`bec_lib.position_generators` for new code."""
2
+
3
+ from bec_lib.position_generators import (
4
+ Direction,
5
+ fermat_spiral_pos,
6
+ get_round_roi_scan_positions,
7
+ hex_grid_2d,
8
+ line_scan_positions,
9
+ log_scan_positions,
10
+ multi_region_grid_positions,
11
+ multi_region_line_positions,
12
+ nd_grid_positions,
13
+ oscillating_positions,
14
+ rotate_points,
15
+ round_scan_positions,
16
+ spiral_positions,
17
+ )
18
+
19
+ __all__ = [
20
+ "Direction",
21
+ "rotate_points",
22
+ "spiral_positions",
23
+ "line_scan_positions",
24
+ "log_scan_positions",
25
+ "oscillating_positions",
26
+ "multi_region_line_positions",
27
+ "multi_region_grid_positions",
28
+ "nd_grid_positions",
29
+ "fermat_spiral_pos",
30
+ "round_scan_positions",
31
+ "get_round_roi_scan_positions",
32
+ "hex_grid_2d",
33
+ ]
@@ -20,9 +20,9 @@ from typing import Annotated
20
20
 
21
21
  import numpy as np
22
22
 
23
+ from bec_lib import position_generators
23
24
  from bec_lib.device import DeviceBase
24
25
  from bec_lib.scan_args import DefaultArgType, ScanArgument
25
- from bec_server.scan_server.scans import position_generators
26
26
  from bec_server.scan_server.scans.scan_base import ScanBase, ScanType
27
27
  from bec_server.scan_server.scans.scan_modifier import scan_hook
28
28
 
@@ -54,6 +54,18 @@ class RoundROIScan(ScanBase):
54
54
  ],
55
55
  }
56
56
 
57
+ position_preview = "bec_lib.position_generators.get_round_roi_scan_positions"
58
+ position_preview_parameter_mapping = {
59
+ "motor_1_start": "start_motor_1",
60
+ "motor_1_stop": "stop_motor_1",
61
+ "motor_2_start": "start_motor_2",
62
+ "motor_2_stop": "stop_motor_2",
63
+ "radial_step": "shell_spacing",
64
+ "points_in_first_shell": "pos_in_first_ring",
65
+ "center_1": "center_1",
66
+ "center_2": "center_2",
67
+ }
68
+
57
69
  def __init__(
58
70
  self,
59
71
  motor_1: DeviceBase,