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.
Files changed (105) hide show
  1. mx_bluesky/_version.py +2 -2
  2. mx_bluesky/beamlines/i04/redis_to_murko_forwarder.py +178 -0
  3. mx_bluesky/beamlines/i24/serial/__init__.py +0 -6
  4. mx_bluesky/beamlines/i24/serial/dcid.py +125 -151
  5. mx_bluesky/beamlines/i24/serial/extruder/EX-gui-edm/DiamondExtruder-I24-py3v1.edl +1 -1
  6. mx_bluesky/beamlines/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +88 -43
  7. mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/DiamondChipI24-py3v1.edl +1 -1
  8. mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/MappingLite-oxford_py3v1.edl +2 -46
  9. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +85 -122
  10. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +58 -66
  11. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_StartUp_py3v1.py +1 -19
  12. mx_bluesky/beamlines/i24/serial/parameters/__init__.py +11 -2
  13. mx_bluesky/beamlines/i24/serial/parameters/constants.py +16 -2
  14. mx_bluesky/beamlines/i24/serial/parameters/experiment_parameters.py +94 -19
  15. mx_bluesky/beamlines/i24/serial/parameters/utils.py +19 -0
  16. mx_bluesky/beamlines/i24/serial/setup_beamline/pv.py +2 -0
  17. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +61 -8
  18. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_zebra_plans.py +81 -40
  19. mx_bluesky/beamlines/i24/serial/write_nexus.py +66 -67
  20. mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/aperture_change_callback.py +1 -1
  21. mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/grid_detection_callback.py +19 -1
  22. mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/ispyb_callback_base.py +40 -34
  23. mx_bluesky/{hyperion → common}/external_interaction/callbacks/common/ispyb_mapping.py +4 -4
  24. mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/logging_callback.py +1 -1
  25. mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/zocalo_callback.py +14 -9
  26. mx_bluesky/{hyperion → common}/external_interaction/callbacks/xray_centre/ispyb_callback.py +46 -38
  27. mx_bluesky/{hyperion → common}/external_interaction/callbacks/xray_centre/ispyb_mapping.py +2 -2
  28. mx_bluesky/{hyperion → common}/external_interaction/callbacks/xray_centre/nexus_callback.py +20 -15
  29. mx_bluesky/common/external_interaction/config_server.py +11 -0
  30. mx_bluesky/common/external_interaction/ispyb/__init__.py +0 -0
  31. mx_bluesky/{hyperion → common}/external_interaction/ispyb/data_model.py +2 -0
  32. mx_bluesky/{hyperion → common}/external_interaction/ispyb/exp_eye_store.py +67 -17
  33. mx_bluesky/{hyperion → common}/external_interaction/ispyb/ispyb_store.py +20 -18
  34. mx_bluesky/{hyperion → common}/external_interaction/ispyb/ispyb_utils.py +2 -2
  35. mx_bluesky/common/external_interaction/nexus/__init__.py +0 -0
  36. mx_bluesky/{hyperion → common}/external_interaction/nexus/nexus_utils.py +21 -6
  37. mx_bluesky/{hyperion → common}/external_interaction/nexus/write_nexus.py +5 -5
  38. mx_bluesky/common/external_interaction/test_config_server.py +38 -0
  39. mx_bluesky/common/parameters/components.py +10 -8
  40. mx_bluesky/common/parameters/constants.py +6 -0
  41. mx_bluesky/common/parameters/gridscan.py +102 -53
  42. mx_bluesky/common/plans/do_fgs.py +4 -4
  43. mx_bluesky/{hyperion → common/utils}/exceptions.py +27 -1
  44. mx_bluesky/common/utils/log.py +17 -7
  45. mx_bluesky/hyperion/__main__.py +15 -14
  46. mx_bluesky/hyperion/device_setup_plans/check_beamstop.py +27 -0
  47. mx_bluesky/hyperion/device_setup_plans/dcm_pitch_roll_mirror_adjuster.py +34 -37
  48. mx_bluesky/hyperion/device_setup_plans/manipulate_sample.py +7 -7
  49. mx_bluesky/hyperion/device_setup_plans/position_detector.py +1 -1
  50. mx_bluesky/hyperion/device_setup_plans/read_hardware_for_setup.py +3 -3
  51. mx_bluesky/hyperion/device_setup_plans/setup_panda.py +21 -4
  52. mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +62 -36
  53. mx_bluesky/hyperion/device_setup_plans/smargon.py +3 -3
  54. mx_bluesky/hyperion/device_setup_plans/utils.py +4 -0
  55. mx_bluesky/hyperion/device_setup_plans/xbpm_feedback.py +8 -8
  56. mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py +28 -17
  57. mx_bluesky/hyperion/experiment_plans/common/xrc_result.py +10 -1
  58. mx_bluesky/hyperion/experiment_plans/experiment_registry.py +9 -9
  59. mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +54 -58
  60. mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +22 -31
  61. mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +57 -40
  62. mx_bluesky/hyperion/experiment_plans/oav_grid_detection_plan.py +3 -3
  63. mx_bluesky/hyperion/experiment_plans/oav_snapshot_plan.py +8 -2
  64. mx_bluesky/hyperion/experiment_plans/optimise_attenuation_plan.py +6 -14
  65. mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +12 -11
  66. mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +4 -4
  67. mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +39 -30
  68. mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +36 -18
  69. mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +33 -21
  70. mx_bluesky/hyperion/experiment_plans/set_energy_plan.py +10 -9
  71. mx_bluesky/hyperion/external_interaction/callbacks/__init__.py +0 -4
  72. mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +31 -20
  73. mx_bluesky/hyperion/external_interaction/callbacks/common/callback_util.py +46 -30
  74. mx_bluesky/hyperion/external_interaction/callbacks/robot_load/ispyb_callback.py +39 -24
  75. mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +25 -24
  76. mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_mapping.py +1 -1
  77. mx_bluesky/hyperion/external_interaction/callbacks/rotation/nexus_callback.py +13 -9
  78. mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/__init__.py +0 -0
  79. mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/sample_handling_callback.py +50 -0
  80. mx_bluesky/hyperion/external_interaction/config_server.py +15 -1
  81. mx_bluesky/hyperion/parameters/components.py +3 -2
  82. mx_bluesky/hyperion/parameters/constants.py +1 -0
  83. mx_bluesky/hyperion/parameters/gridscan.py +56 -89
  84. mx_bluesky/hyperion/parameters/load_centre_collect.py +51 -6
  85. mx_bluesky/hyperion/parameters/robot_load.py +40 -0
  86. mx_bluesky/hyperion/parameters/rotation.py +28 -3
  87. mx_bluesky/hyperion/utils/context.py +1 -1
  88. mx_bluesky/hyperion/utils/validation.py +5 -3
  89. {mx_bluesky-1.4.1a0.dist-info → mx_bluesky-1.4.3.dist-info}/METADATA +6 -6
  90. mx_bluesky-1.4.3.dist-info/RECORD +155 -0
  91. {mx_bluesky-1.4.1a0.dist-info → mx_bluesky-1.4.3.dist-info}/WHEEL +1 -1
  92. mx_bluesky/common/parameters/robot_load.py +0 -16
  93. mx_bluesky/hyperion/external_interaction/exceptions.py +0 -13
  94. mx_bluesky/hyperion/log.py +0 -15
  95. mx_bluesky-1.4.1a0.dist-info/RECORD +0 -150
  96. /mx_bluesky/{hyperion/external_interaction/callbacks/xray_centre → common/external_interaction}/__init__.py +0 -0
  97. /mx_bluesky/{hyperion/external_interaction/ispyb → common/external_interaction/callbacks/common}/__init__.py +0 -0
  98. /mx_bluesky/{hyperion → common}/external_interaction/callbacks/common/abstract_event.py +0 -0
  99. /mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/log_uid_tag_callback.py +0 -0
  100. /mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/plan_reactive_callback.py +0 -0
  101. /mx_bluesky/{hyperion/external_interaction/nexus → common/external_interaction/callbacks/xray_centre}/__init__.py +0 -0
  102. /mx_bluesky/{hyperion → common}/utils/utils.py +0 -0
  103. {mx_bluesky-1.4.1a0.dist-info → mx_bluesky-1.4.3.dist-info}/LICENSE +0 -0
  104. {mx_bluesky-1.4.1a0.dist-info → mx_bluesky-1.4.3.dist-info}/entry_points.txt +0 -0
  105. {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(zebra.pc.gate_input, SOFT_IN2, group=group)
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], SOFT_IN2, group=group
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], PULSE1, group=group
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], SOFT_IN2, group=group
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], PULSE2, group=group
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(zebra.output.out_pvs[DET_TTL], AND4, group=group)
219
- yield from bps.abs_set(zebra.output.out_pvs[LASER_TTL], AND3, group=group)
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(zebra.pc.gate_input, SOFT_IN2, group=group)
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(zebra.output.pulse_1.input, PC_GATE, group=group)
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(zebra.output.pulse_2.input, PC_GATE, group=group)
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], SOFT_IN2, group=group
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], PC_PULSE, group=group
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(zebra.pc.gate_input, IN3_TTL, group=group)
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(zebra.output.out_pvs[TTL_EIGER], AND3, group=group)
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(zebra.output.out_pvs[TTL_PILATUS], AND3, group=group)
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(zebra.output.pulse_2.input, PC_GATE, group=group)
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(zebra.output.out_pvs[TTL_FAST_SHUTTER], PULSE2, group=group)
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(zebra.output.out_pvs[2], PC_GATE, group=group)
400
- yield from bps.abs_set(zebra.output.out_pvs[3], DISCONNECT, group=group)
401
- yield from bps.abs_set(zebra.output.out_pvs[4], OR1, group=group)
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(zebra.output.pulse_1.input, DISCONNECT, group=group)
404
- yield from bps.abs_set(zebra.output.pulse_2.input, DISCONNECT, group=group)
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(zebra.pc.gate_input, SOFT_IN3, group=group)
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(zebra.pc.pulse_input, DISCONNECT, group=group)
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], PC_ARM, group=group
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], IN1_TTL, group=group
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, cagetstring
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
- wavelength: float,
24
- expt_type: Literal["fixed-target", "extruder"] = "fixed-target",
21
+ wavelength_in_a: float,
22
+ beam_center_in_pix: tuple[float, float],
23
+ start_time: datetime | None = None,
25
24
  ):
