mx-bluesky 0.0.1__tar.gz → 0.0.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 (122) hide show
  1. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/PKG-INFO +8 -3
  2. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/README.rst +5 -1
  3. mx_bluesky-0.0.2/deploy/deploy_mxbluesky.py +190 -0
  4. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/dls_dev_setup.sh +6 -0
  5. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/pyproject.toml +2 -1
  6. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/FT-gui-edm/pumpprobe-py3v1.edl +53 -2
  7. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +14 -3
  8. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +15 -11
  9. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/i24ssx_moveonclick.py +16 -19
  10. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/_version.py +2 -2
  11. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky.egg-info/PKG-INFO +8 -3
  12. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky.egg-info/SOURCES.txt +1 -0
  13. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky.egg-info/requires.txt +2 -1
  14. mx_bluesky-0.0.2/start_jupyter.sh +2 -0
  15. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/tests/I24/serial/fixed_target/test_ft_collect.py +34 -1
  16. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/tests/I24/serial/fixed_target/test_moveonclick.py +7 -7
  17. mx_bluesky-0.0.1/start_jupyter.sh +0 -2
  18. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.devcontainer/Dockerfile +0 -0
  19. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.devcontainer/devcontainer.json +0 -0
  20. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.github/CONTRIBUTING.rst +0 -0
  21. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.github/actions/install_requirements/action.yml +0 -0
  22. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.github/dependabot.yml +0 -0
  23. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.github/pages/index.html +0 -0
  24. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.github/pages/make_switcher.py +0 -0
  25. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.github/workflows/code.yml +0 -0
  26. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.github/workflows/docs.yml +0 -0
  27. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.github/workflows/docs_clean.yml +0 -0
  28. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.github/workflows/linkcheck.yml +0 -0
  29. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.gitignore +0 -0
  30. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.pre-commit-config.yaml +0 -0
  31. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.vscode/extensions.json +0 -0
  32. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.vscode/launch.json +0 -0
  33. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.vscode/mx-bluesky.code-workspace +0 -0
  34. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.vscode/settings.json +0 -0
  35. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/.vscode/tasks.json +0 -0
  36. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/LICENSE +0 -0
  37. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/deploy/deploy_edm_for_ssx.sh +0 -0
  38. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/conf.py +0 -0
  39. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/developer/explanations/decisions/0001-record-architecture-decisions.rst +0 -0
  40. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/developer/explanations/decisions.rst +0 -0
  41. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/developer/how-to/build-docs.rst +0 -0
  42. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/developer/how-to/contribute.rst +0 -0
  43. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/developer/how-to/lint.rst +0 -0
  44. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/developer/how-to/make-release.rst +0 -0
  45. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/developer/how-to/run-tests.rst +0 -0
  46. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/developer/how-to/static-analysis.rst +0 -0
  47. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/developer/how-to/update-tools.rst +0 -0
  48. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/developer/index.rst +0 -0
  49. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/developer/reference/standards.rst +0 -0
  50. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/developer/tutorials/dev-install.rst +0 -0
  51. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/genindex.rst +0 -0
  52. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/images/dls-favicon.ico +0 -0
  53. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/images/dls-logo.svg +0 -0
  54. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/index.rst +0 -0
  55. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/user/explanations/docs-structure.rst +0 -0
  56. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/user/how-to/run-container.rst +0 -0
  57. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/user/index.rst +0 -0
  58. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/user/reference/api.rst +0 -0
  59. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/docs/user/tutorials/installation.rst +0 -0
  60. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/setup.cfg +0 -0
  61. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/__init__.py +0 -0
  62. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/__init__.py +0 -0
  63. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/dcid.py +0 -0
  64. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/extruder/EX-gui-edm/DetStage.edl +0 -0
  65. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/extruder/EX-gui-edm/DiamondExtruder-I24-py3v1.edl +0 -0
  66. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/extruder/EX-gui-edm/microdrop_alignment.edl +0 -0
  67. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/extruder/__init__.py +0 -0
  68. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +0 -0
  69. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/FT-gui-edm/CustomChip_py3v1.edl +0 -0
  70. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/FT-gui-edm/DetStage.edl +0 -0
  71. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/FT-gui-edm/DiamondChipI24-py3v1.edl +0 -0
  72. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/FT-gui-edm/ME14E-GeneralPurpose.edl +0 -0
  73. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/FT-gui-edm/ME14E-motors.edl +0 -0
  74. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/FT-gui-edm/MappingLite-oxford_py3v1.edl +0 -0
  75. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/FT-gui-edm/PMAC_Command.edl +0 -0
  76. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/FT-gui-edm/Shutter_Control.edl +0 -0
  77. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/FT-gui-edm/microdrop_alignment.edl +0 -0
  78. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/FT-gui-edm/nudgechip.edl +0 -0
  79. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/__init__.py +0 -0
  80. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/ft_utils.py +0 -0
  81. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/i24ssx_Chip_Mapping_py3v1.py +0 -0
  82. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/fixed_target/i24ssx_Chip_StartUp_py3v1.py +0 -0
  83. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/log.py +0 -0
  84. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/parameters/__init__.py +0 -0
  85. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/parameters/constants.py +0 -0
  86. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/parameters/fixed_target/cs/cs_maker.json +0 -0
  87. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/parameters/fixed_target/cs/fiducial_1.txt +0 -0
  88. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/parameters/fixed_target/cs/fiducial_2.txt +0 -0
  89. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/parameters/fixed_target/cs/motor_direction.txt +0 -0
  90. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/parameters/fixed_target/litemaps/currentchip.map +0 -0
  91. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/parameters/fixed_target/parameters.txt +0 -0
  92. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/parameters/fixed_target/pvar_files/minichip-oxford.pvar +0 -0
  93. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/parameters/fixed_target/pvar_files/oxford.pvar +0 -0
  94. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/run_serial.py +0 -0
  95. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/run_ssx.sh +0 -0
  96. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/set_visit_directory.sh +0 -0
  97. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/setup_beamline/__init__.py +0 -0
  98. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/setup_beamline/ca.py +0 -0
  99. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/setup_beamline/pv.py +0 -0
  100. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/setup_beamline/pv_abstract.py +0 -0
  101. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/setup_beamline/setup_beamline.py +0 -0
  102. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/setup_beamline/setup_detector.py +0 -0
  103. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/I24/serial/write_nexus.py +0 -0
  104. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/__init__.py +0 -0
  105. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/__main__.py +0 -0
  106. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/example.py +0 -0
  107. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky/jupyter_example.ipynb +0 -0
  108. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky.egg-info/dependency_links.txt +0 -0
  109. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky.egg-info/entry_points.txt +0 -0
  110. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/src/mx_bluesky.egg-info/top_level.txt +0 -0
  111. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/tests/I24/serial/extruder/test_extruder_collect.py +0 -0
  112. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/tests/I24/serial/fixed_target/__init__.py +0 -0
  113. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/tests/I24/serial/fixed_target/test_chip_manager.py +0 -0
  114. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/tests/I24/serial/fixed_target/test_chip_startup.py +0 -0
  115. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/tests/I24/serial/setup_beamline/test_pv_abstract.py +0 -0
  116. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/tests/I24/serial/setup_beamline/test_setup_beamline.py +0 -0
  117. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/tests/I24/serial/setup_beamline/test_setup_detector.py +0 -0
  118. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/tests/I24/serial/test_dcid.py +0 -0
  119. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/tests/I24/serial/test_log.py +0 -0
  120. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/tests/__init__.py +0 -0
  121. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/tests/test_cli.py +0 -0
  122. {mx_bluesky-0.0.1 → mx_bluesky-0.0.2}/tests/test_example.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mx_bluesky
