mx-bluesky 1.4.1a0__py3-none-any.whl → 1.4.3__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/_version.py +2 -2
- mx_bluesky/beamlines/i04/redis_to_murko_forwarder.py +178 -0
- mx_bluesky/beamlines/i24/serial/__init__.py +0 -6
- mx_bluesky/beamlines/i24/serial/dcid.py +125 -151
- 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 +88 -43
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/DiamondChipI24-py3v1.edl +1 -1
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/MappingLite-oxford_py3v1.edl +2 -46
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +85 -122
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +58 -66
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_StartUp_py3v1.py +1 -19
- mx_bluesky/beamlines/i24/serial/parameters/__init__.py +11 -2
- mx_bluesky/beamlines/i24/serial/parameters/constants.py +16 -2
- mx_bluesky/beamlines/i24/serial/parameters/experiment_parameters.py +94 -19
- mx_bluesky/beamlines/i24/serial/parameters/utils.py +19 -0
- mx_bluesky/beamlines/i24/serial/setup_beamline/pv.py +2 -0
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +61 -8
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_zebra_plans.py +81 -40
- mx_bluesky/beamlines/i24/serial/write_nexus.py +66 -67
- mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/aperture_change_callback.py +1 -1
- mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/grid_detection_callback.py +19 -1
- mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/ispyb_callback_base.py +40 -34
- mx_bluesky/{hyperion → common}/external_interaction/callbacks/common/ispyb_mapping.py +4 -4
- mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/logging_callback.py +1 -1
- mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/zocalo_callback.py +14 -9
- mx_bluesky/{hyperion → common}/external_interaction/callbacks/xray_centre/ispyb_callback.py +46 -38
- mx_bluesky/{hyperion → common}/external_interaction/callbacks/xray_centre/ispyb_mapping.py +2 -2
- mx_bluesky/{hyperion → common}/external_interaction/callbacks/xray_centre/nexus_callback.py +20 -15
- mx_bluesky/common/external_interaction/config_server.py +11 -0
- mx_bluesky/common/external_interaction/ispyb/__init__.py +0 -0
- mx_bluesky/{hyperion → common}/external_interaction/ispyb/data_model.py +2 -0
- mx_bluesky/{hyperion → common}/external_interaction/ispyb/exp_eye_store.py +67 -17
- mx_bluesky/{hyperion → common}/external_interaction/ispyb/ispyb_store.py +20 -18
- mx_bluesky/{hyperion → common}/external_interaction/ispyb/ispyb_utils.py +2 -2
- mx_bluesky/common/external_interaction/nexus/__init__.py +0 -0
- mx_bluesky/{hyperion → common}/external_interaction/nexus/nexus_utils.py +21 -6
- mx_bluesky/{hyperion → common}/external_interaction/nexus/write_nexus.py +5 -5
- mx_bluesky/common/external_interaction/test_config_server.py +38 -0
- mx_bluesky/common/parameters/components.py +10 -8
- mx_bluesky/common/parameters/constants.py +6 -0
- mx_bluesky/common/parameters/gridscan.py +102 -53
- mx_bluesky/common/plans/do_fgs.py +4 -4
- mx_bluesky/{hyperion → common/utils}/exceptions.py +27 -1
- mx_bluesky/common/utils/log.py +17 -7
- mx_bluesky/hyperion/__main__.py +15 -14
- mx_bluesky/hyperion/device_setup_plans/check_beamstop.py +27 -0
- mx_bluesky/hyperion/device_setup_plans/dcm_pitch_roll_mirror_adjuster.py +34 -37
- mx_bluesky/hyperion/device_setup_plans/manipulate_sample.py +7 -7
- mx_bluesky/hyperion/device_setup_plans/position_detector.py +1 -1
- mx_bluesky/hyperion/device_setup_plans/read_hardware_for_setup.py +3 -3
- mx_bluesky/hyperion/device_setup_plans/setup_panda.py +21 -4
- mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +62 -36
- mx_bluesky/hyperion/device_setup_plans/smargon.py +3 -3
- mx_bluesky/hyperion/device_setup_plans/utils.py +4 -0
- mx_bluesky/hyperion/device_setup_plans/xbpm_feedback.py +8 -8
- mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py +28 -17
- mx_bluesky/hyperion/experiment_plans/common/xrc_result.py +10 -1
- mx_bluesky/hyperion/experiment_plans/experiment_registry.py +9 -9
- mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +54 -58
- mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +22 -31
- mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +57 -40
- mx_bluesky/hyperion/experiment_plans/oav_grid_detection_plan.py +3 -3
- mx_bluesky/hyperion/experiment_plans/oav_snapshot_plan.py +8 -2
- mx_bluesky/hyperion/experiment_plans/optimise_attenuation_plan.py +6 -14
- mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +12 -11
- mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +4 -4
- mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +39 -30
- mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +36 -18
- mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +33 -21
- mx_bluesky/hyperion/experiment_plans/set_energy_plan.py +10 -9
- mx_bluesky/hyperion/external_interaction/callbacks/__init__.py +0 -4
- mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +31 -20
- mx_bluesky/hyperion/external_interaction/callbacks/common/callback_util.py +46 -30
- mx_bluesky/hyperion/external_interaction/callbacks/robot_load/ispyb_callback.py +39 -24
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +25 -24
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_mapping.py +1 -1
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/nexus_callback.py +13 -9
- mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/__init__.py +0 -0
- mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/sample_handling_callback.py +50 -0
- mx_bluesky/hyperion/external_interaction/config_server.py +15 -1
- mx_bluesky/hyperion/parameters/components.py +3 -2
- mx_bluesky/hyperion/parameters/constants.py +1 -0
- mx_bluesky/hyperion/parameters/gridscan.py +56 -89
- mx_bluesky/hyperion/parameters/load_centre_collect.py +51 -6
- mx_bluesky/hyperion/parameters/robot_load.py +40 -0
- mx_bluesky/hyperion/parameters/rotation.py +28 -3
- mx_bluesky/hyperion/utils/context.py +1 -1
- mx_bluesky/hyperion/utils/validation.py +5 -3
- {mx_bluesky-1.4.1a0.dist-info → mx_bluesky-1.4.3.dist-info}/METADATA +6 -6
- mx_bluesky-1.4.3.dist-info/RECORD +155 -0
- {mx_bluesky-1.4.1a0.dist-info → mx_bluesky-1.4.3.dist-info}/WHEEL +1 -1
- mx_bluesky/common/parameters/robot_load.py +0 -16
- mx_bluesky/hyperion/external_interaction/exceptions.py +0 -13
- mx_bluesky/hyperion/log.py +0 -15
- mx_bluesky-1.4.1a0.dist-info/RECORD +0 -150
- /mx_bluesky/{hyperion/external_interaction/callbacks/xray_centre → common/external_interaction}/__init__.py +0 -0
- /mx_bluesky/{hyperion/external_interaction/ispyb → common/external_interaction/callbacks/common}/__init__.py +0 -0
- /mx_bluesky/{hyperion → common}/external_interaction/callbacks/common/abstract_event.py +0 -0
- /mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/log_uid_tag_callback.py +0 -0
- /mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/plan_reactive_callback.py +0 -0
- /mx_bluesky/{hyperion/external_interaction/nexus → common/external_interaction/callbacks/xray_centre}/__init__.py +0 -0
- /mx_bluesky/{hyperion → common}/utils/utils.py +0 -0
- {mx_bluesky-1.4.1a0.dist-info → mx_bluesky-1.4.3.dist-info}/LICENSE +0 -0
- {mx_bluesky-1.4.1a0.dist-info → mx_bluesky-1.4.3.dist-info}/entry_points.txt +0 -0
- {mx_bluesky-1.4.1a0.dist-info → mx_bluesky-1.4.3.dist-info}/top_level.txt +0 -0
|
@@ -10,20 +10,7 @@ schematics corresponds to soft_in_2 in the code.
|
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
import bluesky.plan_stubs as bps
|
|
13
|
-
from dodal.devices.zebra import (
|
|
14
|
-
AND3,
|
|
15
|
-
AND4,
|
|
16
|
-
DISCONNECT,
|
|
17
|
-
IN1_TTL,
|
|
18
|
-
IN3_TTL,
|
|
19
|
-
OR1,
|
|
20
|
-
PC_ARM,
|
|
21
|
-
PC_GATE,
|
|
22
|
-
PC_PULSE,
|
|
23
|
-
PULSE1,
|
|
24
|
-
PULSE2,
|
|
25
|
-
SOFT_IN2,
|
|
26
|
-
SOFT_IN3,
|
|
13
|
+
from dodal.devices.zebra.zebra import (
|
|
27
14
|
ArmDemand,
|
|
28
15
|
ArmSource,
|
|
29
16
|
I24Axes,
|
|
@@ -131,7 +118,9 @@ def setup_zebra_for_quickshot_plan(
|
|
|
131
118
|
yield from bps.abs_set(zebra.pc.gate_start, GATE_START, group=group)
|
|
132
119
|
yield from bps.abs_set(zebra.pc.gate_width, gate_width, group=group)
|
|
133
120
|
|
|
134
|
-
yield from bps.abs_set(
|
|
121
|
+
yield from bps.abs_set(
|
|
122
|
+
zebra.pc.gate_input, zebra.mapping.sources.SOFT_IN2, group=group
|
|
123
|
+
)
|
|
135
124
|
yield from bps.sleep(0.1)
|
|
136
125
|
|
|
137
126
|
if wait:
|
|
@@ -144,17 +133,25 @@ def set_logic_gates_for_porto_triggering(
|
|
|
144
133
|
):
|
|
145
134
|
# To OUT2_TTL
|
|
146
135
|
yield from bps.abs_set(
|
|
147
|
-
zebra.logic_gates.and_gates[3].sources[1],
|
|
136
|
+
zebra.logic_gates.and_gates[3].sources[1],
|
|
137
|
+
zebra.mapping.sources.SOFT_IN2,
|
|
138
|
+
group=group,
|
|
148
139
|
)
|
|
149
140
|
yield from bps.abs_set(
|
|
150
|
-
zebra.logic_gates.and_gates[3].sources[2],
|
|
141
|
+
zebra.logic_gates.and_gates[3].sources[2],
|
|
142
|
+
zebra.mapping.sources.PULSE1,
|
|
143
|
+
group=group,
|
|
151
144
|
)
|
|
152
145
|
# To OUT1_TTL
|
|
153
146
|
yield from bps.abs_set(
|
|
154
|
-
zebra.logic_gates.and_gates[4].sources[1],
|
|
147
|
+
zebra.logic_gates.and_gates[4].sources[1],
|
|
148
|
+
zebra.mapping.sources.SOFT_IN2,
|
|
149
|
+
group=group,
|
|
155
150
|
)
|
|
156
151
|
yield from bps.abs_set(
|
|
157
|
-
zebra.logic_gates.and_gates[4].sources[2],
|
|
152
|
+
zebra.logic_gates.and_gates[4].sources[2],
|
|
153
|
+
zebra.mapping.sources.PULSE2,
|
|
154
|
+
group=group,
|
|
158
155
|
)
|
|
159
156
|
yield from bps.wait(group=group)
|
|
160
157
|
|
|
@@ -215,10 +212,16 @@ def setup_zebra_for_extruder_with_pump_probe_plan(
|
|
|
215
212
|
# Set TTL out depending on detector type
|
|
216
213
|
DET_TTL = TTL_EIGER if det_type == "eiger" else TTL_PILATUS
|
|
217
214
|
LASER_TTL = TTL_PILATUS if det_type == "eiger" else TTL_EIGER
|
|
218
|
-
yield from bps.abs_set(
|
|
219
|
-
|
|
215
|
+
yield from bps.abs_set(
|
|
216
|
+
zebra.output.out_pvs[DET_TTL], zebra.mapping.sources.AND4, group=group
|
|
217
|
+
)
|
|
218
|
+
yield from bps.abs_set(
|
|
219
|
+
zebra.output.out_pvs[LASER_TTL], zebra.mapping.sources.AND3, group=group
|
|
220
|
+
)
|
|
220
221
|
|
|
221
|
-
yield from bps.abs_set(
|
|
222
|
+
yield from bps.abs_set(
|
|
223
|
+
zebra.pc.gate_input, zebra.mapping.sources.SOFT_IN2, group=group
|
|
224
|
+
)
|
|
222
225
|
|
|
223
226
|
assert pump_exp and pump_delay, "Must supply pump_exp and pump_delay!"
|
|
224
227
|
gate_width, gate_step = get_zebra_settings_for_extruder(
|
|
@@ -242,7 +245,9 @@ def setup_zebra_for_extruder_with_pump_probe_plan(
|
|
|
242
245
|
SSX_LOGGER.info(
|
|
243
246
|
f"Pulse1 starting at {pulse1_delay} with width set to laser dwell {pump_exp}."
|
|
244
247
|
)
|
|
245
|
-
yield from bps.abs_set(
|
|
248
|
+
yield from bps.abs_set(
|
|
249
|
+
zebra.output.pulse_1.input, zebra.mapping.sources.PC_GATE, group=group
|
|
250
|
+
)
|
|
246
251
|
yield from bps.abs_set(zebra.output.pulse_1.delay, pulse1_delay, group=group)
|
|
247
252
|
yield from bps.abs_set(zebra.output.pulse_1.width, pump_exp, group=group)
|
|
248
253
|
SSX_LOGGER.info(
|
|
@@ -251,7 +256,9 @@ def setup_zebra_for_extruder_with_pump_probe_plan(
|
|
|
251
256
|
exposure time {exp_time}.
|
|
252
257
|
"""
|
|
253
258
|
)
|
|
254
|
-
yield from bps.abs_set(
|
|
259
|
+
yield from bps.abs_set(
|
|
260
|
+
zebra.output.pulse_2.input, zebra.mapping.sources.PC_GATE, group=group
|
|
261
|
+
)
|
|
255
262
|
yield from bps.abs_set(zebra.output.pulse_2.delay, pump_delay, group=group)
|
|
256
263
|
yield from bps.abs_set(zebra.output.pulse_2.width, exp_time, group=group)
|
|
257
264
|
|
|
@@ -308,20 +315,30 @@ def setup_zebra_for_fastchip_plan(
|
|
|
308
315
|
|
|
309
316
|
# Logic Gates
|
|
310
317
|
yield from bps.abs_set(
|
|
311
|
-
zebra.logic_gates.and_gates[3].sources[1],
|
|
318
|
+
zebra.logic_gates.and_gates[3].sources[1],
|
|
319
|
+
zebra.mapping.sources.SOFT_IN2,
|
|
320
|
+
group=group,
|
|
312
321
|
)
|
|
313
322
|
yield from bps.abs_set(
|
|
314
|
-
zebra.logic_gates.and_gates[3].sources[2],
|
|
323
|
+
zebra.logic_gates.and_gates[3].sources[2],
|
|
324
|
+
zebra.mapping.sources.PC_PULSE,
|
|
325
|
+
group=group,
|
|
315
326
|
)
|
|
316
327
|
|
|
317
|
-
yield from bps.abs_set(
|
|
328
|
+
yield from bps.abs_set(
|
|
329
|
+
zebra.pc.gate_input, zebra.mapping.sources.IN3_TTL, group=group
|
|
330
|
+
)
|
|
318
331
|
|
|
319
332
|
# Set TTL out depending on detector type
|
|
320
333
|
# And calculate some of the other settings
|
|
321
334
|
if det_type == "eiger":
|
|
322
|
-
yield from bps.abs_set(
|
|
335
|
+
yield from bps.abs_set(
|
|
336
|
+
zebra.output.out_pvs[TTL_EIGER], zebra.mapping.sources.AND3, group=group
|
|
337
|
+
)
|
|
323
338
|
if det_type == "pilatus":
|
|
324
|
-
yield from bps.abs_set(
|
|
339
|
+
yield from bps.abs_set(
|
|
340
|
+
zebra.output.out_pvs[TTL_PILATUS], zebra.mapping.sources.AND3, group=group
|
|
341
|
+
)
|
|
325
342
|
|
|
326
343
|
# Square wave - needs a small drop to make it work for eiger
|
|
327
344
|
pulse_width = exposure_time - 0.0001 if det_type == "eiger" else exposure_time / 2
|
|
@@ -374,13 +391,19 @@ def open_fast_shutter_at_each_position_plan(
|
|
|
374
391
|
)
|
|
375
392
|
SSX_LOGGER.debug("Controlling the fast shutter on PULSE2.")
|
|
376
393
|
# Output panel pulse_2 settings
|
|
377
|
-
yield from bps.abs_set(
|
|
394
|
+
yield from bps.abs_set(
|
|
395
|
+
zebra.output.pulse_2.input, zebra.mapping.sources.PC_GATE, group=group
|
|
396
|
+
)
|
|
378
397
|
yield from bps.abs_set(zebra.output.pulse_2.delay, 0.0, group=group)
|
|
379
398
|
pulse2_width = num_exposures * exposure_time + SHUTTER_OPEN_TIME
|
|
380
399
|
yield from bps.abs_set(zebra.output.pulse_2.width, pulse2_width, group=group)
|
|
381
400
|
|
|
382
401
|
# Fast shutter
|
|
383
|
-
yield from bps.abs_set(
|
|
402
|
+
yield from bps.abs_set(
|
|
403
|
+
zebra.output.out_pvs[TTL_FAST_SHUTTER],
|
|
404
|
+
zebra.mapping.sources.PULSE2,
|
|
405
|
+
group=group,
|
|
406
|
+
)
|
|
384
407
|
|
|
385
408
|
if wait:
|
|
386
409
|
yield from bps.wait(group=group)
|
|
@@ -396,12 +419,22 @@ def reset_pc_gate_and_pulse(zebra: Zebra, group: str = "reset_pc"):
|
|
|
396
419
|
|
|
397
420
|
def reset_output_panel(zebra: Zebra, group: str = "reset_zebra_outputs"):
|
|
398
421
|
# Reset TTL out
|
|
399
|
-
yield from bps.abs_set(
|
|
400
|
-
|
|
401
|
-
|
|
422
|
+
yield from bps.abs_set(
|
|
423
|
+
zebra.output.out_pvs[2], zebra.mapping.sources.PC_GATE, group=group
|
|
424
|
+
)
|
|
425
|
+
yield from bps.abs_set(
|
|
426
|
+
zebra.output.out_pvs[3], zebra.mapping.sources.DISCONNECT, group=group
|
|
427
|
+
)
|
|
428
|
+
yield from bps.abs_set(
|
|
429
|
+
zebra.output.out_pvs[4], zebra.mapping.sources.OR1, group=group
|
|
430
|
+
)
|
|
402
431
|
|
|
403
|
-
yield from bps.abs_set(
|
|
404
|
-
|
|
432
|
+
yield from bps.abs_set(
|
|
433
|
+
zebra.output.pulse_1.input, zebra.mapping.sources.DISCONNECT, group=group
|
|
434
|
+
)
|
|
435
|
+
yield from bps.abs_set(
|
|
436
|
+
zebra.output.pulse_2.input, zebra.mapping.sources.DISCONNECT, group=group
|
|
437
|
+
)
|
|
405
438
|
|
|
406
439
|
yield from bps.wait(group=group)
|
|
407
440
|
|
|
@@ -418,16 +451,24 @@ def zebra_return_to_normal_plan(
|
|
|
418
451
|
# Reset PC_GATE and PC_SOURCE to "Position"
|
|
419
452
|
yield from setup_pc_sources(zebra, TrigSource.POSITION, TrigSource.POSITION)
|
|
420
453
|
|
|
421
|
-
yield from bps.abs_set(
|
|
454
|
+
yield from bps.abs_set(
|
|
455
|
+
zebra.pc.gate_input, zebra.mapping.sources.SOFT_IN3, group=group
|
|
456
|
+
)
|
|
422
457
|
yield from bps.abs_set(zebra.pc.num_gates, 1, group=group)
|
|
423
|
-
yield from bps.abs_set(
|
|
458
|
+
yield from bps.abs_set(
|
|
459
|
+
zebra.pc.pulse_input, zebra.mapping.sources.DISCONNECT, group=group
|
|
460
|
+
)
|
|
424
461
|
|
|
425
462
|
# Logic Gates
|
|
426
463
|
yield from bps.abs_set(
|
|
427
|
-
zebra.logic_gates.and_gates[3].sources[1],
|
|
464
|
+
zebra.logic_gates.and_gates[3].sources[1],
|
|
465
|
+
zebra.mapping.sources.PC_ARM,
|
|
466
|
+
group=group,
|
|
428
467
|
)
|
|
429
468
|
yield from bps.abs_set(
|
|
430
|
-
zebra.logic_gates.and_gates[3].sources[2],
|
|
469
|
+
zebra.logic_gates.and_gates[3].sources[2],
|
|
470
|
+
zebra.mapping.sources.IN1_TTL,
|
|
471
|
+
group=group,
|
|
431
472
|
)
|
|
432
473
|
|
|
433
474
|
# Reset TTL out
|
|
@@ -3,7 +3,6 @@ import pathlib
|
|
|
3
3
|
import pprint
|
|
4
4
|
import time
|
|
5
5
|
from datetime import datetime
|
|
6
|
-
from typing import Literal
|
|
7
6
|
|
|
8
7
|
import requests
|
|
9
8
|
|
|
@@ -13,43 +12,49 @@ from mx_bluesky.beamlines.i24.serial.parameters import (
|
|
|
13
12
|
ExtruderParameters,
|
|
14
13
|
FixedTargetParameters,
|
|
15
14
|
)
|
|
16
|
-
from mx_bluesky.beamlines.i24.serial.setup_beamline import Eiger, caget
|
|
15
|
+
from mx_bluesky.beamlines.i24.serial.setup_beamline import Eiger, caget
|
|
17
16
|
|
|
18
17
|
|
|
19
18
|
def call_nexgen(
|
|
20
19
|
chip_prog_dict: dict | None,
|
|
21
|
-
start_time: datetime,
|
|
22
20
|
parameters: ExtruderParameters | FixedTargetParameters,
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
wavelength_in_a: float,
|
|
22
|
+
beam_center_in_pix: tuple[float, float],
|
|
23
|
+
start_time: datetime | None = None,
|
|
25
24
|
):
|
|
26
|
-
|
|
27
|
-
print(f"det_type: {det_type}")
|
|
25
|
+
"""Call the nexus writer by sending a request to nexgen-server.
|
|
28
26
|
|
|
27
|
+
Args:
|
|
28
|
+
chip_prog_dict (dict | None): Dictionary containing most of the information \
|
|
29
|
+
passed to the program runner for the collection. Only used for fixed target.
|
|
30
|
+
start_time
|
|
31
|
+
parameters (SerialAndLaserExperiment): Collection parameters.
|
|
32
|
+
wavelength_in_a (float): Wavelength, in A.
|
|
33
|
+
beam_center_in_pix (list[float]): Beam center position on detector, in pixels.
|
|
34
|
+
start_time (datetime, optional): Collection start time.
|
|
35
|
+
|
|
36
|
+
Raises:
|
|
37
|
+
ValueError: For a wrong experiment type passed (either unknwon or not matched \
|
|
38
|
+
to parameter model).
|
|
39
|
+
|
|
40
|
+
"""
|
|
29
41
|
current_chip_map = None
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
pump_status = parameters.pump_status
|
|
44
|
-
else:
|
|
45
|
-
raise ValueError(f"{expt_type=} not recognised")
|
|
42
|
+
match parameters:
|
|
43
|
+
case FixedTargetParameters():
|
|
44
|
+
if not (
|
|
45
|
+
parameters.map_type == MappingType.NoMap
|
|
46
|
+
or parameters.chip.chip_type == ChipType.Custom
|
|
47
|
+
):
|
|
48
|
+
# For nexgen >= 0.9.10
|
|
49
|
+
current_chip_map = parameters.chip_map
|
|
50
|
+
pump_status = bool(parameters.pump_repeat)
|
|
51
|
+
total_numb_imgs = parameters.total_num_images
|
|
52
|
+
case ExtruderParameters():
|
|
53
|
+
total_numb_imgs = parameters.num_images
|
|
54
|
+
pump_status = parameters.pump_status
|
|
46
55
|
|
|
47
|
-
filename_prefix =
|
|
48
|
-
meta_h5 =
|
|
49
|
-
pathlib.Path(parameters.visit)
|
|
50
|
-
/ parameters.directory
|
|
51
|
-
/ f"{filename_prefix}_meta.h5"
|
|
52
|
-
)
|
|
56
|
+
filename_prefix = parameters.filename
|
|
57
|
+
meta_h5 = parameters.visit / parameters.directory / f"{filename_prefix}_meta.h5"
|
|
53
58
|
t0 = time.time()
|
|
54
59
|
max_wait = 60 # seconds
|
|
55
60
|
SSX_LOGGER.info(f"Watching for {meta_h5}")
|
|
@@ -62,44 +67,38 @@ def call_nexgen(
|
|
|
62
67
|
time.sleep(1)
|
|
63
68
|
if not meta_h5.exists():
|
|
64
69
|
SSX_LOGGER.warning(f"Giving up waiting for {meta_h5} after {max_wait} seconds")
|
|
65
|
-
return
|
|
70
|
+
return
|
|
66
71
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
SSX_LOGGER.debug(
|
|
72
|
-
f"Call to nexgen server with the following chip definition: \n{chip_prog_dict}"
|
|
73
|
-
)
|
|
72
|
+
bit_depth = int(caget(Eiger.pv.bit_depth))
|
|
73
|
+
SSX_LOGGER.debug(
|
|
74
|
+
f"Call to nexgen server with the following chip definition: \n{chip_prog_dict}"
|
|
75
|
+
)
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
access_token = pathlib.Path("/scratch/ssx_nexgen.key").read_text().strip()
|
|
78
|
+
url = "https://ssx-nexgen.diamond.ac.uk/ssx_eiger/write"
|
|
79
|
+
headers = {"Authorization": f"Bearer {access_token}"}
|
|
78
80
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
# the following will raise an error if the request was unsuccessful
|
|
104
|
-
return response.status_code == requests.codes.ok
|
|
105
|
-
return False
|
|
81
|
+
payload = {
|
|
82
|
+
"beamline": "i24",
|
|
83
|
+
"beam_center": beam_center_in_pix,
|
|
84
|
+
"chipmap": current_chip_map,
|
|
85
|
+
"chip_info": chip_prog_dict,
|
|
86
|
+
"det_dist": parameters.detector_distance_mm,
|
|
87
|
+
"exp_time": parameters.exposure_time_s,
|
|
88
|
+
"expt_type": parameters.nexgen_experiment_type,
|
|
89
|
+
"filename": filename_prefix,
|
|
90
|
+
"num_imgs": total_numb_imgs,
|
|
91
|
+
"pump_status": pump_status,
|
|
92
|
+
"pump_exp": parameters.laser_dwell_s,
|
|
93
|
+
"pump_delay": parameters.laser_delay_s,
|
|
94
|
+
"transmission": parameters.transmission,
|
|
95
|
+
"visitpath": os.fspath(meta_h5.parent),
|
|
96
|
+
"wavelength": wavelength_in_a,
|
|
97
|
+
"bit_depth": bit_depth,
|
|
98
|
+
"start_time": start_time,
|
|
99
|
+
}
|
|
100
|
+
SSX_LOGGER.info(f"Sending POST request to {url} with payload:")
|
|
101
|
+
SSX_LOGGER.info(pprint.pformat(payload))
|
|
102
|
+
response = requests.post(url, headers=headers, json=payload)
|
|
103
|
+
response.raise_for_status()
|
|
104
|
+
SSX_LOGGER.info(f"Response: {response.text} (status code: {response.status_code})")
|
|
@@ -5,10 +5,28 @@ from bluesky.callbacks import CallbackBase
|
|
|
5
5
|
from dodal.devices.oav.utils import calculate_x_y_z_of_pixel
|
|
6
6
|
from event_model.documents import Event
|
|
7
7
|
|
|
8
|
-
from mx_bluesky.
|
|
8
|
+
from mx_bluesky.common.utils.log import LOGGER
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class GridParamUpdate(TypedDict):
|
|
12
|
+
"""
|
|
13
|
+
Grid parameters extracted from the grid detection.
|
|
14
|
+
Positions are in motor-space.
|
|
15
|
+
|
|
16
|
+
Attributes:
|
|
17
|
+
x_start_um: x position of the centre of the first xy-gridscan box in microns
|
|
18
|
+
y_start_um: y position of the centre of the first xy-gridscan box in microns
|
|
19
|
+
y2_start_um: y position of the centre of the first xz-gridscan box in microns
|
|
20
|
+
z_start_um: z position of the centre of the first xy-gridscan box in microns
|
|
21
|
+
z2_start_um: z position of the centre of the first xz-gridscan box in microns
|
|
22
|
+
x_steps: Number of grid boxes in x-direction for xy- and xz- gridscans
|
|
23
|
+
y_steps: Number of grid boxes in y-direction for xy-gridscan
|
|
24
|
+
z_steps: Number of grid boxes in z-direction for xz-gridscan
|
|
25
|
+
x_step_size_um: x-dimension of the grid box
|
|
26
|
+
y_step_size_um: y-dimension of the grid box
|
|
27
|
+
z_step_size_um: z-dimension of the grid box
|
|
28
|
+
"""
|
|
29
|
+
|
|
12
30
|
x_start_um: float
|
|
13
31
|
y_start_um: float
|
|
14
32
|
y2_start_um: float
|
|
@@ -9,26 +9,26 @@ from dodal.devices.detector import DetectorParams
|
|
|
9
9
|
from dodal.devices.detector.det_resolution import resolution
|
|
10
10
|
from dodal.devices.synchrotron import SynchrotronMode
|
|
11
11
|
|
|
12
|
-
from mx_bluesky.common.
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
from mx_bluesky.common.external_interaction.callbacks.common.logging_callback import (
|
|
13
|
+
format_doc_for_log,
|
|
14
|
+
)
|
|
15
|
+
from mx_bluesky.common.external_interaction.callbacks.common.plan_reactive_callback import (
|
|
15
16
|
PlanReactiveCallback,
|
|
16
17
|
)
|
|
17
|
-
from mx_bluesky.
|
|
18
|
+
from mx_bluesky.common.external_interaction.ispyb.data_model import (
|
|
18
19
|
DataCollectionInfo,
|
|
19
20
|
DataCollectionPositionInfo,
|
|
20
21
|
ScanDataInfo,
|
|
21
22
|
)
|
|
22
|
-
from mx_bluesky.
|
|
23
|
+
from mx_bluesky.common.external_interaction.ispyb.ispyb_store import (
|
|
23
24
|
IspybIds,
|
|
24
25
|
StoreInIspyb,
|
|
25
26
|
)
|
|
26
|
-
from mx_bluesky.
|
|
27
|
-
from mx_bluesky.
|
|
28
|
-
from mx_bluesky.
|
|
29
|
-
from mx_bluesky.
|
|
30
|
-
|
|
31
|
-
from .logging_callback import format_doc_for_log
|
|
27
|
+
from mx_bluesky.common.external_interaction.ispyb.ispyb_utils import get_ispyb_config
|
|
28
|
+
from mx_bluesky.common.parameters.components import DiffractionExperimentWithSample
|
|
29
|
+
from mx_bluesky.common.parameters.constants import DocDescriptorNames, SimConstants
|
|
30
|
+
from mx_bluesky.common.utils.log import ISPYB_ZOCALO_CALLBACK_LOGGER, set_dcgid_tag
|
|
31
|
+
from mx_bluesky.common.utils.utils import convert_eV_to_angstrom
|
|
32
32
|
|
|
33
33
|
D = TypeVar("D")
|
|
34
34
|
if TYPE_CHECKING:
|
|
@@ -63,25 +63,25 @@ class BaseISPyBCallback(PlanReactiveCallback):
|
|
|
63
63
|
"""Subclasses should run super().__init__() with parameters, then set
|
|
64
64
|
self.ispyb to the type of ispyb relevant to the experiment and define the type
|
|
65
65
|
for self.ispyb_ids."""
|
|
66
|
-
|
|
67
|
-
super().__init__(log=
|
|
66
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.debug("Initialising ISPyB callback")
|
|
67
|
+
super().__init__(log=ISPYB_ZOCALO_CALLBACK_LOGGER, emit=emit)
|
|
68
68
|
self._oav_snapshot_event_idx: int = 0
|
|
69
69
|
self.params: DiffractionExperimentWithSample | None = None
|
|
70
70
|
self.ispyb: StoreInIspyb
|
|
71
71
|
self.descriptors: dict[str, EventDescriptor] = {}
|
|
72
72
|
self.ispyb_config = get_ispyb_config()
|
|
73
73
|
if (
|
|
74
|
-
self.ispyb_config ==
|
|
75
|
-
or self.ispyb_config ==
|
|
74
|
+
self.ispyb_config == SimConstants.ISPYB_CONFIG
|
|
75
|
+
or self.ispyb_config == SimConstants.DEV_ISPYB_DATABASE_CFG
|
|
76
76
|
):
|
|
77
|
-
|
|
77
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.warning(
|
|
78
78
|
f"{self.__class__} using dev ISPyB config: {self.ispyb_config}. If you"
|
|
79
79
|
"want to use the real database, please set the ISPYB_CONFIG_PATH "
|
|
80
80
|
"environment variable."
|
|
81
81
|
)
|
|
82
82
|
self.uid_to_finalize_on: str | None = None
|
|
83
83
|
self.ispyb_ids: IspybIds = IspybIds()
|
|
84
|
-
self.log =
|
|
84
|
+
self.log = ISPYB_ZOCALO_CALLBACK_LOGGER
|
|
85
85
|
|
|
86
86
|
def activity_gated_start(self, doc: RunStart):
|
|
87
87
|
self._oav_snapshot_event_idx = 0
|
|
@@ -94,31 +94,33 @@ class BaseISPyBCallback(PlanReactiveCallback):
|
|
|
94
94
|
def activity_gated_event(self, doc: Event) -> Event:
|
|
95
95
|
"""Subclasses should extend this to add a call to set_dcig_tag from
|
|
96
96
|
hyperion.log"""
|
|
97
|
-
|
|
97
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.debug("ISPyB handler received event document.")
|
|
98
98
|
assert self.ispyb is not None, "ISPyB deposition wasn't initialised!"
|
|
99
99
|
assert self.params is not None, "ISPyB handler didn't receive parameters!"
|
|
100
100
|
|
|
101
101
|
event_descriptor = self.descriptors.get(doc["descriptor"])
|
|
102
102
|
if event_descriptor is None:
|
|
103
|
-
|
|
103
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.warning(
|
|
104
104
|
f"Ispyb handler {self} received event doc {format_doc_for_log(doc)} and "
|
|
105
105
|
"has no corresponding descriptor record"
|
|
106
106
|
)
|
|
107
107
|
return doc
|
|
108
108
|
match event_descriptor.get("name"):
|
|
109
|
-
case
|
|
109
|
+
case DocDescriptorNames.HARDWARE_READ_PRE:
|
|
110
110
|
scan_data_infos = self._handle_ispyb_hardware_read(doc)
|
|
111
|
-
case
|
|
111
|
+
case DocDescriptorNames.HARDWARE_READ_DURING:
|
|
112
112
|
scan_data_infos = self._handle_ispyb_transmission_flux_read(doc)
|
|
113
113
|
case _:
|
|
114
114
|
return self._tag_doc(doc)
|
|
115
115
|
self.ispyb_ids = self.ispyb.update_deposition(self.ispyb_ids, scan_data_infos)
|
|
116
|
-
|
|
116
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.info(f"Received ISPYB IDs: {self.ispyb_ids}")
|
|
117
117
|
return self._tag_doc(doc)
|
|
118
118
|
|
|
119
119
|
def _handle_ispyb_hardware_read(self, doc) -> Sequence[ScanDataInfo]:
|
|
120
120
|
assert self.params, "Event handled before activity_gated_start received params"
|
|
121
|
-
|
|
121
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.info(
|
|
122
|
+
"ISPyB handler received event from read hardware"
|
|
123
|
+
)
|
|
122
124
|
assert isinstance(
|
|
123
125
|
synchrotron_mode := doc["data"]["synchrotron-synchrotron_mode"],
|
|
124
126
|
SynchrotronMode,
|
|
@@ -127,8 +129,8 @@ class BaseISPyBCallback(PlanReactiveCallback):
|
|
|
127
129
|
hwscan_data_collection_info = DataCollectionInfo(
|
|
128
130
|
undulator_gap1=doc["data"]["undulator-current_gap"],
|
|
129
131
|
synchrotron_mode=synchrotron_mode.value,
|
|
130
|
-
slitgap_horizontal=doc["data"]["
|
|
131
|
-
slitgap_vertical=doc["data"]["
|
|
132
|
+
slitgap_horizontal=doc["data"]["s4_slit_gaps-xgap"],
|
|
133
|
+
slitgap_vertical=doc["data"]["s4_slit_gaps-ygap"],
|
|
132
134
|
)
|
|
133
135
|
hwscan_data_collection_info = _update_based_on_energy(
|
|
134
136
|
doc, self.params.detector_params, hwscan_data_collection_info
|
|
@@ -141,7 +143,9 @@ class BaseISPyBCallback(PlanReactiveCallback):
|
|
|
141
143
|
scan_data_infos = self.populate_info_for_update(
|
|
142
144
|
hwscan_data_collection_info, hwscan_position_info, self.params
|
|
143
145
|
)
|
|
144
|
-
|
|
146
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.info(
|
|
147
|
+
"Updating ispyb data collection after hardware read."
|
|
148
|
+
)
|
|
145
149
|
return scan_data_infos
|
|
146
150
|
|
|
147
151
|
def _handle_ispyb_transmission_flux_read(self, doc) -> Sequence[ScanDataInfo]:
|
|
@@ -156,7 +160,7 @@ class BaseISPyBCallback(PlanReactiveCallback):
|
|
|
156
160
|
beamsize_at_sampley=beamsize_y_mm,
|
|
157
161
|
focal_spot_size_at_samplex=beamsize_x_mm,
|
|
158
162
|
focal_spot_size_at_sampley=beamsize_y_mm,
|
|
159
|
-
flux=doc["data"]["
|
|
163
|
+
flux=doc["data"]["flux-flux_reading"],
|
|
160
164
|
)
|
|
161
165
|
if transmission := doc["data"]["attenuator-actual_transmission"]:
|
|
162
166
|
# Ispyb wants the transmission in a percentage, we use fractions
|
|
@@ -167,7 +171,9 @@ class BaseISPyBCallback(PlanReactiveCallback):
|
|
|
167
171
|
scan_data_infos = self.populate_info_for_update(
|
|
168
172
|
hwscan_data_collection_info, None, self.params
|
|
169
173
|
)
|
|
170
|
-
|
|
174
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.info(
|
|
175
|
+
"Updating ispyb data collection after flux read."
|
|
176
|
+
)
|
|
171
177
|
self.append_to_comment(f"Aperture: {aperture}. ")
|
|
172
178
|
return scan_data_infos
|
|
173
179
|
|
|
@@ -183,10 +189,10 @@ class BaseISPyBCallback(PlanReactiveCallback):
|
|
|
183
189
|
def activity_gated_stop(self, doc: RunStop) -> RunStop:
|
|
184
190
|
"""Subclasses must check that they are recieving a stop document for the correct
|
|
185
191
|
uid to use this method!"""
|
|
186
|
-
assert (
|
|
187
|
-
|
|
188
|
-
)
|
|
189
|
-
|
|
192
|
+
assert self.ispyb is not None, (
|
|
193
|
+
"ISPyB handler received stop document, but deposition object doesn't exist!"
|
|
194
|
+
)
|
|
195
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.debug("ISPyB handler received stop document.")
|
|
190
196
|
exit_status = (
|
|
191
197
|
doc.get("exit_status") or "Exit status not available in stop document!"
|
|
192
198
|
)
|
|
@@ -195,7 +201,7 @@ class BaseISPyBCallback(PlanReactiveCallback):
|
|
|
195
201
|
try:
|
|
196
202
|
self.ispyb.end_deposition(self.ispyb_ids, exit_status, reason)
|
|
197
203
|
except Exception as e:
|
|
198
|
-
|
|
204
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.warning(
|
|
199
205
|
f"Failed to finalise ISPyB deposition on stop document: {format_doc_for_log(doc)} with exception: {e}"
|
|
200
206
|
)
|
|
201
207
|
return self._tag_doc(doc)
|
|
@@ -205,7 +211,7 @@ class BaseISPyBCallback(PlanReactiveCallback):
|
|
|
205
211
|
try:
|
|
206
212
|
self.ispyb.append_to_comment(id, comment)
|
|
207
213
|
except TypeError:
|
|
208
|
-
|
|
214
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.warning(
|
|
209
215
|
"ISPyB deposition not initialised, can't update comment."
|
|
210
216
|
)
|
|
211
217
|
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from mx_bluesky.common.
|
|
4
|
-
from mx_bluesky.hyperion.external_interaction.ispyb.data_model import (
|
|
3
|
+
from mx_bluesky.common.external_interaction.ispyb.data_model import (
|
|
5
4
|
DataCollectionGroupInfo,
|
|
6
5
|
DataCollectionInfo,
|
|
7
6
|
)
|
|
8
|
-
from mx_bluesky.
|
|
7
|
+
from mx_bluesky.common.external_interaction.ispyb.ispyb_store import (
|
|
9
8
|
EIGER_FILE_SUFFIX,
|
|
10
9
|
I03_EIGER_DETECTOR,
|
|
11
10
|
)
|
|
12
|
-
from mx_bluesky.
|
|
11
|
+
from mx_bluesky.common.external_interaction.ispyb.ispyb_utils import (
|
|
13
12
|
get_current_time_string,
|
|
14
13
|
)
|
|
14
|
+
from mx_bluesky.common.parameters.components import DiffractionExperimentWithSample
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def populate_data_collection_group(params: DiffractionExperimentWithSample):
|