mx-bluesky 0.0.1__py3-none-any.whl → 0.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. mx_bluesky/__main__.py +1 -2
  2. mx_bluesky/_version.py +14 -2
  3. mx_bluesky/example.py +4 -4
  4. mx_bluesky/i04/__init__.py +3 -0
  5. mx_bluesky/i04/callbacks/murko_callback.py +45 -0
  6. mx_bluesky/i04/thawing_plan.py +84 -0
  7. mx_bluesky/i24/serial/__init__.py +49 -0
  8. mx_bluesky/i24/serial/blueapi_config.yaml +12 -0
  9. mx_bluesky/{I24 → i24}/serial/dcid.py +53 -41
  10. mx_bluesky/{I24 → i24}/serial/extruder/EX-gui-edm/DetStage.edl +1 -2
  11. mx_bluesky/{I24 → i24}/serial/extruder/EX-gui-edm/DiamondExtruder-I24-py3v1.edl +28 -32
  12. mx_bluesky/{I24 → i24}/serial/extruder/EX-gui-edm/microdrop_alignment.edl +0 -1
  13. mx_bluesky/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +513 -0
  14. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/CustomChip_py3v1.edl +1 -2
  15. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/DetStage.edl +1 -2
  16. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/DiamondChipI24-py3v1.edl +46 -41
  17. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/ME14E-GeneralPurpose.edl +0 -1
  18. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/MappingLite-oxford_py3v1.edl +10 -11
  19. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/PMAC_Command.edl +0 -1
  20. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/Shutter_Control.edl +0 -1
  21. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/microdrop_alignment.edl +0 -1
  22. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/nudgechip.edl +0 -1
  23. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/pumpprobe-py3v1.edl +300 -119
  24. mx_bluesky/i24/serial/fixed_target/FT-gui-edm/short1-laser.png +0 -0
  25. mx_bluesky/i24/serial/fixed_target/FT-gui-edm/short2-laser.png +0 -0
  26. mx_bluesky/{I24 → i24}/serial/fixed_target/ft_utils.py +24 -1
  27. mx_bluesky/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +798 -0
  28. mx_bluesky/{I24 → i24}/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +374 -408
  29. mx_bluesky/{I24 → i24}/serial/fixed_target/i24ssx_Chip_Mapping_py3v1.py +34 -40
  30. mx_bluesky/i24/serial/fixed_target/i24ssx_Chip_StartUp_py3v1.py +325 -0
  31. mx_bluesky/{I24 → i24}/serial/fixed_target/i24ssx_moveonclick.py +40 -45
  32. mx_bluesky/i24/serial/log.py +156 -0
  33. mx_bluesky/i24/serial/parameters/__init__.py +15 -0
  34. mx_bluesky/i24/serial/parameters/constants.py +47 -0
  35. mx_bluesky/i24/serial/parameters/experiment_parameters.py +124 -0
  36. mx_bluesky/i24/serial/parameters/fixed_target/cs/cs_maker.json +9 -0
  37. mx_bluesky/{I24 → i24}/serial/parameters/fixed_target/cs/motor_direction.txt +1 -1
  38. mx_bluesky/{I24 → i24}/serial/parameters/fixed_target/pvar_files/minichip-oxford.pvar +1 -1
  39. mx_bluesky/i24/serial/parameters/utils.py +40 -0
  40. mx_bluesky/i24/serial/run_extruder.sh +19 -0
  41. mx_bluesky/i24/serial/run_fixed_target.sh +22 -0
  42. mx_bluesky/i24/serial/run_serial.py +36 -0
  43. mx_bluesky/{I24 → i24}/serial/set_visit_directory.sh +6 -1
  44. mx_bluesky/{I24 → i24}/serial/setup_beamline/pv.py +1 -62
  45. mx_bluesky/{I24 → i24}/serial/setup_beamline/pv_abstract.py +6 -7
  46. mx_bluesky/{I24 → i24}/serial/setup_beamline/setup_beamline.py +90 -269
  47. mx_bluesky/{I24 → i24}/serial/setup_beamline/setup_detector.py +47 -40
  48. mx_bluesky/i24/serial/setup_beamline/setup_zebra_plans.py +459 -0
  49. mx_bluesky/i24/serial/start_blueapi.sh +28 -0
  50. mx_bluesky/i24/serial/write_nexus.py +102 -0
  51. mx_bluesky/parameters/__init__.py +31 -0
  52. mx_bluesky/parameters/components.py +200 -0
  53. {mx_bluesky-0.0.1.dist-info → mx_bluesky-0.3.1.dist-info}/METADATA +37 -26
  54. mx_bluesky-0.3.1.dist-info/RECORD +67 -0
  55. {mx_bluesky-0.0.1.dist-info → mx_bluesky-0.3.1.dist-info}/WHEEL +1 -1
  56. mx_bluesky-0.3.1.dist-info/entry_points.txt +4 -0
  57. mx_bluesky/I24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +0 -476
  58. mx_bluesky/I24/serial/fixed_target/FT-gui-edm/ME14E-motors.edl +0 -1874
  59. mx_bluesky/I24/serial/fixed_target/__init__.py +0 -0
  60. mx_bluesky/I24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +0 -695
  61. mx_bluesky/I24/serial/fixed_target/i24ssx_Chip_StartUp_py3v1.py +0 -463
  62. mx_bluesky/I24/serial/log.py +0 -101
  63. mx_bluesky/I24/serial/parameters/__init__.py +0 -5
  64. mx_bluesky/I24/serial/parameters/constants.py +0 -39
  65. mx_bluesky/I24/serial/parameters/fixed_target/cs/cs_maker.json +0 -9
  66. mx_bluesky/I24/serial/parameters/fixed_target/cs/fiducial_1.txt +0 -4
  67. mx_bluesky/I24/serial/parameters/fixed_target/cs/fiducial_2.txt +0 -4
  68. mx_bluesky/I24/serial/parameters/fixed_target/litemaps/currentchip.map +0 -81
  69. mx_bluesky/I24/serial/parameters/fixed_target/parameters.txt +0 -13
  70. mx_bluesky/I24/serial/run_serial.py +0 -52
  71. mx_bluesky/I24/serial/write_nexus.py +0 -113
  72. mx_bluesky-0.0.1.dist-info/RECORD +0 -58
  73. mx_bluesky-0.0.1.dist-info/entry_points.txt +0 -4
  74. /mx_bluesky/{I24 → i24}/__init__.py +0 -0
  75. /mx_bluesky/{I24/serial → i24/serial/extruder}/__init__.py +0 -0
  76. /mx_bluesky/{I24/serial/extruder → i24/serial/fixed_target}/__init__.py +0 -0
  77. /mx_bluesky/{I24 → i24}/serial/parameters/fixed_target/pvar_files/oxford.pvar +0 -0
  78. /mx_bluesky/{I24 → i24}/serial/run_ssx.sh +0 -0
  79. /mx_bluesky/{I24 → i24}/serial/setup_beamline/__init__.py +0 -0
  80. /mx_bluesky/{I24 → i24}/serial/setup_beamline/ca.py +0 -0
  81. {mx_bluesky-0.0.1.dist-info → mx_bluesky-0.3.1.dist-info}/LICENSE +0 -0
  82. {mx_bluesky-0.0.1.dist-info → mx_bluesky-0.3.1.dist-info}/top_level.txt +0 -0
@@ -2,9 +2,7 @@
2
2
  Chip manager for fixed target
3
3
  This version changed to python3 March2020 by RLO