3
- Version: 0.0.1
3
+ Version: 0.0.2
4
4
  Summary: Bluesky tools for MX Beamlines
5
5
  Author-email: Dominic Oram <dominic.oram@diamond.ac.uk>
6
6
  License: Apache License
@@ -221,8 +221,9 @@ Requires-Dist: jupyterlab
221
221
  Requires-Dist: matplotlib
222
222
  Requires-Dist: requests
223
223
  Requires-Dist: opencv-python
224
- Requires-Dist: dls-dodal==1.8.0
224
+ Requires-Dist: dls-dodal==1.9.0
225
225
  Provides-Extra: dev
226
+ Requires-Dist: GitPython; extra == "dev"
226
227
  Requires-Dist: black; extra == "dev"
227
228
  Requires-Dist: mypy; extra == "dev"
228
229
  Requires-Dist: pipdeptree; extra == "dev"
@@ -256,7 +257,11 @@ Getting Started
256
257
 
257
258
  To get started with developing this repo at DLS run ```dls_dev_setup.sh``.
258
259
 
259
- We recommend developing with VSCode. You can do this at DLS by running::
260
+ If you want to develop interactively at the beamline we recommend using jupyter notebooks. You can get started with this by running::
261
+
262
+ $ ./start_jupyter.sh
263
+
264
+ If you're doing more in-depth development we recommend developing with VSCode. You can do this at DLS by running::
260
265
 
261
266
 
262
267
  $ module load vscode
@@ -17,7 +17,11 @@ Getting Started
17
17
 
18
18
  To get started with developing this repo at DLS run ```dls_dev_setup.sh``.
19
19
 
20
- We recommend developing with VSCode. You can do this at DLS by running::
20
+ If you want to develop interactively at the beamline we recommend using jupyter notebooks. You can get started with this by running::
21
+
22
+ $ ./start_jupyter.sh
23
+
24
+ If you're doing more in-depth development we recommend developing with VSCode. You can do this at DLS by running::
21
25
 
22
26
 
23
27
  $ module load vscode
