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
@@ -3,23 +3,24 @@ Chip mapping utilities for fixed target
3
3
 
4
4
  This version changed to python3 March2020 by RLO
5
5
  """
6
+
6
7
  import logging
7
8
  import time
8
9
 
9
10
  import numpy as np
10
11
  from matplotlib import pyplot as plt
11
12
 
12
- from mx_bluesky.I24.serial import log
13
- from mx_bluesky.I24.serial.fixed_target.ft_utils import ChipType
14
- from mx_bluesky.I24.serial.fixed_target.i24ssx_Chip_StartUp_py3v1 import (
13
+ from mx_bluesky.i24.serial import log
14
+ from mx_bluesky.i24.serial.fixed_target.ft_utils import ChipType
15
+ from mx_bluesky.i24.serial.fixed_target.i24ssx_Chip_StartUp_py3v1 import (
15
16
  check_files,
16
- get_format,
17
17
  get_shot_order,
18
18
  get_xy,
19
- scrape_parameter_file,
19
+ read_parameter_file,
20
20
  write_file,
21
21
  )
22
- from mx_bluesky.I24.serial.parameters.constants import PARAM_FILE_PATH_FT
22
+ from mx_bluesky.i24.serial.parameters import get_chip_format
23
+ from mx_bluesky.i24.serial.parameters.constants import PARAM_FILE_PATH_FT
23
24
 
24
25
  logger = logging.getLogger("I24ssx.chip_mapping")
25
26
 
@@ -34,7 +35,7 @@ def setup_logging():
34
35
  def read_file_make_dict(fid, chip_type, switch=False):
35
36
  a_dict = {}
36
37
  b_dict = {}
37
- with open(fid, "r") as f:
38
+ with open(fid) as f:
38
39
  for line in f.readlines():
39
40
  if line.startswith("#"):
40
41
  continue
@@ -78,36 +79,36 @@ def plot_file(fid, chip_type):
78
79
  ax1.set_xlim(-1, 26)
79
80
  ax1.set_ylim(-1, 26)
80
81
  ax1.invert_yaxis()
81
- check_files(["%s.png" % chip_type])
82
- plt.savefig("%s.png" % fid[:-5], dpi=200, bbox_inches="tight", pad_inches=0.05)
82
+ check_files("i24", [f"{chip_type}.png"])
83
+ plt.savefig(f"{fid[:-5]}.png", dpi=200, bbox_inches="tight", pad_inches=0.05)
83
84
  return 1
84
85
 
85
86
 
86
87
  @log.log_on_entry
87
88
  def convert_chip_to_hex(fid, chip_type):
88
89
  chip_dict = read_file_make_dict(fid, chip_type, True)
89
- chip_format = get_format(chip_type)
90
- check_files(["%s.full" % chip_type])
91
- with open("%s.full" % fid[:-5], "w") as g:
90
+ chip_format = get_chip_format(ChipType(chip_type))
91
+ check_files("i24", [f"{chip_type}.full"])
92
+ with open(f"{fid[:-5]}.full", "w") as g:
92
93
  # Normal
93
94
  if chip_type in [ChipType.Oxford, ChipType.OxfordInner]:
94
95
  shot_order_list = get_shot_order(chip_type)
95
96
  logger.info("Shot Order List: \n")
96
- logger.info("%s" % shot_order_list[:14])
97
- logger.info("%s" % shot_order_list[-14:])
97
+ logger.info(f"{shot_order_list[:14]}")
98
+ logger.info(f"{shot_order_list[-14:]}")
98
99
  for i, k in enumerate(shot_order_list):
99
100
  if i % 20 == 0:
100
101
  logger.info("\n")
101
102
  else:
102
- logger.info("%s" % k)
103
+ logger.info(f"{k}")
103
104
  sorted_pres_list = []
104
105
  for addr in shot_order_list:
105
106
  sorted_pres_list.append(chip_dict[addr])
106
107
 
107
- windows_per_block = chip_format[2]
108
- number_of_lines = len(sorted_pres_list) / windows_per_block
108
+ windows_per_block = chip_format.x_num_steps
109
+ number_of_lines = int(len(sorted_pres_list) / windows_per_block)
109
110
  hex_length = windows_per_block / 4
110
- pad = 7 - hex_length
111
+ pad = int(7 - hex_length)
111
112
  for i in range(number_of_lines):
112
113
  sublist = sorted_pres_list[
113
114
  i * windows_per_block : (i * windows_per_block) + windows_per_block
@@ -116,24 +117,24 @@ def convert_chip_to_hex(fid, chip_type):
116
117
  right_list = sublist
117
118
  else:
118
119
  right_list = sublist[::-1]
119
- hex_string = ("{0:0>%sX}" % hex_length).format(
120
+ hex_string = (f"{{0:0>{hex_length}X}}").format(
120
121
  int("".join(str(x) for x in right_list), 2)
121
122
  )
122
- hex_string = hex_string + pad * "0"
123
+ hex_string = hex_string + (pad * "0")
123
124
  pvar = 5001 + i
124
- line = "P%s=$%s" % (pvar, hex_string)
125
+ line = f"P{pvar}=${hex_string}"
125
126
  g.write(line + "\n")
126
127
  logger.info("hex string: %s" % (hex_string + 4 * "0"))
127
- logger.info("line number= %s" % i)
128
+ logger.info(f"line number= {i}")
128
129
  logger.info(
129
- "right_list: \n%s\n" % ("".join(str(x) for x in right_list))
130
+ "right_list: \n{}\n".format("".join(str(x) for x in right_list))
130
131
  )
131
- logger.info("PVAR: %s" % line)
132
+ logger.info(f"PVAR: {line}")
132
133
  if (i + 1) % windows_per_block == 0:
133
134
  logger.info(
134
135
  "\n %s" % (40 * (" %i" % ((i / windows_per_block) + 2)))
135
136
  )
136
- logger.info("hex_length: %s" % hex_length)
137
+ logger.info(f"hex_length: {hex_length}")
137
138
  else:
138
139
  logger.warning("Chip type unknown, no conversion done.")
139
140
  return 0
@@ -141,24 +142,17 @@ def convert_chip_to_hex(fid, chip_type):
141
142
 
142
143
  def main():
143
144
  setup_logging()
144
- (
145
- chip_name,
146
- visit,
147
- sub_dir,
148
- n_exposures,
149
- chip_type,
150
- map_type,
151
- ) = scrape_parameter_file()
152
-
153
- check_files([".spec"])
145
+ params = read_parameter_file()
146
+
147
+ check_files("i24", [".spec"])
154
148
  write_file(suffix=".spec", order="shot")
155
149
 
156
- logger.info("PARAMETER PATH = %s" % PARAM_FILE_PATH_FT)
157
- fid = PARAM_FILE_PATH_FT / f"{chip_name}.spec"
158
- logger.info("FID = %s" % fid)
150
+ logger.info(f"PARAMETER PATH = {PARAM_FILE_PATH_FT}")
151
+ fid = PARAM_FILE_PATH_FT / f"{params.filename}.spec"
152
+ logger.info(f"FID = {fid}")
159
153
 
160
- plot_file(fid, chip_type)
161
- convert_chip_to_hex(fid, chip_type)
154
+ plot_file(fid, params.chip.chip_type.value)
155
+ convert_chip_to_hex(fid, params.chip.chip_type.value)
162
156
 
163
157
 
164
158
  if __name__ == "__main__":
@@ -0,0 +1,325 @@
1
+ """
2
+ Startup utilities for chip
3
+ """
4
+
5
+ import logging
6
+ import os
7
+ import string
8
+ import time
9
+ from pathlib import Path
10
+
11
+ import numpy as np
12
+
13
+ from mx_bluesky.i24.serial import log
14
+ from mx_bluesky.i24.serial.fixed_target.ft_utils import ChipType
15
+ from mx_bluesky.i24.serial.parameters import FixedTargetParameters, get_chip_format
16
+ from mx_bluesky.i24.serial.parameters.constants import (
17
+ HEADER_FILES_PATH,
18
+ PARAM_FILE_NAME,
19
+ PARAM_FILE_PATH_FT,
20
+ )
21
+
22
+ logger = logging.getLogger("I24ssx.chip_startup")
23
+
24
+
25
+ def setup_logging():
26
+ # Log should now change name daily.
27
+ logfile = time.strftime("i24fixedtarget_%d%B%y.log").lower()
28
+ log.config(logfile)
29
+
30
+
31
+ def read_parameter_file(
32
+ param_path: Path | str = PARAM_FILE_PATH_FT,
33
+ ) -> FixedTargetParameters:
34
+ if not isinstance(param_path, Path):
35
+ param_path = Path(param_path)
36
+ params_file = param_path / PARAM_FILE_NAME
37
+ params = FixedTargetParameters.from_file(params_file)
38
+ return params
39
+
40
+
41
+ @log.log_on_entry
42
+ def fiducials(chip_type: int):
43
+ fiducial_list: list | None = None
44
+ if chip_type in [ChipType.Oxford, ChipType.OxfordInner, ChipType.Minichip]:
45
+ fiducial_list = []
46
+ elif chip_type == ChipType.Custom:
47
+ # No fiducial for custom
48
+ logger.warning("No fiducials for custom chip")
49
+ else:
50
+ logger.warning(f"Unknown chip_type, {chip_type}, in fiducials")
51
+ return fiducial_list
52
+
53
+
54
+ def get_xy(addr: str, chip_type: ChipType):
55
+ entry = addr.split("_")[-2:]
56
+ R, C = entry[0][0], entry[0][1]
57
+ r2, c2 = entry[1][0], entry[1][1]
58
+ blockR = string.ascii_uppercase.index(R)
59
+ blockC = int(C) - 1
60
+ lowercase_list = list(string.ascii_lowercase + string.ascii_uppercase + "0")
61
+ windowR = lowercase_list.index(r2)
62
+ windowC = lowercase_list.index(c2)
63
+
64
+ chip_params = get_chip_format(chip_type)
65
+
66
+ x = (
67
+ (blockC * chip_params.b2b_horz)
68
+ + (blockC * (chip_params.x_num_steps - 1) * chip_params.x_step_size)
69
+ + (windowC * chip_params.x_step_size)
70
+ )
71
+ y = (
72
+ (blockR * chip_params.b2b_vert)
73
+ + (blockR * (chip_params.y_num_steps - 1) * chip_params.y_step_size)
74
+ + (windowR * chip_params.y_step_size)
75
+ )
76
+ return x, y
77
+
78
+
79
+ def pathli(l_in=None, way="typewriter", reverse=False):
80
+ if l_in is None:
81
+ l_in = []
82
+ if reverse is True:
83
+ li = list(reversed(l_in))
84
+ else:
85
+ li = list(l_in)
86
+ long_list = []
87
+ if li:
88
+ if way == "typewriter":
89
+ for i in range(len(li) ** 2):
90
+ long_list.append(li[i % len(li)])
91
+ elif way == "snake":
92
+ lr = list(reversed(li))
93
+ for rep in range(len(li)):
94
+ if rep % 2 == 0:
95
+ long_list += li
96
+ else:
97
+ long_list += lr
98
+ elif way == "snake53":
99
+ lr = list(reversed(li))
100
+ for rep in range(53):
101
+ if rep % 2 == 0:
102
+ long_list += li
103
+ else:
104
+ long_list += lr
105
+ elif way == "expand":
106
+ for entry in li:
107
+ for _ in range(len(li)):
108
+ long_list.append(entry)
109
+ elif way == "expand28":
110
+ for entry in li:
111
+ for _ in range(28):
112
+ long_list.append(entry)
113
+ elif way == "expand25":
114
+ for entry in li:
115
+ for _ in range(25):
116
+ long_list.append(entry)
117
+ else:
118
+ logger.warning(f"No known path, way = {way}")
119
+ else:
120
+ logger.warning("No list written")
121
+ return long_list
122
+
123
+
124
+ def zippum(list_1_args, list_2_args):
125
+ list_1, type_1, reverse_1 = list_1_args
126
+ list_2, type_2, reverse_2 = list_2_args
127
+ A_path = pathli(list_1, type_1, reverse_1)
128
+ B_path = pathli(list_2, type_2, reverse_2)
129
+ zipped_list = []
130
+ for a, b in zip(A_path, B_path, strict=False):
131
+ zipped_list.append(a + b)
132
+ return zipped_list
133
+
134
+
135
+ def get_alphanumeric(chip_type: ChipType):
136
+ cell_format = get_chip_format(chip_type)
137
+ blk_num = cell_format.x_blocks
138
+ wnd_num = cell_format.x_num_steps
139
+ uppercase_list = list(string.ascii_uppercase)[:blk_num]
140
+ lowercase_list = list(string.ascii_lowercase + string.ascii_uppercase + "0")[
141
+ :wnd_num
142
+ ]
143
+ number_list = [str(x) for x in range(1, blk_num + 1)]
144
+
145
+ block_list = zippum([uppercase_list, "expand", 0], [number_list, "typewriter", 0])
146
+ window_list = zippum(
147
+ [lowercase_list, "expand", 0], [lowercase_list, "typewriter", 0]
148
+ )
149
+
150
+ alphanumeric_list = []
151
+ for block in block_list:
152
+ for window in window_list:
153
+ alphanumeric_list.append(block + "_" + window)
154
+ logger.info(f"Length of alphanumeric list = {len(alphanumeric_list)}")
155
+ return alphanumeric_list
156
+
157
+
158
+ @log.log_on_entry
159
+ def get_shot_order(chip_type: ChipType):
160
+ cell_format = get_chip_format(chip_type)
161
+ blk_num = cell_format.x_blocks
162
+ wnd_num = cell_format.x_num_steps
163
+ uppercase_list = list(string.ascii_uppercase)[:blk_num]
164
+ number_list = [str(x) for x in range(1, blk_num + 1)]
165
+ lowercase_list = list(string.ascii_lowercase + string.ascii_uppercase + "0")[
166
+ :wnd_num
167
+ ]
168
+
169
+ block_list = zippum([uppercase_list, "snake", 0], [number_list, "expand", 0])
170
+ window_dn = zippum([lowercase_list, "expand", 0], [lowercase_list, "snake", 0])
171
+ window_up = zippum([lowercase_list, "expand", 1], [lowercase_list, "snake", 0])
172
+
173
+ switch = 0
174
+ count = 0
175
+ collect_list = []
176
+ for block in block_list:
177
+ if switch == 0:
178
+ for window in window_dn:
179
+ collect_list.append(block + "_" + window)
180
+ count += 1
181
+ if count == blk_num:
182
+ count = 0
183
+ switch = 1
184
+ else:
185
+ for window in window_up:
186
+ collect_list.append(block + "_" + window)
187
+ count += 1
188
+ if count == blk_num:
189
+ count = 0
190
+ switch = 0
191
+
192
+ logger.info(f"Length of collect list = {len(collect_list)}")
193
+ return collect_list
194
+
195
+
196
+ @log.log_on_entry
197
+ def write_file(
198
+ location: str = "i24",
199
+ suffix: str = ".addr",
200
+ order: str = "alphanumeric",
201
+ param_file_path: Path = PARAM_FILE_PATH_FT,
202
+ save_path: Path = HEADER_FILES_PATH,
203
+ ):
204
+ if location == "i24":
205
+ params = read_parameter_file(param_file_path)
206
+ else:
207
+ msg = f"Unknown location, {location}"
208
+ logger.error(msg)
209
+ raise ValueError(msg)
210
+ chip_file_path = save_path / f"chips/{params.directory}/{params.filename}{suffix}"
211
+
212
+ fiducial_list = fiducials(params.chip.chip_type.value)
213
+
214
+ if order == "alphanumeric":
215
+ addr_list = get_alphanumeric(params.chip.chip_type)
216
+ elif order == "shot":
217
+ addr_list = get_shot_order(params.chip.chip_type)
218
+ else:
219
+ raise ValueError(f"{order=} unrecognised")
220
+
221
+ with open(chip_file_path, "a") as g:
222
+ for addr in addr_list:
223
+ xtal_name = "_".join([params.filename, addr])
224
+ (x, y) = get_xy(xtal_name, params.chip.chip_type)
225
+ if addr in fiducial_list:
226
+ pres = "0"
227
+ else:
228
+ if "rand" in suffix:
229
+ pres = str(np.random.randint(2))
230
+ else:
231
+ pres = "-1"
232
+ line = "\t".join([xtal_name, str(x), str(y), "0.0", pres]) + "\n"
233
+ g.write(line)
234
+
235
+ logger.info(f"Write {chip_file_path} completed")
236
+
237
+
238
+ @log.log_on_entry
239
+ def check_files(
240
+ location: str,
241
+ suffix_list: list[str],
242
+ param_file_path: Path | str = PARAM_FILE_PATH_FT,
243
+ save_path: Path = HEADER_FILES_PATH,
244
+ ):
245
+ if location == "i24":
246
+ params = read_parameter_file(param_file_path)
247
+ else:
248
+ msg = f"Unknown location, {location}"
249
+ logger.error(msg)
250
+ raise ValueError(msg)
251
+ chip_file_path = save_path / f"chips/{params.directory}/{params.filename}"
252
+
253
+ try:
254
+ os.stat(chip_file_path)
255
+ except Exception:
256
+ os.makedirs(chip_file_path)
257
+ for suffix in suffix_list:
258
+ full_fid = chip_file_path.with_suffix(suffix)
259
+ if full_fid.is_file():
260
+ time_str = time.strftime("%Y%m%d_%H%M%S_")
261
+ timestamp_fid = ( # noqa: F841
262
+ full_fid.parent / f"{time_str}_{params.filename}{full_fid.suffix}"
263
+ )
264
+ # FIXME hack / fix. Actually move the file
265
+ logger.info(f"File {full_fid} Already Exists")
266
+ logger.debug("Check files done")
267
+ return 1
268
+
269
+
270
+ @log.log_on_entry
271
+ def write_headers(
272
+ location: str,
273
+ suffix_list: list[str],
274
+ param_file_path: Path = PARAM_FILE_PATH_FT,
275
+ save_path: Path = HEADER_FILES_PATH,
276
+ ):
277
+ if location == "i24":
278
+ params = read_parameter_file(param_file_path)
279
+ chip_file_path = save_path / f"chips/{params.directory}/{params.filename}"
280
+
281
+ for suffix in suffix_list:
282
+ full_fid = chip_file_path.with_suffix(suffix)
283
+ with open(full_fid, "w") as g:
284
+ g.write(
285
+ "#23456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\n#\n"
286
+ )
287
+ g.write(f"#&i24\tchip_name = {params.filename}\n")
288
+ g.write(f"#&i24\tvisit = {params.visit}\n")
289
+ g.write(f"#&i24\tsub_dir = {params.directory}\n")
290
+ g.write(f"#&i24\tn_exposures = {params.num_exposures}\n")
291
+ g.write(f"#&i24\tchip_type = {params.chip.chip_type.value}\n")
292
+ g.write(f"#&i24\tmap_type = {params.map_type.value}\n")
293
+ g.write(f"#&i24\tpump_repeat = {params.pump_repeat.value}\n")
294
+ g.write(f"#&i24\tpumpexptime = {params.laser_dwell_s}\n")
295
+ g.write(f"#&i24\texptime = {params.laser_delay_s}\n")
296
+ g.write(f"#&i24\tdcdetdist = {params.detector_distance_mm}\n")
297
+ g.write(f"#&i24\tprepumpexptime = {params.pre_pump_exposure_s}\n")
298
+ g.write(f"#&i24\tdet_Type = {params.detector_name}\n")
299
+ g.write("#\n")
300
+ g.write(
301
+ "#XtalAddr XCoord YCoord ZCoord Present Shot Spare04 Spare03 Spare02 Spare01\n"
302
+ )
303
+ else:
304
+ msg = f"Unknown location, {location}"
305
+ logger.error(msg)
306
+ raise ValueError(msg)
307
+ logger.debug("Write headers done")
308
+
309
+
310
+ def run():
311
+ logger.debug("Run Startup")
312
+ check_files("i24", [".addr", ".shot"])
313
+ logger.info("Checked Files")
314
+ write_headers("i24", [".addr", ".shot"])
315
+ logger.info("Written Headers")
316
+ logger.info("Writing to Files has been disabled. Headers Only")
317
+ # Makes a file with random crystal positions
318
+ check_files("i24", ["rando.spec"])
319
+ write_headers("i24", ["rando.spec"])
320
+ logger.debug("StartUp Done")
321
+
322
+
323
+ if __name__ == "__main__":
324
+ setup_logging()
325
+ run()
@@ -2,15 +2,19 @@
2
2
  Move on click gui for fixed targets at I24
3
3
  Robin Owen 12 Jan 2021
4
4
  """
5
+
5
6
  import logging
6
7
 
8
+ import bluesky.plan_stubs as bps
7
9
  import cv2 as cv
10
+ from bluesky.run_engine import RunEngine
8
11
  from dodal.beamlines import i24
12
+ from dodal.devices.i24.pmac import PMAC
9
13
  from dodal.devices.oav.oav_detector import OAV
10
14
 
11
- from mx_bluesky.I24.serial.fixed_target import i24ssx_Chip_Manager_py3v1 as manager
12
- from mx_bluesky.I24.serial.parameters.constants import OAV1_CAM
13
- from mx_bluesky.I24.serial.setup_beamline import caput, pv
15
+ from mx_bluesky.i24.serial.fixed_target import i24ssx_Chip_Manager_py3v1 as manager
16
+ from mx_bluesky.i24.serial.fixed_target.ft_utils import Fiducials
17
+ from mx_bluesky.i24.serial.parameters.constants import OAV1_CAM
14
18
 
15
19
  logger = logging.getLogger("I24ssx.moveonclick")
16
20
 
@@ -25,41 +29,28 @@ def _get_beam_centre(oav: OAV):
25
29
  Args:
26
30
  oav (OAV): the OAV device.
27
31
  """
28
- beamX, beamY = oav.parameters.beam_centre_i, oav.parameters.beam_centre_j
29
- # Re-scale beam position to an image of 1024x768 to get the correct values
30
- # See https://github.com/DiamondLightSource/dodal/issues/249
31
- beamX *= 1292 / 1024
32
- beamY *= 964 / 768
33
- return int(beamX), int(beamY)
34
-
35
-
36
- # TODO In the future, this should be done automatically in the OAV device
37
- # See https://github.com/DiamondLightSource/dodal/issues/224
38
- def get_beam_centre():
39
- # Get I24 oav device from dodal
40
- oav = i24.oav()
41
-
42
- beamX, beamY = _get_beam_centre(oav)
43
- return beamX, beamY
32
+ return oav.parameters.beam_centre_i, oav.parameters.beam_centre_j
44
33
 
45
34
 
46
35
  # Register clicks and move chip stages
47
36
  def onMouse(event, x, y, flags, param):
48
- beamX, beamY = get_beam_centre()
49
37
  if event == cv.EVENT_LBUTTONUP:
50
- logger.info("Clicked X and Y %s %s" % (x, y))
38
+ pmac = param[0]
39
+ oav = param[1]
40
+ beamX, beamY = _get_beam_centre(oav)
41
+ logger.info(f"Clicked X and Y {x} {y}")
51
42
  xmove = -1 * (beamX - x) * zoomcalibrator
52
43
  ymove = -1 * (beamY - y) * zoomcalibrator
53
- logger.info("Moving X and Y %s %s" % (xmove, ymove))
44
+ logger.info(f"Moving X and Y {xmove} {ymove}")
54
45
  xmovepmacstring = "#1J:" + str(xmove)
55
46
  ymovepmacstring = "#2J:" + str(ymove)
56
- caput(pv.me14e_pmac_str, xmovepmacstring)
57
- caput(pv.me14e_pmac_str, ymovepmacstring)
47
+ yield from bps.abs_set(pmac.pmac_string, xmovepmacstring, wait=True)
48
+ yield from bps.abs_set(pmac.pmac_string, ymovepmacstring, wait=True)
58
49
 
59
50
 
60
- def update_ui(frame):
51
+ def update_ui(oav, frame):
61
52
  # Get beam x and y values
62
- beamX, beamY = get_beam_centre()
53
+ beamX, beamY = _get_beam_centre(oav)
63
54
 
64
55
  # Overlay text and beam centre
65
56
  cv.ellipse(
@@ -140,12 +131,15 @@ def update_ui(frame):
140
131
 
141
132
 
142
133
  def start_viewer(oav1: str = OAV1_CAM):
134
+ # Get devices out of dodal
135
+ oav: OAV = i24.oav()
136
+ pmac: PMAC = i24.pmac()
143
137
  # Create a video caputure from OAV1
144
138
  cap = cv.VideoCapture(oav1)
145
139
 
146
140
  # Create window named OAV1view and set onmouse to this
147
141
  cv.namedWindow("OAV1view")
148
- cv.setMouseCallback("OAV1view", onMouse) # type: ignore
142
+ cv.setMouseCallback("OAV1view", onMouse, param=[pmac, oav]) # type: ignore
149
143
 
150
144
  logger.info("Showing camera feed. Press escape to close")
151
145
  # Read captured video and store them in success and frame
@@ -155,42 +149,42 @@ def start_viewer(oav1: str = OAV1_CAM):
155
149
  while success:
156
150
  success, frame = cap.read()
157
151
 
158
- update_ui(frame)
152
+ update_ui(oav, frame)
159
153
 
160
154
  k = cv.waitKey(1)
161
155
  if k == 113: # Q
162
- manager.moveto("zero")
156
+ yield from manager.moveto(Fiducials.zero, pmac)
163
157
  if k == 119: # W
164
- manager.moveto("f1")
158
+ yield from manager.moveto(Fiducials.fid1, pmac)
165
159
  if k == 101: # E
166
- manager.moveto("f2")
160
+ yield from manager.moveto(Fiducials.fid2, pmac)
167
161
  if k == 97: # A
168
- caput(pv.me14e_pmac_str, r"\#1hmz\#2hmz\#3hmz")
162
+ yield from bps.trigger(pmac.home, wait=True)
169
163
  print("Current position set as origin")
170
164
  if k == 115: # S
171
- manager.fiducial(1)
165
+ yield from manager.fiducial(1)
172
166
  if k == 100: # D
173
- manager.fiducial(2)
167
+ yield from manager.fiducial(2)
174
168
  if k == 99: # C
175
- manager.cs_maker()
169
+ yield from manager.cs_maker(pmac)
176
170
  if k == 98: # B
177
- manager.block_check() # doesn't work well for blockcheck as image doesn't update
171
+ yield from manager.block_check() # doesn't work well for blockcheck as image doesn't update
178
172
  if k == 104: # H
179
- caput(pv.me14e_pmac_str, "#2J:-10")
173
+ yield from bps.abs_set(pmac.pmac_string, "#2J:-10", wait=True)
180
174
  if k == 110: # N
181
- caput(pv.me14e_pmac_str, "#2J:10")
175
+ yield from bps.abs_set(pmac.pmac_string, "#2J:10", wait=True)
182
176
  if k == 109: # M
183
- caput(pv.me14e_pmac_str, "#1J:-10")
177
+ yield from bps.abs_set(pmac.pmac_string, "#1J:-10", wait=True)
184
178
  if k == 98: # B
185
- caput(pv.me14e_pmac_str, "#1J:10")
179
+ yield from bps.abs_set(pmac.pmac_string, "#1J:10", wait=True)
186
180
  if k == 105: # I
187
- caput(pv.me14e_pmac_str, "#3J:-150")
181
+ yield from bps.abs_set(pmac.pmac_string, "#3J:-150", wait=True)
188
182
  if k == 111: # O
189
- caput(pv.me14e_pmac_str, "#3J:150")
183
+ yield from bps.abs_set(pmac.pmac_string, "#3J:150", wait=True)
190
184
  if k == 117: # U
191
- caput(pv.me14e_pmac_str, "#3J:-1000")
185
+ yield from bps.abs_set(pmac.pmac_string, "#3J:-1000", wait=True)
192
186
  if k == 112: # P
193
- caput(pv.me14e_pmac_str, "#3J:1000")
187
+ yield from bps.abs_set(pmac.pmac_string, "#3J:1000", wait=True)
194
188
  if k == 0x1B: # esc
195
189
  cv.destroyWindow("OAV1view")
196
190
  print("Pressed escape. Closing window")
@@ -201,4 +195,5 @@ def start_viewer(oav1: str = OAV1_CAM):
201
195
 
202
196
 
203
197
  if __name__ == "__main__":
204
- start_viewer()
198
+ RE = RunEngine()
199
+ RE(start_viewer())