4
4
  """
5
- from __future__ import annotations
6
5
 
7
- import argparse
8
6
  import json
9
7
  import logging
10
8
  import re
@@ -12,31 +10,53 @@ import shutil
12
10
  import sys
13
11
  import time
14
12
  from pathlib import Path
13
+ from pprint import pformat
15
14
  from time import sleep
16
15
 
16
+ import bluesky.plan_stubs as bps
17
17
  import numpy as np
18
-
19
- from mx_bluesky.I24.serial import log
20
- from mx_bluesky.I24.serial.fixed_target import i24ssx_Chip_Mapping_py3v1 as mapping
21
- from mx_bluesky.I24.serial.fixed_target import i24ssx_Chip_StartUp_py3v1 as startup
22
- from mx_bluesky.I24.serial.fixed_target.ft_utils import ChipType, MappingType
23
- from mx_bluesky.I24.serial.parameters.constants import (
18
+ from blueapi.core import MsgGenerator
19
+ from dodal.beamlines import i24
20
+ from dodal.common import inject
21
+ from dodal.devices.i24.beamstop import Beamstop, BeamstopPositions
22
+ from dodal.devices.i24.dual_backlight import BacklightPositions, DualBacklight
23
+ from dodal.devices.i24.i24_detector_motion import DetectorMotion
24
+ from dodal.devices.i24.pmac import PMAC, EncReset, LaserSettings
25
+
26
+ from mx_bluesky.i24.serial import log
27
+ from mx_bluesky.i24.serial.fixed_target import i24ssx_Chip_Mapping_py3v1 as mapping
28
+ from mx_bluesky.i24.serial.fixed_target import i24ssx_Chip_StartUp_py3v1 as startup
29
+ from mx_bluesky.i24.serial.fixed_target.ft_utils import (
30
+ ChipType,
31
+ Fiducials,
32
+ MappingType,
33
+ )
34
+ from mx_bluesky.i24.serial.parameters import get_chip_format
35
+ from mx_bluesky.i24.serial.parameters.constants import (
24
36
  CS_FILES_PATH,
25
37
  FULLMAP_PATH,
26
38
  LITEMAP_PATH,
39
+ PARAM_FILE_NAME,
27
40
  PARAM_FILE_PATH_FT,
28
41
  PVAR_FILE_PATH,
29
42
  )
30
- from mx_bluesky.I24.serial.setup_beamline import caget, caput, pv
31
- from mx_bluesky.I24.serial.setup_beamline.setup_detector import get_detector_type
43
+ from mx_bluesky.i24.serial.setup_beamline import Pilatus, caget, caput, pv
44
+ from mx_bluesky.i24.serial.setup_beamline.setup_detector import get_detector_type
32
45
 
33
46
  logger = logging.getLogger("I24ssx.chip_manager")
34
47
 
35
-
36
- def _coerce_to_path(path: Path | str) -> Path:
37
- if not isinstance(path, Path):
38
- return Path(path)
39
- return path
48
+ # An approximation of the chip size for the move during fiducials alignment.
49
+ CHIP_MOVES = {
50
+ ChipType.Oxford: 25.40,
51
+ ChipType.OxfordInner: 24.60,
52
+ ChipType.Custom: 25.40,
53
+ ChipType.Minichip: 25.40,
54
+ }
55
+ CHIPTYPE_PV = pv.me14e_gp1
56
+ MAPTYPE_PV = pv.me14e_gp2
57
+ NUM_EXPOSURES_PV = pv.me14e_gp3
58
+ PUMP_REPEAT_PV = pv.me14e_gp4
59
+ MAP_FILEPATH_PV = pv.me14e_gp5
40
60
 
41
61
 
42
62
  def setup_logging():
@@ -46,47 +66,40 @@ def setup_logging():
46
66
 
47
67
 
48
68
  @log.log_on_entry
49
- def initialise():
50
- # commented out filter lines 230719 as this stage not connected
51
- logger.info("Setting VMAX VELO ACCL HHL LLM pvs")
52
-
53
- caput(pv.me14e_stage_x + ".VMAX", 20)
54
- caput(pv.me14e_stage_y + ".VMAX", 20)
55
- caput(pv.me14e_stage_z + ".VMAX", 20)
56
- # caput(pv.me14e_filter + '.VMAX', 20)
57
- caput(pv.me14e_stage_x + ".VELO", 20)
58
- caput(pv.me14e_stage_y + ".VELO", 20)
59
- caput(pv.me14e_stage_z + ".VELO", 20)
60
- # caput(pv.me14e_filter + '.VELO', 20)
61
- caput(pv.me14e_stage_x + ".ACCL", 0.01)
62
- caput(pv.me14e_stage_y + ".ACCL", 0.01)
63
- caput(pv.me14e_stage_z + ".ACCL", 0.01)
64
- # caput(pv.me14e_filter + '.ACCL', 0.01)
65
- caput(pv.me14e_stage_x + ".HLM", 30)
66
- caput(pv.me14e_stage_x + ".LLM", -29)
67
- caput(pv.me14e_stage_y + ".HLM", 30)
68
- caput(pv.me14e_stage_y + ".LLM", -30)
69
- # caput(pv.me14e_stage_x + '.LLM', -30)
70
- caput(pv.me14e_stage_z + ".HLM", 5.1)
71
- caput(pv.me14e_stage_z + ".LLM", -4.1)
72
- # caput(pv.me14e_filter + '.HLM', 45.0)
73
- # caput(pv.me14e_filter + '.LLM', -45.0)
74
- caput(pv.me14e_gp1, 1)
75
- caput(pv.me14e_gp2, 0)
76
- caput(pv.me14e_gp3, 1)
77
- caput(pv.me14e_gp4, 0)
69
+ def initialise_stages(
70
+ pmac: PMAC = inject("pmac"),
71
+ ) -> MsgGenerator:
72
+ """Initialise the portable stages PVs, usually used only once right after setting \
73
+ up the stages either after use at different facility.
74
+ """
75
+ setup_logging()
76
+ group = "initialise_stages"
77
+ logger.info("Setting velocity, acceleration and limits for stages")
78
+
79
+ yield from bps.abs_set(pmac.x.velocity, 20, group=group)
80
+ yield from bps.abs_set(pmac.y.velocity, 20, group=group)
81
+ yield from bps.abs_set(pmac.z.velocity, 20, group=group)
82
+ yield from bps.abs_set(pmac.x.acceleration_time, 0.01, group=group)
83
+ yield from bps.abs_set(pmac.y.acceleration_time, 0.01, group=group)
84
+ yield from bps.abs_set(pmac.z.acceleration_time, 0.01, group=group)
85
+ yield from bps.abs_set(pmac.x.high_limit_travel, 30, group=group)
86
+ yield from bps.abs_set(pmac.x.low_limit_travel, -29, group=group)
87
+ yield from bps.abs_set(pmac.y.high_limit_travel, 30, group=group)
88
+ yield from bps.abs_set(pmac.y.low_limit_travel, -30, group=group)
89
+ yield from bps.abs_set(pmac.z.high_limit_travel, 5.1, group=group)
90
+ yield from bps.abs_set(pmac.z.low_limit_travel, -4.1, group=group)
91
+ caput(CHIPTYPE_PV, 1) # chip type
92
+ caput(MAPTYPE_PV, 0) # map type
93
+ caput(NUM_EXPOSURES_PV, 1) # num exposures
94
+ caput(PUMP_REPEAT_PV, 0) # pump repeat
78
95
  caput(pv.me14e_filepath, "test")
79
96
  caput(pv.me14e_chip_name, "albion")
80
97
  caput(pv.me14e_dcdetdist, 1480)
81
98
  caput(pv.me14e_exptime, 0.01)
82
- caput(pv.me14e_pmac_str, "m508=100 m509=150")
83
- caput(pv.me14e_pmac_str, "m608=100 m609=150")
84
- caput(pv.me14e_pmac_str, "m708=100 m709=150")
85
- caput(pv.me14e_pmac_str, "m808=100 m809=150")
86
-
87
- # Define detector in use
88
- logger.debug("Define detector in use.")
89
- det_type = get_detector_type()
99
+ yield from bps.abs_set(pmac.enc_reset, EncReset.ENC5, group=group)
100
+ yield from bps.abs_set(pmac.enc_reset, EncReset.ENC6, group=group)
101
+ yield from bps.abs_set(pmac.enc_reset, EncReset.ENC7, group=group)
102
+ yield from bps.abs_set(pmac.enc_reset, EncReset.ENC8, group=group)
90
103
 
91
104
  caput(pv.pilat_cbftemplate, 0)
92
105
 
@@ -98,91 +111,77 @@ def initialise():
98
111
  sys.stdout.write(".")
99
112
  sys.stdout.flush()
100
113
 
101
- caput(pv.me14e_gp100, "press set params to read visit")
102
- caput(pv.me14e_gp101, det_type.name)
103
-
104
- logger.info("Initialisation Complete")
114
+ logger.info("Initialisation of the stages complete")
115
+ yield from bps.wait(group=group)
105
116
 
106
117
 
107
118
  @log.log_on_entry
108
- def write_parameter_file(param_path: Path | str = PARAM_FILE_PATH_FT):
109
- param_path = _coerce_to_path(param_path)
119
+ def write_parameter_file(
120
+ detector_stage: DetectorMotion = inject("detector_motion"),
121
+ ) -> MsgGenerator:
122
+ setup_logging()
123
+ param_path: Path = PARAM_FILE_PATH_FT
124
+ # Create directory if it doesn't yet exist.
110
125
  param_path.mkdir(parents=True, exist_ok=True)
111
126
 
112
- param_fid = "parameters.txt"
113
- logger.info("Writing Parameter File: %s" % (param_path / param_fid).as_posix())
114
-
115
- visit = caget(pv.me14e_gp100)
127
+ logger.info(f"Writing Parameter File: {(param_path / PARAM_FILE_NAME).as_posix()}")
116
128
 
117
129
  filename = caget(pv.me14e_chip_name)
118
-
119
- exptime = caget(pv.me14e_exptime)
120
- dcdetdist = caget(pv.me14e_dcdetdist)
121
- protein_name = caget(pv.me14e_filepath)
122
- pump_repeat = caget(pv.me14e_gp4)
123
- pumpexptime = caget(pv.me14e_gp103)
124
- pumpdelay = caget(pv.me14e_gp110)
125
- prepumpexptime = caget(pv.me14e_gp109)
126
- n_exposures = caget(pv.me14e_gp3)
127
- map_type = caget(pv.me14e_gp2)
128
- chip_type = caget(pv.me14e_gp1)
129
- det_type = get_detector_type()
130
+ det_type = yield from get_detector_type(detector_stage)
131
+ chip_params = get_chip_format(ChipType(int(caget(CHIPTYPE_PV))))
132
+ map_type = int(caget(MAPTYPE_PV))
133
+ pump_repeat = int(caget(PUMP_REPEAT_PV))
130
134
 
131
135
  # If file name ends in a digit this causes processing/pilatus pain.
132
136
  # Append an underscore
133
- if det_type == "pilatus":
137
+ if isinstance(det_type, Pilatus):
134
138
  caput(pv.pilat_cbftemplate, 0)
135
139
  m = re.search(r"\d+$", filename)
136
140
  if m is not None:
137
141
  # Note for future reference. Appending underscore causes more hassle and
138
142
  # high probability of users accidentally overwriting data. Use a dash
139
143
  filename = filename + "-"
140
- logger.info(
141
- "Requested filename ends in a number. Appended dash: %s" % filename
144
+ logger.debug(
145
+ f"Requested filename ends in a number. Appended dash: {filename}"
142
146
  )
143
147
 
144
- # historical - use chip_name instead of filename
145
- chip_name = filename
146
-
147
- with open(param_path / param_fid, "w") as f:
148
- f.write("visit \t\t%s\n" % visit)
149
- f.write("chip_name \t%s\n" % chip_name)
150
- f.write("protein_name \t%s\n" % protein_name)
151
- f.write("n_exposures \t%s\n" % n_exposures)
152
- f.write("chip_type \t%s\n" % chip_type)
153
- f.write("map_type \t%s\n" % map_type)
154
- f.write("pump_repeat \t%s\n" % pump_repeat)
155
- f.write("pumpexptime \t%s\n" % pumpexptime)
156
- f.write("pumpdelay \t%s\n" % pumpdelay)
157
- f.write("prepumpexptime \t%s\n" % prepumpexptime)
158
- f.write("exptime \t%s\n" % exptime)
159
- f.write("dcdetdist \t%s\n" % dcdetdist)
160
- f.write("det_type \t%s\n" % str(det_type))
161
-
162
- 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))
148
+ params_dict = {
149
+ "visit": log._read_visit_directory_from_file().as_posix(), # noqa
150
+ "directory": caget(pv.me14e_filepath),
151
+ "filename": filename,
152
+ "exposure_time_s": caget(pv.me14e_exptime),
153
+ "detector_distance_mm": caget(pv.me14e_dcdetdist),
154
+ "detector_name": str(det_type),
155
+ "num_exposures": int(caget(NUM_EXPOSURES_PV)),
156
+ "chip": chip_params.dict(),
157
+ "map_type": map_type,
158
+ "pump_repeat": pump_repeat,
159
+ "checker_pattern": bool(caget(pv.me14e_gp111)),
160
+ "laser_dwell_s": float(caget(pv.me14e_gp103)) if pump_repeat != 0 else None,
161
+ "laser_delay_s": float(caget(pv.me14e_gp110)) if pump_repeat != 0 else None,
162
+ "pre_pump_exposure_s": float(caget(pv.me14e_gp109))
163
+ if pump_repeat != 0
164
+ else None,
165
+ }
166
+
167
+ with open(param_path / PARAM_FILE_NAME, "w") as f:
168
+ json.dump(params_dict, f, indent=4)
169
+
170
+ logger.info("Information written to file \n")
171
+ logger.info(pformat(params_dict))
172
+
174
173
  if map_type == MappingType.Full:
175
174
  # This step creates some header files (.addr, .spec), containing the parameters,
176
175
  # that are only needed when full mapping is in use.
177
- logger.debug("Running start up now.")
176
+ logger.info("Full mapping in use. Running start up now.")
178
177
  startup.run()
178
+ yield from bps.null()
179
179
 
180
180
 
181
- def scrape_pvar_file(fid: str, pvar_dir: Path | str = PVAR_FILE_PATH):
181
+ def scrape_pvar_file(fid: str, pvar_dir: Path = PVAR_FILE_PATH):
182
182
  block_start_list = []
183
- pvar_dir = _coerce_to_path(pvar_dir)
184
183
 
185
- with open(pvar_dir / fid, "r") as f:
184
+ with open(pvar_dir / fid) as f:
186
185
  lines = f.readlines()
187
186
  for line in lines:
188
187
  line = line.rstrip()
@@ -206,40 +205,40 @@ def scrape_pvar_file(fid: str, pvar_dir: Path | str = PVAR_FILE_PATH):
206
205
  @log.log_on_entry
207
206
  def define_current_chip(
208
207
  chipid: str = "oxford",
209
- param_path: Path | str = PVAR_FILE_PATH,
210
- ):
208
+ pmac: PMAC = inject("pmac"),
209
+ ) -> MsgGenerator:
210
+ setup_logging()
211
211
  logger.debug("Run load stock map for just the first block")
212
- load_stock_map("Just The First Block")
212
+ yield from load_stock_map("Just The First Block")
213
213
  """