26
- det_type = parameters.detector_name
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
- if expt_type == "fixed-target" and isinstance(parameters, FixedTargetParameters):
31
- if not (
32
- parameters.map_type == MappingType.NoMap
33
- or parameters.chip.chip_type == ChipType.Custom
34
- ):
35
- # NOTE Nexgen server is still on nexgen v0.7.2 (fully working for ssx)
36
- # Will need to be updated, for correctness sake map needs to be None.
37
- current_chip_map = "/dls_sw/i24/scripts/fastchips/litemaps/currentchip.map"
38
- pump_status = bool(parameters.pump_repeat)
39
- total_numb_imgs = parameters.total_num_images
40
- elif expt_type == "extruder" and isinstance(parameters, ExtruderParameters):
41
- # chip_prog_dict should be None for extruder (passed as input for now)
42
- total_numb_imgs = parameters.num_images
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 = cagetstring(Eiger.pv.filenameRBV)
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 False
70
+ return
66
71
 
67
- transmission = (float(caget(Eiger.pv.transmission)),)
68
-
69
- if det_type == Eiger.name:
70
- bit_depth = int(caget(Eiger.pv.bit_depth))
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
- access_token = pathlib.Path("/scratch/ssx_nexgen.key").read_text().strip()
76
- url = "https://ssx-nexgen.diamond.ac.uk/ssx_eiger/write"
77
- headers = {"Authorization": f"Bearer {access_token}"}
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
- payload = {
80
- "beamline": "i24",
81
- "beam_center": [caget(Eiger.pv.beamx), caget(Eiger.pv.beamy)],
82
- "chipmap": current_chip_map,
83
- "chip_info": chip_prog_dict,
84
- "det_dist": parameters.detector_distance_mm,
85
- "exp_time": parameters.exposure_time_s,
86
- "expt_type": expt_type,
87
- "filename": filename_prefix,
88
- "num_imgs": total_numb_imgs,
89
- "pump_status": pump_status,
90
- "pump_exp": parameters.laser_dwell_s,
91
- "pump_delay": parameters.laser_delay_s,
92
- "transmission": transmission[0],
93
- "visitpath": os.fspath(meta_h5.parent),
94
- "wavelength": wavelength,
95
- "bit_depth": bit_depth,
96
- }
97
- SSX_LOGGER.info(f"Sending POST request to {url} with payload:")
98
- SSX_LOGGER.info(pprint.pformat(payload))
99
- response = requests.post(url, headers=headers, json=payload)
100
- SSX_LOGGER.info(
101
- f"Response: {response.text} (status code: {response.status_code})"
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})")
@@ -1,7 +1,7 @@
1
1
  from bluesky.callbacks import CallbackBase
