mx-bluesky 0.0.2__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 +273 -143
  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 -412
  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 +39 -41
  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.2.dist-info → mx_bluesky-0.3.1.dist-info}/METADATA +33 -27
  54. mx_bluesky-0.3.1.dist-info/RECORD +67 -0
  55. {mx_bluesky-0.0.2.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 -706
  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.2.dist-info/RECORD +0 -58
  73. mx_bluesky-0.0.2.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.2.dist-info → mx_bluesky-0.3.1.dist-info}/LICENSE +0 -0
  82. {mx_bluesky-0.0.2.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,95 +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
-
131
- checkerpattern = bool(caget(pv.me14e_gp111))
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))
132
134
 
133
135
  # If file name ends in a digit this causes processing/pilatus pain.
134
136
  # Append an underscore
135
- if det_type == "pilatus":
137
+ if isinstance(det_type, Pilatus):
136
138
  caput(pv.pilat_cbftemplate, 0)
137
139
  m = re.search(r"\d+$", filename)
138
140
  if m is not None:
139
141
  # Note for future reference. Appending underscore causes more hassle and
140
142
  # high probability of users accidentally overwriting data. Use a dash
141
143
  filename = filename + "-"
142
- logger.info(
143
- "Requested filename ends in a number. Appended dash: %s" % filename
144
+ logger.debug(
145
+ f"Requested filename ends in a number. Appended dash: {filename}"
144
146
  )
145
147
 
146
- # historical - use chip_name instead of filename
147
- chip_name = filename
148
-
149
- with open(param_path / param_fid, "w") as f:
150
- f.write("visit \t\t%s\n" % visit)
151
- f.write("chip_name \t%s\n" % chip_name)
152
- f.write("protein_name \t%s\n" % protein_name)
153
- f.write("n_exposures \t%s\n" % n_exposures)
154
- f.write("chip_type \t%s\n" % chip_type)
155
- f.write("map_type \t%s\n" % map_type)
156
- f.write("pump_repeat \t%s\n" % pump_repeat)
157
- f.write("pumpexptime \t%s\n" % pumpexptime)
158
- f.write("pumpdelay \t%s\n" % pumpdelay)
159
- f.write("prepumpexptime \t%s\n" % prepumpexptime)
160
- f.write("exptime \t%s\n" % exptime)
161
- f.write("dcdetdist \t%s\n" % dcdetdist)
162
- f.write("det_type \t%s\n" % str(det_type))
163
- f.write("checkerpattern \t%s\n" % str(checkerpattern))
164
-
165
- logger.info("Information written to file")
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}")
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
+
178
173
  if map_type == MappingType.Full:
179
174
  # This step creates some header files (.addr, .spec), containing the parameters,
180
175
  # that are only needed when full mapping is in use.
181
- logger.debug("Running start up now.")
176
+ logger.info("Full mapping in use. Running start up now.")
182
177
  startup.run()
178
+ yield from bps.null()
183
179
 
184
180
 
185
- 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):
186
182
  block_start_list = []
187
- pvar_dir = _coerce_to_path(pvar_dir)
188
183
 
189
- with open(pvar_dir / fid, "r") as f:
184
+ with open(pvar_dir / fid) as f:
190
185
  lines = f.readlines()
191
186
  for line in lines:
192
187
  line = line.rstrip()
@@ -210,40 +205,40 @@ def scrape_pvar_file(fid: str, pvar_dir: Path | str = PVAR_FILE_PATH):
210
205
  @log.log_on_entry
211
206
  def define_current_chip(
212
207
  chipid: str = "oxford",
213
- param_path: Path | str = PVAR_FILE_PATH,
214
- ):
208
+ pmac: PMAC = inject("pmac"),
209
+ ) -> MsgGenerator:
210
+ setup_logging()
215
211
  logger.debug("Run load stock map for just the first block")
216
- load_stock_map("Just The First Block")
212
+ yield from load_stock_map("Just The First Block")
217
213
  """
218
214
  Not sure what this is for:
219
215
  print 'Setting Mapping Type to Lite'
220
216
  caput(pv.me14e_gp2, 1)
221
217
  """
222
- chip_type = int(caget(pv.me14e_gp1))
223
- 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}")
224
220
  if chipid == "oxford":
225
- caput(pv.me14e_gp1, 1)
221
+ caput(CHIPTYPE_PV, 0)
226
222
 
227
- param_path = _coerce_to_path(param_path)
228
-
229
- with open(param_path / f"{chipid}.pvar", "r") as f:
230
- logger.info("Opening %s.pvar" % chipid)
223
+ with open(PVAR_FILE_PATH / f"{chipid}.pvar") as f:
224
+ logger.info(f"Opening {chipid}.pvar")
231
225
  for line in f.readlines():