214
214
  Not sure what this is for:
215
215
  print 'Setting Mapping Type to Lite'
216
216
  caput(pv.me14e_gp2, 1)
217
217
  """
218
- chip_type = int(caget(pv.me14e_gp1))
219
- logger.info("Chip type:%s Chipid:%s" % (chip_type, chipid))
218
+ chip_type = int(caget(CHIPTYPE_PV))
219
+ logger.info(f"Chip type:{chip_type} Chipid:{chipid}")
220
220
  if chipid == "oxford":
221
- caput(pv.me14e_gp1, 1)
222
-
223
- param_path = _coerce_to_path(param_path)
221
+ caput(CHIPTYPE_PV, 0)
224
222
 
225
- with open(param_path / f"{chipid}.pvar", "r") as f:
226
- logger.info("Opening %s.pvar" % chipid)
223
+ with open(PVAR_FILE_PATH / f"{chipid}.pvar") as f:
224
+ logger.info(f"Opening {chipid}.pvar")
227
225
  for line in f.readlines():
228
226
  if line.startswith("#"):
229
227
  continue
230
228
  line_from_file = line.rstrip("\n")
231
- logger.info("%s" % line_from_file)
232
- caput(pv.me14e_pmac_str, line_from_file)
229
+ logger.info(f"{line_from_file}")
230
+ yield from bps.abs_set(pmac.pmac_string, line_from_file)
233
231
 
234
232
 
235
233
  @log.log_on_entry
236
- def save_screen_map(litemap_path: Path | str = LITEMAP_PATH):
237
- litemap_path = _coerce_to_path(litemap_path)
234
+ def save_screen_map() -> MsgGenerator:
235
+ setup_logging()
236
+ litemap_path: Path = LITEMAP_PATH
238
237
  litemap_path.mkdir(parents=True, exist_ok=True)
239
238
 
240
- logger.info("Saving %s currentchip.map" % litemap_path.as_posix())
239
+ logger.info(f"Saving {litemap_path.as_posix()} currentchip.map")
241
240
  with open(litemap_path / "currentchip.map", "w") as f:
242
- logger.info("Printing only blocks with block_val == 1")
241
+ logger.debug("Printing only blocks with block_val == 1")
243
242
  for x in range(1, 82):
244
243
  block_str = "ME14E-MO-IOC-01:GP%i" % (x + 10)
245
244
  block_val = int(caget(block_str))
@@ -247,23 +246,29 @@ def save_screen_map(litemap_path: Path | str = LITEMAP_PATH):
247
246
  logger.info("%s %d" % (block_str, block_val))
248
247
  line = "%02dstatus P3%02d1 \t%s\n" % (x, x, block_val)
249
248
  f.write(line)
250
- return 0
249
+ yield from bps.null()
251
250
 
252
251
 
253
252
  @log.log_on_entry
254
253
  def upload_parameters(
255
- chipid: str = "oxford",
256
- litemap_path: Path | str = LITEMAP_PATH,
257
- ):
254
+ chipid: str = "oxford", pmac: PMAC = inject("pmac"), width: int | None = None
255
+ ) -> MsgGenerator:
256
+ setup_logging()
258
257
  logger.info("Uploading Parameters to the GeoBrick")
259
258
  if chipid == "oxford":
260
- caput(pv.me14e_gp1, 0)
259
+ caput(CHIPTYPE_PV, 0)
261
260
  width = 8
262
- litemap_path = _coerce_to_path(litemap_path)
261
+ else:
262
+ if width is None:
263
+ raise Exception("Supply a width if chipid is not oxford")
263
264
 
264
- with open(litemap_path / "currentchip.map", "r") as f:
265
- logger.info("Chipid %s" % chipid)
266
- logger.info("width %d" % width)
265
+ map_file: Path = LITEMAP_PATH / "currentchip.map"
266
+ if not map_file.exists():
267
+ raise FileNotFoundError(f"The file {map_file} has not yet been created")
268
+
269
+ with open(map_file) as f:
270
+ logger.info(f"Chipid {chipid}")
271
+ logger.info(f"width {width}")
267
272
  x = 1
268
273
  for line in f.readlines()[: width**2]:
269
274
  cols = line.split()
@@ -281,33 +286,42 @@ def upload_parameters(
281
286
  x = 1
282
287
  else:
283
288
  x += 1
284
- caput(pv.me14e_pmac_str, s)
289
+ yield from bps.abs_set(pmac.pmac_string, s, wait=True)
285
290
  sleep(0.02)
286
291
 
287
292
  logger.warning("Automatic Setting Mapping Type to Lite has been disabled")
288
293
  logger.debug("Upload parameters done.")
294
+ yield from bps.null()
289
295
 
290
296
 
291
297
  @log.log_on_entry
292
- def upload_full(fullmap_path: Path | str = FULLMAP_PATH):
293
- fullmap_path = _coerce_to_path(fullmap_path)
298
+ def upload_full(pmac: PMAC | None = None) -> MsgGenerator:
299
+ setup_logging()
300
+ if not pmac:
301
+ pmac = i24.pmac()
294
302
 
295
- with open(fullmap_path / "currentchip.full", "r") as fh:
303
+ map_file: Path = FULLMAP_PATH / "currentchip.full"
304
+ if not map_file.exists():
305
+ raise FileNotFoundError(f"The file {map_file} has not yet been created")
306
+ with open(map_file) as fh:
296
307
  f = fh.readlines()
297
308
 
298
- for i in range(len(f) // 2):
309
+ for _i in range(len(f) // 2):
299
310
  pmac_list = []
300
- for j in range(2):
311
+ for _j in range(2):
301
312
  pmac_list.append(f.pop(0).rstrip("\n"))
302
313
  writeline = " ".join(pmac_list)
303
- logger.info("%s" % writeline)
304
- caput(pv.me14e_pmac_str, writeline)
305
- sleep(0.02)
314
+ logger.info(f"{writeline}")
315
+ yield from bps.abs_set(pmac.pmac_string, writeline, wait=True)
316
+ yield from bps.sleep(0.02)
306
317
  logger.debug("Upload fullmap done")
318
+ yield from bps.null()
307
319
 
308
320
 
309
321
  @log.log_on_entry
310
- def load_stock_map(map_choice: str = "clear"):
322
+ def load_stock_map(map_choice: str = "clear") -> MsgGenerator:
323
+ # TODO See https://github.com/DiamondLightSource/mx_bluesky/issues/122
324
+ setup_logging()
311
325
  logger.info("Adjusting Lite Map EDM Screen")
312
326
  logger.debug("Please wait, adjusting lite map")
313
327
  #
@@ -402,7 +416,7 @@ def load_stock_map(map_choice: str = "clear"):
402
416
  28,
403
417
  27,
404
418
  10,
405
- ] + x77
419
+ ] + x77 # noqa
406
420
  x44 = [22, 21, 20, 19, 30, 35, 46, 45, 44, 43, 38, 27, 28, 29, 36, 37]
407
421
  x49 = [x + 1 for x in range(49)]
408
422
  x66 = [
@@ -492,24 +506,26 @@ def load_stock_map(map_choice: str = "clear"):
492
506
  map_dict["half1"] = half1
493
507
  map_dict["half2"] = half2
494
508
 
495
- logger.info("Clearing GP 10-74")
509
+ logger.info("Clearing GP 10-74") # Actually 11-44
496
510
  for i in range(1, 65):
497
511
  pvar = "ME14E-MO-IOC-01:GP" + str(i + 10)
498
512
  caput(pvar, 0)
499
513
  sys.stdout.write(".")
500
514
  sys.stdout.flush()
501
515
  logger.info("Map cleared")
502
- logger.info("Loading Map Choice %s" % map_choice)
516
+ logger.info(f"Loading Map Choice {map_choice}")
503
517
  for i in map_dict[map_choice]:
504
518
  pvar = "ME14E-MO-IOC-01:GP" + str(i + 10)
505
519
  caput(pvar, 1)
506
520
  logger.debug("Load stock map done.")
521
+ yield from bps.null()
507
522
 
508
523
 
509
524
  @log.log_on_entry
510
- def load_lite_map(litemap_path: Path | str = LITEMAP_PATH):
525
+ def load_lite_map() -> MsgGenerator:
526
+ setup_logging()
511
527
  logger.debug("Run load stock map with 'clear' setting.")
512
- load_stock_map("clear")
528
+ yield from load_stock_map("clear")
513
529
  # fmt: off
514
530
  # Oxford_block_dict is wrong (columns and rows need to flip) added in script below to generate it automatically however kept this for backwards compatiability/reference
515
531
  oxford_block_dict = { # noqa: F841
@@ -523,7 +539,7 @@ def load_lite_map(litemap_path: Path | str = LITEMAP_PATH):
523
539
  'H1': '64', 'H2': '63', 'H3': '62', 'H4': '61', 'H5': '60', 'H6': '59', 'H7': '58', 'H8': '57',
524
540
  }
525
541
  # fmt: on
526
- chip_type = int(caget(pv.me14e_gp1))
542
+ chip_type = int(caget(CHIPTYPE_PV))
527
543
  if chip_type in [ChipType.Oxford, ChipType.OxfordInner]:
528
544
  logger.info("Oxford Block Order")
529
545
  rows = ["A", "B", "C", "D", "E", "F", "G", "H"]
@@ -551,14 +567,14 @@ def load_lite_map(litemap_path: Path | str = LITEMAP_PATH):
551
567
  label = "%02.d" % (lab_num + 1)
552
568
  btn_names[button_name] = label
553
569
  block_dict = btn_names
570
+ else:
571
+ raise ValueError(f"{chip_type=} unrecognised")
554
572
 
555
- litemap_path = _coerce_to_path(litemap_path)
556
-
557
- litemap_fid = str(caget(pv.me14e_gp5)) + ".lite"
573
+ litemap_fid = f"{caget(MAP_FILEPATH_PV)}.lite"
558
574
  logger.info("Please wait, loading LITE map")
559
- logger.info("Loading Lite Map")
560
- logger.info("Opening %s" % (litemap_path / litemap_fid))
561
- with open(litemap_path / litemap_fid, "r") as fh:
575
+ logger.debug("Loading Lite Map")
576
+ logger.info("Opening %s" % (LITEMAP_PATH / litemap_fid))
577
+ with open(LITEMAP_PATH / litemap_fid) as fh:
562
578
  f = fh.readlines()
563
579
  for line in f:
564
580
  entry = line.split()
@@ -566,151 +582,140 @@ def load_lite_map(litemap_path: Path | str = LITEMAP_PATH):
566
582
  yesno = entry[1]
567
583
  block_num = block_dict[block_name]
568
584
  pvar = "ME14E-MO-IOC-01:GP" + str(int(block_num) + 10)
569
- logger.info("Block: %s \tScanned: %s \tPVAR: %s" % (block_name, yesno, pvar))
585
+ logger.info(f"Block: {block_name} \tScanned: {yesno} \tPVAR: {pvar}")
570
586
  logger.debug("Load lite map done")
587
+ yield from bps.null()
571
588
 
572
589
 
573
590
  @log.log_on_entry
574
- def load_full_map(fullmap_path: Path | str = FULLMAP_PATH):
575
- (
576
- chip_name,
577
- visit,
578
- sub_dir,
579
- n_exposures,
580
- chip_type,
581
- map_type,
582
- ) = startup.scrape_parameter_file()
583
- fullmap_path = _coerce_to_path(fullmap_path)
584
-
585
- fullmap_fid = fullmap_path / f"{str(caget(pv.me14e_gp5))}.spec"
586
- logger.info("Opening %s" % fullmap_fid)
587
- mapping.plot_file(fullmap_fid, chip_type)
588
- mapping.convert_chip_to_hex(fullmap_fid, chip_type)
589
- shutil.copy2(fullmap_fid.with_suffix(".full"), fullmap_path / "currentchip.full")
591
+ def load_full_map() -> MsgGenerator:
592
+ setup_logging()
593
+ params = startup.read_parameter_file()
594
+
595
+ fullmap_fid = FULLMAP_PATH / f"{caget(MAP_FILEPATH_PV)}.spec"
596
+ logger.info(f"Opening {fullmap_fid}")
597
+ mapping.plot_file(fullmap_fid, params.chip.chip_type.value)
598
+ mapping.convert_chip_to_hex(fullmap_fid, params.chip.chip_type.value)
599
+ shutil.copy2(fullmap_fid.with_suffix(".full"), FULLMAP_PATH / "currentchip.full")
590
600
  logger.info(
591
- "Copying %s to %s"
592
- % (fullmap_fid.with_suffix(".full"), fullmap_path / "currentchip.full")
601
+ "Copying {} to {}".format(
602
+ fullmap_fid.with_suffix(".full"), FULLMAP_PATH / "currentchip.full"
603
+ )
593
604
  )
594
605
  logger.debug("Load full map done")
606
+ yield from bps.null()
595
607
 
596
608
 
597
609
  @log.log_on_entry
598
- def moveto(place: str = "origin"):
599
- logger.info("Move to: %s" % place)
600
- chip_type = int(caget(pv.me14e_gp1))
601
- logger.info("Chip type is%s" % chip_type)
602
-
603
- if chip_type == ChipType.Oxford or chip_type == ChipType.Minichip:
604
- # Oxford and minichip
605
- # As minichip is nothing more than a smaller oxford,
606
- # they should move the same way
607
- logger.info("Oxford Move")
608
- if place == "origin":
609
- caput(pv.me14e_stage_x, 0.0)
610
- caput(pv.me14e_stage_y, 0.0)
611
- if place == "f1":
612
- caput(pv.me14e_stage_x, 25.40)
613
- caput(pv.me14e_stage_y, 0.0)
614
- if place == "f2":
615
- caput(pv.me14e_stage_x, 0.0)
616
- caput(pv.me14e_stage_y, 25.40)
617
-
618
- elif chip_type == ChipType.OxfordInner:
619
- logger.info("Oxford Inner Move")
620
- if place == "origin":
621
- caput(pv.me14e_stage_x, 0.0)
622
- caput(pv.me14e_stage_y, 0.0)
623
- if place == "f1":
624
- caput(pv.me14e_stage_x, 24.60)
625
- caput(pv.me14e_stage_y, 0.0)
626
- if place == "f2":
627
- caput(pv.me14e_stage_x, 0.0)
628
- caput(pv.me14e_stage_y, 24.60)
629
-
630
- elif chip_type == ChipType.Custom:
631
- logger.info("Custom Chip Move")
632
- if place == "origin":
633
- caput(pv.me14e_stage_x, 0.0)
634
- caput(pv.me14e_stage_y, 0.0)
635
- if place == "f1":
636
- caput(pv.me14e_stage_x, 25.40)
637
- caput(pv.me14e_stage_y, 0.0)
638
- if place == "f2":
639
- caput(pv.me14e_stage_x, 0.0)
640
- caput(pv.me14e_stage_y, 25.40)
641
-
642
- else:
610
+ def moveto(place: str = "origin", pmac: PMAC = inject("pmac")) -> MsgGenerator:
611
+ setup_logging()
612
+ logger.info(f"Move to: {place}")
613
+ if place == Fiducials.zero:
614
+ logger.info("Chip aspecific move.")
615
+ yield from bps.trigger(pmac.to_xyz_zero)
616
+ return
617
+
618
+ chip_type = ChipType(int(caget(CHIPTYPE_PV)))
619
+ logger.info(f"Chip type is {chip_type}")
620
+ if chip_type not in list(ChipType):
643
621
  logger.warning("Unknown chip_type move")
622
+ return
623
+
624
+ logger.info(f"{str(chip_type)} Move")
625
+ chip_move = CHIP_MOVES[chip_type]
626
+
627
+ if place == Fiducials.origin:
628
+ yield from bps.mv(pmac.x, 0.0, pmac.y, 0.0)
629
+ if place == Fiducials.fid1:
630
+ yield from bps.mv(pmac.x, chip_move, pmac.y, 0.0)
631
+ if place == Fiducials.fid2:
632
+ yield from bps.mv(pmac.x, 0.0, pmac.y, chip_move)
633
+
634
+
635
+ @log.log_on_entry
636
+ def moveto_preset(
637
+ place: str,
638
+ pmac: PMAC = inject("pmac"),
639
+ beamstop: Beamstop = inject("beamstop"),
640
+ backlight: DualBacklight = inject("backlight"),
641
+ det_stage: DetectorMotion = inject("detector_motion"),
642
+ ) -> MsgGenerator:
643
+ setup_logging()
644
644
 
645
645
  # Non Chip Specific Move
646
646
  if place == "zero":
647
- logger.info("Moving to %s" % place)
648
- caput(pv.me14e_pmac_str, "!x0y0z0")
647
+ logger.info(f"Moving to {place}")
648
+ yield from bps.trigger(pmac.to_xyz_zero)
649
649
 
650
650
  elif place == "load_position":
651
651
  logger.info("load position")
652
- caput(pv.bs_mp_select, "Robot")
653
- caput(pv.bl_mp_select, "Out")
654
- caput(pv.det_z, 1300)
652
+ yield from bps.abs_set(
653
+ beamstop.pos_select, BeamstopPositions.ROBOT, group=place
654
+ )
655
+ yield from bps.abs_set(backlight, BacklightPositions.OUT, group=place)
656
+ yield from bps.abs_set(det_stage.z, 1300, group=place)
657
+ yield from bps.wait(group=place)
655
658
 
656
659
  elif place == "collect_position":
657
660
  logger.info("collect position")
658
661
  caput(pv.me14e_filter, 20)
659
- caput(pv.me14e_stage_x, 0.0)
660
- caput(pv.me14e_stage_y, 0.0)
661
- caput(pv.me14e_stage_z, 0.0)
662
- caput(pv.bs_mp_select, "Data Collection")
663
- caput(pv.bl_mp_select, "In")
662
+ yield from bps.mv(pmac.x, 0.0, pmac.y, 0.0, pmac.z, 0.0)
663
+ yield from bps.abs_set(
664
+ beamstop.pos_select, BeamstopPositions.DATA_COLLECTION, group=place
665
+ )
666
+ yield from bps.abs_set(backlight, BacklightPositions.IN, group=place)
667
+ yield from bps.wait(group=place)
664
668
 
665
669
  elif place == "microdrop_position":
666
670
  logger.info("microdrop align position")
667
- caput(pv.me14e_stage_x, 6.0)
668
- caput(pv.me14e_stage_y, -7.8)
669
- caput(pv.me14e_stage_z, 0.0)
671
+ yield from bps.mv(pmac.x, 6.0, pmac.y, -7.8, pmac.z, 0.0)
672
+
670
673
 
671
- elif place == "laser1on": # these are in laser edm
674
+ @log.log_on_entry
675
+ def laser_control(laser_setting: str, pmac: PMAC = inject("pmac")) -> MsgGenerator:
676
+ setup_logging()
677
+ logger.info(f"Move to: {laser_setting}")
678
+ if laser_setting == "laser1on": # these are in laser edm
672
679
  logger.info("Laser 1 /BNC2 shutter is open")
673
680
  # Use M712 = 0 if triggering on falling edge. M712 =1 if on rising edge
674
681
  # Be sure to also change laser1off
675
682
  # caput(pv.me14e_pmac_str, ' M712=0 M711=1')
676
- caput(pv.me14e_pmac_str, " M712=1 M711=1")
683
+ yield from bps.abs_set(pmac.laser, LaserSettings.LASER_1_ON, wait=True)
677
684
 
678
- elif place == "laser1off":
685
+ elif laser_setting == "laser1off":
679
686
  logger.info("Laser 1 shutter is closed")
680
- caput(pv.me14e_pmac_str, " M712=0 M711=1")
687
+ yield from bps.abs_set(pmac.laser, LaserSettings.LASER_1_OFF, wait=True)
681
688
 
682
- elif place == "laser2on":
689
+ elif laser_setting == "laser2on":
683
690
  logger.info("Laser 2 / BNC3 shutter is open")
684
- caput(pv.me14e_pmac_str, " M812=1 M811=1")
691
+ yield from bps.abs_set(pmac.laser, LaserSettings.LASER_2_ON, wait=True)
685
692
 
686
- elif place == "laser2off":
693
+ elif laser_setting == "laser2off":
687
694
  logger.info("Laser 2 shutter is closed")
688
- caput(pv.me14e_pmac_str, " M812=0 M811=1")
695
+ yield from bps.abs_set(pmac.laser, LaserSettings.LASER_2_OFF, wait=True)
689
696
 
690
- elif place == "laser1burn":
697
+ elif laser_setting == "laser1burn":
691
698
  led_burn_time = caget(pv.me14e_gp103)
692
699
  logger.info("Laser 1 on")
693
- logger.info("Burn time is %s s" % led_burn_time)
694
- caput(pv.me14e_pmac_str, " M712=1 M711=1")
695
- sleep(int(float(led_burn_time)))
700
+ logger.info(f"Burn time is {led_burn_time} s")
701
+ yield from bps.abs_set(pmac.laser, LaserSettings.LASER_1_ON, wait=True)
702
+ yield from bps.sleep(led_burn_time)
696
703
  logger.info("Laser 1 off")
697
- caput(pv.me14e_pmac_str, " M712=0 M711=1")
704
+ yield from bps.abs_set(pmac.laser, LaserSettings.LASER_1_OFF, wait=True)
698
705
 
699
- elif place == "laser2burn":
706
+ elif laser_setting == "laser2burn":
700
707
  led_burn_time = caget(pv.me14e_gp109)
701
708
  logger.info("Laser 2 on")
702
- logger.info("burntime %s s" % led_burn_time)
703
- caput(pv.me14e_pmac_str, " M812=1 M811=1")
704
- sleep(int(float(led_burn_time)))
709
+ logger.info(f"burntime {led_burn_time} s")
710
+ yield from bps.abs_set(pmac.laser, LaserSettings.LASER_2_ON, wait=True)
711
+ yield from bps.sleep(led_burn_time)
705
712
  logger.info("Laser 2 off")
706
- caput(pv.me14e_pmac_str, " M812=0 M811=1")
713
+ yield from bps.abs_set(pmac.laser, LaserSettings.LASER_2_OFF, wait=True)
707
714
 
708
715
 
709
716
  @log.log_on_entry
710
- def scrape_mtr_directions(param_path: Path | str = CS_FILES_PATH):
711
- param_path = _coerce_to_path(param_path)
712
-
713
- with open(param_path / "motor_direction.txt", "r") as f:
717
+ def scrape_mtr_directions(motor_file_path: Path = CS_FILES_PATH):
718
+ with open(motor_file_path / "motor_direction.txt") as f:
714
719
  lines = f.readlines()
715
720
  mtr1_dir, mtr2_dir, mtr3_dir = 1.0, 1.0, 1.0
716
721
  for line in lines:
@@ -722,62 +727,57 @@ def scrape_mtr_directions(param_path: Path | str = CS_FILES_PATH):
722
727
  mtr3_dir = float(line.split("=")[1])
723
728
  else:
724
729
  continue
725
- logger.info("mt1_dir %s mtr2_dir %s mtr3_dir %s" % (mtr1_dir, mtr2_dir, mtr3_dir))
730
+ logger.debug(f"mt1_dir {mtr1_dir} mtr2_dir {mtr2_dir} mtr3_dir {mtr3_dir}")
726
731
  return mtr1_dir, mtr2_dir, mtr3_dir
727
732
 
728
733
 
729
734
  @log.log_on_entry
730
- def fiducial(point: int = 1, param_path: Path | str = CS_FILES_PATH):
735
+ def fiducial(point: int = 1, pmac: PMAC = inject("pmac")) -> MsgGenerator:
736
+ setup_logging()
731
737
  scale = 10000.0 # noqa: F841
732
- param_path = _coerce_to_path(param_path)
733
-
734
- mtr1_dir, mtr2_dir, mtr3_dir = scrape_mtr_directions(param_path)
735
-
736
- rbv_1 = float(caget(pv.me14e_stage_x + ".RBV"))
737
- rbv_2 = float(caget(pv.me14e_stage_y + ".RBV"))
738
- rbv_3 = float(caget(pv.me14e_stage_z + ".RBV"))
739
738
 
740
- raw_1 = float(caget(pv.me14e_stage_x + ".RRBV"))
741
- raw_2 = float(caget(pv.me14e_stage_y + ".RRBV"))
742
- raw_3 = float(caget(pv.me14e_stage_z + ".RRBV"))
739
+ mtr1_dir, mtr2_dir, mtr3_dir = scrape_mtr_directions(CS_FILES_PATH)
743
740
 
744
- f_x = rbv_1
745
- f_y = rbv_2
746
- f_z = rbv_3
741
+ rbv_1 = yield from bps.rd(pmac.x.user_readback)
742
+ rbv_2 = yield from bps.rd(pmac.y.user_readback)
743
+ rbv_3 = yield from bps.rd(pmac.z.user_readback)
747
744
 
748
- logger.info("Writing Fiducial File %s/fiducial_%s.txt" % (param_path, point))
745
+ output_param_path = PARAM_FILE_PATH_FT
746
+ output_param_path.mkdir(parents=True, exist_ok=True)
747
+ logger.info(f"Writing Fiducial File {output_param_path}/fiducial_{point}.txt")
749
748
  logger.info("MTR\tRBV\tRAW\tCorr\tf_value")
750
- logger.info("MTR1\t%1.4f\t%i\t%i\t%1.4f" % (rbv_1, raw_1, mtr1_dir, f_x))
751
- logger.info("MTR2\t%1.4f\t%i\t%i\t%1.4f" % (rbv_2, raw_2, mtr2_dir, f_y))
752
- logger.info("MTR3\t%1.4f\t%i\t%i\t%1.4f" % (rbv_3, raw_3, mtr3_dir, f_z))
753
-
754
- with open(param_path / f"fiducial_{point}.txt", "w") as f:
755
- f.write("MTR\tRBV\tRAW\tCorr\tf_value\n")
756
- f.write("MTR1\t%1.4f\t%i\t%i\t%1.4f\n" % (rbv_1, raw_1, mtr1_dir, f_x))
757
- f.write("MTR2\t%1.4f\t%i\t%i\t%1.4f\n" % (rbv_2, raw_2, mtr2_dir, f_y))
758
- f.write("MTR3\t%1.4f\t%i\t%i\t%1.4f" % (rbv_3, raw_3, mtr3_dir, f_z))
749
+ logger.info("MTR1\t%1.4f\t%i" % (rbv_1, mtr1_dir))
750
+ logger.info("MTR2\t%1.4f\t%i" % (rbv_2, mtr2_dir))
751
+ logger.info("MTR3\t%1.4f\t%i" % (rbv_3, mtr3_dir))
752
+
753
+ with open(output_param_path / f"fiducial_{point}.txt", "w") as f:
754
+ f.write("MTR\tRBV\tCorr\n")
755
+ f.write("MTR1\t%1.4f\t%i\n" % (rbv_1, mtr1_dir))
756
+ f.write("MTR2\t%1.4f\t%i\n" % (rbv_2, mtr2_dir))
757
+ f.write("MTR3\t%1.4f\t%i" % (rbv_3, mtr3_dir))
759
758
  logger.info(f"Fiducial {point} set.")
759
+ yield from bps.null()
760
760
 
761
761
 
762
- def scrape_mtr_fiducials(point: int, param_path: Path | str = CS_FILES_PATH):
763
- param_path = _coerce_to_path(param_path)
764
-
765
- with open(param_path / f"fiducial_{point}.txt", "r") as f:
762
+ def scrape_mtr_fiducials(
763
+ point: int, param_path: Path = PARAM_FILE_PATH_FT
764
+ ) -> tuple[float, float, float]:
765
+ with open(param_path / f"fiducial_{point}.txt") as f:
766
766
  f_lines = f.readlines()[1:]
767
- f_x = float(f_lines[0].rsplit()[4])
768
- f_y = float(f_lines[1].rsplit()[4])
769
- f_z = float(f_lines[2].rsplit()[4])
767
+ f_x = float(f_lines[0].rsplit()[1])
768
+ f_y = float(f_lines[1].rsplit()[1])
769
+ f_z = float(f_lines[2].rsplit()[1])
770
770
  return f_x, f_y, f_z
771
771
 
772
772
 
773
773
  @log.log_on_entry
774
- def cs_maker():
774
+ def cs_maker(pmac: PMAC = inject("pmac")) -> MsgGenerator:
775
775
  """