2
2
  from event_model.documents.run_start import RunStart
3
3
 
4
- from mx_bluesky.hyperion.log import LOGGER
4
+ from mx_bluesky.common.utils.log import LOGGER
5
5
 
6
6
  from .logging_callback import format_doc_for_log
7
7
 
@@ -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.hyperion.log import LOGGER
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.parameters.components import DiffractionExperimentWithSample
13
- from mx_bluesky.common.utils.log import set_dcgid_tag
14
- from mx_bluesky.hyperion.external_interaction.callbacks.plan_reactive_callback import (
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.hyperion.external_interaction.ispyb.data_model import (
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.hyperion.external_interaction.ispyb.ispyb_store import (
23
+ from mx_bluesky.common.external_interaction.ispyb.ispyb_store import (
23
24
  IspybIds,
24
25
  StoreInIspyb,
25
26
  )
26
- from mx_bluesky.hyperion.external_interaction.ispyb.ispyb_utils import get_ispyb_config
27
- from mx_bluesky.hyperion.log import ISPYB_LOGGER
28
- from mx_bluesky.hyperion.parameters.constants import CONST
29
- from mx_bluesky.hyperion.utils.utils import convert_eV_to_angstrom
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
- ISPYB_LOGGER.debug("Initialising ISPyB callback")
67
- super().__init__(log=ISPYB_LOGGER, emit=emit)
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 == CONST.SIM.ISPYB_CONFIG
75
- or self.ispyb_config == CONST.SIM.DEV_ISPYB_DATABASE_CFG
74
+ self.ispyb_config == SimConstants.ISPYB_CONFIG
75
+ or self.ispyb_config == SimConstants.DEV_ISPYB_DATABASE_CFG
76
76
  ):
77
- ISPYB_LOGGER.warning(
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 = ISPYB_LOGGER
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
- ISPYB_LOGGER.debug("ISPyB handler received event document.")
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
- ISPYB_LOGGER.warning(
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 CONST.DESCRIPTORS.HARDWARE_READ_PRE:
109
+ case DocDescriptorNames.HARDWARE_READ_PRE:
110
110
  scan_data_infos = self._handle_ispyb_hardware_read(doc)
111
- case CONST.DESCRIPTORS.HARDWARE_READ_DURING:
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
- ISPYB_LOGGER.info(f"Received ISPYB IDs: {self.ispyb_ids}")
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
- ISPYB_LOGGER.info("ISPyB handler received event from read hardware")
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"]["s4_slit_gaps_xgap"],
131
- slitgap_vertical=doc["data"]["s4_slit_gaps_ygap"],
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
- ISPYB_LOGGER.info("Updating ispyb data collection after hardware read.")
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"]["flux_flux_reading"],
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
- ISPYB_LOGGER.info("Updating ispyb data collection after flux read.")
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
- self.ispyb is not None
188
- ), "ISPyB handler received stop document, but deposition object doesn't exist!"
189
- ISPYB_LOGGER.debug("ISPyB handler received stop document.")
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
- ISPYB_LOGGER.warning(
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
- ISPYB_LOGGER.warning(
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.parameters.components import DiffractionExperimentWithSample
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.hyperion.external_interaction.ispyb.ispyb_store import (
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.hyperion.external_interaction.ispyb.ispyb_utils import (
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):
@@ -2,7 +2,7 @@ import json
2
2
 
3
3
  from bluesky.callbacks import CallbackBase
4
4
 
5
- from mx_bluesky.hyperion.log import LOGGER
5
+ from mx_bluesky.common.utils.log import LOGGER
6
6
 
7
7
 
8
8
  class _BestEffortEncoder(json.JSONEncoder):