232
226
  if line.startswith("#"):
233
227
  continue
234
228
  line_from_file = line.rstrip("\n")
235
- logger.info("%s" % line_from_file)
236
- 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)
237
231
 
238
232
 
239
233
  @log.log_on_entry
240
- def save_screen_map(litemap_path: Path | str = LITEMAP_PATH):
241
- litemap_path = _coerce_to_path(litemap_path)
234
+ def save_screen_map() -> MsgGenerator:
235
+ setup_logging()
236
+ litemap_path: Path = LITEMAP_PATH
242
237
  litemap_path.mkdir(parents=True, exist_ok=True)
243
238
 
244
- logger.info("Saving %s currentchip.map" % litemap_path.as_posix())
239
+ logger.info(f"Saving {litemap_path.as_posix()} currentchip.map")
245
240
  with open(litemap_path / "currentchip.map", "w") as f:
246
- logger.info("Printing only blocks with block_val == 1")
241
+ logger.debug("Printing only blocks with block_val == 1")
247
242
  for x in range(1, 82):
248
243
  block_str = "ME14E-MO-IOC-01:GP%i" % (x + 10)
249
244
  block_val = int(caget(block_str))
@@ -251,23 +246,29 @@ def save_screen_map(litemap_path: Path | str = LITEMAP_PATH):
251
246
  logger.info("%s %d" % (block_str, block_val))
252
247
  line = "%02dstatus P3%02d1 \t%s\n" % (x, x, block_val)
253
248
  f.write(line)
254
- return 0
249
+ yield from bps.null()
255
250
 
256
251
 
257
252
  @log.log_on_entry
258
253
  def upload_parameters(
259
- chipid: str = "oxford",
260
- litemap_path: Path | str = LITEMAP_PATH,
261
- ):
254
+ chipid: str = "oxford", pmac: PMAC = inject("pmac"), width: int | None = None
255
+ ) -> MsgGenerator:
256
+ setup_logging()
262
257
  logger.info("Uploading Parameters to the GeoBrick")
263
258
  if chipid == "oxford":
264
- caput(pv.me14e_gp1, 0)
259
+ caput(CHIPTYPE_PV, 0)
265
260
  width = 8
266
- 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")
264
+
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")
267
268
 
268
- with open(litemap_path / "currentchip.map", "r") as f:
269
- logger.info("Chipid %s" % chipid)
270
- logger.info("width %d" % width)
269
+ with open(map_file) as f:
270
+ logger.info(f"Chipid {chipid}")
271
+ logger.info(f"width {width}")
271
272
  x = 1
272
273
  for line in f.readlines()[: width**2]:
273
274
  cols = line.split()
@@ -285,33 +286,42 @@ def upload_parameters(
285
286
  x = 1
286
287
  else:
287
288
  x += 1
288
- caput(pv.me14e_pmac_str, s)
289
+ yield from bps.abs_set(pmac.pmac_string, s, wait=True)
289
290
  sleep(0.02)
290
291
 
291
292
  logger.warning("Automatic Setting Mapping Type to Lite has been disabled")
292
293
  logger.debug("Upload parameters done.")
294
+ yield from bps.null()
293
295
 
294
296
 
295
297
  @log.log_on_entry
296
- def upload_full(fullmap_path: Path | str = FULLMAP_PATH):
297
- 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()
298
302
 
299
- 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:
300
307
  f = fh.readlines()
301
308
 
302
- for i in range(len(f) // 2):
309
+ for _i in range(len(f) // 2):
303
310
  pmac_list = []
304
- for j in range(2):
311
+ for _j in range(2):
305
312
  pmac_list.append(f.pop(0).rstrip("\n"))
306
313
  writeline = " ".join(pmac_list)
307
- logger.info("%s" % writeline)
308
- caput(pv.me14e_pmac_str, writeline)
309
- 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)
310
317
  logger.debug("Upload fullmap done")
318
+ yield from bps.null()
311
319
 
312
320
 
313
321
  @log.log_on_entry
314
- 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()
315
325
  logger.info("Adjusting Lite Map EDM Screen")
316
326
  logger.debug("Please wait, adjusting lite map")
317
327
  #
@@ -406,7 +416,7 @@ def load_stock_map(map_choice: str = "clear"):
406
416
  28,
407
417
  27,
408
418
  10,
409
- ] + x77
419
+ ] + x77 # noqa
410
420
  x44 = [22, 21, 20, 19, 30, 35, 46, 45, 44, 43, 38, 27, 28, 29, 36, 37]
411
421
  x49 = [x + 1 for x in range(49)]