@@ -0,0 +1,190 @@
1
+ """
2
+ Deploy latest release of mx_bluesky either on a beamline or in dev mode.
3
+ """
4
+
5
+ import argparse
6
+ import os
7
+ from subprocess import PIPE, CalledProcessError, Popen
8
+ from typing import List, Tuple
9
+
10
+ from git import Repo
11
+ from packaging.version import Version
12
+
13
+ recognised_beamlines = ["i24"]
14
+
15
+ help_message = """
16
+ To deploy mx_bluesky on a specific beamline, pass only the --beamline argument.
17
+ This will put the latest release in /dls_sw/ixx/software/bluesky/mx_bluesky_v#.#.# and \
18
+ set the permissions accordingly. \n
19
+ To run in dev mode instead, only the --dev-path should be passed, a test release will \
20
+ be placed in {dev_path}/mxbluesky_release_test/bluesky. \n
21
+ Finally, if both a --beamline and a --dev-path are specified, a beamline-specific test \
22
+ deployment will be put in the test directory.
23
+ """
24
+
25
+
26
+ class repo:
27
+ # Set name, setup remote origin, get the latest version"""
28
+ def __init__(self, name: str, repo_args):
29
+ self.name = name
30
+ self.repo = Repo(repo_args)
31
+
32
+ self.origin = self.repo.remotes.origin
33
+ self.origin.fetch()
34
+
35
+ self.versions = [t.name for t in self.repo.tags]
36
+ self.versions.sort(key=Version, reverse=True)
37
+ print(f"Found {self.name}_versions:\n{os.linesep.join(self.versions)}")
38
+ self.latest_version_str = self.versions[0]
39
+
40
+ def deploy(self, url, beamline: str = None):
41
+ print(f"Cloning latest version {self.name} into {self.deploy_location}")
42
+
43
+ deploy_repo = Repo.init(self.deploy_location)
44
+ deploy_origin = deploy_repo.create_remote("origin", self.origin.url)
45
+
46
+ deploy_origin.fetch()
47
+ deploy_repo.git.checkout(self.latest_version_str)
48
+
49
+ print("Setting permissions")
50
+ groups_to_give_permission = get_permission_groups(beamline)
51
+ setfacl_params = ",".join(
52
+ [f"g:{group}:rwx" for group in groups_to_give_permission]
53
+ )
54
+
55
+ # Set permissions and defaults
56
+ os.system(f"setfacl -R -m {setfacl_params} {self.deploy_location}")
57
+ os.system(f"setfacl -dR -m {setfacl_params} {self.deploy_location}")
58
+
59
+ # Deploy location depends on the latest mx_bluesky version (...software/bluesky/mx_bluesky_V...)
60
+ def set_deploy_location(self, release_area):
61
+ self.deploy_location = os.path.join(release_area, self.name)
62
+ if os.path.isdir(self.deploy_location):
63
+ raise Exception(
64
+ f"{self.deploy_location} already exists, stopping deployment for {self.name}"
65
+ )
66
+
67
+
68
+ # Get permission groups depending on beamline/dev install
69
+ def get_permission_groups(beamline: str = None) -> List:
70
+ beamline_groups = ["gda2", "dls_dasc"]
71
+ if beamline:
72
+ beamline_groups.append(f"{beamline}_staff")
73
+ return beamline_groups
74
+
75
+
76
+ # Get the release directory based off the beamline and the latest mx_bluesky version
77
+ def get_beamline_and_release_dir_from_args(repo: repo) -> Tuple[str, str]:
78
+ if repo.name != "mx_bluesky":
79
+ raise ValueError("This function should only be used with the mx_bluesky repo")
80
+
81
+ parser = argparse.ArgumentParser(
82
+ formatter_class=argparse.RawTextHelpFormatter,
83
+ description=__doc__,
84
+ epilog=help_message,
85
+ )
86
+ parser.add_argument(
87
+ "--beamline",
88
+ type=str,
89
+ choices=recognised_beamlines,
90
+ help="The beamline to deploy mx-bluesky to.",
91
+ )
92
+ parser.add_argument(
93
+ "--dev-path",
94
+ type=str,
95
+ help="Path for dev deployment.",
96
+ )
97
+
98
+ args = parser.parse_args()
99
+ if not args.beamline:
100
+ print("Running as dev")
101
+ if not args.dev_path:
102
+ raise ValueError("The path for the dev install hasn't been specified.")
103
+ return None, os.path.join(args.dev_path, "mxbluesky_release_test/bluesky")
104
+ elif args.beamline and args.dev_path:
105
+ print(
106
+ f"""
107
+ WARNING! Running a {args.beamline} deployment as dev, which will be placed
108
+ in {args.dev_path}.
109
+ """
110
+ )
111
+ return args.beamline, os.path.join(
112
+ args.dev_path, f"mxbluesky_{args.beamline}_release_test/bluesky"
113
+ )
114
+ else:
115
+ print(f"Deploying on beamline {args.beamline}.")
116
+ return args.beamline, f"/dls_sw/{args.beamline}/software/bluesky"
117
+
118
+
119
+ def run_process_and_print_output(proc_to_run):
120
+ with Popen(proc_to_run, stdout=PIPE, bufsize=1, universal_newlines=True) as p:
121
+ if p.stdout is not None:
122
+ for line in p.stdout:
123
+ print(line, end="")
124
+ if p.returncode != 0:
125
+ raise CalledProcessError(p.returncode, p.args)
126
+
127
+
128
+ if __name__ == "__main__":
129
+ mx_repo = repo(
130
+ name="mx_bluesky",
131
+ repo_args=os.path.join(os.path.dirname(__file__), "../.git"),
132
+ )
133
+
134
+ # Gives path to /bluesky
135
+ beamline, release_area = get_beamline_and_release_dir_from_args(mx_repo)
136
+
137
+ release_area_version = os.path.join(
138
+ release_area, f"mx_bluesky_{mx_repo.latest_version_str}"
139
+ )
140
+
141
+ print(f"Putting releases into {release_area_version}")
142
+
143
+ dodal_repo = repo(
144
+ name="dodal",
145
+ repo_args=os.path.join(os.path.dirname(__file__), "../../dodal/.git"),
146
+ )
147
+
148
+ dodal_repo.set_deploy_location(release_area_version)
149
+ mx_repo.set_deploy_location(release_area_version)
150
+
151
+ # Deploy mx_bluesky repo
152
+ mx_repo.deploy(mx_repo.origin.url, beamline)
153
+
154
+ # Get version of dodal that latest mx_bluesky version uses
155
+ with open(f"{release_area_version}/mx_bluesky/pyproject.toml", "r") as setup_file:
156
+ dodal_url = [
157
+ line
158
+ for line in setup_file
159
+ if "https://github.com/DiamondLightSource/python-dodal" in line
160
+ ]
161
+
162
+ # Now deploy the correct version of dodal
163
+ dodal_repo.deploy(dodal_url, beamline)
164
+
165
+ # Set up environment and run /dls_dev_env.sh...
166
+ os.chdir(mx_repo.deploy_location)
167
+ print(f"Setting up environment in {mx_repo.deploy_location}")
168
+
169
+ if mx_repo.name == "mx_bluesky":
170
+ run_process_and_print_output("./dls_dev_setup.sh")
171
+
172
+ # If on beamline I24 also deploy the screens to run ssx collections
173
+ if beamline == "i24":
174
+ print("Setting up edm screens for serial collections on I24.")
175
+ run_process_and_print_output("./deploy/deploy_edm_for_ssx.sh")
176
+
177
+ move_symlink = input(
178
+ """Move symlink (y/n)? WARNING: this will affect the running version!
179
+ Only do so if you have informed the beamline scientist and you're sure mx_bluesky is not running.
180
+ """
181
+ )
182
+ # Creates symlink: software/bluesky/mx_bluesky_version -> software/bluesky/mx_bluesky
183
+ if move_symlink == "y":
184
+ live_location = os.path.join(release_area, "mx_bluesky")
185
+ new_tmp_location = os.path.join(release_area, "tmp_art")
186
+ os.symlink(mx_repo.deploy_location, new_tmp_location)
187
+ os.rename(new_tmp_location, live_location)
188
+ print(f"New version moved to {live_location}")
189
+ else:
190
+ print("Quiting without latest version being updated")
@@ -1,3 +1,9 @@
1
+ #!/bin/bash
2
+
3
+ # controls_dev sets pip up to look at a local pypi server, which is incomplete
4
+ module unload controls_dev
5
+
6
+
1
7
  module load python/3.10
