mx-bluesky 1.2.0__py3-none-any.whl → 1.4.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.
- mx_bluesky/__init__.py +8 -3
- mx_bluesky/__main__.py +12 -7
- mx_bluesky/_version.py +2 -2
- mx_bluesky/beamlines/i04/callbacks/murko_callback.py +14 -4
- mx_bluesky/beamlines/i04/redis_to_murko_forwarder.py +178 -0
- mx_bluesky/beamlines/i04/thawing_plan.py +49 -11
- mx_bluesky/beamlines/i24/serial/__init__.py +3 -0
- mx_bluesky/beamlines/i24/serial/dcid.py +143 -171
- mx_bluesky/beamlines/i24/serial/extruder/EX-gui-edm/DiamondExtruder-I24-py3v1.edl +1 -1
- mx_bluesky/beamlines/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +121 -110
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/DiamondChipI24-py3v1.edl +3 -6
- mx_bluesky/beamlines/i24/serial/fixed_target/ft_utils.py +0 -1
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +164 -169
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +149 -225
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_StartUp_py3v1.py +7 -216
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_moveonclick.py +18 -17
- mx_bluesky/beamlines/i24/serial/log.py +58 -49
- mx_bluesky/beamlines/i24/serial/parameters/__init__.py +4 -0
- mx_bluesky/beamlines/i24/serial/parameters/constants.py +6 -1
- mx_bluesky/beamlines/i24/serial/parameters/experiment_parameters.py +42 -15
- mx_bluesky/beamlines/i24/serial/parameters/fixed_target/cs/cs_maker.json +3 -3
- mx_bluesky/beamlines/i24/serial/run_extruder.sh +30 -5
- mx_bluesky/beamlines/i24/serial/run_fixed_target.sh +30 -5
- mx_bluesky/beamlines/i24/serial/run_serial.py +24 -8
- mx_bluesky/beamlines/i24/serial/setup_beamline/ca.py +0 -2
- mx_bluesky/beamlines/i24/serial/setup_beamline/pv.py +2 -0
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +104 -82
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_detector.py +9 -20
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_zebra_plans.py +26 -28
- mx_bluesky/beamlines/i24/serial/write_nexus.py +74 -72
- mx_bluesky/common/__init__.py +0 -0
- mx_bluesky/common/device_setup_plans/read_hardware_for_setup.py +14 -0
- mx_bluesky/common/external_interaction/config_server.py +46 -0
- mx_bluesky/common/parameters/components.py +258 -0
- mx_bluesky/common/parameters/constants.py +143 -0
- mx_bluesky/common/parameters/gridscan.py +94 -0
- mx_bluesky/common/parameters/robot_load.py +16 -0
- mx_bluesky/common/plans/__init__.py +1 -0
- mx_bluesky/common/plans/do_fgs.py +121 -0
- mx_bluesky/common/utils/log.py +118 -0
- mx_bluesky/{hyperion → common/utils}/tracing.py +2 -2
- mx_bluesky/hyperion/__main__.py +13 -10
- mx_bluesky/hyperion/device_setup_plans/dcm_pitch_roll_mirror_adjuster.py +47 -52
- mx_bluesky/hyperion/device_setup_plans/read_hardware_for_setup.py +6 -12
- mx_bluesky/hyperion/device_setup_plans/setup_oav.py +6 -12
- mx_bluesky/hyperion/device_setup_plans/setup_panda.py +5 -6
- mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +49 -18
- mx_bluesky/hyperion/device_setup_plans/smargon.py +9 -9
- mx_bluesky/hyperion/device_setup_plans/utils.py +2 -2
- mx_bluesky/hyperion/device_setup_plans/xbpm_feedback.py +4 -4
- mx_bluesky/hyperion/exceptions.py +13 -1
- mx_bluesky/hyperion/experiment_plans/__init__.py +4 -0
- mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py +83 -0
- mx_bluesky/hyperion/experiment_plans/common/xrc_result.py +47 -0
- mx_bluesky/hyperion/experiment_plans/experiment_registry.py +9 -9
- mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +147 -169
- mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +48 -22
- mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +75 -9
- mx_bluesky/hyperion/experiment_plans/oav_grid_detection_plan.py +21 -20
- mx_bluesky/hyperion/experiment_plans/oav_snapshot_plan.py +9 -6
- mx_bluesky/hyperion/experiment_plans/optimise_attenuation_plan.py +2 -2
- mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +40 -21
- mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +22 -22
- mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +43 -39
- mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +69 -18
- mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +17 -7
- mx_bluesky/hyperion/experiment_plans/set_energy_plan.py +13 -13
- mx_bluesky/hyperion/external_interaction/callbacks/__init__.py +0 -4
- mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +5 -2
- mx_bluesky/hyperion/external_interaction/callbacks/common/abstract_event.py +66 -0
- mx_bluesky/hyperion/external_interaction/callbacks/common/callback_util.py +5 -0
- mx_bluesky/hyperion/external_interaction/callbacks/common/ispyb_mapping.py +1 -1
- mx_bluesky/hyperion/external_interaction/callbacks/grid_detection_callback.py +30 -25
- mx_bluesky/hyperion/external_interaction/callbacks/ispyb_callback_base.py +29 -12
- mx_bluesky/hyperion/external_interaction/callbacks/log_uid_tag_callback.py +1 -1
- mx_bluesky/hyperion/external_interaction/callbacks/robot_load/ispyb_callback.py +19 -11
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +7 -4
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/nexus_callback.py +5 -3
- mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/__init__.py +0 -0
- mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/sample_handling_callback.py +84 -0
- mx_bluesky/hyperion/external_interaction/callbacks/xray_centre/ispyb_callback.py +38 -27
- mx_bluesky/hyperion/external_interaction/callbacks/xray_centre/nexus_callback.py +5 -4
- mx_bluesky/hyperion/external_interaction/config_server.py +11 -28
- mx_bluesky/hyperion/external_interaction/exceptions.py +0 -9
- mx_bluesky/hyperion/external_interaction/ispyb/exp_eye_store.py +65 -15
- mx_bluesky/hyperion/external_interaction/ispyb/ispyb_store.py +1 -1
- mx_bluesky/hyperion/external_interaction/nexus/nexus_utils.py +2 -2
- mx_bluesky/hyperion/external_interaction/nexus/write_nexus.py +1 -1
- mx_bluesky/hyperion/log.py +0 -84
- mx_bluesky/hyperion/parameters/components.py +4 -251
- mx_bluesky/hyperion/parameters/constants.py +22 -119
- mx_bluesky/hyperion/parameters/gridscan.py +35 -74
- mx_bluesky/hyperion/parameters/load_centre_collect.py +16 -11
- mx_bluesky/hyperion/parameters/rotation.py +23 -10
- mx_bluesky/hyperion/utils/utils.py +17 -0
- mx_bluesky/hyperion/utils/validation.py +5 -6
- {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.1.dist-info}/METADATA +36 -33
- {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.1.dist-info}/RECORD +102 -89
- {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.1.dist-info}/WHEEL +1 -1
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Mapping_py3v1.py +0 -161
- mx_bluesky/example.py +0 -19
- mx_bluesky/hyperion/parameters/robot_load.py +0 -16
- {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.1.dist-info}/LICENSE +0 -0
- {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.1.dist-info}/entry_points.txt +0 -0
- {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.1.dist-info}/top_level.txt +0 -0
|
@@ -2,34 +2,20 @@
|
|
|
2
2
|
Startup utilities for chip
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
import logging
|
|
6
|
-
import os
|
|
7
5
|
import string
|
|
8
|
-
import time
|
|
9
6
|
from pathlib import Path
|
|
10
7
|
|
|
11
|
-
import numpy as np
|
|
12
|
-
|
|
13
|
-
from mx_bluesky.beamlines.i24.serial import log
|
|
14
8
|
from mx_bluesky.beamlines.i24.serial.fixed_target.ft_utils import ChipType
|
|
9
|
+
from mx_bluesky.beamlines.i24.serial.log import SSX_LOGGER, log_on_entry
|
|
15
10
|
from mx_bluesky.beamlines.i24.serial.parameters import (
|
|
16
11
|
FixedTargetParameters,
|
|
17
12
|
get_chip_format,
|
|
18
13
|
)
|
|
19
14
|
from mx_bluesky.beamlines.i24.serial.parameters.constants import (
|
|
20
|
-
HEADER_FILES_PATH,
|
|
21
15
|
PARAM_FILE_NAME,
|
|
22
16
|
PARAM_FILE_PATH_FT,
|
|
23
17
|
)
|
|
24
18
|
|
|
25
|
-
logger = logging.getLogger("I24ssx.chip_startup")
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def setup_logging():
|
|
29
|
-
# Log should now change name daily.
|
|
30
|
-
logfile = time.strftime("i24fixedtarget_%d%B%y.log").lower()
|
|
31
|
-
log.config(logfile)
|
|
32
|
-
|
|
33
19
|
|
|
34
20
|
def read_parameter_file(
|
|
35
21
|
param_path: Path | str = PARAM_FILE_PATH_FT,
|
|
@@ -41,44 +27,19 @@ def read_parameter_file(
|
|
|
41
27
|
return params
|
|
42
28
|
|
|
43
29
|
|
|
44
|
-
@
|
|
30
|
+
@log_on_entry
|
|
45
31
|
def fiducials(chip_type: int):
|
|
46
32
|
fiducial_list: list | None = None
|
|
47
33
|
if chip_type in [ChipType.Oxford, ChipType.OxfordInner, ChipType.Minichip]:
|
|
48
34
|
fiducial_list = []
|
|
49
35
|
elif chip_type == ChipType.Custom:
|
|
50
36
|
# No fiducial for custom
|
|
51
|
-
|
|
37
|
+
SSX_LOGGER.warning("No fiducials for custom chip")
|
|
52
38
|
else:
|
|
53
|
-
|
|
39
|
+
SSX_LOGGER.warning(f"Unknown chip_type, {chip_type}, in fiducials")
|
|
54
40
|
return fiducial_list
|
|
55
41
|
|
|
56
42
|
|
|
57
|
-
def get_xy(addr: str, chip_type: ChipType):
|
|
58
|
-
entry = addr.split("_")[-2:]
|
|
59
|
-
R, C = entry[0][0], entry[0][1]
|
|
60
|
-
r2, c2 = entry[1][0], entry[1][1]
|
|
61
|
-
blockR = string.ascii_uppercase.index(R)
|
|
62
|
-
blockC = int(C) - 1
|
|
63
|
-
lowercase_list = list(string.ascii_lowercase + string.ascii_uppercase + "0")
|
|
64
|
-
windowR = lowercase_list.index(r2)
|
|
65
|
-
windowC = lowercase_list.index(c2)
|
|
66
|
-
|
|
67
|
-
chip_params = get_chip_format(chip_type)
|
|
68
|
-
|
|
69
|
-
x = (
|
|
70
|
-
(blockC * chip_params.b2b_horz)
|
|
71
|
-
+ (blockC * (chip_params.x_num_steps - 1) * chip_params.x_step_size)
|
|
72
|
-
+ (windowC * chip_params.x_step_size)
|
|
73
|
-
)
|
|
74
|
-
y = (
|
|
75
|
-
(blockR * chip_params.b2b_vert)
|
|
76
|
-
+ (blockR * (chip_params.y_num_steps - 1) * chip_params.y_step_size)
|
|
77
|
-
+ (windowR * chip_params.y_step_size)
|
|
78
|
-
)
|
|
79
|
-
return x, y
|
|
80
|
-
|
|
81
|
-
|
|
82
43
|
def pathli(l_in=None, way="typewriter", reverse=False):
|
|
83
44
|
if l_in is None:
|
|
84
45
|
l_in = []
|
|
@@ -118,9 +79,9 @@ def pathli(l_in=None, way="typewriter", reverse=False):
|
|
|
118
79
|
for _ in range(25):
|
|
119
80
|
long_list.append(entry)
|
|
120
81
|
else:
|
|
121
|
-
|
|
82
|
+
SSX_LOGGER.warning(f"No known path, way = {way}")
|
|
122
83
|
else:
|
|
123
|
-
|
|
84
|
+
SSX_LOGGER.warning("No list written")
|
|
124
85
|
return long_list
|
|
125
86
|
|
|
126
87
|
|
|
@@ -154,175 +115,5 @@ def get_alphanumeric(chip_type: ChipType):
|
|
|
154
115
|
for block in block_list:
|
|
155
116
|
for window in window_list:
|
|
156
117
|
alphanumeric_list.append(block + "_" + window)
|
|
157
|
-
|
|
118
|
+
SSX_LOGGER.info(f"Length of alphanumeric list = {len(alphanumeric_list)}")
|
|
158
119
|
return alphanumeric_list
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
@log.log_on_entry
|
|
162
|
-
def get_shot_order(chip_type: ChipType):
|
|
163
|
-
cell_format = get_chip_format(chip_type)
|
|
164
|
-
blk_num = cell_format.x_blocks
|
|
165
|
-
wnd_num = cell_format.x_num_steps
|
|
166
|
-
uppercase_list = list(string.ascii_uppercase)[:blk_num]
|
|
167
|
-
number_list = [str(x) for x in range(1, blk_num + 1)]
|
|
168
|
-
lowercase_list = list(string.ascii_lowercase + string.ascii_uppercase + "0")[
|
|
169
|
-
:wnd_num
|
|
170
|
-
]
|
|
171
|
-
|
|
172
|
-
block_list = zippum([uppercase_list, "snake", 0], [number_list, "expand", 0])
|
|
173
|
-
window_dn = zippum([lowercase_list, "expand", 0], [lowercase_list, "snake", 0])
|
|
174
|
-
window_up = zippum([lowercase_list, "expand", 1], [lowercase_list, "snake", 0])
|
|
175
|
-
|
|
176
|
-
switch = 0
|
|
177
|
-
count = 0
|
|
178
|
-
collect_list = []
|
|
179
|
-
for block in block_list:
|
|
180
|
-
if switch == 0:
|
|
181
|
-
for window in window_dn:
|
|
182
|
-
collect_list.append(block + "_" + window)
|
|
183
|
-
count += 1
|
|
184
|
-
if count == blk_num:
|
|
185
|
-
count = 0
|
|
186
|
-
switch = 1
|
|
187
|
-
else:
|
|
188
|
-
for window in window_up:
|
|
189
|
-
collect_list.append(block + "_" + window)
|
|
190
|
-
count += 1
|
|
191
|
-
if count == blk_num:
|
|
192
|
-
count = 0
|
|
193
|
-
switch = 0
|
|
194
|
-
|
|
195
|
-
logger.info(f"Length of collect list = {len(collect_list)}")
|
|
196
|
-
return collect_list
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
@log.log_on_entry
|
|
200
|
-
def write_file(
|
|
201
|
-
location: str = "i24",
|
|
202
|
-
suffix: str = ".addr",
|
|
203
|
-
order: str = "alphanumeric",
|
|
204
|
-
param_file_path: Path = PARAM_FILE_PATH_FT,
|
|
205
|
-
save_path: Path = HEADER_FILES_PATH,
|
|
206
|
-
):
|
|
207
|
-
if location == "i24":
|
|
208
|
-
params = read_parameter_file(param_file_path)
|
|
209
|
-
else:
|
|
210
|
-
msg = f"Unknown location, {location}"
|
|
211
|
-
logger.error(msg)
|
|
212
|
-
raise ValueError(msg)
|
|
213
|
-
chip_file_path = save_path / f"chips/{params.directory}/{params.filename}{suffix}"
|
|
214
|
-
|
|
215
|
-
fiducial_list = fiducials(params.chip.chip_type.value)
|
|
216
|
-
|
|
217
|
-
if order == "alphanumeric":
|
|
218
|
-
addr_list = get_alphanumeric(params.chip.chip_type)
|
|
219
|
-
elif order == "shot":
|
|
220
|
-
addr_list = get_shot_order(params.chip.chip_type)
|
|
221
|
-
else:
|
|
222
|
-
raise ValueError(f"{order=} unrecognised")
|
|
223
|
-
|
|
224
|
-
with open(chip_file_path, "a") as g:
|
|
225
|
-
for addr in addr_list:
|
|
226
|
-
xtal_name = "_".join([params.filename, addr])
|
|
227
|
-
(x, y) = get_xy(xtal_name, params.chip.chip_type)
|
|
228
|
-
if addr in fiducial_list:
|
|
229
|
-
pres = "0"
|
|
230
|
-
else:
|
|
231
|
-
if "rand" in suffix:
|
|
232
|
-
pres = str(np.random.randint(2))
|
|
233
|
-
else:
|
|
234
|
-
pres = "-1"
|
|
235
|
-
line = "\t".join([xtal_name, str(x), str(y), "0.0", pres]) + "\n"
|
|
236
|
-
g.write(line)
|
|
237
|
-
|
|
238
|
-
logger.info(f"Write {chip_file_path} completed")
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
@log.log_on_entry
|
|
242
|
-
def check_files(
|
|
243
|
-
location: str,
|
|
244
|
-
suffix_list: list[str],
|
|
245
|
-
param_file_path: Path | str = PARAM_FILE_PATH_FT,
|
|
246
|
-
save_path: Path = HEADER_FILES_PATH,
|
|
247
|
-
):
|
|
248
|
-
if location == "i24":
|
|
249
|
-
params = read_parameter_file(param_file_path)
|
|
250
|
-
else:
|
|
251
|
-
msg = f"Unknown location, {location}"
|
|
252
|
-
logger.error(msg)
|
|
253
|
-
raise ValueError(msg)
|
|
254
|
-
chip_file_path = save_path / f"chips/{params.directory}/{params.filename}"
|
|
255
|
-
|
|
256
|
-
try:
|
|
257
|
-
os.stat(chip_file_path)
|
|
258
|
-
except Exception:
|
|
259
|
-
os.makedirs(chip_file_path)
|
|
260
|
-
for suffix in suffix_list:
|
|
261
|
-
full_fid = chip_file_path.with_suffix(suffix)
|
|
262
|
-
if full_fid.is_file():
|
|
263
|
-
time_str = time.strftime("%Y%m%d_%H%M%S_")
|
|
264
|
-
timestamp_fid = ( # noqa: F841
|
|
265
|
-
full_fid.parent / f"{time_str}_{params.filename}{full_fid.suffix}"
|
|
266
|
-
)
|
|
267
|
-
# FIXME hack / fix. Actually move the file
|
|
268
|
-
logger.info(f"File {full_fid} Already Exists")
|
|
269
|
-
logger.debug("Check files done")
|
|
270
|
-
return 1
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
@log.log_on_entry
|
|
274
|
-
def write_headers(
|
|
275
|
-
location: str,
|
|
276
|
-
suffix_list: list[str],
|
|
277
|
-
param_file_path: Path = PARAM_FILE_PATH_FT,
|
|
278
|
-
save_path: Path = HEADER_FILES_PATH,
|
|
279
|
-
):
|
|
280
|
-
if location == "i24":
|
|
281
|
-
params = read_parameter_file(param_file_path)
|
|
282
|
-
chip_file_path = save_path / f"chips/{params.directory}/{params.filename}"
|
|
283
|
-
|
|
284
|
-
for suffix in suffix_list:
|
|
285
|
-
full_fid = chip_file_path.with_suffix(suffix)
|
|
286
|
-
with open(full_fid, "w") as g:
|
|
287
|
-
g.write(
|
|
288
|
-
"#23456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\n#\n"
|
|
289
|
-
)
|
|
290
|
-
g.write(f"#&i24\tchip_name = {params.filename}\n")
|
|
291
|
-
g.write(f"#&i24\tvisit = {params.visit}\n")
|
|
292
|
-
g.write(f"#&i24\tsub_dir = {params.directory}\n")
|
|
293
|
-
g.write(f"#&i24\tn_exposures = {params.num_exposures}\n")
|
|
294
|
-
g.write(f"#&i24\tchip_type = {params.chip.chip_type.value}\n")
|
|
295
|
-
g.write(f"#&i24\tmap_type = {params.map_type.value}\n")
|
|
296
|
-
g.write(f"#&i24\tpump_repeat = {params.pump_repeat.value}\n")
|
|
297
|
-
g.write(f"#&i24\tpumpexptime = {params.laser_dwell_s}\n")
|
|
298
|
-
g.write(f"#&i24\texptime = {params.laser_delay_s}\n")
|
|
299
|
-
g.write(f"#&i24\tdcdetdist = {params.detector_distance_mm}\n")
|
|
300
|
-
g.write(f"#&i24\tprepumpexptime = {params.pre_pump_exposure_s}\n")
|
|
301
|
-
g.write(f"#&i24\tdet_Type = {params.detector_name}\n")
|
|
302
|
-
g.write("#\n")
|
|
303
|
-
g.write(
|
|
304
|
-
"#XtalAddr XCoord YCoord ZCoord Present Shot Spare04 Spare03 Spare02 Spare01\n"
|
|
305
|
-
)
|
|
306
|
-
else:
|
|
307
|
-
msg = f"Unknown location, {location}"
|
|
308
|
-
logger.error(msg)
|
|
309
|
-
raise ValueError(msg)
|
|
310
|
-
logger.debug("Write headers done")
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
def run():
|
|
314
|
-
logger.debug("Run Startup")
|
|
315
|
-
check_files("i24", [".addr", ".shot"])
|
|
316
|
-
logger.info("Checked Files")
|
|
317
|
-
write_headers("i24", [".addr", ".shot"])
|
|
318
|
-
logger.info("Written Headers")
|
|
319
|
-
logger.info("Writing to Files has been disabled. Headers Only")
|
|
320
|
-
# Makes a file with random crystal positions
|
|
321
|
-
check_files("i24", ["rando.spec"])
|
|
322
|
-
write_headers("i24", ["rando.spec"])
|
|
323
|
-
logger.debug("StartUp Done")
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
if __name__ == "__main__":
|
|
327
|
-
setup_logging()
|
|
328
|
-
run()
|
|
@@ -3,7 +3,6 @@ Move on click gui for fixed targets at I24
|
|
|
3
3
|
Robin Owen 12 Jan 2021
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
import logging
|
|
7
6
|
from collections.abc import Sequence
|
|
8
7
|
|
|
9
8
|
import bluesky.plan_stubs as bps
|
|
@@ -17,10 +16,9 @@ from mx_bluesky.beamlines.i24.serial.fixed_target import (
|
|
|
17
16
|
i24ssx_Chip_Manager_py3v1 as manager,
|
|
18
17
|
)
|
|
19
18
|
from mx_bluesky.beamlines.i24.serial.fixed_target.ft_utils import Fiducials
|
|
19
|
+
from mx_bluesky.beamlines.i24.serial.log import SSX_LOGGER
|
|
20
20
|
from mx_bluesky.beamlines.i24.serial.parameters.constants import OAV1_CAM
|
|
21
21
|
|
|
22
|
-
logger = logging.getLogger("I24ssx.moveonclick")
|
|
23
|
-
|
|
24
22
|
|
|
25
23
|
def _get_beam_centre(oav: OAV):
|
|
26
24
|
"""Extract the beam centre x/y positions from the display.configuration file.
|
|
@@ -28,28 +26,32 @@ def _get_beam_centre(oav: OAV):
|
|
|
28
26
|
Args:
|
|
29
27
|
oav (OAV): the OAV device.
|
|
30
28
|
"""
|
|
31
|
-
|
|
29
|
+
beam_x = yield from bps.rd(oav.beam_centre_i)
|
|
30
|
+
beam_y = yield from bps.rd(oav.beam_centre_j)
|
|
31
|
+
return beam_x, beam_y
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
def _calculate_zoom_calibrator(oav: OAV):
|
|
35
35
|
"""Set the scale for the zoom calibrator for the pmac moves."""
|
|
36
|
-
currentzoom = yield from bps.rd(oav.zoom_controller.percentage)
|
|
36
|
+
currentzoom = yield from bps.rd(oav.zoom_controller.percentage) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
|
|
37
37
|
zoomcalibrator = 1.547 - (0.03 * currentzoom) + (0.0001634 * currentzoom**2)
|
|
38
38
|
return zoomcalibrator
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
def _move_on_mouse_click_plan(
|
|
42
|
-
oav: OAV,
|
|
42
|
+
oav: OAV,
|
|
43
|
+
pmac: PMAC,
|
|
44
|
+
clicked_position: Sequence[int],
|
|
43
45
|
):
|
|
44
46
|
"""A plan that calculates the zoom calibrator and moves to the clicked \
|
|
45
47
|
position coordinates.
|
|
46
48
|
"""
|
|
47
49
|
zoomcalibrator = yield from _calculate_zoom_calibrator(oav)
|
|
48
|
-
beamX, beamY =
|
|
50
|
+
beamX, beamY = yield from _get_beam_centre(oav)
|
|
49
51
|
x, y = clicked_position
|
|
50
52
|
xmove = -1 * (beamX - x) * zoomcalibrator
|
|
51
|
-
ymove =
|
|
52
|
-
|
|
53
|
+
ymove = 1 * (beamY - y) * zoomcalibrator
|
|
54
|
+
SSX_LOGGER.info(f"Moving X and Y {xmove} {ymove}")
|
|
53
55
|
xmovepmacstring = "#1J:" + str(xmove)
|
|
54
56
|
ymovepmacstring = "#2J:" + str(ymove)
|
|
55
57
|
yield from bps.abs_set(pmac.pmac_string, xmovepmacstring, wait=True)
|
|
@@ -62,14 +64,13 @@ def onMouse(event, x, y, flags, param):
|
|
|
62
64
|
RE = param[0]
|
|
63
65
|
pmac = param[1]
|
|
64
66
|
oav = param[2]
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
RE(_move_on_mouse_click_plan(oav, pmac, (beamX, beamY), (x, y)))
|
|
67
|
+
SSX_LOGGER.info(f"Clicked X and Y {x} {y}")
|
|
68
|
+
RE(_move_on_mouse_click_plan(oav, pmac, (x, y)))
|
|
68
69
|
|
|
69
70
|
|
|
70
|
-
def update_ui(oav, frame):
|
|
71
|
+
def update_ui(oav, frame, RE):
|
|
71
72
|
# Get beam x and y values
|
|
72
|
-
beamX, beamY = _get_beam_centre(oav)
|
|
73
|
+
beamX, beamY = RE(_get_beam_centre(oav)).plan_result
|
|
73
74
|
|
|
74
75
|
# Overlay text and beam centre
|
|
75
76
|
cv.ellipse(
|
|
@@ -156,7 +157,7 @@ def start_viewer(oav: OAV, pmac: PMAC, RE: RunEngine, oav1: str = OAV1_CAM):
|
|
|
156
157
|
cv.namedWindow("OAV1view")
|
|
157
158
|
cv.setMouseCallback("OAV1view", onMouse, param=[RE, pmac, oav]) # type: ignore
|
|
158
159
|
|
|
159
|
-
|
|
160
|
+
SSX_LOGGER.info("Showing camera feed. Press escape to close")
|
|
160
161
|
# Read captured video and store them in success and frame
|
|
161
162
|
success, frame = cap.read()
|
|
162
163
|
|
|
@@ -164,7 +165,7 @@ def start_viewer(oav: OAV, pmac: PMAC, RE: RunEngine, oav1: str = OAV1_CAM):
|
|
|
164
165
|
while success:
|
|
165
166
|
success, frame = cap.read()
|
|
166
167
|
|
|
167
|
-
update_ui(oav, frame)
|
|
168
|
+
update_ui(oav, frame, RE)
|
|
168
169
|
|
|
169
170
|
k = cv.waitKey(1)
|
|
170
171
|
if k == 113: # Q
|
|
@@ -212,7 +213,7 @@ def start_viewer(oav: OAV, pmac: PMAC, RE: RunEngine, oav1: str = OAV1_CAM):
|
|
|
212
213
|
|
|
213
214
|
|
|
214
215
|
if __name__ == "__main__":
|
|
215
|
-
RE = RunEngine()
|
|
216
|
+
RE = RunEngine(call_returns_result=True)
|
|
216
217
|
# Get devices out of dodal
|
|
217
218
|
oav: OAV = i24.oav()
|
|
218
219
|
pmac: PMAC = i24.pmac()
|
|
@@ -1,39 +1,30 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
import logging
|
|
3
3
|
import logging.config
|
|
4
|
+
import time
|
|
4
5
|
from os import environ
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
)
|
|
8
|
+
import bluesky.plan_stubs as bps
|
|
9
|
+
from bluesky.log import logger as bluesky_logger
|
|
10
|
+
from bluesky.utils import MsgGenerator
|
|
11
|
+
from dodal.log import DEFAULT_GRAYLOG_PORT, ophyd_async_logger
|
|
12
12
|
from dodal.log import LOGGER as dodal_logger
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class OphydDebugFilter(logging.Filter): # NOTE yet to be fully tested
|
|
18
|
-
"""Do not send ophyd debug log messages to stream handler."""
|
|
14
|
+
from mx_bluesky.common.utils.log import do_default_logging_setup
|
|
19
15
|
|
|
20
|
-
|
|
21
|
-
return "ophyd" not in record.getMessage().lower()
|
|
16
|
+
VISIT_PATH = Path("/dls_sw/i24/etc/ssx_current_visit.txt")
|
|
22
17
|
|
|
23
18
|
|
|
24
19
|
# Logging set up
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
SSX_LOGGER = logging.getLogger("I24serial")
|
|
21
|
+
SSX_LOGGER.addHandler(logging.NullHandler())
|
|
22
|
+
SSX_LOGGER.parent = dodal_logger
|
|
23
|
+
|
|
28
24
|
|
|
29
25
|
logging_config = {
|
|
30
26
|
"version": 1,
|
|
31
27
|
"disable_existing_loggers": False,
|
|
32
|
-
"filters": {
|
|
33
|
-
"ophyd_filter": {
|
|
34
|
-
"()": OphydDebugFilter,
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
28
|
"formatters": {
|
|
38
29
|
"default": {
|
|
39
30
|
"class": "logging.Formatter",
|
|
@@ -42,18 +33,17 @@ logging_config = {
|
|
|
42
33
|
},
|
|
43
34
|
"handlers": {
|
|
44
35
|
"console": {
|
|
45
|
-
"level": "
|
|
36
|
+
"level": "INFO",
|
|
46
37
|
"class": "logging.StreamHandler",
|
|
47
38
|
"formatter": "default",
|
|
48
|
-
"filters": ["ophyd_filter"],
|
|
49
39
|
"stream": "ext://sys.stdout",
|
|
50
40
|
}
|
|
51
41
|
},
|
|
52
42
|
"loggers": {
|
|
53
|
-
"
|
|
43
|
+
"I24serial": {
|
|
54
44
|
"handlers": ["console"],
|
|
55
45
|
"level": "DEBUG",
|
|
56
|
-
"propagate":
|
|
46
|
+
"propagate": False,
|
|
57
47
|
}
|
|
58
48
|
},
|
|
59
49
|
}
|
|
@@ -68,10 +58,8 @@ def _read_visit_directory_from_file() -> Path:
|
|
|
68
58
|
|
|
69
59
|
|
|
70
60
|
def _get_logging_file_path() -> Path:
|
|
71
|
-
"""Get the path to write the
|
|
72
|
-
If on a beamline, this will be written to the
|
|
73
|
-
BEAMLINE envrionment variable. If no envrionment variable is found it will default
|
|
74
|
-
it to the tmp/dev directory.
|
|
61
|
+
"""Get the path to write the serial experiment specific log file to.
|
|
62
|
+
If on a beamline, this will be written to the tmp folder in the current visit.
|
|
75
63
|
Returns:
|
|
76
64
|
logging_path (Path): Path to the log file for the file handler to write to.
|
|
77
65
|
"""
|
|
@@ -87,24 +75,11 @@ def _get_logging_file_path() -> Path:
|
|
|
87
75
|
return logging_path
|
|
88
76
|
|
|
89
77
|
|
|
90
|
-
def
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
- Remove dodal stream handler to avoid double messages (for now, use only the \
|
|
96
|
-
i24ssx default stream to keep the output expected by the scientists.)
|
|
97
|
-
"""
|
|
98
|
-
handlers = set_up_all_logging_handlers( # noqa: F841
|
|
99
|
-
dodal_logger,
|
|
100
|
-
_get_logging_file_path(),
|
|
101
|
-
"dodal.log",
|
|
102
|
-
dev_mode,
|
|
103
|
-
ERROR_LOG_BUFFER_LINES,
|
|
104
|
-
)
|
|
105
|
-
integrate_bluesky_and_ophyd_logging(dodal_logger)
|
|
106
|
-
# Remove dodal StreamHandler to avoid duplication of messages above debug
|
|
107
|
-
dodal_logger.removeHandler(dodal_logger.handlers[0])
|
|
78
|
+
def _integrate_bluesky_logs(parent_logger: logging.Logger):
|
|
79
|
+
# Integrate only bluesky and ophyd_async logger
|
|
80
|
+
for log in [bluesky_logger, ophyd_async_logger]:
|
|
81
|
+
log.parent = parent_logger
|
|
82
|
+
log.setLevel(logging.DEBUG)
|
|
108
83
|
|
|
109
84
|
|
|
110
85
|
def config(
|
|
@@ -124,7 +99,15 @@ def config(
|
|
|
124
99
|
dev_mode (bool, optional): If true, will log to graylog on localhost instead \
|
|
125
100
|
of production. Defaults to False.
|
|
126
101
|
"""
|
|
127
|
-
|
|
102
|
+
do_default_logging_setup(
|
|
103
|
+
"mx-bluesky.log",
|
|
104
|
+
DEFAULT_GRAYLOG_PORT,
|
|
105
|
+
dev_mode=dev_mode,
|
|
106
|
+
integrate_all_logs=False,
|
|
107
|
+
)
|
|
108
|
+
# Remove dodal StreamHandler to avoid duplication of messages above debug
|
|
109
|
+
dodal_logger.removeHandler(dodal_logger.handlers[0])
|
|
110
|
+
_integrate_bluesky_logs(dodal_logger)
|
|
128
111
|
|
|
129
112
|
if logfile:
|
|
130
113
|
logs = _get_logging_file_path() / logfile
|
|
@@ -135,14 +118,40 @@ def config(
|
|
|
135
118
|
FH = logging.FileHandler(logs, mode=write_mode, encoding="utf-8", delay=delayed)
|
|
136
119
|
FH.setLevel(logging.DEBUG)
|
|
137
120
|
FH.setFormatter(fileFormatter)
|
|
138
|
-
|
|
121
|
+
SSX_LOGGER.addHandler(FH)
|
|
139
122
|
|
|
140
123
|
|
|
141
124
|
def log_on_entry(func):
|
|
142
125
|
@functools.wraps(func)
|
|
143
126
|
def decorator(*args, **kwargs):
|
|
144
127
|
name = func.__name__
|
|
145
|
-
|
|
128
|
+
SSX_LOGGER.debug(f"Running {name} ")
|
|
146
129
|
return func(*args, **kwargs)
|
|
147
130
|
|
|
148
131
|
return decorator
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def setup_collection_logs(expt: str, dev_mode: bool = False) -> MsgGenerator:
|
|
135
|
+
"""A small plan to set up the logging from blueapi on start up as we're running \
|
|
136
|
+
on procserv.
|
|
137
|
+
This setup will likely change once the beamline has a cluster.
|
|
138
|
+
"""
|
|
139
|
+
if (
|
|
140
|
+
expt == "Serial Fixed"
|
|
141
|
+
): # SSXType.FIXED: See https://github.com/DiamondLightSource/mx-bluesky/issues/608
|
|
142
|
+
logfile = time.strftime("i24fixedtarget_%d%B%y.log").lower()
|
|
143
|
+
else:
|
|
144
|
+
logfile = time.strftime("i24extruder_%d%B%y.log").lower()
|
|
145
|
+
|
|
146
|
+
config(logfile, dev_mode=dev_mode)
|
|
147
|
+
yield from bps.null()
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def clean_up_log_config_at_end() -> MsgGenerator:
|
|
151
|
+
"""A small plan for blueapi to tidy up logging configuration."""
|
|
152
|
+
# See https://github.com/DiamondLightSource/mx-bluesky/issues/609
|
|
153
|
+
for handler in SSX_LOGGER.handlers:
|
|
154
|
+
SSX_LOGGER.removeHandler(handler)
|
|
155
|
+
for handler in dodal_logger.handlers:
|
|
156
|
+
dodal_logger.removeHandler(handler)
|
|
157
|
+
yield from bps.null()
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
from mx_bluesky.beamlines.i24.serial.parameters.constants import SSXType
|
|
2
2
|
from mx_bluesky.beamlines.i24.serial.parameters.experiment_parameters import (
|
|
3
|
+
BeamSettings,
|
|
3
4
|
ChipDescription,
|
|
4
5
|
ExtruderParameters,
|
|
5
6
|
FixedTargetParameters,
|
|
7
|
+
SerialAndLaserExperiment,
|
|
6
8
|
)
|
|
7
9
|
from mx_bluesky.beamlines.i24.serial.parameters.utils import get_chip_format
|
|
8
10
|
|
|
9
11
|
__all__ = [
|
|
10
12
|
"SSXType",
|
|
13
|
+
"BeamSettings",
|
|
11
14
|
"ExtruderParameters",
|
|
12
15
|
"ChipDescription",
|
|
13
16
|
"FixedTargetParameters",
|
|
17
|
+
"SerialAndLaserExperiment",
|
|
14
18
|
"get_chip_format",
|
|
15
19
|
]
|
|
@@ -10,6 +10,12 @@ class SSXType(Enum):
|
|
|
10
10
|
EXTRUDER = "Serial Jet"
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
BEAM_CENTER_POS: dict[str, list] = {
|
|
14
|
+
"eiger": [1600.0, 1697.4],
|
|
15
|
+
"pilatus": [1284.7, 1308.6],
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
13
19
|
OAV_CONFIG_FILES = {
|
|
14
20
|
"zoom_params_file": "/dls_sw/i24/software/gda_versions/gda_9_34/config/xml/jCameraManZoomLevels.xml",
|
|
15
21
|
"oav_config_json": "/dls_sw/i24/software/daq_configuration/json/OAVCentring.json",
|
|
@@ -41,7 +47,6 @@ PARAM_FILE_NAME = "parameters.json"
|
|
|
41
47
|
PARAM_FILE_PATH = _params_file_location()
|
|
42
48
|
PARAM_FILE_PATH_FT = PARAM_FILE_PATH / "fixed_target"
|
|
43
49
|
LITEMAP_PATH = PARAM_FILE_PATH_FT / "litemaps"
|
|
44
|
-
FULLMAP_PATH = PARAM_FILE_PATH_FT / "fullmaps"
|
|
45
50
|
# Paths for r only
|
|
46
51
|
PVAR_FILE_PATH = INTERNAL_FILES_PATH / "fixed_target/pvar_files"
|
|
47
52
|
CS_FILES_PATH = INTERNAL_FILES_PATH / "fixed_target/cs"
|