412
422
  x66 = [
@@ -496,24 +506,26 @@ def load_stock_map(map_choice: str = "clear"):
496
506
  map_dict["half1"] = half1
497
507
  map_dict["half2"] = half2
498
508
 
499
- logger.info("Clearing GP 10-74")
509
+ logger.info("Clearing GP 10-74") # Actually 11-44
500
510
  for i in range(1, 65):
501
511
  pvar = "ME14E-MO-IOC-01:GP" + str(i + 10)
502
512
  caput(pvar, 0)
503
513
  sys.stdout.write(".")
504
514
  sys.stdout.flush()
505
515
  logger.info("Map cleared")
506
- logger.info("Loading Map Choice %s" % map_choice)
516
+ logger.info(f"Loading Map Choice {map_choice}")
507
517
  for i in map_dict[map_choice]:
508
518
  pvar = "ME14E-MO-IOC-01:GP" + str(i + 10)
509
519
  caput(pvar, 1)
510
520
  logger.debug("Load stock map done.")
521
+ yield from bps.null()
511
522
 
512
523
 
513
524
  @log.log_on_entry
514
- def load_lite_map(litemap_path: Path | str = LITEMAP_PATH):
525
+ def load_lite_map() -> MsgGenerator:
526
+ setup_logging()
515
527
  logger.debug("Run load stock map with 'clear' setting.")
516
- load_stock_map("clear")
528
+ yield from load_stock_map("clear")
517
529
  # fmt: off
518
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
519
531
  oxford_block_dict = { # noqa: F841
@@ -527,7 +539,7 @@ def load_lite_map(litemap_path: Path | str = LITEMAP_PATH):
527
539
  'H1': '64', 'H2': '63', 'H3': '62', 'H4': '61', 'H5': '60', 'H6': '59', 'H7': '58', 'H8': '57',
528
540
  }
529
541
  # fmt: on
530
- chip_type = int(caget(pv.me14e_gp1))
542
+ chip_type = int(caget(CHIPTYPE_PV))
531
543
  if chip_type in [ChipType.Oxford, ChipType.OxfordInner]:
532
544
  logger.info("Oxford Block Order")
533
545
  rows = ["A", "B", "C", "D", "E", "F", "G", "H"]
@@ -555,14 +567,14 @@ def load_lite_map(litemap_path: Path | str = LITEMAP_PATH):
555
567
  label = "%02.d" % (lab_num + 1)
556
568
  btn_names[button_name] = label
557
569
  block_dict = btn_names
570
+ else:
571
+ raise ValueError(f"{chip_type=} unrecognised")
558
572
 
559
- litemap_path = _coerce_to_path(litemap_path)
560
-
561
- litemap_fid = str(caget(pv.me14e_gp5)) + ".lite"
573
+ litemap_fid = f"{caget(MAP_FILEPATH_PV)}.lite"
562
574
  logger.info("Please wait, loading LITE map")
563
- logger.info("Loading Lite Map")
564
- logger.info("Opening %s" % (litemap_path / litemap_fid))
565
- 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:
566
578
  f = fh.readlines()
567
579
  for line in f:
568
580
  entry = line.split()
@@ -570,151 +582,140 @@ def load_lite_map(litemap_path: Path | str = LITEMAP_PATH):
570
582
  yesno = entry[1]
571
583
  block_num = block_dict[block_name]
572
584
  pvar = "ME14E-MO-IOC-01:GP" + str(int(block_num) + 10)
573
- logger.info("Block: %s \tScanned: %s \tPVAR: %s" % (block_name, yesno, pvar))
585
+ logger.info(f"Block: {block_name} \tScanned: {yesno} \tPVAR: {pvar}")
574
586
  logger.debug("Load lite map done")
587
+ yield from bps.null()
575
588
 
576
589
 
577
590
  @log.log_on_entry
578
- def load_full_map(fullmap_path: Path | str = FULLMAP_PATH):
579
- (
580
- chip_name,
581
- visit,
582
- sub_dir,
583
- n_exposures,
584
- chip_type,
585
- map_type,
586
- ) = startup.scrape_parameter_file()
587
- fullmap_path = _coerce_to_path(fullmap_path)
588
-
589
- fullmap_fid = fullmap_path / f"{str(caget(pv.me14e_gp5))}.spec"
590
- logger.info("Opening %s" % fullmap_fid)
591
- mapping.plot_file(fullmap_fid, chip_type)
592
- mapping.convert_chip_to_hex(fullmap_fid, chip_type)
593
- 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")
594
600
  logger.info(
595
- "Copying %s to %s"
596
- % (fullmap_fid.with_suffix(".full"), fullmap_path / "currentchip.full")
601
+ "Copying {} to {}".format(
602
+ fullmap_fid.with_suffix(".full"), FULLMAP_PATH / "currentchip.full"
603
+ )
597
604
  )
598
605
  logger.debug("Load full map done")
606
+ yield from bps.null()
599
607
 
600
608
 
601
609
  @log.log_on_entry
602
- def moveto(place: str = "origin"):
603
- logger.info("Move to: %s" % place)
604
- chip_type = int(caget(pv.me14e_gp1))
605
- logger.info("Chip type is%s" % chip_type)
606
-
607
- if chip_type == ChipType.Oxford or chip_type == ChipType.Minichip:
608
- # Oxford and minichip
609
- # As minichip is nothing more than a smaller oxford,
610
- # they should move the same way
611
- logger.info("Oxford Move")
612
- if place == "origin":
613
- caput(pv.me14e_stage_x, 0.0)
614
- caput(pv.me14e_stage_y, 0.0)
615
- if place == "f1":
616
- caput(pv.me14e_stage_x, 25.40)
617
- caput(pv.me14e_stage_y, 0.0)
618
- if place == "f2":
619
- caput(pv.me14e_stage_x, 0.0)
620
- caput(pv.me14e_stage_y, 25.40)
621
-
622
- elif chip_type == ChipType.OxfordInner:
623
- logger.info("Oxford Inner Move")
624
- if place == "origin":
625
- caput(pv.me14e_stage_x, 0.0)
626
- caput(pv.me14e_stage_y, 0.0)
627
- if place == "f1":
628
- caput(pv.me14e_stage_x, 24.60)
629
- caput(pv.me14e_stage_y, 0.0)
630
- if place == "f2":
631
- caput(pv.me14e_stage_x, 0.0)
632
- caput(pv.me14e_stage_y, 24.60)
633
-
634
- elif chip_type == ChipType.Custom:
635
- logger.info("Custom Chip Move")
636
- if place == "origin":
637
- caput(pv.me14e_stage_x, 0.0)
638
- caput(pv.me14e_stage_y, 0.0)
639
- if place == "f1":
640
- caput(pv.me14e_stage_x, 25.40)
641
- caput(pv.me14e_stage_y, 0.0)
642
- if place == "f2":
643
- caput(pv.me14e_stage_x, 0.0)
644
- caput(pv.me14e_stage_y, 25.40)
645
-
646
- 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):
647
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()
648
644
 
649
645
  # Non Chip Specific Move
650
646
  if place == "zero":
651
- logger.info("Moving to %s" % place)
652
- caput(pv.me14e_pmac_str, "!x0y0z0")
647
+ logger.info(f"Moving to {place}")
648
+ yield from bps.trigger(pmac.to_xyz_zero)
653
649
 
654
650
  elif place == "load_position":
655
651
  logger.info("load position")
656
- caput(pv.bs_mp_select, "Robot")
657
- caput(pv.bl_mp_select, "Out")
658
- 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)
659
658
 
660
659
  elif place == "collect_position":
661
660
  logger.info("collect position")
662
661
  caput(pv.me14e_filter, 20)
663
- caput(pv.me14e_stage_x, 0.0)
664
- caput(pv.me14e_stage_y, 0.0)
665
- caput(pv.me14e_stage_z, 0.0)
666
- caput(pv.bs_mp_select, "Data Collection")
667
- 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)
668
668
 
669
669
  elif place == "microdrop_position":
670
670
  logger.info("microdrop align position")
671
- caput(pv.me14e_stage_x, 6.0)
672
- caput(pv.me14e_stage_y, -7.8)
673
- 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
+
674
673
 
675
- 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
676
679
  logger.info("Laser 1 /BNC2 shutter is open")
677
680
  # Use M712 = 0 if triggering on falling edge. M712 =1 if on rising edge
678
681
  # Be sure to also change laser1off
679
682
  # caput(pv.me14e_pmac_str, ' M712=0 M711=1')
680
- caput(pv.me14e_pmac_str, " M712=1 M711=1")
683
+ yield from bps.abs_set(pmac.laser, LaserSettings.LASER_1_ON, wait=True)
681
684
 
682
- elif place == "laser1off":
685
+ elif laser_setting == "laser1off":
683
686
  logger.info("Laser 1 shutter is closed")
684
- caput(pv.me14e_pmac_str, " M712=0 M711=1")
687
+ yield from bps.abs_set(pmac.laser, LaserSettings.LASER_1_OFF, wait=True)
685
688
 
686
- elif place == "laser2on":
689
+ elif laser_setting == "laser2on":
687
690
  logger.info("Laser 2 / BNC3 shutter is open")
688
- caput(pv.me14e_pmac_str, " M812=1 M811=1")
691
+ yield from bps.abs_set(pmac.laser, LaserSettings.LASER_2_ON, wait=True)
689
692
 
690
- elif place == "laser2off":
693
+ elif laser_setting == "laser2off":
691
694
  logger.info("Laser 2 shutter is closed")
692
- caput(pv.me14e_pmac_str, " M812=0 M811=1")
695
+ yield from bps.abs_set(pmac.laser, LaserSettings.LASER_2_OFF, wait=True)
693
696
 
694
- elif place == "laser1burn":
697
+ elif laser_setting == "laser1burn":
695
698
  led_burn_time = caget(pv.me14e_gp103)
696
699
  logger.info("Laser 1 on")
697
- logger.info("Burn time is %s s" % led_burn_time)
698
- caput(pv.me14e_pmac_str, " M712=1 M711=1")
699
- 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)
700
703
  logger.info("Laser 1 off")
701
- caput(pv.me14e_pmac_str, " M712=0 M711=1")
704
+ yield from bps.abs_set(pmac.laser, LaserSettings.LASER_1_OFF, wait=True)
702
705
 
703
- elif place == "laser2burn":
706
+ elif laser_setting == "laser2burn":
704
707
  led_burn_time = caget(pv.me14e_gp109)
705
708
  logger.info("Laser 2 on")
706
- logger.info("burntime %s s" % led_burn_time)
707
- caput(pv.me14e_pmac_str, " M812=1 M811=1")
708
- 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)
709
712
  logger.info("Laser 2 off")
710
- caput(pv.me14e_pmac_str, " M812=0 M811=1")
713
+ yield from bps.abs_set(pmac.laser, LaserSettings.LASER_2_OFF, wait=True)
711
714
 
712
715
 
713
716
  @log.log_on_entry
714
- def scrape_mtr_directions(param_path: Path | str = CS_FILES_PATH):
715
- param_path = _coerce_to_path(param_path)
716
-
717
- 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:
718
719
  lines = f.readlines()
719
720
  mtr1_dir, mtr2_dir, mtr3_dir = 1.0, 1.0, 1.0
720
721
  for line in lines:
@@ -726,62 +727,57 @@ def scrape_mtr_directions(param_path: Path | str = CS_FILES_PATH):
726
727
  mtr3_dir = float(line.split("=")[1])
727
728
  else:
728
729
  continue
729
- 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}")
730
731
  return mtr1_dir, mtr2_dir, mtr3_dir
731
732
 
732
733
 
733
734
  @log.log_on_entry
734
- 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()
735
737
  scale = 10000.0 # noqa: F841
736
- param_path = _coerce_to_path(param_path)
737
-
738
- mtr1_dir, mtr2_dir, mtr3_dir = scrape_mtr_directions(param_path)
739
-
740
- rbv_1 = float(caget(pv.me14e_stage_x + ".RBV"))
741
- rbv_2 = float(caget(pv.me14e_stage_y + ".RBV"))
742
- rbv_3 = float(caget(pv.me14e_stage_z + ".RBV"))
743
738
 
744
- raw_1 = float(caget(pv.me14e_stage_x + ".RRBV"))
745
- raw_2 = float(caget(pv.me14e_stage_y + ".RRBV"))
746
- raw_3 = float(caget(pv.me14e_stage_z + ".RRBV"))
739
+ mtr1_dir, mtr2_dir, mtr3_dir = scrape_mtr_directions(CS_FILES_PATH)
747
740
 
748
- f_x = rbv_1
749
- f_y = rbv_2
750
- 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)
751
744
 
752
- 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")
753
748
  logger.info("MTR\tRBV\tRAW\tCorr\tf_value")
754
- logger.info("MTR1\t%1.4f\t%i\t%i\t%1.4f" % (rbv_1, raw_1, mtr1_dir, f_x))
755
- logger.info("MTR2\t%1.4f\t%i\t%i\t%1.4f" % (rbv_2, raw_2, mtr2_dir, f_y))
756
- logger.info("MTR3\t%1.4f\t%i\t%i\t%1.4f" % (rbv_3, raw_3, mtr3_dir, f_z))
757
-
758
- with open(param_path / f"fiducial_{point}.txt", "w") as f:
759
- f.write("MTR\tRBV\tRAW\tCorr\tf_value\n")
760
- f.write("MTR1\t%1.4f\t%i\t%i\t%1.4f\n" % (rbv_1, raw_1, mtr1_dir, f_x))
761
- f.write("MTR2\t%1.4f\t%i\t%i\t%1.4f\n" % (rbv_2, raw_2, mtr2_dir, f_y))
762
- 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))
763
758
  logger.info(f"Fiducial {point} set.")
759
+ yield from bps.null()
764
760
 
765
761
 
766
- def scrape_mtr_fiducials(point: int, param_path: Path | str = CS_FILES_PATH):
767
- param_path = _coerce_to_path(param_path)
768
-
769
- 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:
770
766
  f_lines = f.readlines()[1:]
771
- f_x = float(f_lines[0].rsplit()[4])
772
- f_y = float(f_lines[1].rsplit()[4])
773
- 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])
774
770
  return f_x, f_y, f_z
775
771
 
776
772
 
777
773
  @log.log_on_entry
778
- def cs_maker():
774
+ def cs_maker(pmac: PMAC = inject("pmac")) -> MsgGenerator:
779
775
  """
780
776
  Coordinate system.
781
777
 
782
778
  Values for scalex, scaley, scalez, and skew, as well as the sign of
783
779
  Sx, Sy, Sz are stored in a .json file and should be modified there.
784
- 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
785
781
 
786
782
  Theory
787
783
  Rx: rotation about X-axis, pitch
@@ -805,24 +801,25 @@ def cs_maker():
805
801
  This should be measured in situ prior to expriment, ie. measure by hand using
806
802
  opposite and adjacent RBV after calibration of scale factors.
807
803
  """
808
- chip_type = int(caget(pv.me14e_gp1))
804
+ setup_logging()
805
+ chip_type = int(caget(CHIPTYPE_PV))
809
806
  fiducial_dict = {}
810
807
  fiducial_dict[0] = [25.400, 25.400]
811
808
  fiducial_dict[1] = [24.600, 24.600]
812
809
  fiducial_dict[2] = [25.400, 25.400]
813
810
  fiducial_dict[3] = [18.25, 18.25]
814
- 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]}")
815
812
 
816
813
  mtr1_dir, mtr2_dir, mtr3_dir = scrape_mtr_directions()
817
814
  f1_x, f1_y, f1_z = scrape_mtr_fiducials(1)
818
815
  f2_x, f2_y, f2_z = scrape_mtr_fiducials(2)
819
- logger.info("mtr1 direction: %s" % mtr1_dir)
820
- logger.info("mtr2 direction: %s" % mtr2_dir)
821
- 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}")
822
819
 
823
820
  # Scale parameters saved in json file
824
821
  try:
825
- with open(CS_FILES_PATH / "cs_maker.json", "r") as fh:
822
+ with open(CS_FILES_PATH / "cs_maker.json") as fh:
826
823
  cs_info = json.load(fh)
827
824
  except json.JSONDecodeError:
828
825
  logger.error("Invalid JSON file.")
@@ -857,22 +854,22 @@ def cs_maker():
857
854
  Sz1 = -1 * f1_y / fiducial_dict[chip_type][0]
858
855
  Sz2 = f2_x / fiducial_dict[chip_type][1]
859
856
  Sz = Sz_dir * ((Sz1 + Sz2) / 2)
860
- Cz = np.sqrt((1 - Sz**2))
861
- logger.info("Sz1 , %1.4f, %1.4f" % (Sz1, np.degrees(np.arcsin(Sz1))))
862
- logger.info("Sz2 , %1.4f, %1.4f" % (Sz2, np.degrees(np.arcsin(Sz2))))
863
- logger.info("Sz , %1.4f, %1.4f" % (Sz, np.degrees(np.arcsin(Sz))))
864
- 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}")
865
862
  # Rotation Around Y
866
863
  Sy = Sy_dir * f1_z / fiducial_dict[chip_type][0]
867
- Cy = np.sqrt((1 - Sy**2))
868
- logger.info("Sy , %1.4f, %1.4f" % (Sy, np.degrees(np.arcsin(Sy))))
869
- 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}")
870
867
  # Rotation Around X
871
868
  # If stages upsidedown (I24) change sign of Sx
872
869
  Sx = Sx_dir * f2_z / fiducial_dict[chip_type][1]
873
- Cx = np.sqrt((1 - Sx**2))
874
- logger.info("Sx , %1.4f, %1.4f" % (Sx, np.degrees(np.arcsin(Sx))))
875
- 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}")
876
873
 
877
874
  x1factor = mtr1_dir * scalex * (Cy * Cz)
878
875
  y1factor = mtr2_dir * scaley * (-1.0 * Cx * Sz)
@@ -886,14 +883,14 @@ def cs_maker():
886
883
  y3factor = mtr2_dir * scaley * ((Cx * Sy * Sz) + (Sx * Cz))
887
884
  z3factor = mtr3_dir * scalez * (Cx * Cy)
888
885
 
889
- logger.info("Skew being used is: %1.4f" % skew)
886
+ logger.info(f"Skew being used is: {skew:1.4f}")
890
887
  s1 = np.degrees(np.arcsin(Sz1))
891
888
  s2 = np.degrees(np.arcsin(Sz2))
892
889
  rot = np.degrees(np.arcsin((Sz1 + Sz2) / 2))
893
890
  calc_skew = (s1 - rot) - (s2 - rot)
894
- logger.info("s1:%1.4f s2:%1.4f rot:%1.4f" % (s1, s2, rot))
895
- logger.info("Calculated rotation from current fiducials is: %1.4f" % rot)
896
- 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}")
897
894
  logger.info("Calculated Skew has been known to have the wrong sign")
898
895
 
899
896
  sinD = np.sin((skew / 2) * (np.pi / 180))
@@ -903,10 +900,10 @@ def cs_maker():
903
900
  new_x2factor = (x2factor * cosD) + (y2factor * sinD)
904
901
  new_y2factor = (x2factor * sinD) + (y2factor * cosD)
905
902
 
906
- cs1 = "#1->%+1.3fX%+1.3fY%+1.3fZ" % (new_x1factor, new_y1factor, z1factor)
907
- cs2 = "#2->%+1.3fX%+1.3fY%+1.3fZ" % (new_x2factor, new_y2factor, z2factor)
908
- cs3 = "#3->%+1.3fX%+1.3fY%+1.3fZ" % (x3factor, y3factor, z3factor)
909
- 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}")
910
907
  logger.info(
911
908
  """These next values should be 1.
912
909
  This is the sum of the squares of the factors divided by their scale."""
@@ -914,52 +911,70 @@ def cs_maker():
914
911
  sqfact1 = np.sqrt(x1factor**2 + y1factor**2 + z1factor**2) / scalex
915
912
  sqfact2 = np.sqrt(x2factor**2 + y2factor**2 + z2factor**2) / scaley
916
913
  sqfact3 = np.sqrt(x3factor**2 + y3factor**2 + z3factor**2) / scalez
917
- logger.info("%1.4f \n %1.4f \n %1.4f" % (sqfact1, sqfact2, sqfact3))
918
- logger.info("Long wait, please be patient")
919
- 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)
920
917
  sleep(2.5)
921
- caput(pv.me14e_pmac_str, "&2")
922
- caput(pv.me14e_pmac_str, cs1)
923
- caput(pv.me14e_pmac_str, cs2)
924
- caput(pv.me14e_pmac_str, cs3)
925
- 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)
926
920
  sleep(0.1)
927
- caput(pv.me14e_pmac_str, "#1hmz#2hmz#3hmz")
921
+ yield from bps.trigger(pmac.home, wait=True)
928
922
  sleep(0.1)
929
- logger.info("Chip_type is %s" % chip_type)
923
+ logger.debug(f"Chip_type is {chip_type}")
930
924
  if chip_type == 0:
931
- caput(pv.me14e_pmac_str, "!x0.4y0.4")
925
+ yield from bps.abs_set(pmac.pmac_string, "!x0.4y0.4", wait=True)
932
926
  sleep(0.1)
933
- caput(pv.me14e_pmac_str, "#1hmz#2hmz#3hmz")
927
+ yield from bps.trigger(pmac.home, wait=True)
934
928
  else:
935
- caput(pv.me14e_pmac_str, "#1hmz#2hmz#3hmz")
929
+ yield from bps.trigger(pmac.home, wait=True)
936
930
  logger.debug("CSmaker done.")
931
+ yield from bps.null()
937
932
 
938
933
 
939
- def cs_reset():
940
- cs1 = "#1->-10000X+0Y+0Z"
941
- cs2 = "#2->+0X+10000Y+0Z"
942
- 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"
943
940
  strg = "\n".join([cs1, cs2, cs3])
944
941
  print(strg)
945
- caput(pv.me14e_pmac_str, "&2")
946
- sleep(0.5)
947
- caput(pv.me14e_pmac_str, cs1)
948
- sleep(0.5)
949
- caput(pv.me14e_pmac_str, cs2)
950
- sleep(0.5)
951
- caput(pv.me14e_pmac_str, cs3)
942
+ yield from set_pmac_strings_for_cs(pmac, {"cs1": cs1, "cs2": cs2, "cs3": cs3})
952
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)
953
966
 
954
967
 
955
968
  @log.log_on_entry
956
- def pumpprobe_calc():
969
+ def pumpprobe_calc() -> MsgGenerator:
970
+ # TODO See https://github.com/DiamondLightSource/mx_bluesky/issues/122
971
+ setup_logging()
957
972
  logger.info("Calculate and show exposure and dwell time for each option.")
958
973
  exptime = float(caget(pv.me14e_exptime))
959
974
  pumpexptime = float(caget(pv.me14e_gp103))
960
975
  movetime = 0.008
961
- logger.info("X-ray exposure time %s" % exptime)
962
- logger.info("Laser dwell time %s" % pumpexptime)
976
+ logger.info(f"X-ray exposure time {exptime}")
977
+ logger.info(f"Laser dwell time {pumpexptime}")
963
978
  repeat1 = 2 * 20 * (movetime + (pumpexptime + exptime) / 2)
964
979
  repeat2 = 4 * 20 * (movetime + (pumpexptime + exptime) / 2)
965
980
  repeat3 = 6 * 20 * (movetime + (pumpexptime + exptime) / 2)
@@ -974,17 +989,19 @@ def pumpprobe_calc():
974
989
  ):
975
990
  rounded = round(repeat, 4)
976
991
  caput(pv_name, rounded)
977
- logger.info("Repeat (%s): %s s" % (pv_name, rounded))
978
- # logger.info("repeat10 (%s): %s s" % (pv.me14e_gp108, round(repeat10, 4)))
992
+ logger.info(f"Repeat ({pv_name}): {rounded} s")
979
993
  logger.debug("PP calculations done")
994
+ yield from bps.null()
980
995
 
981
996
 
982
997
  @log.log_on_entry
983
- 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
984
1001
  caput(pv.me14e_gp9, 0)
985
1002
  while True:
986
1003
  if int(caget(pv.me14e_gp9)) == 0:
987
- chip_type = int(caget(pv.me14e_gp1))
1004
+ chip_type = int(caget(CHIPTYPE_PV))
988
1005
  if chip_type == ChipType.Minichip:
989
1006
  logger.info("Oxford mini chip in use.")
990
1007
  block_start_list = scrape_pvar_file("minichip_oxford.pvar")
@@ -1003,72 +1020,17 @@ def block_check():
1003
1020
  sleep(1.0)
1004
1021
  break
1005
1022
  block, x, y = entry
1006
- logger.info("Block: %s -> (x=%s y=%s)" % (block, x, y))
1007
- 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)
1008
1025
  time.sleep(0.4)
1009
1026
  else:
1010
1027
  logger.warning("Block Check Aborted due to GP 9 not equalling 0")
1011
1028
  break
1012
1029
  break
1013
1030
  logger.debug("Block check done")
1031
+ yield from bps.null()
1014
1032
 
1015
1033
 
1016
- def parse_args_and_run_parsed_function(args):
1017
- print(f"Run with {args}")
1018
- parser = argparse.ArgumentParser()
1019
- subparsers = parser.add_subparsers(
1020
- help="Choose command.",
1021
- required=True,
1022
- dest="sub-command",
1023
- )
1024
- parser_init = subparsers.add_parser(
1025
- "initialise",
1026
- )
1027
- parser_init.set_defaults(func=initialise)
1028
- parser_moveto = subparsers.add_parser(
1029
- "moveto",
1030
- )
1031
- parser_moveto.add_argument("place", type=str)
1032
- parser_moveto.set_defaults(func=moveto)
1033
- parser_fid = subparsers.add_parser("fiducial")
1034
- parser_fid.add_argument("point", type=int)
1035
- parser_fid.set_defaults(func=fiducial)
1036
- parser_csm = subparsers.add_parser("cs_maker")
1037
- parser_csm.set_defaults(func=cs_maker)
1038
- parser_pp = subparsers.add_parser("pumpprobe_calc")
1039
- parser_pp.set_defaults(func=pumpprobe_calc)
1040
- parser_write = subparsers.add_parser("write_parameter_file")
1041
- parser_write.set_defaults(func=write_parameter_file)
1042
- parser_def = subparsers.add_parser("define_current_chip")
1043
- parser_def.add_argument("chipid", type=str)
1044
- parser_def.set_defaults(func=define_current_chip)
1045
- parser_stockmap = subparsers.add_parser("load_stock_map")
1046
- parser_stockmap.add_argument("map_choice", type=str)
1047
- parser_stockmap.set_defaults(func=load_stock_map)
1048
- parser_litemap = subparsers.add_parser("load_lite_map")
1049
- parser_litemap.set_defaults(func=load_lite_map)
1050
- parser_fullmap = subparsers.add_parser("load_full_map")
1051
- parser_fullmap.set_defaults(func=load_full_map)
1052
- parser_save = subparsers.add_parser("save_screen_map")
1053
- parser_save.set_defaults(func=save_screen_map)
1054
- parser_upld = subparsers.add_parser("upload_full")
1055
- parser_upld.set_defaults(func=upload_full)
1056
- parser_params = subparsers.add_parser("upload_parameters")
1057
- parser_params.add_argument("chipid", type=str)
1058
- parser_params.set_defaults(func=upload_parameters)
1059
- parser_csr = subparsers.add_parser("cs_reset")
1060
- parser_csr.set_defaults(func=cs_reset)
1061
- parser_block = subparsers.add_parser("block_check")
1062
- parser_block.set_defaults(func=block_check)
1063
-
1064
- args = parser.parse_args(args)
1065
-
1066
- args_dict = vars(args)
1067
- args_dict.pop("sub-command")
1068
- args_dict.pop("func")(**args_dict)
1069
-
1070
-
1071
- if __name__ == "__main__":
1072
- setup_logging()
1073
-
1074
- 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