2
8
 
3
9
  if [ -d "./.venv" ]
@@ -20,7 +20,7 @@ dependencies = [
20
20
  "matplotlib",
21
21
  "requests",
22
22
  "opencv-python",
23
- "dls-dodal==1.8.0",
23
+ "dls-dodal==1.9.0",
24
24
  ]
25
25
  dynamic = ["version"]
26
26
  license.file = "LICENSE"
@@ -29,6 +29,7 @@ requires-python = ">=3.9"
29
29
 
30
30
  [project.optional-dependencies]
31
31
  dev = [
32
+ "GitPython",
32
33
  "black",
33
34
  "mypy",
34
35
  "pipdeptree",
@@ -3,8 +3,8 @@ beginScreenProperties
3
3
  major 4
4
4
  minor 0
5
5
  release 1
6
- x 1570
7
- y 705
6
+ x 3174
7
+ y 381
8
8
  w 900
9
9
  h 700
10
10
  font "arial-medium-r-18.0"
@@ -1559,3 +1559,54 @@ value {
1559
1559
  autoSize
1560
1560
  endObjectProperties
1561
1561
 
1562
+ # (Static Text)
1563
+ object activeXTextClass
1564
+ beginObjectProperties
1565
+ major 4
1566
+ minor 1
1567
+ release 1
1568
+ x 6
1569
+ y 275
1570
+ w 191
1571
+ h 27
1572
+ font "arial-bold-r-24.0"
1573
+ fgColor index 12
1574
+ bgColor index 0
1575
+ useDisplayBg
1576
+ value {
1577
+ "Checker Pattern"
1578
+ }
1579
+ autoSize
1580
+ endObjectProperties
1581
+
1582
+ # (Menu Mux)
1583
+ object menuMuxClass
1584
+ beginObjectProperties
1585
+ major 4
1586
+ minor 1
1587
+ release 0
1588
+ x 207
1589
+ y 276
1590
+ w 82
1591
+ h 24
1592
+ fgColor index 14
1593
+ bgColor index 3
1594
+ topShadowColor index 1
1595
+ botShadowColor index 8
1596
+ controlPv "ME14E-MO-IOC-01:GP111"
1597
+ font "arial-medium-r-18.0"
1598
+ numItems 2
1599
+ symbolTag {
1600
+ 0 "False"
1601
+ 1 "True"
1602
+ }
1603
+ symbol0 {
1604
+ 0 "NN"
1605
+ 1 "ML"
1606
+ }
1607
+ value0 {
1608
+ 0 "none"
1609
+ 1 "True"
1610
+ }
1611
+ endObjectProperties
1612
+
@@ -11,8 +11,11 @@ import time
11
11
  from datetime import datetime
12
12
  from pathlib import Path
13
13
  from time import sleep
14
+ from typing import Dict, List
14
15
 
15
16
  import numpy as np
17
+ from dodal.beamlines import i24
18
+ from dodal.devices.i24.pmac import PMAC
16
19
 
17
20
  from mx_bluesky.I24.serial import log
18
21
  from mx_bluesky.I24.serial.dcid import DCID
@@ -164,7 +167,9 @@ def get_chip_prog_values(
164
167
 
165
168
 
166
169
  @log.log_on_entry
167
- def load_motion_program_data(motion_program_dict, map_type, pump_repeat):
170
+ def load_motion_program_data(
171
+ pmac: PMAC, motion_program_dict: Dict[str, List], map_type: int, pump_repeat: int
172
+ ):
168
173
  logger.info("Loading motion program data for chip.")
169
174
  logger.info("Pump_repeat is %s" % pump_repeat)
170
175
  if pump_repeat == PumpProbeSetting.NoPP:
@@ -184,6 +189,10 @@ def load_motion_program_data(motion_program_dict, map_type, pump_repeat):
184
189
  # Pump setting chosen
185
190
  prefix = 14
186
191
  logger.info("Setting program prefix to %s" % prefix)
192
+ pmac.pmac_string.set("P1439=0")
193
+ if bool(caget(pv.me14e_gp111)) is True:
194
+ logger.info("Checker pattern setting enabled.")
195
+ pmac.pmac_string.set("P1439=1")
187
196
  else:
188
197
  logger.warning("Unknown Pump repeat, pump_repeat = %s" % pump_repeat)
189
198
  return
@@ -196,7 +205,7 @@ def load_motion_program_data(motion_program_dict, map_type, pump_repeat):
196
205
  value = str(v[1])
197
206
  s = "P%s=%s" % (str(pvar), str(value))
198
207
  logger.info("%s \t %s" % (key, s))
199
- caput(pv.me14e_pmac_str, s)
208
+ pmac.pmac_string.set(s)
200
209
  sleep(0.02)
201
210
  sleep(0.2)
202
211
 
@@ -537,6 +546,8 @@ def finish_i24(chip_prog_dict, start_time):
537
546
 
538
547
 
539
548
  def main():
549
+ # Dodal devices
550
+ pmac = i24.pmac()
540
551
  # ABORT BUTTON
541
552
  logger.info("Running a chip collection on I24")
542
553
  caput(pv.me14e_gp9, 0)
@@ -587,7 +598,7 @@ def main():
587
598
  n_exposures=n_exposures,
588
599
  )
589
600
  logger.info("Loading Motion Program Data")
590
- load_motion_program_data(chip_prog_dict, map_type, pump_repeat)
601
+ load_motion_program_data(pmac, chip_prog_dict, map_type, pump_repeat)
591
602
 
592
603
  start_time, dcid = start_i24()
593
604
 
@@ -128,6 +128,8 @@ def write_parameter_file(param_path: Path | str = PARAM_FILE_PATH_FT):
128
128
  chip_type = caget(pv.me14e_gp1)
129
129
  det_type = get_detector_type()
130
130
 
131
+ checkerpattern = bool(caget(pv.me14e_gp111))
132
+
131
133
  # If file name ends in a digit this causes processing/pilatus pain.
132
134
  # Append an underscore
133
135
  if det_type == "pilatus":
@@ -158,19 +160,21 @@ def write_parameter_file(param_path: Path | str = PARAM_FILE_PATH_FT):
158
160
  f.write("exptime \t%s\n" % exptime)
159
161
  f.write("dcdetdist \t%s\n" % dcdetdist)
160
162
  f.write("det_type \t%s\n" % str(det_type))
163
+ f.write("checkerpattern \t%s\n" % str(checkerpattern))
161
164
 
162
165
  logger.info("Information written to file")
163
- logger.info("visit: %s" % visit)
164
- logger.info("filename: %s" % chip_name)
165
- logger.info("protein_name: %s" % protein_name)
166
- logger.info("n_exposures: %s" % n_exposures)
167
- logger.info("chip_type: %s" % chip_type)
168
- logger.info("map_type: %s" % map_type)
169
- logger.info("pump_repeat: %s" % pump_repeat)
170
- logger.info("pumpexptime: %s" % pumpexptime)
171
- logger.info("pumpdelay: %s" % pumpdelay)
172
- logger.info("prepumpexptime: %s" % prepumpexptime)
173
- logger.info("detector type: %s" % str(det_type))
166
+ logger.info(f"visit: {visit}")
167
+ logger.info(f"filename: {chip_name}")
168
+ logger.info(f"protein_name: {protein_name}")
169
+ logger.info(f"n_exposures: {n_exposures}")
170
+ logger.info(f"chip_type: {chip_type}")
171
+ logger.info(f"map_type: {map_type}")
172
+ logger.info(f"pump_repeat: {pump_repeat}")
173
+ logger.info(f"pumpexptime: {pumpexptime}")
174
+ logger.info(f"pumpdelay: {pumpdelay}")
175
+ logger.info(f"prepumpexptime: {prepumpexptime}")
176
+ logger.info(f"detector type: {str(det_type)}")
177
+ logger.info(f"checker pattern: {checkerpattern}")
174
178
  if map_type == MappingType.Full:
175
179
  # This step creates some header files (.addr, .spec), containing the parameters,
176
180
  # that are only needed when full mapping is in use.
@@ -10,7 +10,6 @@ from dodal.devices.oav.oav_detector import OAV
10
10
 
11
11
  from mx_bluesky.I24.serial.fixed_target import i24ssx_Chip_Manager_py3v1 as manager
12
12
  from mx_bluesky.I24.serial.parameters.constants import OAV1_CAM
13
- from mx_bluesky.I24.serial.setup_beamline import caput, pv
14
13
 
15
14
  logger = logging.getLogger("I24ssx.moveonclick")
16
15
 
@@ -25,12 +24,7 @@ def _get_beam_centre(oav: OAV):
25
24
  Args:
26
25
  oav (OAV): the OAV device.
27
26
  """
28
- beamX, beamY = oav.parameters.beam_centre_i, oav.parameters.beam_centre_j
29
- # Re-scale beam position to an image of 1024x768 to get the correct values
30
- # See https://github.com/DiamondLightSource/dodal/issues/249
31
- beamX *= 1292 / 1024
32
- beamY *= 964 / 768
33
- return int(beamX), int(beamY)
27
+ return oav.parameters.beam_centre_i, oav.parameters.beam_centre_j
34
28
 
35
29
 
36
30
  # TODO In the future, this should be done automatically in the OAV device
@@ -45,6 +39,7 @@ def get_beam_centre():
45
39
 
46
40
  # Register clicks and move chip stages
47
41
  def onMouse(event, x, y, flags, param):
42
+ pmac = param
48
43
  beamX, beamY = get_beam_centre()
49
44
  if event == cv.EVENT_LBUTTONUP:
50
45
  logger.info("Clicked X and Y %s %s" % (x, y))
@@ -53,8 +48,8 @@ def onMouse(event, x, y, flags, param):
53
48
  logger.info("Moving X and Y %s %s" % (xmove, ymove))
54
49
  xmovepmacstring = "#1J:" + str(xmove)
55
50
  ymovepmacstring = "#2J:" + str(ymove)
56
- caput(pv.me14e_pmac_str, xmovepmacstring)
57
- caput(pv.me14e_pmac_str, ymovepmacstring)
51
+ pmac.pmac_string.set(xmovepmacstring)
52
+ pmac.pmac_string.set(ymovepmacstring)
58
53
 
59
54
 
60
55
  def update_ui(frame):
@@ -140,12 +135,14 @@ def update_ui(frame):
140
135
 
141
136
 
142
137
  def start_viewer(oav1: str = OAV1_CAM):
138
+ # Get PMAC device
139
+ pmac = i24.pmac()
143
140
  # Create a video caputure from OAV1
144
141
  cap = cv.VideoCapture(oav1)
145
142
 
146
143
  # Create window named OAV1view and set onmouse to this
147
144
  cv.namedWindow("OAV1view")
148
- cv.setMouseCallback("OAV1view", onMouse) # type: ignore
145
+ cv.setMouseCallback("OAV1view", onMouse, param=pmac) # type: ignore
149
146
 
150
147
  logger.info("Showing camera feed. Press escape to close")
151
148
  # Read captured video and store them in success and frame
@@ -165,7 +162,7 @@ def start_viewer(oav1: str = OAV1_CAM):
165
162
  if k == 101: # E
166
163
  manager.moveto("f2")
167
164
  if k == 97: # A
168
- caput(pv.me14e_pmac_str, r"\#1hmz\#2hmz\#3hmz")
165
+ pmac.pmac_string.set(r"\#1hmz\#2hmz\#3hmz")
169
166
  print("Current position set as origin")
170
167
  if k == 115: # S
171
168
  manager.fiducial(1)
@@ -176,21 +173,21 @@ def start_viewer(oav1: str = OAV1_CAM):
176
173
  if k == 98: # B
177
174
  manager.block_check() # doesn't work well for blockcheck as image doesn't update
178
175
  if k == 104: # H
179
- caput(pv.me14e_pmac_str, "#2J:-10")
176
+ pmac.pmac_string.set("#2J:-10")
180
177
  if k == 110: # N
181
- caput(pv.me14e_pmac_str, "#2J:10")
178
+ pmac.pmac_string.set("#2J:10")
182
179
  if k == 109: # M
183
- caput(pv.me14e_pmac_str, "#1J:-10")
180
+ pmac.pmac_string.set("#1J:-10")
184
181
  if k == 98: # B
185
- caput(pv.me14e_pmac_str, "#1J:10")
182
+ pmac.pmac_string.set("#1J:10")
186
183
  if k == 105: # I
187
- caput(pv.me14e_pmac_str, "#3J:-150")
184
+ pmac.pmac_string.set("#3J:-150")
188
185
  if k == 111: # O
189
- caput(pv.me14e_pmac_str, "#3J:150")
186
+ pmac.pmac_string.set("#3J:150")
190
187
  if k == 117: # U
191
- caput(pv.me14e_pmac_str, "#3J:-1000")
188
+ pmac.pmac_string.set("#3J:-1000")
192
189
  if k == 112: # P
193
- caput(pv.me14e_pmac_str, "#3J:1000")
190
+ pmac.pmac_string.set("#3J:1000")
194
191
  if k == 0x1B: # esc
195
192
  cv.destroyWindow("OAV1view")
196
193
  print("Pressed escape. Closing window")
@@ -1,4 +1,4 @@
1
1
  # file generated by setuptools_scm
2
2
  # don't change, don't track in version control
3
- __version__ = version = '0.0.1'
4
- __version_tuple__ = version_tuple = (0, 0, 1)
3
+ __version__ = version = '0.0.2'
4
+ __version_tuple__ = version_tuple = (0, 0, 2)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mx-bluesky
3
- Version: 0.0.1
3
+ Version: 0.0.2
4
4
  Summary: Bluesky tools for MX Beamlines
5
5
  Author-email: Dominic Oram <dominic.oram@diamond.ac.uk>
6
6
  License: Apache License
@@ -221,8 +221,9 @@ Requires-Dist: jupyterlab
221
221
  Requires-Dist: matplotlib
222
222
  Requires-Dist: requests
223
223
  Requires-Dist: opencv-python
224
- Requires-Dist: dls-dodal==1.8.0
224
+ Requires-Dist: dls-dodal==1.9.0
225
225
  Provides-Extra: dev
226
+ Requires-Dist: GitPython; extra == "dev"
226
227
  Requires-Dist: black; extra == "dev"
227
228
  Requires-Dist: mypy; extra == "dev"
228
229
  Requires-Dist: pipdeptree; extra == "dev"
@@ -256,7 +257,11 @@ Getting Started
256
257
 
257
258
  To get started with developing this repo at DLS run ```dls_dev_setup.sh``.
258
259
 
259
- We recommend developing with VSCode. You can do this at DLS by running::
260
+ If you want to develop interactively at the beamline we recommend using jupyter notebooks. You can get started with this by running::
261
+
262
+ $ ./start_jupyter.sh
263
+
264
+ If you're doing more in-depth development we recommend developing with VSCode. You can do this at DLS by running::
260
265
 
261
266
 
262
267
  $ module load vscode
@@ -22,6 +22,7 @@ start_jupyter.sh
22
22
  .vscode/settings.json
23
23
  .vscode/tasks.json
24
24
  deploy/deploy_edm_for_ssx.sh
25
+ deploy/deploy_mxbluesky.py
25
26
  docs/conf.py
26
27
  docs/genindex.rst
27
28
  docs/index.rst
@@ -5,9 +5,10 @@ jupyterlab
5
5
  matplotlib
6
6
  requests
7
7
  opencv-python
8
- dls-dodal==1.8.0
8
+ dls-dodal==1.9.0
9
9
 
10
10
  [dev]
11
+ GitPython
11
12
  black
12
13
  mypy
13
14
  pipdeptree
@@ -0,0 +1,2 @@
1
+ source .venv/bin/activate
2
+ jupyter-lab --matplotlib=qt5 ./src/mx_bluesky/jupyter_example.ipynb
@@ -1,4 +1,4 @@
1
- from unittest.mock import mock_open, patch
1
+ from unittest.mock import MagicMock, call, mock_open, patch
2
2
 
3
3
  import pytest
4
4
 
@@ -6,6 +6,7 @@ from mx_bluesky.I24.serial.fixed_target.i24ssx_Chip_Collect_py3v1 import (
6
6
  datasetsizei24,
7
7
  get_chip_prog_values,
8
8
  get_prog_num,
9
+ load_motion_program_data,
9
10
  start_i24,
10
11
  )
11
12
 
@@ -79,6 +80,38 @@ def test_get_prog_number(chip_type, map_type, pump_repeat, expected_prog):
79
80
  assert get_prog_num(chip_type, map_type, pump_repeat) == expected_prog
80
81
 
81
82
 
83
+ @pytest.mark.parametrize(
84
+ "map_type, pump_repeat, checker, expected_calls",
85
+ [
86
+ (0, 0, False, ["P1100=1"]), # Full chip, no pump probe, no checker
87
+ (1, 0, False, ["P1200=1"]), # Mapping lite, no pp, no checker
88
+ (
89
+ 1,
90
+ 2,
91
+ False,
92
+ ["P1439=0", "P1400=1"],
93
+ ), # Map irrelevant, pp to Repeat1, no checker
94
+ (
95
+ 0,
96
+ 3,
97
+ True,
98
+ ["P1439=0", "P1439=1", "P1400=1"],
99
+ ), # Map irrelevant, pp to Repeat2, checker enabled
100
+ ],
101
+ )
102
+ @patch("mx_bluesky.I24.serial.fixed_target.i24ssx_Chip_Collect_py3v1.i24.pmac")
103
+ @patch("mx_bluesky.I24.serial.fixed_target.i24ssx_Chip_Collect_py3v1.caget")
104
+ def test_load_motion_program_data_(
105
+ fake_caget, fake_pmac, map_type, pump_repeat, checker, expected_calls
106
+ ):
107
+ test_dict = {"N_EXPOSURES": [0, 1]}
108
+ fake_caget.return_value = checker
109
+ fake_pmac.pmac_string = MagicMock()
110
+ load_motion_program_data(fake_pmac, test_dict, map_type, pump_repeat)
111
+ call_list = [call.set(i) for i in expected_calls]
112
+ fake_pmac.pmac_string.assert_has_calls(call_list)
113
+
114
+
82
115
  @patch("mx_bluesky.I24.serial.fixed_target.i24ssx_Chip_Collect_py3v1.datasetsizei24")
83
116
  @patch("mx_bluesky.I24.serial.fixed_target.i24ssx_Chip_Collect_py3v1.DCID")
84
117
  @patch("mx_bluesky.I24.serial.fixed_target.i24ssx_Chip_Collect_py3v1.caput")
@@ -18,22 +18,22 @@ from mx_bluesky.I24.serial.fixed_target.i24ssx_moveonclick import (
18
18
  ((638, 392), "#1J:-3828", "#2J:-2352"),
19
19
  ],
20
20
  )
21
- @patch("mx_bluesky.I24.serial.fixed_target.i24ssx_moveonclick.caput")
21
+ @patch("mx_bluesky.I24.serial.fixed_target.i24ssx_moveonclick.i24.pmac")
22
22
  @patch("mx_bluesky.I24.serial.fixed_target.i24ssx_moveonclick.get_beam_centre")
23
23
  def test_onMouse_gets_beam_position_and_sends_correct_str(
24
24
  fake_get_beam_pos,
25
- fake_caput,
25
+ fake_pmac,
26
26
  beam_position,
27
27
  expected_1J,
28
28
  expected_2J,
29
29
  ):
30
30
  fake_get_beam_pos.side_effect = [beam_position]
31
- onMouse(cv.EVENT_LBUTTONUP, 0, 0, "", "")
32
- assert fake_caput.call_count == 2
33
- fake_caput.assert_has_calls(
31
+ fake_pmac.pmac_string = MagicMock()
32
+ onMouse(cv.EVENT_LBUTTONUP, 0, 0, "", param=fake_pmac)
33
+ fake_pmac.pmac_string.assert_has_calls(
34
34
  [
35
- call(ANY, expected_1J),
36
- call(ANY, expected_2J),
35
+ call.set(expected_1J),
36
+ call.set(expected_2J),
37
37
  ]
38
38
  )
39
39
 
@@ -1,2 +0,0 @@
1
- source .venv/bin/activate
2
- jupyter-lab --matplotlib=qt5
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes