mx-bluesky 1.4.5__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 (63) 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 +1 -1
  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 +1 -1
  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/__init__.py +0 -0
  16. mx_bluesky/beamlines/i24/serial/web_gui_plans/general_plans.py +109 -0
  17. mx_bluesky/beamlines/i24/serial/write_nexus.py +2 -2
  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 +2 -2
  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 +1 -1
  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/{hyperion/experiment_plans/common → common}/xrc_result.py +16 -0
  29. mx_bluesky/hyperion/__main__.py +4 -0
  30. mx_bluesky/hyperion/device_setup_plans/setup_oav.py +5 -5
  31. mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +2 -2
  32. mx_bluesky/hyperion/device_setup_plans/smargon.py +6 -6
  33. mx_bluesky/hyperion/device_setup_plans/utils.py +2 -2
  34. mx_bluesky/hyperion/device_setup_plans/xbpm_feedback.py +4 -4
  35. mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py +2 -6
  36. mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +33 -87
  37. mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +6 -6
  38. mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +3 -5
  39. mx_bluesky/hyperion/experiment_plans/oav_grid_detection_plan.py +11 -11
  40. mx_bluesky/hyperion/experiment_plans/oav_snapshot_plan.py +4 -4
  41. mx_bluesky/hyperion/experiment_plans/optimise_attenuation_plan.py +1 -1
  42. mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +2 -4
  43. mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +10 -10
  44. mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +10 -10
  45. mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +2 -4
  46. mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +7 -9
  47. mx_bluesky/hyperion/external_interaction/agamemnon.py +104 -0
  48. mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +1 -1
  49. mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/sample_handling_callback.py +14 -9
  50. mx_bluesky/hyperion/external_interaction/config_server.py +6 -6
  51. mx_bluesky/hyperion/parameters/device_composites.py +49 -0
  52. mx_bluesky/hyperion/parameters/gridscan.py +1 -1
  53. mx_bluesky/hyperion/utils/__init__.py +1 -0
  54. mx_bluesky/hyperion/utils/context.py +0 -65
  55. mx_bluesky/hyperion/utils/validation.py +3 -3
  56. {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.6.dist-info}/METADATA +4 -3
  57. {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.6.dist-info}/RECORD +61 -56
  58. {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.6.dist-info}/WHEEL +1 -1
  59. {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.6.dist-info}/entry_points.txt +1 -0
  60. mx_bluesky/common/device_setup_plans/read_hardware_for_setup.py +0 -14
  61. mx_bluesky/hyperion/device_setup_plans/read_hardware_for_setup.py +0 -54
  62. {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.6.dist-info}/LICENSE +0 -0
  63. {mx_bluesky-1.4.5.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.5'
16
- __version_tuple__ = version_tuple = (1, 4, 5)
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
 
@@ -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
  }
@@ -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
@@ -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
@@ -116,7 +116,7 @@ class GridscanISPyBCallback(BaseISPyBCallback):
116
116
  scan_data_infos = [
117
117
  ScanDataInfo(
118
118
  data_collection_info=populate_remaining_data_collection_info(
119
- None,
119
+ "MX-Bluesky: Xray centring 1 -",
120
120
  None,
121
121
  populate_xy_data_collection_info(
122
122
  self.params.detector_params,
@@ -126,7 +126,7 @@ class GridscanISPyBCallback(BaseISPyBCallback):
126
126
  ),
127
127
  ScanDataInfo(
128
128
  data_collection_info=populate_remaining_data_collection_info(
129
- None,
129
+ "MX-Bluesky: Xray centring 2 -",
130
130
  None,
131
131
  populate_xz_data_collection_info(self.params.detector_params),
132
132
  self.params,
@@ -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(
@@ -130,7 +130,7 @@ class PlanGroupCheckpointConstants:
130
130
  class DeviceSettingsConstants:
131
131
  PANDA_FLYSCAN_SETTINGS_FILENAME = "panda-gridscan"
132
132
  PANDA_FLYSCAN_SETTINGS_DIR = os.path.abspath(
133
- f"{ROOT_DIR}/hyperion/resources/panda/{PANDA_FLYSCAN_SETTINGS_FILENAME}"
133
+ f"{ROOT_DIR}/hyperion/resources/panda/"
134
134
  )
135
135
 
136
136
 
@@ -1,9 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dodal.devices.aperturescatterguard import ApertureValue
4
+ from dodal.devices.detector.det_dim_constants import EIGER2_X_9M_SIZE, EIGER2_X_16M_SIZE
5
+ from dodal.devices.detector.detector import DetectorParams
4
6
  from dodal.devices.fast_grid_scan import (
5
7
  ZebraGridScanParams,
6
8
  )
9
+ from dodal.utils import get_beamline_name
7
10
  from pydantic import Field, PrivateAttr
8
11
  from scanspec.core import Path as ScanPath
9
12
  from scanspec.specs import Line, Static
@@ -18,11 +21,12 @@ from mx_bluesky.common.parameters.components import (
18
21
  XyzStarts,
19
22
  )
20
23
  from mx_bluesky.common.parameters.constants import (
24
+ DetectorParamConstants,
21
25
  GridscanParamConstants,
22
26
  HardwareConstants,
23
27
  )
24
28
 
25
- """Parameter models in this file are abstract. They should be inherited by a top-level model"""
29
+ DETECTOR_SIZE_PER_BEAMLINE = {"i02-1": EIGER2_X_9M_SIZE, "dev": EIGER2_X_16M_SIZE}
26
30
 
27
31
 
28
32
  class GridCommon(
@@ -146,3 +150,34 @@ class SpecifiedThreeDGridScan(
146
150
  @property
147
151
  def num_images(self) -> int:
148
152
  return len(self.scan_points["sam_x"])
153
+
154
+ @property
155
+ def detector_params(self):
156
+ self.det_dist_to_beam_converter_path = (
157
+ self.det_dist_to_beam_converter_path
158
+ or DetectorParamConstants.BEAM_XY_LUT_PATH
159
+ )
160
+ optional_args = {}
161
+ if self.run_number:
162
+ optional_args["run_number"] = self.run_number
163
+ assert self.detector_distance_mm is not None, (
164
+ "Detector distance must be filled before generating DetectorParams"
165
+ )
166
+ return DetectorParams(
167
+ detector_size_constants=DETECTOR_SIZE_PER_BEAMLINE[
168
+ get_beamline_name("dev")
169
+ ],
170
+ expected_energy_ev=self.demand_energy_ev,
171
+ exposure_time=self.exposure_time_s,
172
+ directory=self.storage_directory,
173
+ prefix=self.file_name,
174
+ detector_distance=self.detector_distance_mm,
175
+ omega_start=self.omega_start_deg or 0,
176
+ omega_increment=0,
177
+ num_images_per_trigger=1,
178
+ num_triggers=self.num_images,
179
+ use_roi_mode=self.use_roi_mode,
180
+ det_dist_to_beam_converter_path=self.det_dist_to_beam_converter_path,
181
+ trigger_mode=self.trigger_mode,
182
+ **optional_args,
183
+ )
@@ -14,12 +14,10 @@ from dodal.log import LOGGER
14
14
  from dodal.plan_stubs.check_topup import check_topup_and_wait_if_necessary
15
15
  from scanspec.core import AxesPoints, Axis
16
16
 
17
- from mx_bluesky.common.device_setup_plans.read_hardware_for_setup import (
18
- read_hardware_for_zocalo,
19
- )
20
17
  from mx_bluesky.common.parameters.constants import (
21
18
  PlanNameConstants,
22
19
  )
20
+ from mx_bluesky.common.plans.read_hardware import read_hardware_for_zocalo
23
21
  from mx_bluesky.common.utils.tracing import TRACER
24
22
 
25
23
 
@@ -30,7 +28,7 @@ def _wait_for_zocalo_to_stage_then_do_fgs(
30
28
  during_collection_plan: Callable[[], MsgGenerator] | None = None,
31
29
  ):
32
30
  expected_images = yield from bps.rd(grid_scan_device.expected_images)
33
- exposure_sec_per_image = yield from bps.rd(detector.cam.acquire_time) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
31
+ exposure_sec_per_image = yield from bps.rd(detector.cam.acquire_time) # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855)
34
32
  LOGGER.info("waiting for topup if necessary...")
35
33
  yield from check_topup_and_wait_if_necessary(
36
34
  synchrotron,
@@ -101,8 +99,8 @@ def kickoff_and_complete_gridscan(
101
99
  }
102
100
  )
103
101
  @bpp.contingency_decorator(
104
- except_plan=lambda e: (yield from bps.stop(detector)), # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
105
- else_plan=lambda: (yield from bps.unstage(detector)), # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
102
+ except_plan=lambda e: (yield from bps.stop(detector)), # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855)
103
+ else_plan=lambda: (yield from bps.unstage(detector)),
106
104
  )
107
105
  def _decorated_do_fgs():
108
106
  yield from _wait_for_zocalo_to_stage_then_do_fgs(