776
776
  Coordinate system.
777
777
 
778
778
  Values for scalex, scaley, scalez, and skew, as well as the sign of
779
779
  Sx, Sy, Sz are stored in a .json file and should be modified there.
780
- Location of file: src/mx_bluesky/I24/serial/parameters/cs_maker.json
780
+ Location of file: src/mx_bluesky/i24/serial/parameters/cs_maker.json
781
781
 
782
782
  Theory
783
783
  Rx: rotation about X-axis, pitch
@@ -801,24 +801,25 @@ def cs_maker():
801
801
  This should be measured in situ prior to expriment, ie. measure by hand using
802
802
  opposite and adjacent RBV after calibration of scale factors.
803
803
  """
804
- chip_type = int(caget(pv.me14e_gp1))
804
+ setup_logging()
805
+ chip_type = int(caget(CHIPTYPE_PV))
805
806
  fiducial_dict = {}
806
807
  fiducial_dict[0] = [25.400, 25.400]
807
808
  fiducial_dict[1] = [24.600, 24.600]
808
809
  fiducial_dict[2] = [25.400, 25.400]
809
810
  fiducial_dict[3] = [18.25, 18.25]
810
- logger.info("Chip type is %s with size %s" % (chip_type, fiducial_dict[chip_type]))
811
+ logger.info(f"Chip type is {chip_type} with size {fiducial_dict[chip_type]}")
811
812
 
812
813
  mtr1_dir, mtr2_dir, mtr3_dir = scrape_mtr_directions()
813
814
  f1_x, f1_y, f1_z = scrape_mtr_fiducials(1)
814
815
  f2_x, f2_y, f2_z = scrape_mtr_fiducials(2)
815
- logger.info("mtr1 direction: %s" % mtr1_dir)
816
- logger.info("mtr2 direction: %s" % mtr2_dir)
817
- logger.info("mtr3 direction: %s" % mtr3_dir)
816
+ logger.info(f"mtr1 direction: {mtr1_dir}")
817
+ logger.info(f"mtr2 direction: {mtr2_dir}")
818
+ logger.info(f"mtr3 direction: {mtr3_dir}")
818
819
 
819
820
  # Scale parameters saved in json file
820
821
  try:
821
- with open(CS_FILES_PATH / "cs_maker.json", "r") as fh:
822
+ with open(CS_FILES_PATH / "cs_maker.json") as fh:
822
823
  cs_info = json.load(fh)
823
824
  except json.JSONDecodeError:
824
825
  logger.error("Invalid JSON file.")
@@ -853,22 +854,22 @@ def cs_maker():
853
854
  Sz1 = -1 * f1_y / fiducial_dict[chip_type][0]
854
855
  Sz2 = f2_x / fiducial_dict[chip_type][1]
855
856
  Sz = Sz_dir * ((Sz1 + Sz2) / 2)
856
- Cz = np.sqrt((1 - Sz**2))
857
- logger.info("Sz1 , %1.4f, %1.4f" % (Sz1, np.degrees(np.arcsin(Sz1))))
858
- logger.info("Sz2 , %1.4f, %1.4f" % (Sz2, np.degrees(np.arcsin(Sz2))))
859
- logger.info("Sz , %1.4f, %1.4f" % (Sz, np.degrees(np.arcsin(Sz))))
860
- logger.info("Cz , %1.4f, %1.4f" % (Cz, np.degrees(np.arcsin(Cz))))
857
+ Cz = np.sqrt(1 - Sz**2)
858
+ logger.info(f"Sz1 , {Sz1:1.4f}, {np.degrees(np.arcsin(Sz1)):1.4f}")
859
+ logger.info(f"Sz2 , {Sz2:1.4f}, {np.degrees(np.arcsin(Sz2)):1.4f}")
860
+ logger.info(f"Sz , {Sz:1.4f}, {np.degrees(np.arcsin(Sz)):1.4f}")
861
+ logger.info(f"Cz , {Cz:1.4f}, {np.degrees(np.arcsin(Cz)):1.4f}")
861
862
  # Rotation Around Y
862
863
  Sy = Sy_dir * f1_z / fiducial_dict[chip_type][0]
863
- Cy = np.sqrt((1 - Sy**2))
864
- logger.info("Sy , %1.4f, %1.4f" % (Sy, np.degrees(np.arcsin(Sy))))
865
- logger.info("Cy , %1.4f, %1.4f" % (Cy, np.degrees(np.arcsin(Cy))))
864
+ Cy = np.sqrt(1 - Sy**2)
865
+ logger.info(f"Sy , {Sy:1.4f}, {np.degrees(np.arcsin(Sy)):1.4f}")
866
+ logger.info(f"Cy , {Cy:1.4f}, {np.degrees(np.arcsin(Cy)):1.4f}")
866
867
  # Rotation Around X
867
868
  # If stages upsidedown (I24) change sign of Sx
868
869
  Sx = Sx_dir * f2_z / fiducial_dict[chip_type][1]
869
- Cx = np.sqrt((1 - Sx**2))
870
- logger.info("Sx , %1.4f, %1.4f" % (Sx, np.degrees(np.arcsin(Sx))))
871
- logger.info("Cx , %1.4f, %1.4f" % (Cx, np.degrees(np.arcsin(Cx))))
870
+ Cx = np.sqrt(1 - Sx**2)
871
+ logger.info(f"Sx , {Sx:1.4f}, {np.degrees(np.arcsin(Sx)):1.4f}")
872
+ logger.info(f"Cx , {Cx:1.4f}, {np.degrees(np.arcsin(Cx)):1.4f}")
872
873
 
873
874
  x1factor = mtr1_dir * scalex * (Cy * Cz)
874
875
  y1factor = mtr2_dir * scaley * (-1.0 * Cx * Sz)
@@ -882,14 +883,14 @@ def cs_maker():
882
883
  y3factor = mtr2_dir * scaley * ((Cx * Sy * Sz) + (Sx * Cz))
883
884
  z3factor = mtr3_dir * scalez * (Cx * Cy)
884
885
 
885
- logger.info("Skew being used is: %1.4f" % skew)
886
+ logger.info(f"Skew being used is: {skew:1.4f}")
886
887
  s1 = np.degrees(np.arcsin(Sz1))
887
888
  s2 = np.degrees(np.arcsin(Sz2))
888
889
  rot = np.degrees(np.arcsin((Sz1 + Sz2) / 2))
889
890
  calc_skew = (s1 - rot) - (s2 - rot)
890
- logger.info("s1:%1.4f s2:%1.4f rot:%1.4f" % (s1, s2, rot))
891
- logger.info("Calculated rotation from current fiducials is: %1.4f" % rot)
892
- logger.info("Calculated Skew from current fiducials is: %1.4f" % calc_skew)
891
+ logger.info(f"s1:{s1:1.4f} s2:{s2:1.4f} rot:{rot:1.4f}")
892
+ logger.info(f"Calculated rotation from current fiducials is: {rot:1.4f}")
893
+ logger.info(f"Calculated Skew from current fiducials is: {calc_skew:1.4f}")
893
894
  logger.info("Calculated Skew has been known to have the wrong sign")
894
895
 
895
896
  sinD = np.sin((skew / 2) * (np.pi / 180))
@@ -899,10 +900,10 @@ def cs_maker():
899
900
  new_x2factor = (x2factor * cosD) + (y2factor * sinD)
900
901
  new_y2factor = (x2factor * sinD) + (y2factor * cosD)
901
902
 
902
- cs1 = "#1->%+1.3fX%+1.3fY%+1.3fZ" % (new_x1factor, new_y1factor, z1factor)
903
- cs2 = "#2->%+1.3fX%+1.3fY%+1.3fZ" % (new_x2factor, new_y2factor, z2factor)
904
- cs3 = "#3->%+1.3fX%+1.3fY%+1.3fZ" % (x3factor, y3factor, z3factor)
905
- logger.info("PMAC strings. \ncs1: %s \ncs2: %scs3: %s" % (cs1, cs2, cs3))
903
+ cs1 = f"#1->{new_x1factor:+1.3f}X{new_y1factor:+1.3f}Y{z1factor:+1.3f}Z"
904
+ cs2 = f"#2->{new_x2factor:+1.3f}X{new_y2factor:+1.3f}Y{z2factor:+1.3f}Z"
905
+ cs3 = f"#3->{x3factor:+1.3f}X{y3factor:+1.3f}Y{z3factor:+1.3f}Z"
906
+ logger.info(f"PMAC strings. \ncs1: {cs1} \ncs2: {cs2}cs3: {cs3}")
906
907
  logger.info(
907
908
  """These next values should be 1.
908
909
  This is the sum of the squares of the factors divided by their scale."""
@@ -910,52 +911,70 @@ def cs_maker():
910
911
  sqfact1 = np.sqrt(x1factor**2 + y1factor**2 + z1factor**2) / scalex
911
912
  sqfact2 = np.sqrt(x2factor**2 + y2factor**2 + z2factor**2) / scaley
912
913
  sqfact3 = np.sqrt(x3factor**2 + y3factor**2 + z3factor**2) / scalez
913
- logger.info("%1.4f \n %1.4f \n %1.4f" % (sqfact1, sqfact2, sqfact3))
914
- logger.info("Long wait, please be patient")
915
- caput(pv.me14e_pmac_str, "!x0y0z0")
914
+ logger.info(f"{sqfact1:1.4f} \n {sqfact2:1.4f} \n {sqfact3:1.4f}")
915
+ logger.debug("Long wait, please be patient")
916
+ yield from bps.trigger(pmac.to_xyz_zero)
916
917
  sleep(2.5)
917
- caput(pv.me14e_pmac_str, "&2")
918
- caput(pv.me14e_pmac_str, cs1)
919
- caput(pv.me14e_pmac_str, cs2)
920
- caput(pv.me14e_pmac_str, cs3)
921
- caput(pv.me14e_pmac_str, "!x0y0z0")
918
+ yield from set_pmac_strings_for_cs(pmac, {"cs1": cs1, "cs2": cs2, "cs3": cs3})
919
+ yield from bps.trigger(pmac.to_xyz_zero)
922
920
  sleep(0.1)
923
- caput(pv.me14e_pmac_str, "#1hmz#2hmz#3hmz")
921
+ yield from bps.trigger(pmac.home, wait=True)
924
922
  sleep(0.1)
925
- logger.info("Chip_type is %s" % chip_type)
923
+ logger.debug(f"Chip_type is {chip_type}")
926
924
  if chip_type == 0:
927
- caput(pv.me14e_pmac_str, "!x0.4y0.4")
925
+ yield from bps.abs_set(pmac.pmac_string, "!x0.4y0.4", wait=True)
928
926
  sleep(0.1)
929
- caput(pv.me14e_pmac_str, "#1hmz#2hmz#3hmz")
927
+ yield from bps.trigger(pmac.home, wait=True)
930
928
  else:
931
- caput(pv.me14e_pmac_str, "#1hmz#2hmz#3hmz")
929
+ yield from bps.trigger(pmac.home, wait=True)
932
930
  logger.debug("CSmaker done.")
931
+ yield from bps.null()
933
932
 
934
933
 
935
- def cs_reset():
936
- cs1 = "#1->-10000X+0Y+0Z"
937
- cs2 = "#2->+0X+10000Y+0Z"
938
- cs3 = "#3->0X+0Y+10000Z"
934
+ def cs_reset(pmac: PMAC = inject("pmac")) -> MsgGenerator:
935
+ """Used to clear CS when using Custom Chip"""
936
+ setup_logging()
937
+ cs1 = "#1->10000X+0Y+0Z"
938
+ cs2 = "#2->+0X-10000Y+0Z"
939
+ cs3 = "#3->0X+0Y-10000Z"
939
940
  strg = "\n".join([cs1, cs2, cs3])
940
941
  print(strg)
941
- caput(pv.me14e_pmac_str, "&2")
942
- sleep(0.5)
943
- caput(pv.me14e_pmac_str, cs1)
944
- sleep(0.5)
945
- caput(pv.me14e_pmac_str, cs2)
946
- sleep(0.5)
947
- caput(pv.me14e_pmac_str, cs3)
942
+ yield from set_pmac_strings_for_cs(pmac, {"cs1": cs1, "cs2": cs2, "cs3": cs3})
948
943
  logger.debug("CSreset Done")
944
+ yield from bps.null()
945
+
946
+
947
+ def set_pmac_strings_for_cs(pmac: PMAC, cs_str: dict):
948
+ """ A plan to set the pmac_string for the (x,y,z) axes while making or resetting \
949
+ the coordinate system.
950
+
951
+ Args:
952
+ pmac (PMAC): PMAC device
953
+ cs_str (dict): A dictionary containing a string for each axis, in the format: \
954
+ {
955
+ "cs1": "#1->1X+0Y+0Z",
956
+ "cs2": "#2->...",
957
+ "cs3": "#3->...",
958
+ }
959
+
960
+ Note. On the PMAC the axes allocations are: #1 - X, #2 - Y, #3 - Z.
961
+ """
962
+ yield from bps.abs_set(pmac.pmac_string, "&2", wait=True)
963
+ yield from bps.abs_set(pmac.pmac_string, cs_str["cs1"], wait=True)
964
+ yield from bps.abs_set(pmac.pmac_string, cs_str["cs2"], wait=True)
965
+ yield from bps.abs_set(pmac.pmac_string, cs_str["cs3"], wait=True)
949
966
 
950
967
 
951
968
  @log.log_on_entry
952
- def pumpprobe_calc():
969
+ def pumpprobe_calc() -> MsgGenerator:
970
+ # TODO See https://github.com/DiamondLightSource/mx_bluesky/issues/122
971
+ setup_logging()
953
972
  logger.info("Calculate and show exposure and dwell time for each option.")
954
973
  exptime = float(caget(pv.me14e_exptime))
955
974
  pumpexptime = float(caget(pv.me14e_gp103))
956
975
  movetime = 0.008
957
- logger.info("X-ray exposure time %s" % exptime)
958
- logger.info("Laser dwell time %s" % pumpexptime)
976
+ logger.info(f"X-ray exposure time {exptime}")
977
+ logger.info(f"Laser dwell time {pumpexptime}")
959
978
  repeat1 = 2 * 20 * (movetime + (pumpexptime + exptime) / 2)
960
979
  repeat2 = 4 * 20 * (movetime + (pumpexptime + exptime) / 2)
961
980
  repeat3 = 6 * 20 * (movetime + (pumpexptime + exptime) / 2)
@@ -970,17 +989,19 @@ def pumpprobe_calc():
970
989
  ):
971
990
  rounded = round(repeat, 4)
972
991
  caput(pv_name, rounded)
973
- logger.info("Repeat (%s): %s s" % (pv_name, rounded))
974
- # logger.info("repeat10 (%s): %s s" % (pv.me14e_gp108, round(repeat10, 4)))
992
+ logger.info(f"Repeat ({pv_name}): {rounded} s")
975
993
  logger.debug("PP calculations done")
994
+ yield from bps.null()
976
995
 
977
996
 
978
997
  @log.log_on_entry
979
- def block_check():
998
+ def block_check(pmac: PMAC = inject("pmac")) -> MsgGenerator:
999
+ setup_logging()
1000
+ # TODO See https://github.com/DiamondLightSource/mx_bluesky/issues/117
980
1001
  caput(pv.me14e_gp9, 0)
981
1002
  while True:
982
1003
  if int(caget(pv.me14e_gp9)) == 0:
983
- chip_type = int(caget(pv.me14e_gp1))
1004
+ chip_type = int(caget(CHIPTYPE_PV))
984
1005
  if chip_type == ChipType.Minichip:
985
1006
  logger.info("Oxford mini chip in use.")
986
1007
  block_start_list = scrape_pvar_file("minichip_oxford.pvar")
@@ -999,72 +1020,17 @@ def block_check():
999
1020
  sleep(1.0)
1000
1021
  break
1001
1022
  block, x, y = entry
1002
- logger.info("Block: %s -> (x=%s y=%s)" % (block, x, y))
1003
- caput(pv.me14e_pmac_str, "!x%sy%s" % (x, y))
1023
+ logger.debug(f"Block: {block} -> (x={x} y={y})")
1024
+ yield from bps.abs_set(pmac.pmac_string, f"!x{x}y{y}", wait=True)
1004
1025
  time.sleep(0.4)
1005
1026
  else:
1006
1027
  logger.warning("Block Check Aborted due to GP 9 not equalling 0")
1007
1028
  break
1008
1029
  break
1009
1030
  logger.debug("Block check done")
1031
+ yield from bps.null()
1010
1032
 
1011
1033
 
1012
- def parse_args_and_run_parsed_function(args):
1013
- print(f"Run with {args}")
1014
- parser = argparse.ArgumentParser()
1015
- subparsers = parser.add_subparsers(
1016
- help="Choose command.",
1017
- required=True,
1018
- dest="sub-command",
1019
- )
1020
- parser_init = subparsers.add_parser(
1021
- "initialise",
1022
- )
1023
- parser_init.set_defaults(func=initialise)
1024
- parser_moveto = subparsers.add_parser(
1025
- "moveto",
1026
- )
1027
- parser_moveto.add_argument("place", type=str)
1028
- parser_moveto.set_defaults(func=moveto)
1029
- parser_fid = subparsers.add_parser("fiducial")
1030
- parser_fid.add_argument("point", type=int)
1031
- parser_fid.set_defaults(func=fiducial)
1032
- parser_csm = subparsers.add_parser("cs_maker")
1033
- parser_csm.set_defaults(func=cs_maker)
1034
- parser_pp = subparsers.add_parser("pumpprobe_calc")
1035
- parser_pp.set_defaults(func=pumpprobe_calc)
1036
- parser_write = subparsers.add_parser("write_parameter_file")
1037
- parser_write.set_defaults(func=write_parameter_file)
1038
- parser_def = subparsers.add_parser("define_current_chip")
1039
- parser_def.add_argument("chipid", type=str)
1040
- parser_def.set_defaults(func=define_current_chip)
1041
- parser_stockmap = subparsers.add_parser("load_stock_map")
1042
- parser_stockmap.add_argument("map_choice", type=str)
1043
- parser_stockmap.set_defaults(func=load_stock_map)
1044
- parser_litemap = subparsers.add_parser("load_lite_map")
1045
- parser_litemap.set_defaults(func=load_lite_map)
1046
- parser_fullmap = subparsers.add_parser("load_full_map")
1047
- parser_fullmap.set_defaults(func=load_full_map)
1048
- parser_save = subparsers.add_parser("save_screen_map")
1049
- parser_save.set_defaults(func=save_screen_map)
1050
- parser_upld = subparsers.add_parser("upload_full")
1051
- parser_upld.set_defaults(func=upload_full)
1052
- parser_params = subparsers.add_parser("upload_parameters")
1053
- parser_params.add_argument("chipid", type=str)
1054
- parser_params.set_defaults(func=upload_parameters)
1055
- parser_csr = subparsers.add_parser("cs_reset")
1056
- parser_csr.set_defaults(func=cs_reset)
1057
- parser_block = subparsers.add_parser("block_check")
1058
- parser_block.set_defaults(func=block_check)
1059
-
1060
- args = parser.parse_args(args)
1061
-
1062
- args_dict = vars(args)
1063
- args_dict.pop("sub-command")
1064
- args_dict.pop("func")(**args_dict)
1065
-
1066
-
1067
- if __name__ == "__main__":
1068
- setup_logging()
1069
-
1070
- parse_args_and_run_parsed_function(sys.argv[1:])
1034
+ # setup_logging now called in all functions.
1035
+ # TODO See logging issue on blueapi
1036
+ # https://github.com/DiamondLightSource/blueapi/issues/494