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
@@ -4,9 +4,7 @@ This version in python3 new Feb2021 by RLO
4
4
  - March 21 added logging and Eiger functionality
5
5
  """
6
6
 
7
- import json
8
7
  import re
9
- import shutil
10
8
  import sys
11
9
  import time
12
10
  from datetime import datetime
@@ -18,25 +16,29 @@ import bluesky.plan_stubs as bps
18
16
  import bluesky.preprocessors as bpp
19
17
  from bluesky.utils import MsgGenerator
20
18
  from dodal.common import inject
19
+ from dodal.devices.attenuator.attenuator import ReadOnlyAttenuator
21
20
  from dodal.devices.hutch_shutter import HutchShutter, ShutterDemand
22
21
  from dodal.devices.i24.aperture import Aperture
22
+ from dodal.devices.i24.beam_center import DetectorBeamCenter
23
23
  from dodal.devices.i24.beamstop import Beamstop
24
24
  from dodal.devices.i24.dcm import DCM
25
25
  from dodal.devices.i24.dual_backlight import DualBacklight
26
+ from dodal.devices.i24.focus_mirrors import FocusMirrorsMode
26
27
  from dodal.devices.i24.i24_detector_motion import DetectorMotion
27
- from dodal.devices.zebra import DISCONNECT, SOFT_IN3, Zebra
28
+ from dodal.devices.zebra.zebra import Zebra
28
29
 
29
- from mx_bluesky.beamlines.i24.serial.dcid import DCID
30
+ from mx_bluesky.beamlines.i24.serial.dcid import (
31
+ DCID,
32
+ get_pilatus_filename_template_from_device,
33
+ read_beam_info_from_hardware,
34
+ )
30
35
  from mx_bluesky.beamlines.i24.serial.log import (
31
36
  SSX_LOGGER,
32
37
  _read_visit_directory_from_file,
33
38
  log_on_entry,
34
39
  )
35
- from mx_bluesky.beamlines.i24.serial.parameters import ExtruderParameters, SSXType
36
- from mx_bluesky.beamlines.i24.serial.parameters.constants import (
37
- PARAM_FILE_NAME,
38
- PARAM_FILE_PATH,
39
- )
40
+ from mx_bluesky.beamlines.i24.serial.parameters import ExtruderParameters
41
+ from mx_bluesky.beamlines.i24.serial.parameters.constants import BEAM_CENTER_LUT_FILES
40
42
  from mx_bluesky.beamlines.i24.serial.setup_beamline import Pilatus, caget, caput, pv
41
43
  from mx_bluesky.beamlines.i24.serial.setup_beamline import setup_beamline as sup
42
44
  from mx_bluesky.beamlines.i24.serial.setup_beamline.setup_detector import (
@@ -45,8 +47,6 @@ from mx_bluesky.beamlines.i24.serial.setup_beamline.setup_detector import (
45
47
  )
46
48
  from mx_bluesky.beamlines.i24.serial.setup_beamline.setup_zebra_plans import (
47
49
  GATE_START,
48
- TTL_EIGER,
49
- TTL_PILATUS,
50
50
  arm_zebra,
51
51
  disarm_zebra,
52
52
  open_fast_shutter,
@@ -114,13 +114,22 @@ def laser_check(
114
114
 
115
115
  det_type = yield from get_detector_type(detector_stage)
116
116
 
117
- LASER_TTL = TTL_EIGER if isinstance(det_type, Pilatus) else TTL_PILATUS
117
+ LASER_TTL = (
118
+ zebra.mapping.outputs.TTL_EIGER
119
+ if isinstance(det_type, Pilatus)
120
+ else zebra.mapping.outputs.TTL_PILATUS
121
+ )
122
+
118
123
  if mode == "laseron":
119
- yield from bps.abs_set(zebra.output.out_pvs[LASER_TTL], SOFT_IN3)
124
+ yield from bps.abs_set(
125
+ zebra.output.out_pvs[LASER_TTL], zebra.mapping.sources.SOFT_IN3
126
+ )
120
127
  yield from set_shutter_mode(zebra, "auto")
121
128
 
122
129
  if mode == "laseroff":
123
- yield from bps.abs_set(zebra.output.out_pvs[LASER_TTL], DISCONNECT)
130
+ yield from bps.abs_set(
131
+ zebra.output.out_pvs[LASER_TTL], zebra.mapping.sources.DISCONNECT
132
+ )
124
133
  yield from set_shutter_mode(zebra, "manual")
125
134
 
126
135
 
@@ -134,10 +143,20 @@ def enter_hutch(
134
143
 
135
144
 
136
145
  @log_on_entry
137
- def write_parameter_file(detector_stage: DetectorMotion):
138
- """Writes a json parameter file that can later be parsed by the model."""
139
- param_file: Path = PARAM_FILE_PATH / PARAM_FILE_NAME
140
- SSX_LOGGER.debug(f"Writing Parameter File to: {param_file}\n")
146
+ def read_parameters(detector_stage: DetectorMotion, attenuator: ReadOnlyAttenuator):
147
+ """ Read the parameters from user input and create the parameter model for an \
148
+ extruder collection.
149
+
150
+ Args:
151
+ detector_stage (DetectorMotion): The detector stage device.
152
+ attenuator (ReadOnlyAttenuator): A read-only attenuator device to get the \
153
+ transmission value.
154
+
155
+ Returns:
156
+ ExtruderParameters: Parameter model for extruder collections
157
+
158
+ """
159
+ SSX_LOGGER.info("Creating parameter model from input.")
141
160
 
142
161
  det_type = yield from get_detector_type(detector_stage)
143
162
  SSX_LOGGER.warning(f"DETECTOR TYPE: {det_type}")
@@ -154,9 +173,11 @@ def write_parameter_file(detector_stage: DetectorMotion):
154
173
  f"Requested filename ends in a number. Appended dash: {filename}"
155
174
  )
156
175
 
176
+ transmission = yield from bps.rd(attenuator.actual_transmission)
177
+
157
178
  pump_status = bool(int(caget(pv.ioc12_gp6)))
158
- pump_exp = float(caget(pv.ioc12_gp9)) if pump_status else None
159
- pump_delay = float(caget(pv.ioc12_gp10)) if pump_status else None
179
+ pump_exp = float(caget(pv.ioc12_gp9)) if pump_status else 0.0
180
+ pump_delay = float(caget(pv.ioc12_gp10)) if pump_status else 0.0
160
181
 
161
182
  params_dict = {
162
183
  "visit": _read_visit_directory_from_file().as_posix(), # noqa
@@ -165,17 +186,17 @@ def write_parameter_file(detector_stage: DetectorMotion):
165
186
  "exposure_time_s": float(caget(pv.ioc12_gp5)),
166
187
  "detector_distance_mm": float(caget(pv.ioc12_gp7)),
167
188
  "detector_name": str(det_type),
189
+ "transmission": transmission,
168
190
  "num_images": int(caget(pv.ioc12_gp4)),
169
191
  "pump_status": pump_status,
170
192
  "laser_dwell_s": pump_exp,
171
193
  "laser_delay_s": pump_delay,
172
194
  }
173
- with open(param_file, "w") as f:
174
- json.dump(params_dict, f, indent=4)
175
195
 
176
196
  SSX_LOGGER.info("Parameters \n")
177
197
  SSX_LOGGER.info(pformat(params_dict))
178
198
  yield from bps.null()
199
+ return ExtruderParameters(**params_dict)
179
200
 
180
201
 
181
202
  @log_on_entry
@@ -187,10 +208,22 @@ def main_extruder_plan(
187
208
  detector_stage: DetectorMotion,
188
209
  shutter: HutchShutter,
189
210
  dcm: DCM,
211
+ mirrors: FocusMirrorsMode,
212
+ beam_center_device: DetectorBeamCenter,
190
213
  parameters: ExtruderParameters,
191
214
  dcid: DCID,
192
215
  start_time: datetime,
193
216
  ) -> MsgGenerator:
217
+ beam_center_pixels = sup.compute_beam_center_position_from_lut(
218
+ BEAM_CENTER_LUT_FILES[parameters.detector_name],
219
+ parameters.detector_distance_mm,
220
+ parameters.detector_size_constants,
221
+ )
222
+ yield from sup.set_detector_beam_center_plan(
223
+ beam_center_device,
224
+ beam_center_pixels,
225
+ )
226
+
194
227
  # Setting up the beamline
195
228
  SSX_LOGGER.info("Open hutch shutter")
196
229
  yield from bps.abs_set(shutter, ShutterDemand.OPEN, wait=True)
@@ -262,7 +295,6 @@ def main_extruder_plan(
262
295
  SSX_LOGGER.info("Using Eiger detector")
263
296
 
264
297
  SSX_LOGGER.debug(f"Creating the directory for the collection in {filepath}.")
265
- Path(filepath).mkdir(parents=True, exist_ok=True)
266
298
 
267
299
  caput(pv.eiger_seqID, int(caget(pv.eiger_seqID)) + 1)
268
300
  SSX_LOGGER.info(f"Eiger quickshot setup: filepath {filepath}")
@@ -316,16 +348,22 @@ def main_extruder_plan(
316
348
  SSX_LOGGER.error(err)
317
349
  raise UnknownDetectorType(err)
318
350
 
351
+ beam_settings = yield from read_beam_info_from_hardware(
352
+ dcm, mirrors, beam_center_device, parameters.detector_name
353
+ )
354
+
319
355
  # Do DCID creation BEFORE arming the detector
356
+ if parameters.detector_name == "eiger":
357
+ filetemplate = f"{parameters.filename}.nxs"
358
+ else:
359
+ filetemplate = yield from get_pilatus_filename_template_from_device()
320
360
  dcid.generate_dcid(
321
- visit=parameters.visit.name,
361
+ beam_settings=beam_settings,
322
362
  image_dir=parameters.collection_directory.as_posix(),
323
- start_time=start_time,
363
+ file_template=filetemplate,
324
364
  num_images=parameters.num_images,
325
- exposure_time=parameters.exposure_time_s,
326
- pump_exposure_time=parameters.laser_dwell_s,
327
- pump_delay=parameters.laser_delay_s or 0,
328
- pump_status=int(parameters.pump_status),
365
+ start_time=start_time,
366
+ pump_probe=parameters.pump_status,
329
367
  )
330
368
 
331
369
  # Collect
@@ -341,9 +379,16 @@ def main_extruder_plan(
341
379
  dcid.notify_start()
342
380
 
343
381
  if parameters.detector_name == "eiger":
344
- wavelength = yield from bps.rd(dcm.wavelength_in_a)
345
382
  SSX_LOGGER.debug("Call nexgen server for nexus writing.")
346
- call_nexgen(None, start_time, parameters, wavelength, "extruder")
383
+ beam_x = yield from bps.rd(beam_center_device.beam_x)
384
+ beam_y = yield from bps.rd(beam_center_device.beam_y)
385
+ call_nexgen(
386
+ None,
387
+ parameters,
388
+ beam_settings.wavelength_in_a,
389
+ (beam_x, beam_y),
390
+ start_time,
391
+ )
347
392
 
348
393
  timeout_time = time.time() + parameters.num_images * parameters.exposure_time_s + 10
349
394
 
@@ -436,11 +481,6 @@ def collection_complete_plan(
436
481
  dcid.collection_complete(end_time, aborted=False)
437
482
  SSX_LOGGER.info(f"End Time = {end_time.ctime()}")
438
483
 
439
- # Copy parameter file
440
- shutil.copy2(
441
- PARAM_FILE_PATH / PARAM_FILE_NAME,
442
- collection_directory / PARAM_FILE_NAME,
443
- )
444
484
  yield from bps.null()
445
485
 
446
486
 
@@ -452,19 +492,22 @@ def run_extruder_plan(
452
492
  detector_stage: DetectorMotion = inject("detector_motion"),
453
493
  shutter: HutchShutter = inject("shutter"),
454
494
  dcm: DCM = inject("dcm"),
495
+ mirrors: FocusMirrorsMode = inject("focus_mirrors"),
496
+ attenuator: ReadOnlyAttenuator = inject("attenuator"),
455
497
  ) -> MsgGenerator:
456
498
  start_time = datetime.now()
457
499
  SSX_LOGGER.info(f"Collection start time: {start_time.ctime()}")
458
500
 
459
- yield from write_parameter_file(detector_stage)
460
- parameters = ExtruderParameters.from_file(PARAM_FILE_PATH / PARAM_FILE_NAME)
501
+ parameters: ExtruderParameters = yield from read_parameters(
502
+ detector_stage, attenuator
503
+ )
504
+ # Create collection directory
505
+ parameters.collection_directory.mkdir(parents=True, exist_ok=True)
506
+
507
+ beam_center_device = sup.get_beam_center_device(parameters.detector_name)
461
508
 
462
509
  # DCID - not generated yet
463
- dcid = DCID(
464
- emit_errors=False,
465
- ssx_type=SSXType.EXTRUDER,
466
- detector=parameters.detector_name,
467
- )
510
+ dcid = DCID(emit_errors=False, expt_params=parameters)
468
511
 
469
512
  yield from bpp.contingency_wrapper(
470
513
  main_extruder_plan(
@@ -475,6 +518,8 @@ def run_extruder_plan(
475
518
  detector_stage=detector_stage,
476
519
  shutter=shutter,
477
520
  dcm=dcm,
521
+ mirrors=mirrors,
522
+ beam_center_device=beam_center_device,
478
523
  parameters=parameters,
479
524
  dcid=dcid,
480
525
  start_time=start_time,
@@ -323,7 +323,7 @@ font "helvetica-bold-r-24.0"
323
323
  buttonLabel "Start"
324
324
  numCmds 1
325
325
  command {
326
- 0 "blueapi -c CONFIG_LOCATION controller run run_fixed_target_plan '\{\"zebra\":\"zebra\",\"pmac\":\"pmac\",\"aperture\":\"aperture\",\"backlight\":\"backlight\",\"beamstop\":\"beamstop\",\"detector_stage\":\"detector_motion\",\"shutter\":\"shutter\",\"dcm\":\"dcm\"\}'"
326
+ 0 "blueapi -c CONFIG_LOCATION controller run run_fixed_target_plan '\{\"zebra\":\"zebra\",\"pmac\":\"pmac\",\"aperture\":\"aperture\",\"backlight\":\"backlight\",\"beamstop\":\"beamstop\",\"detector_stage\":\"detector_motion\",\"shutter\":\"shutter\",\"dcm\":\"dcm\",\"mirrors\":\"focus_mirrors\",\"attenuator\":\"attenuator\"\}'"
327
327
  }
328
328
  endObjectProperties
329
329
 
@@ -3,8 +3,8 @@ beginScreenProperties
3
3
  major 4
4
4
  minor 0
5
5
  release 1
6
- x 1062
7
- y 369
6
+ x 308
7
+ y 339
8
8
  w 650
9
9
  h 400
10
10
  font "arial-medium-r-18.0"
@@ -179,50 +179,6 @@ font "arial-medium-r-18.0"
179
179
  colorPv "ME14E-MO-IOC-01:GP67"
180
180
  endObjectProperties
181
181
 
182
- # (Shell Command)
183
- object shellCmdClass
184
- beginObjectProperties
185
- major 4
186
- minor 3
187
- release 0
188
- x 40
189
- y 290
190
- w 194
191
- h 40
192
- fgColor index 0
193
- bgColor index 23
194
- topShadowColor index 1
195
- botShadowColor index 11
196
- font "arial-medium-r-18.0"
197
- buttonLabel "Save Screen Map"
198
- numCmds 1
199
- command {
200
- 0 "blueapi -c CONFIG_LOCATION controller run save_screen_map"
201
- }
202
- endObjectProperties
203
-
204
- # (Shell Command)
205
- object shellCmdClass
206
- beginObjectProperties
207
- major 4
208
- minor 3
209
- release 0
210
- x 12
211
- y 337
212
- w 244
213
- h 53
214
- fgColor index 13
215
- bgColor index 49
216
- topShadowColor index 1
217
- botShadowColor index 11
218
- font "arial-medium-r-18.0"
219
- buttonLabel "Upload Parameters"
220
- numCmds 1
221
- command {
222
- 0 "blueapi -c CONFIG_LOCATION controller run upload_parameters '\{\"pmac\":\"pmac\"\}'"
223
- }
224
- endObjectProperties
225
-
226
182
  # (Message Button)
227
183
  object activeMessageButtonClass
228
184
  beginObjectProperties
@@ -2,45 +2,43 @@
2
2
  Fixed target data collection
3
3
  """
4
4
 
5
- import shutil
6
5
  from datetime import datetime
7
6
  from pathlib import Path
8
7
  from time import sleep
9
8
 
10
9
  import bluesky.plan_stubs as bps
11
10
  import bluesky.preprocessors as bpp
12
- import numpy as np
13
11
  from bluesky.utils import MsgGenerator
14
12
  from dodal.common import inject
13
+ from dodal.devices.attenuator.attenuator import ReadOnlyAttenuator
15
14
  from dodal.devices.hutch_shutter import HutchShutter, ShutterDemand
16
15
  from dodal.devices.i24.aperture import Aperture
16
+ from dodal.devices.i24.beam_center import DetectorBeamCenter
17
17
  from dodal.devices.i24.beamstop import Beamstop
18
18
  from dodal.devices.i24.dcm import DCM
19
19
  from dodal.devices.i24.dual_backlight import DualBacklight
20
+ from dodal.devices.i24.focus_mirrors import FocusMirrorsMode
20
21
  from dodal.devices.i24.i24_detector_motion import DetectorMotion
21
22
  from dodal.devices.i24.pmac import PMAC
22
- from dodal.devices.zebra import Zebra
23
+ from dodal.devices.zebra.zebra import Zebra
23
24
 
24
- from mx_bluesky.beamlines.i24.serial.dcid import DCID
25
+ from mx_bluesky.beamlines.i24.serial.dcid import (
26
+ DCID,
27
+ get_pilatus_filename_template_from_device,
28
+ read_beam_info_from_hardware,
29
+ )
25
30
  from mx_bluesky.beamlines.i24.serial.fixed_target.ft_utils import (
26
31
  ChipType,
27
32
  MappingType,
28
33
  PumpProbeSetting,
29
34
  )
30
35
  from mx_bluesky.beamlines.i24.serial.fixed_target.i24ssx_Chip_Manager_py3v1 import (
31
- write_parameter_file,
36
+ read_parameters,
37
+ upload_chip_map_to_geobrick,
32
38
  )
33
39
  from mx_bluesky.beamlines.i24.serial.log import SSX_LOGGER, log_on_entry
34
- from mx_bluesky.beamlines.i24.serial.parameters import (
35
- ChipDescription,
36
- FixedTargetParameters,
37
- SSXType,
38
- )
39
- from mx_bluesky.beamlines.i24.serial.parameters.constants import (
40
- LITEMAP_PATH,
41
- PARAM_FILE_NAME,
42
- PARAM_FILE_PATH_FT,
43
- )
40
+ from mx_bluesky.beamlines.i24.serial.parameters import FixedTargetParameters
41
+ from mx_bluesky.beamlines.i24.serial.parameters.constants import BEAM_CENTER_LUT_FILES
44
42
  from mx_bluesky.beamlines.i24.serial.setup_beamline import caget, cagetstring, caput, pv
45
43
  from mx_bluesky.beamlines.i24.serial.setup_beamline import setup_beamline as sup
46
44
  from mx_bluesky.beamlines.i24.serial.setup_beamline.setup_zebra_plans import (
@@ -101,19 +99,6 @@ def calculate_collection_timeout(parameters: FixedTargetParameters) -> float:
101
99
  return timeout
102
100
 
103
101
 
104
- def copy_files_to_data_location(
105
- dest_dir: Path | str,
106
- param_path: Path = PARAM_FILE_PATH_FT,
107
- map_file: Path = LITEMAP_PATH,
108
- map_type: MappingType = MappingType.Lite,
109
- ):
110
- if not isinstance(dest_dir, Path):
111
- dest_dir = Path(dest_dir)
112
- shutil.copy2(param_path / "parameters.txt", dest_dir / "parameters.txt")
113
- if map_type == MappingType.Lite:
114
- shutil.copy2(map_file / "currentchip.map", dest_dir / "currentchip.map")
115
-
116
-
117
102
  def write_userlog(
118
103
  parameters: FixedTargetParameters,
119
104
  filename: str,
@@ -302,50 +287,18 @@ def get_prog_num(
302
287
 
303
288
 
304
289
  @log_on_entry
305
- def datasetsizei24(
306
- n_exposures: int,
307
- chip_params: ChipDescription,
308
- map_type: MappingType,
309
- ) -> int:
310
- # Calculates how many images will be collected based on map type and N repeats
311
- SSX_LOGGER.info("Calculate total number of images expected in data collection.")
312
-
313
- if map_type == MappingType.NoMap:
314
- if chip_params.chip_type == ChipType.Custom:
315
- total_numb_imgs = chip_params.x_num_steps * chip_params.y_num_steps
316
- SSX_LOGGER.info(
317
- f"Map type: None \tCustom chip \tNumber of images {total_numb_imgs}"
318
- )
319
- else:
320
- chip_format = chip_params.chip_format[:4]
321
- total_numb_imgs = int(np.prod(chip_format))
322
- SSX_LOGGER.info(
323
- f"""Map type: None \tOxford chip {chip_params.chip_type} \t \
324
- Number of images {total_numb_imgs}"""
325
- )
326
-
327
- elif map_type == MappingType.Lite:
328
- SSX_LOGGER.info(f"Using Mapping Lite on chip type {chip_params.chip_type}")
329
- chip_format = chip_params.chip_format[2:4]
330
- block_count = 0
331
- with open(LITEMAP_PATH / "currentchip.map") as f:
332
- for line in f.readlines():
333
- entry = line.split()
334
- if entry[2] == "1":
335
- block_count += 1
336
-
337
- SSX_LOGGER.info(f"Block count={block_count}")
338
- SSX_LOGGER.info(f"Chip format={chip_format}")
339
-
340
- SSX_LOGGER.info(f"Number of exposures={n_exposures}")
341
-
342
- total_numb_imgs = int(np.prod(chip_format) * block_count * n_exposures)
343
- SSX_LOGGER.info(f"Calculated number of images: {total_numb_imgs}")
290
+ def set_datasize(
291
+ parameters: FixedTargetParameters,
292
+ ):
293
+ SSX_LOGGER.info("Setting PV to calculated total number of images")
344
294
 
345
- SSX_LOGGER.info("Set PV to calculated number of images.")
346
- caput(pv.me14e_gp10, int(total_numb_imgs))
295
+ SSX_LOGGER.debug(f"Map type: {parameters.map_type}")
296
+ SSX_LOGGER.debug(f"Chip type: {parameters.chip.chip_type}")
297
+ if parameters.map_type == MappingType.Lite:
298
+ SSX_LOGGER.debug(f"Num exposures: {parameters.num_exposures}")
299
+ SSX_LOGGER.debug(f"Block count: {len(parameters.chip_map)}")
347
300
 
348
- return int(total_numb_imgs)
301
+ caput(pv.me14e_gp10, parameters.total_num_images)
349
302
 
350
303
 
351
304
  @log_on_entry
@@ -357,6 +310,9 @@ def start_i24(
357
310
  detector_stage: DetectorMotion,
358
311
  shutter: HutchShutter,
359
312
  parameters: FixedTargetParameters,
313
+ dcm: DCM,
314
+ mirrors: FocusMirrorsMode,
315
+ beam_center_device: DetectorBeamCenter,
360
316
  dcid: DCID,
361
317
  ):
362
318
  """Set up for I24 fixed target data collection, trigger the detector and open \
@@ -364,6 +320,9 @@ def start_i24(
364
320
  Returns the start_time.
365
321
  """
366
322
 
323
+ beam_settings = yield from read_beam_info_from_hardware(
324
+ dcm, mirrors, beam_center_device, parameters.detector_name
325
+ )
367
326
  SSX_LOGGER.info("Start I24 data collection.")
368
327
  start_time = datetime.now()
369
328
  SSX_LOGGER.info(f"Collection start time {start_time.ctime()}")
@@ -413,16 +372,15 @@ def start_i24(
413
372
 
414
373
  # DCID process depends on detector PVs being set up already
415
374
  SSX_LOGGER.debug("Start DCID process")
375
+ filetemplate = yield from get_pilatus_filename_template_from_device()
416
376
  dcid.generate_dcid(
417
- visit=parameters.visit.name,
377
+ beam_settings=beam_settings,
418
378
  image_dir=filepath,
419
- start_time=start_time,
379
+ file_template=filetemplate,
420
380
  num_images=parameters.total_num_images,
421
- exposure_time=parameters.exposure_time_s,
422
381
  shots_per_position=parameters.num_exposures,
423
- pump_exposure_time=parameters.laser_dwell_s,
424
- pump_delay=parameters.laser_delay_s or 0,
425
- pump_status=parameters.pump_repeat.value,
382
+ start_time=start_time,
383
+ pump_probe=bool(parameters.pump_repeat),
426
384
  )
427
385
 
428
386
  SSX_LOGGER.debug("Arm Pilatus. Arm Zebra.")
@@ -453,7 +411,6 @@ def start_i24(
453
411
  SSX_LOGGER.info("Using Eiger detector")
454
412
 
455
413
  SSX_LOGGER.debug(f"Creating the directory for the collection in {filepath}.")
456
- Path(filepath).mkdir(parents=True, exist_ok=True)
457
414
 
458
415
  SSX_LOGGER.info(f"Triggered Eiger setup: filepath {filepath}")
459
416
  SSX_LOGGER.info(f"Triggered Eiger setup: filename {filename}")
@@ -476,16 +433,15 @@ def start_i24(
476
433
 
477
434
  # DCID process depends on detector PVs being set up already
478
435
  SSX_LOGGER.debug("Start DCID process")
436
+ filetemplate = f"{parameters.filename}.nxs"
479
437
  dcid.generate_dcid(
480
- visit=parameters.visit.name,
438
+ beam_settings=beam_settings,
481
439
  image_dir=filepath,
482
- start_time=start_time,
440
+ file_template=filetemplate,
483
441
  num_images=parameters.total_num_images,
484
- exposure_time=parameters.exposure_time_s,
485
442
  shots_per_position=parameters.num_exposures,
486
- pump_exposure_time=parameters.laser_dwell_s,
487
- pump_delay=parameters.laser_delay_s or 0,
488
- pump_status=parameters.pump_repeat.value,
443
+ start_time=start_time,
444
+ pump_probe=bool(parameters.pump_repeat),
489
445
  )
490
446
 
491
447
  SSX_LOGGER.debug("Arm Zebra.")
@@ -584,11 +540,23 @@ def main_fixed_target_plan(
584
540
  detector_stage: DetectorMotion,
585
541
  shutter: HutchShutter,
586
542
  dcm: DCM,
543
+ mirrors: FocusMirrorsMode,
544
+ beam_center_device: DetectorBeamCenter,
587
545
  parameters: FixedTargetParameters,
588
546
  dcid: DCID,
589
547
  ) -> MsgGenerator:
590
548
  SSX_LOGGER.info("Running a chip collection on I24")
591
549
 
550
+ beam_center_pixels = sup.compute_beam_center_position_from_lut(
551
+ BEAM_CENTER_LUT_FILES[parameters.detector_name],
552
+ parameters.detector_distance_mm,
553
+ parameters.detector_size_constants,
554
+ )
555
+ yield from sup.set_detector_beam_center_plan(
556
+ beam_center_device,
557
+ beam_center_pixels,
558
+ )
559
+
592
560
  SSX_LOGGER.info("Getting Program Dictionary")
593
561
 
594
562
  # If alignment type is Oxford inner it is still an Oxford type chip
@@ -606,12 +574,20 @@ def main_fixed_target_plan(
606
574
  parameters.checker_pattern,
607
575
  )
608
576
 
609
- parameters.total_num_images = datasetsizei24(
610
- parameters.num_exposures, parameters.chip, parameters.map_type
611
- )
577
+ set_datasize(parameters)
612
578
 
613
579
  start_time = yield from start_i24(
614
- zebra, aperture, backlight, beamstop, detector_stage, shutter, parameters, dcid
580
+ zebra,
581
+ aperture,
582
+ backlight,
583
+ beamstop,
584
+ detector_stage,
585
+ shutter,
586
+ parameters,
587
+ dcm,
588
+ mirrors,
589
+ beam_center_device,
590
+ dcid,
615
591
  )
616
592
 
617
593
  SSX_LOGGER.info("Moving to Start")
@@ -626,14 +602,13 @@ def main_fixed_target_plan(
626
602
  SSX_LOGGER.debug("Notify DCID of the start of the collection.")
627
603
  dcid.notify_start()
628
604
 
629
- wavelength = yield from bps.rd(dcm.wavelength_in_a)
630
605
  if parameters.detector_name == "eiger":
606
+ wavelength = yield from bps.rd(dcm.wavelength_in_a)
607
+ beam_x = yield from bps.rd(beam_center_device.beam_x)
608
+ beam_y = yield from bps.rd(beam_center_device.beam_y)
631
609
  SSX_LOGGER.debug("Start nexus writing service.")
632
610
  call_nexgen(
633
- chip_prog_dict,
634
- start_time,
635
- parameters,
636
- wavelength,
611
+ chip_prog_dict, parameters, wavelength, (beam_x, beam_y), start_time
637
612
  )
638
613
 
639
614
  yield from kickoff_and_complete_collection(pmac, parameters)
@@ -670,8 +645,7 @@ def collection_complete_plan(
670
645
  SSX_LOGGER.debug(f"Collection end time {end_time}")
671
646
  dcid.collection_complete(end_time, aborted=False)
672
647
 
673
- # Copy parameter file and eventual chip map to collection directory
674
- copy_files_to_data_location(collection_directory, map_type=map_type)
648
+ # NOTE no files to copy anymore but shoud write userlog here
675
649
  yield from bps.null()
676
650
 
677
651
 
@@ -721,37 +695,24 @@ def run_fixed_target_plan(
721
695
  detector_stage: DetectorMotion = inject("detector_motion"),
722
696
  shutter: HutchShutter = inject("shutter"),
723
697
  dcm: DCM = inject("dcm"),
698
+ mirrors: FocusMirrorsMode = inject("focus_mirrors"),
699
+ attenuator: ReadOnlyAttenuator = inject("attenuator"),
724
700
  ) -> MsgGenerator:
725
- # in the first instance, write params here
726
- yield from write_parameter_file(detector_stage)
727
-
728
- SSX_LOGGER.info("Getting parameters from file.")
729
- parameters = FixedTargetParameters.from_file(PARAM_FILE_PATH_FT / PARAM_FILE_NAME)
730
-
731
- log_msg = f"""
732
- Parameters for I24 serial collection: \n
733
- Chip name is {parameters.filename}
734
- visit = {parameters.visit}
735
- sub_dir = {parameters.directory}
736
- n_exposures = {parameters.num_exposures}
737
- chip_type = {str(parameters.chip.chip_type)}
738
- map_type = {str(parameters.map_type)}
739
- dcdetdist = {parameters.detector_distance_mm}
740
- exptime = {parameters.exposure_time_s}
741
- det_type = {parameters.detector_name}
742
- pump_repeat = {str(parameters.pump_repeat)}
743
- pumpexptime = {parameters.laser_dwell_s}
744
- pumpdelay = {parameters.laser_delay_s}
745
- prepumpexptime = {parameters.pre_pump_exposure_s}
746
- """
747
- SSX_LOGGER.info(log_msg)
701
+ # Read the parameters
702
+ parameters: FixedTargetParameters = yield from read_parameters(
703
+ detector_stage, attenuator
704
+ )
705
+
706
+ # Create collection directory
707
+ parameters.collection_directory.mkdir(parents=True, exist_ok=True)
708
+
709
+ if parameters.chip_map:
710
+ upload_chip_map_to_geobrick(pmac, parameters.chip_map)
711
+
712
+ beam_center_device = sup.get_beam_center_device(parameters.detector_name)
748
713
 
749
714
  # DCID instance - do not create yet
750
- dcid = DCID(
751
- emit_errors=False,
752
- ssx_type=SSXType.FIXED,
753
- detector=parameters.detector_name,
754
- )
715
+ dcid = DCID(emit_errors=False, expt_params=parameters)
755
716
 
756
717
  yield from bpp.contingency_wrapper(
757
718
  main_fixed_target_plan(
@@ -763,6 +724,8 @@ def run_fixed_target_plan(
763
724
  detector_stage,
764
725
  shutter,
765
726
  dcm,
727
+ mirrors,
728
+ beam_center_device,
766
729
  parameters,
767
730
  dcid,
768
731
  ),