mx-bluesky 1.4.4__py3-none-any.whl → 1.4.6__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 (74) hide show
  1. mx_bluesky/_version.py +9 -4
  2. mx_bluesky/beamlines/i04/redis_to_murko_forwarder.py +14 -3
  3. mx_bluesky/beamlines/i04/thawing_plan.py +9 -13
  4. mx_bluesky/beamlines/i24/serial/__init__.py +14 -0
  5. mx_bluesky/beamlines/i24/serial/dcid.py +3 -1
  6. mx_bluesky/beamlines/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +1 -1
  7. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +6 -3
  8. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +11 -11
  9. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_moveonclick.py +3 -3
  10. mx_bluesky/beamlines/i24/serial/log.py +0 -1
  11. mx_bluesky/beamlines/i24/serial/parameters/constants.py +1 -1
  12. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +3 -3
  13. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_detector.py +1 -1
  14. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_zebra_plans.py +2 -2
  15. mx_bluesky/beamlines/i24/serial/web_gui_plans/general_plans.py +109 -0
  16. mx_bluesky/beamlines/i24/serial/write_nexus.py +2 -2
  17. mx_bluesky/common/device_setup_plans/setup_panda.py +9 -0
  18. mx_bluesky/common/external_interaction/callbacks/common/plan_reactive_callback.py +2 -2
  19. mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_callback.py +11 -3
  20. mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_mapping.py +1 -1
  21. mx_bluesky/common/external_interaction/ispyb/exp_eye_store.py +6 -2
  22. mx_bluesky/common/external_interaction/ispyb/ispyb_store.py +7 -0
  23. mx_bluesky/common/parameters/constants.py +16 -0
  24. mx_bluesky/common/parameters/gridscan.py +36 -1
  25. mx_bluesky/common/plans/do_fgs.py +4 -6
  26. mx_bluesky/common/plans/read_hardware.py +78 -0
  27. mx_bluesky/common/utils/context.py +68 -0
  28. mx_bluesky/common/utils/exceptions.py +2 -1
  29. mx_bluesky/{hyperion/experiment_plans/common → common}/xrc_result.py +16 -0
  30. mx_bluesky/definitions.py +4 -0
  31. mx_bluesky/hyperion/__main__.py +11 -42
  32. mx_bluesky/hyperion/device_setup_plans/setup_oav.py +5 -5
  33. mx_bluesky/hyperion/device_setup_plans/setup_panda.py +9 -8
  34. mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +2 -2
  35. mx_bluesky/hyperion/device_setup_plans/smargon.py +6 -6
  36. mx_bluesky/hyperion/device_setup_plans/utils.py +2 -2
  37. mx_bluesky/hyperion/device_setup_plans/xbpm_feedback.py +14 -4
  38. mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py +2 -6
  39. mx_bluesky/hyperion/experiment_plans/experiment_registry.py +0 -15
  40. mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +42 -93
  41. mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +14 -6
  42. mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +26 -21
  43. mx_bluesky/hyperion/experiment_plans/oav_grid_detection_plan.py +11 -11
  44. mx_bluesky/hyperion/experiment_plans/oav_snapshot_plan.py +5 -9
  45. mx_bluesky/hyperion/experiment_plans/optimise_attenuation_plan.py +1 -1
  46. mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +2 -4
  47. mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +10 -10
  48. mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +11 -18
  49. mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +2 -4
  50. mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +19 -10
  51. mx_bluesky/hyperion/experiment_plans/set_energy_plan.py +2 -0
  52. mx_bluesky/hyperion/external_interaction/agamemnon.py +104 -0
  53. mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +19 -2
  54. mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +1 -1
  55. mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/sample_handling_callback.py +14 -9
  56. mx_bluesky/hyperion/external_interaction/config_server.py +13 -2
  57. mx_bluesky/hyperion/parameters/cli.py +1 -9
  58. mx_bluesky/hyperion/parameters/constants.py +6 -1
  59. mx_bluesky/hyperion/parameters/device_composites.py +49 -0
  60. mx_bluesky/hyperion/parameters/gridscan.py +5 -3
  61. mx_bluesky/hyperion/resources/panda/panda-gridscan.yaml +1006 -964
  62. mx_bluesky/hyperion/utils/__init__.py +1 -0
  63. mx_bluesky/hyperion/utils/context.py +0 -65
  64. mx_bluesky/hyperion/utils/validation.py +23 -20
  65. {mx_bluesky-1.4.4.dist-info → mx_bluesky-1.4.6.dist-info}/METADATA +5 -4
  66. {mx_bluesky-1.4.4.dist-info → mx_bluesky-1.4.6.dist-info}/RECORD +71 -66
  67. {mx_bluesky-1.4.4.dist-info → mx_bluesky-1.4.6.dist-info}/WHEEL +1 -1
  68. {mx_bluesky-1.4.4.dist-info → mx_bluesky-1.4.6.dist-info}/entry_points.txt +1 -0
  69. mx_bluesky/common/device_setup_plans/read_hardware_for_setup.py +0 -14
  70. mx_bluesky/hyperion/device_setup_plans/read_hardware_for_setup.py +0 -54
  71. mx_bluesky/hyperion/external_interaction/callbacks/common/callback_util.py +0 -95
  72. /mx_bluesky/{hyperion/external_interaction/callbacks/common → beamlines/i24/serial/web_gui_plans}/__init__.py +0 -0
  73. {mx_bluesky-1.4.4.dist-info → mx_bluesky-1.4.6.dist-info}/LICENSE +0 -0
  74. {mx_bluesky-1.4.4.dist-info → mx_bluesky-1.4.6.dist-info}/top_level.txt +0 -0
mx_bluesky/_version.py CHANGED
@@ -1,8 +1,13 @@
1
- # file generated by setuptools_scm
1
+ # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
+
4
+ __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
5
+
3
6
  TYPE_CHECKING = False
4
7
  if TYPE_CHECKING:
5
- from typing import Tuple, Union
8
+ from typing import Tuple
9
+ from typing import Union
10
+
6
11
  VERSION_TUPLE = Tuple[Union[int, str], ...]
7
12
  else:
8
13
  VERSION_TUPLE = object
@@ -12,5 +17,5 @@ __version__: str
12
17
  __version_tuple__: VERSION_TUPLE
13
18
  version_tuple: VERSION_TUPLE
14
19
 
15
- __version__ = version = '1.4.4'
16
- __version_tuple__ = version_tuple = (1, 4, 4)
20
+ __version__ = version = '1.4.6'
21
+ __version_tuple__ = version_tuple = (1, 4, 6)
@@ -156,8 +156,15 @@ class RedisListener:
156
156
  sample_id = data["sample_id"]
157
157
 
158
158
  # Images are put in redis as raw jpeg bytes, murko needs numpy arrays
159
- raw_image = self.redis_client.hget(f"murko:{sample_id}:raw", uuid)
160
- assert isinstance(raw_image, bytes)
159
+ image_key = f"murko:{sample_id}:raw"
160
+ raw_image = self.redis_client.hget(image_key, uuid)
161
+
162
+ if not isinstance(raw_image, bytes):
163
+ LOGGER.warning(
164
+ f"Image at {image_key}:{uuid} is {raw_image}, expected bytes. Ignoring the data"
165
+ )
166
+ return
167
+
161
168
  image = Image.open(io.BytesIO(raw_image))
162
169
  image = np.asarray(image)
163
170
 
@@ -173,6 +180,10 @@ class RedisListener:
173
180
  self._get_and_handle_message()
174
181
 
175
182
 
176
- if __name__ == "__main__":
183
+ def main():
177
184
  client = RedisListener()
178
185
  client.listen_for_image_data_forever()
186
+
187
+
188
+ if __name__ == "__main__":
189
+ main()
@@ -24,21 +24,17 @@ def thaw_and_stream_to_redis(
24
24
  oav: OAV = inject("oav"),
25
25
  oav_to_redis_forwarder: OAVToRedisForwarder = inject("oav_to_redis_forwarder"),
26
26
  ) -> MsgGenerator:
27
- zoom_percentage = yield from bps.rd(oav.zoom_controller.percentage) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
27
+ zoom_percentage = yield from bps.rd(oav.zoom_controller.percentage)
28
28
  sample_id = yield from bps.rd(robot.sample_id)
29
29
 
30
30
  sample_id = int(sample_id)
31
- zoom_level_before_thawing = yield from bps.rd(oav.zoom_controller.level) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
31
+ zoom_level_before_thawing = yield from bps.rd(oav.zoom_controller.level)
32
32
 
33
- yield from bps.mv(oav.zoom_controller.level, "1.0x") # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
33
+ yield from bps.mv(oav.zoom_controller.level, "1.0x")
34
34
 
35
35
  def switch_forwarder_to_ROI() -> MsgGenerator:
36
36
  yield from bps.complete(oav_to_redis_forwarder, wait=True)
37
- yield from bps.mv(
38
- # See: https://github.com/bluesky/bluesky/issues/1809
39
- oav_to_redis_forwarder.selected_source, # type: ignore
40
- Source.ROI.value, # type: ignore
41
- )
37
+ yield from bps.mv(oav_to_redis_forwarder.selected_source, Source.ROI.value)
42
38
  yield from bps.kickoff(oav_to_redis_forwarder, wait=True)
43
39
 
44
40
  microns_per_pixel_x = yield from bps.rd(oav.microns_per_pixel_x)
@@ -59,10 +55,10 @@ def thaw_and_stream_to_redis(
59
55
  )
60
56
  def _thaw_and_stream_to_redis():
61
57
  yield from bps.mv(
62
- oav_to_redis_forwarder.sample_id, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
63
- sample_id, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
64
- oav_to_redis_forwarder.selected_source, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
65
- Source.FULL_SCREEN.value, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
58
+ oav_to_redis_forwarder.sample_id,
59
+ sample_id,
60
+ oav_to_redis_forwarder.selected_source,
61
+ Source.FULL_SCREEN.value,
66
62
  )
67
63
 
68
64
  yield from bps.kickoff(oav_to_redis_forwarder, wait=True)
@@ -74,7 +70,7 @@ def thaw_and_stream_to_redis(
74
70
  yield from bps.complete(oav_to_redis_forwarder)
75
71
 
76
72
  def cleanup():
77
- yield from bps.mv(oav.zoom_controller.level, zoom_level_before_thawing) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
73
+ yield from bps.mv(oav.zoom_controller.level, zoom_level_before_thawing)
78
74
 
79
75
  yield from bpp.contingency_wrapper(
80
76
  _thaw_and_stream_to_redis(),
@@ -1,3 +1,11 @@
1
+ from mx_bluesky.beamlines.i24.serial.web_gui_plans.general_plans import (
2
+ gui_gonio_move_on_click,
3
+ gui_move_detector,
4
+ gui_set_parameters,
5
+ gui_sleep,
6
+ gui_stage_move_on_click,
7
+ )
8
+
1
9
  from .extruder.i24ssx_Extruder_Collect_py3v2 import (
2
10
  enter_hutch,
3
11
  initialise_extruder,
@@ -43,4 +51,10 @@ __all__ = [
43
51
  "pumpprobe_calc",
44
52
  "setup_collection_logs",
45
53
  "clean_up_log_config_at_end",
54
+ # GUI plans
55
+ "gui_stage_move_on_click",
56
+ "gui_gonio_move_on_click",
57
+ "gui_sleep",
58
+ "gui_move_detector",
59
+ "gui_set_parameters",
46
60
  ]
@@ -213,7 +213,9 @@ class DCID:
213
213
  "transmission": transmission,
214
214
  "visit": self.parameters.visit.name,
215
215
  "wavelength": beam_settings.wavelength_in_a,
216
- "group": {"experimentType": self.parameters.ispyb_experiment_type},
216
+ "group": {
217
+ "experimentType": self.parameters.ispyb_experiment_type.value
218
+ },
217
219
  "xBeam": xbeam,
218
220
  "yBeam": ybeam,
219
221
  "ssx": {
@@ -138,7 +138,7 @@ def enter_hutch(
138
138
  detector_stage: DetectorMotion = inject("detector_motion"),
139
139
  ) -> MsgGenerator:
140
140
  """Move the detector stage before entering hutch."""
141
- yield from bps.mv(detector_stage.z, SAFE_DET_Z) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
141
+ yield from bps.mv(detector_stage.z, SAFE_DET_Z)
142
142
  SSX_LOGGER.debug("Detector moved.")
143
143
 
144
144
 
@@ -290,7 +290,9 @@ def get_prog_num(
290
290
  def set_datasize(
291
291
  parameters: FixedTargetParameters,
292
292
  ):
293
- SSX_LOGGER.info("Setting PV to calculated total number of images")
293
+ SSX_LOGGER.info(
294
+ f"Setting PV to calculated total number of images: {parameters.total_num_images}"
295
+ )
294
296
 
295
297
  SSX_LOGGER.debug(f"Map type: {parameters.map_type}")
296
298
  SSX_LOGGER.debug(f"Chip type: {parameters.chip.chip_type}")
@@ -433,7 +435,8 @@ def start_i24(
433
435
 
434
436
  # DCID process depends on detector PVs being set up already
435
437
  SSX_LOGGER.debug("Start DCID process")
436
- filetemplate = f"{parameters.filename}.nxs"
438
+ complete_filename = cagetstring(pv.eiger_ODfilenameRBV)
439
+ filetemplate = f"{complete_filename}.nxs"
437
440
  dcid.generate_dcid(
438
441
  beam_settings=beam_settings,
439
442
  image_dir=filepath,
@@ -707,7 +710,7 @@ def run_fixed_target_plan(
707
710
  parameters.collection_directory.mkdir(parents=True, exist_ok=True)
708
711
 
709
712
  if parameters.chip_map:
710
- upload_chip_map_to_geobrick(pmac, parameters.chip_map)
713
+ yield from upload_chip_map_to_geobrick(pmac, parameters.chip_map)
711
714
 
712
715
  beam_center_device = sup.get_beam_center_device(parameters.detector_name)
713
716
 
@@ -548,11 +548,11 @@ def moveto(place: str = "origin", pmac: PMAC = inject("pmac")) -> MsgGenerator:
548
548
  chip_move = CHIP_MOVES[chip_type]
549
549
 
550
550
  if place == Fiducials.origin:
551
- yield from bps.mv(pmac.x, 0.0, pmac.y, 0.0) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
551
+ yield from bps.mv(pmac.x, 0.0, pmac.y, 0.0)
552
552
  if place == Fiducials.fid1:
553
- yield from bps.mv(pmac.x, chip_move, pmac.y, 0.0) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
553
+ yield from bps.mv(pmac.x, chip_move, pmac.y, 0.0)
554
554
  if place == Fiducials.fid2:
555
- yield from bps.mv(pmac.x, 0.0, pmac.y, chip_move) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
555
+ yield from bps.mv(pmac.x, 0.0, pmac.y, chip_move)
556
556
 
557
557
 
558
558
  @log_on_entry
@@ -580,7 +580,7 @@ def moveto_preset(
580
580
  elif place == "collect_position":
581
581
  SSX_LOGGER.info("collect position")
582
582
  caput(pv.me14e_filter, 20)
583
- yield from bps.mv(pmac.x, 0.0, pmac.y, 0.0, pmac.z, 0.0) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
583
+ yield from bps.mv(pmac.x, 0.0, pmac.y, 0.0, pmac.z, 0.0)
584
584
  yield from bps.abs_set(
585
585
  beamstop.pos_select, BeamstopPositions.DATA_COLLECTION, group=place
586
586
  )
@@ -589,7 +589,7 @@ def moveto_preset(
589
589
 
590
590
  elif place == "microdrop_position":
591
591
  SSX_LOGGER.info("microdrop align position")
592
- yield from bps.mv(pmac.x, 6.0, pmac.y, -7.8, pmac.z, 0.0) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
592
+ yield from bps.mv(pmac.x, 6.0, pmac.y, -7.8, pmac.z, 0.0)
593
593
 
594
594
 
595
595
  @log_on_entry
@@ -665,15 +665,15 @@ def fiducial(point: int = 1, pmac: PMAC = inject("pmac")) -> MsgGenerator:
665
665
  output_param_path.mkdir(parents=True, exist_ok=True)
666
666
  SSX_LOGGER.info(f"Writing Fiducial File {output_param_path}/fiducial_{point}.txt")
667
667
  SSX_LOGGER.info("MTR\tRBV\tRAW\tCorr\tf_value")
668
- SSX_LOGGER.info(f"MTR1\t{rbv_1:1.4f}\t{mtr1_dir:d}")
669
- SSX_LOGGER.info(f"MTR2\t{rbv_2:1.4f}\t{mtr2_dir:d}")
670
- SSX_LOGGER.info(f"MTR3\t{rbv_3:1.4f}\t{mtr3_dir:d}")
668
+ SSX_LOGGER.info(f"MTR1\t{rbv_1:1.4f}\t{mtr1_dir:f}")
669
+ SSX_LOGGER.info(f"MTR2\t{rbv_2:1.4f}\t{mtr2_dir:f}")
670
+ SSX_LOGGER.info(f"MTR3\t{rbv_3:1.4f}\t{mtr3_dir:f}")
671
671
 
672
672
  with open(output_param_path / f"fiducial_{point}.txt", "w") as f:
673
673
  f.write("MTR\tRBV\tCorr\n")
674
- f.write(f"MTR1\t{rbv_1:1.4f}\t{mtr1_dir:d}\n")
675
- f.write(f"MTR2\t{rbv_2:1.4f}\t{mtr2_dir:d}\n")
676
- f.write(f"MTR3\t{rbv_3:1.4f}\t{mtr3_dir:d}")
674
+ f.write(f"MTR1\t{rbv_1:1.4f}\t{mtr1_dir:f}\n")
675
+ f.write(f"MTR2\t{rbv_2:1.4f}\t{mtr2_dir:f}\n")
676
+ f.write(f"MTR3\t{rbv_3:1.4f}\t{mtr3_dir:f}")
677
677
  SSX_LOGGER.info(f"Fiducial {point} set.")
678
678
  yield from bps.null()
679
679
 
@@ -33,7 +33,7 @@ def _get_beam_centre(oav: OAV):
33
33
 
34
34
  def _calculate_zoom_calibrator(oav: OAV):
35
35
  """Set the scale for the zoom calibrator for the pmac moves."""
36
- currentzoom = yield from bps.rd(oav.zoom_controller.percentage) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
36
+ currentzoom = yield from bps.rd(oav.zoom_controller.percentage)
37
37
  zoomcalibrator = 1.547 - (0.03 * currentzoom) + (0.0001634 * currentzoom**2)
38
38
  return zoomcalibrator
39
39
 
@@ -215,6 +215,6 @@ def start_viewer(oav: OAV, pmac: PMAC, RE: RunEngine, oav1: str = OAV1_CAM):
215
215
  if __name__ == "__main__":
216
216
  RE = RunEngine(call_returns_result=True)
217
217
  # Get devices out of dodal
218
- oav: OAV = i24.oav()
219
- pmac: PMAC = i24.pmac()
218
+ oav: OAV = i24.oav(connect_immediately=True)
219
+ pmac: PMAC = i24.pmac(connect_immediately=True)
220
220
  start_viewer(oav, pmac, RE)
@@ -108,7 +108,6 @@ def config(
108
108
  # Remove dodal StreamHandler to avoid duplication of messages above debug
109
109
  dodal_logger.removeHandler(dodal_logger.handlers[0])
110
110
  _integrate_bluesky_logs(dodal_logger)
111
-
112
111
  if logfile:
113
112
  logs = _get_logging_file_path() / logfile
114
113
  fileFormatter = logging.Formatter(
@@ -25,7 +25,7 @@ BEAM_CENTER_LUT_FILES = {
25
25
 
26
26
 
27
27
  OAV_CONFIG_FILES = {
28
- "zoom_params_file": "/dls_sw/i24/software/gda_versions/gda_9_34/config/xml/jCameraManZoomLevels.xml",
28
+ "zoom_params_file": "/dls_sw/i24/software/gda_versions/gda_9_36/config/xml/jCameraManZoomLevels.xml",
29
29
  "oav_config_json": "/dls_sw/i24/software/daq_configuration/json/OAVCentring.json",
30
30
  "display_config": "/dls_sw/i24/software/gda_versions/var/display.configuration",
31
31
  }
@@ -21,9 +21,9 @@ from mx_bluesky.beamlines.i24.serial.setup_beamline.ca import caget, caput
21
21
 
22
22
  def get_beam_center_device(detector_in_use: str) -> DetectorBeamCenter:
23
23
  if detector_in_use == "eiger":
24
- return i24.eiger_beam_center()
24
+ return i24.eiger_beam_center(connect_immediately=True)
25
25
  else:
26
- return i24.pilatus_beam_center()
26
+ return i24.pilatus_beam_center(connect_immediately=True)
27
27
 
28
28
 
29
29
  def compute_beam_center_position_from_lut(
@@ -84,7 +84,7 @@ def move_detector_stage_to_position_plan(
84
84
  SSX_LOGGER.debug(
85
85
  f"Waiting for detector move. Detector distance: {detector_distance} mm."
86
86
  )
87
- yield from bps.mv(detector_stage.z, detector_distance) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
87
+ yield from bps.mv(detector_stage.z, detector_distance)
88
88
 
89
89
 
90
90
  def set_detector_beam_center_plan(
@@ -55,7 +55,7 @@ def get_detector_type(detector_stage: DetectorMotion) -> Generator[Msg, None, De
55
55
 
56
56
  def _move_detector_stage(detector_stage: DetectorMotion, target: float) -> MsgGenerator:
57
57
  SSX_LOGGER.info(f"Moving detector stage to target position: {target}.")
58
- yield from bps.mv(detector_stage.y, target) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
58
+ yield from bps.mv(detector_stage.y, target)
59
59
 
60
60
 
61
61
  # Workaround in case the PV value has been set to the detector name
@@ -55,12 +55,12 @@ def get_zebra_settings_for_extruder(
55
55
 
56
56
 
57
57
  def arm_zebra(zebra: Zebra):
58
- yield from bps.abs_set(zebra.pc.arm, ArmDemand.ARM, wait=True) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
58
+ yield from bps.abs_set(zebra.pc.arm, ArmDemand.ARM, wait=True)
59
59
  SSX_LOGGER.info("Zebra armed.")
60
60
 
61
61
 
62
62
  def disarm_zebra(zebra: Zebra):
63
- yield from bps.abs_set(zebra.pc.arm, ArmDemand.DISARM, wait=True) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
63
+ yield from bps.abs_set(zebra.pc.arm, ArmDemand.DISARM, wait=True)
64
64
  SSX_LOGGER.info("Zebra disarmed.")
65
65
 
66
66
 
@@ -0,0 +1,109 @@
1
+ # from collections.abc import Sequence
2
+ from typing import Literal
3
+
4
+ import bluesky.plan_stubs as bps
5
+ import bluesky.preprocessors as bpp
6
+ from blueapi.core import MsgGenerator
7
+ from dodal.beamlines import i24
8
+
9
+ from mx_bluesky.beamlines.i24.serial.fixed_target.ft_utils import (
10
+ ChipType,
11
+ MappingType,
12
+ PumpProbeSetting,
13
+ )
14
+ from mx_bluesky.beamlines.i24.serial.fixed_target.i24ssx_moveonclick import (
15
+ _move_on_mouse_click_plan,
16
+ )
17
+ from mx_bluesky.beamlines.i24.serial.log import _read_visit_directory_from_file
18
+ from mx_bluesky.beamlines.i24.serial.parameters import (
19
+ FixedTargetParameters,
20
+ get_chip_format,
21
+ )
22
+ from mx_bluesky.beamlines.i24.serial.setup_beamline import pv
23
+ from mx_bluesky.beamlines.i24.serial.setup_beamline.ca import caput
24
+ from mx_bluesky.beamlines.i24.serial.setup_beamline.pv_abstract import Eiger, Pilatus
25
+ from mx_bluesky.beamlines.i24.serial.setup_beamline.setup_detector import (
26
+ _move_detector_stage,
27
+ get_detector_type,
28
+ )
29
+
30
+
31
+ @bpp.run_decorator()
32
+ def gui_stage_move_on_click(position_px: tuple[int, int]) -> MsgGenerator:
33
+ oav = i24.oav()
34
+ pmac = i24.pmac()
35
+ yield from _move_on_mouse_click_plan(oav, pmac, position_px)
36
+
37
+
38
+ @bpp.run_decorator()
39
+ def gui_gonio_move_on_click(position_px: tuple[int, int]) -> MsgGenerator:
40
+ oav = i24.oav()
41
+ gonio = i24.vgonio()
42
+
43
+ x_pixels_per_micron = yield from bps.rd(oav.microns_per_pixel_x)
44
+ y_pixels_per_micron = yield from bps.rd(oav.microns_per_pixel_y)
45
+
46
+ x_um = position_px[0] * x_pixels_per_micron
47
+ y_um = position_px[1] * y_pixels_per_micron
48
+
49
+ # gonio is in mm?
50
+ yield from bps.mv(gonio.x, x_um / 1000, gonio.yh, y_um / 1000) # type: ignore
51
+
52
+
53
+ # See https://github.com/DiamondLightSource/mx-bluesky/issues/853
54
+ @bpp.run_decorator()
55
+ def gui_sleep(sec: int) -> MsgGenerator:
56
+ for _ in range(sec):
57
+ yield from bps.sleep(1)
58
+
59
+
60
+ @bpp.run_decorator()
61
+ def gui_move_detector(det: Literal["eiger", "pilatus"]) -> MsgGenerator:
62
+ detector_stage = i24.detector_motion()
63
+ det_y_target = Eiger.det_y_target if det == "eiger" else Pilatus.det_y_target
64
+ yield from _move_detector_stage(detector_stage, det_y_target)
65
+ # Make the output readable
66
+ caput(pv.me14e_gp101, det)
67
+
68
+
69
+ @bpp.run_decorator()
70
+ def gui_set_parameters(
71
+ sub_dir: str,
72
+ chip_name: str,
73
+ exp_time: float,
74
+ det_dist: float,
75
+ transmission: float,
76
+ n_shots: int,
77
+ chip_type: str,
78
+ checker_pattern: bool,
79
+ pump_probe: str,
80
+ laser_dwell: float,
81
+ laser_delay: float,
82
+ pre_pump: float,
83
+ ) -> MsgGenerator:
84
+ # NOTE still a work in progress, adding to it as the ui grows
85
+ detector_stage = i24.detector_motion()
86
+ det_type = yield from get_detector_type(detector_stage)
87
+ chip_params = get_chip_format(ChipType[chip_type])
88
+
89
+ params = {
90
+ "visit": _read_visit_directory_from_file().as_posix(), # noqa
91
+ "directory": sub_dir,
92
+ "filename": chip_name,
93
+ "exposure_time_s": exp_time,
94
+ "detector_distance_mm": det_dist,
95
+ "detector_name": str(det_type),
96
+ "num_exposures": n_shots,
97
+ "transmission": transmission,
98
+ "chip": chip_params,
99
+ "map_type": MappingType.NoMap,
100
+ "chip_map": [],
101
+ "pump_repeat": PumpProbeSetting[pump_probe], # pump_repeat,
102
+ "laser_dwell_s": laser_dwell,
103
+ "laser_delay_s": laser_delay,
104
+ "checker_pattern": checker_pattern,
105
+ "pre_pump_exposure_s": pre_pump,
106
+ }
107
+ print(FixedTargetParameters(**params))
108
+ # This will then run the run_fixed_target plan
109
+ yield from bps.sleep(0.5)
@@ -12,7 +12,7 @@ from mx_bluesky.beamlines.i24.serial.parameters import (
12
12
  ExtruderParameters,
13
13
  FixedTargetParameters,
14
14
  )
15
- from mx_bluesky.beamlines.i24.serial.setup_beamline import Eiger, caget
15
+ from mx_bluesky.beamlines.i24.serial.setup_beamline import Eiger, caget, cagetstring
16
16
 
17
17
 
18
18
  def call_nexgen(
@@ -53,7 +53,7 @@ def call_nexgen(
53
53
  total_numb_imgs = parameters.num_images
54
54
  pump_status = parameters.pump_status
55
55
 
56
- filename_prefix = parameters.filename
56
+ filename_prefix = cagetstring(Eiger.pv.filenameRBV)
57
57
  meta_h5 = parameters.visit / parameters.directory / f"{filename_prefix}_meta.h5"
58
58
  t0 = time.time()
59
59
  max_wait = 60 # seconds
@@ -0,0 +1,9 @@
1
+ from ophyd_async.core import YamlSettingsProvider
2
+ from ophyd_async.fastcs.panda import HDFPanda
3
+ from ophyd_async.plan_stubs import apply_panda_settings, retrieve_settings
4
+
5
+
6
+ def load_panda_from_yaml(yaml_directory: str, yaml_file_name: str, panda: HDFPanda):
7
+ provider = YamlSettingsProvider(yaml_directory)
8
+ settings = yield from retrieve_settings(provider, yaml_file_name, panda)
9
+ yield from apply_panda_settings(settings)
@@ -36,7 +36,7 @@ class PlanReactiveCallback(CallbackBase):
36
36
  super().__init__(emit=emit)
37
37
  self.emit_cb = emit # to avoid GC; base class only holds a WeakRef
38
38
  self.active = False
39
- self.activity_uid = 0
39
+ self.activity_uid = ""
40
40
  self.log = log
41
41
 
42
42
  def _run_activity_gated(self, name: str, func, doc, override=False):
@@ -76,7 +76,7 @@ class PlanReactiveCallback(CallbackBase):
76
76
  do_stop = self.active
77
77
  if doc.get("run_start") == self.activity_uid:
78
78
  self.active = False
79
- self.activity_uid = 0
79
+ self.activity_uid = ""
80
80
  return (
81
81
  self._run_activity_gated(
82
82
  "stop", self.activity_gated_stop, doc, override=True
@@ -43,7 +43,10 @@ from mx_bluesky.common.parameters.constants import DocDescriptorNames, PlanNameC
43
43
  from mx_bluesky.common.parameters.gridscan import (
44
44
  GridCommon,
45
45
  )
46
- from mx_bluesky.common.utils.exceptions import ISPyBDepositionNotMade
46
+ from mx_bluesky.common.utils.exceptions import (
47
+ ISPyBDepositionNotMade,
48
+ SampleException,
49
+ )
47
50
  from mx_bluesky.common.utils.log import ISPYB_ZOCALO_CALLBACK_LOGGER, set_dcgid_tag
48
51
 
49
52
  if TYPE_CHECKING:
@@ -113,7 +116,7 @@ class GridscanISPyBCallback(BaseISPyBCallback):
113
116
  scan_data_infos = [
114
117
  ScanDataInfo(
115
118
  data_collection_info=populate_remaining_data_collection_info(
116
- None,
119
+ "MX-Bluesky: Xray centring 1 -",
117
120
  None,
118
121
  populate_xy_data_collection_info(
119
122
  self.params.detector_params,
@@ -123,7 +126,7 @@ class GridscanISPyBCallback(BaseISPyBCallback):
123
126
  ),
124
127
  ScanDataInfo(
125
128
  data_collection_info=populate_remaining_data_collection_info(
126
- None,
129
+ "MX-Bluesky: Xray centring 2 -",
127
130
  None,
128
131
  populate_xz_data_collection_info(self.params.detector_params),
129
132
  self.params,
@@ -281,5 +284,10 @@ class GridscanISPyBCallback(BaseISPyBCallback):
281
284
  )
282
285
  if self.ispyb_ids == IspybIds():
283
286
  raise ISPyBDepositionNotMade("ispyb was not initialised at run start")
287
+ exception_type, message = SampleException.type_and_message_from_reason(
288
+ doc.get("reason", "")
289
+ )
290
+ if exception_type:
291
+ doc["reason"] = message
284
292
  return super().activity_gated_stop(doc)
285
293
  return self._tag_doc(doc)
@@ -43,7 +43,7 @@ def construct_comment_for_gridscan(grid_info: DataCollectionGridInfo) -> str:
43
43
  grid_info.microns_per_pixel_y,
44
44
  )
45
45
  return (
46
- "MX-Bluesky: Xray centring - Diffraction grid scan of "
46
+ "Diffraction grid scan of "
47
47
  f"{grid_info.steps_x} by "
48
48
  f"{grid_info.steps_y} images in "
49
49
  f"{(grid_info.dx_in_mm * 1e3):.1f} um by "
@@ -2,7 +2,7 @@ import configparser
2
2
  from dataclasses import dataclass
3
3
  from enum import StrEnum
4
4
 
5
- from requests import patch, post
5
+ from requests import JSONDecodeError, patch, post
6
6
  from requests.auth import AuthBase
7
7
 
8
8
  from mx_bluesky.common.external_interaction.ispyb.ispyb_utils import (
@@ -34,7 +34,11 @@ def _get_base_url_and_token() -> tuple[str, str]:
34
34
  def _send_and_get_response(auth, url, data, send_func) -> dict:
35
35
  response = send_func(url, auth=auth, json=data)
36
36
  if not response.ok:
37
- raise ISPyBDepositionNotMade(f"Could not write {data} to {url}: {response}")
37
+ try:
38
+ resp_txt = str(response.json())
39
+ except JSONDecodeError:
40
+ resp_txt = str(response)
41
+ raise ISPyBDepositionNotMade(f"Could not write {data} to {url}: {resp_txt}")
38
42
  return response.json()
39
43
 
40
44
 
@@ -206,9 +206,16 @@ class StoreInIspyb:
206
206
  def _store_data_collection_table(
207
207
  self, conn, data_collection_id, data_collection_info
208
208
  ):
209
+ if data_collection_id and data_collection_info.comments:
210
+ self.append_to_comment(
211
+ data_collection_id, data_collection_info.comments, " "
212
+ )
213
+ data_collection_info.comments = None
214
+
209
215
  params = self._fill_common_data_collection_params(
210
216
  conn, data_collection_id, data_collection_info
211
217
  )
218
+
212
219
  return self._upsert_data_collection(conn, params)
213
220
 
214
221
  def _store_single_scan_data(
@@ -1,3 +1,4 @@
1
+ import os
1
2
  from enum import Enum
2
3
 
3
4
  from dodal.devices.aperturescatterguard import ApertureValue
@@ -6,6 +7,8 @@ from dodal.devices.zocalo.zocalo_constants import ZOCALO_ENV as ZOCALO_ENV_FROM_
6
7
  from dodal.utils import get_beamline_name
7
8
  from pydantic.dataclasses import dataclass
8
9
 
10
+ from mx_bluesky.definitions import ROOT_DIR
11
+
9
12
  BEAMLINE = get_beamline_name("test")
10
13
  TEST_MODE = BEAMLINE == "test"
11
14
 
@@ -75,6 +78,10 @@ class HardwareConstants:
75
78
  THAWING_TIME = 20
76
79
  TIP_OFFSET_UM = 0
77
80
 
81
+ # Value quoted in https://www.dectris.com/en/detectors/x-ray-detectors/eiger2/eiger2-for-synchrotrons/eiger2-x/,
82
+ # causes dropped frames, so increase value for safety
83
+ PANDA_FGS_EIGER_DEADTIME_S = 5e-5
84
+
78
85
 
79
86
  @dataclass(frozen=True)
80
87
  class GridscanParamConstants:
@@ -118,6 +125,15 @@ class PlanGroupCheckpointConstants:
118
125
  READY_FOR_OAV = "ready_for_oav"
119
126
 
120
127
 
128
+ # Eventually replace below with https://github.com/DiamondLightSource/mx-bluesky/issues/798
129
+ @dataclass(frozen=True)
130
+ class DeviceSettingsConstants:
131
+ PANDA_FLYSCAN_SETTINGS_FILENAME = "panda-gridscan"
132
+ PANDA_FLYSCAN_SETTINGS_DIR = os.path.abspath(
133
+ f"{ROOT_DIR}/hyperion/resources/panda/"
134
+ )
135
+
136
+
121
137
  @dataclass(frozen=True)
122
138
  class SimConstants:
123
139
  BEAMLINE = "BL03S"