mx-bluesky 1.4.0__py3-none-any.whl → 1.4.1__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 (78) 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/i04/thawing_plan.py +1 -1
  4. mx_bluesky/beamlines/i24/serial/dcid.py +143 -171
  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 +54 -21
  7. mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/DiamondChipI24-py3v1.edl +2 -5
  8. mx_bluesky/beamlines/i24/serial/fixed_target/ft_utils.py +0 -1
  9. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +67 -50
  10. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +26 -79
  11. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_StartUp_py3v1.py +0 -199
  12. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_moveonclick.py +4 -6
  13. mx_bluesky/beamlines/i24/serial/log.py +1 -1
  14. mx_bluesky/beamlines/i24/serial/parameters/__init__.py +4 -0
  15. mx_bluesky/beamlines/i24/serial/parameters/constants.py +6 -1
  16. mx_bluesky/beamlines/i24/serial/parameters/experiment_parameters.py +42 -15
  17. mx_bluesky/beamlines/i24/serial/run_fixed_target.sh +4 -3
  18. mx_bluesky/beamlines/i24/serial/setup_beamline/pv.py +2 -0
  19. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +103 -81
  20. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_detector.py +1 -2
  21. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_zebra_plans.py +24 -26
  22. mx_bluesky/beamlines/i24/serial/write_nexus.py +74 -72
  23. mx_bluesky/common/external_interaction/config_server.py +46 -0
  24. mx_bluesky/common/parameters/components.py +52 -15
  25. mx_bluesky/common/parameters/constants.py +11 -1
  26. mx_bluesky/common/parameters/gridscan.py +94 -0
  27. mx_bluesky/{hyperion → common}/parameters/robot_load.py +2 -2
  28. mx_bluesky/common/plans/do_fgs.py +2 -2
  29. mx_bluesky/common/utils/log.py +2 -0
  30. mx_bluesky/hyperion/__main__.py +2 -1
  31. mx_bluesky/hyperion/device_setup_plans/dcm_pitch_roll_mirror_adjuster.py +21 -31
  32. mx_bluesky/hyperion/device_setup_plans/setup_panda.py +4 -4
  33. mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +1 -1
  34. mx_bluesky/hyperion/device_setup_plans/smargon.py +3 -3
  35. mx_bluesky/hyperion/exceptions.py +13 -1
  36. mx_bluesky/hyperion/experiment_plans/__init__.py +4 -0
  37. mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py +83 -0
  38. mx_bluesky/hyperion/experiment_plans/common/xrc_result.py +47 -0
  39. mx_bluesky/hyperion/experiment_plans/experiment_registry.py +9 -9
  40. mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +133 -97
  41. mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +42 -18
  42. mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +75 -9
  43. mx_bluesky/hyperion/experiment_plans/oav_grid_detection_plan.py +2 -2
  44. mx_bluesky/hyperion/experiment_plans/oav_snapshot_plan.py +1 -1
  45. mx_bluesky/hyperion/experiment_plans/optimise_attenuation_plan.py +2 -2
  46. mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +36 -17
  47. mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +5 -5
  48. mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +28 -28
  49. mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +64 -16
  50. mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +11 -3
  51. mx_bluesky/hyperion/experiment_plans/set_energy_plan.py +10 -10
  52. mx_bluesky/hyperion/external_interaction/callbacks/__init__.py +0 -4
  53. mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +4 -0
  54. mx_bluesky/hyperion/external_interaction/callbacks/common/abstract_event.py +66 -0
  55. mx_bluesky/hyperion/external_interaction/callbacks/common/callback_util.py +5 -0
  56. mx_bluesky/hyperion/external_interaction/callbacks/grid_detection_callback.py +15 -15
  57. mx_bluesky/hyperion/external_interaction/callbacks/robot_load/ispyb_callback.py +18 -10
  58. mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +3 -1
  59. mx_bluesky/hyperion/external_interaction/callbacks/rotation/nexus_callback.py +5 -3
  60. mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/__init__.py +0 -0
  61. mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/sample_handling_callback.py +84 -0
  62. mx_bluesky/hyperion/external_interaction/callbacks/xray_centre/ispyb_callback.py +15 -9
  63. mx_bluesky/hyperion/external_interaction/callbacks/xray_centre/nexus_callback.py +5 -4
  64. mx_bluesky/hyperion/external_interaction/config_server.py +8 -37
  65. mx_bluesky/hyperion/external_interaction/exceptions.py +0 -9
  66. mx_bluesky/hyperion/external_interaction/ispyb/exp_eye_store.py +65 -15
  67. mx_bluesky/hyperion/parameters/components.py +4 -9
  68. mx_bluesky/hyperion/parameters/constants.py +0 -1
  69. mx_bluesky/hyperion/parameters/gridscan.py +33 -76
  70. mx_bluesky/hyperion/parameters/load_centre_collect.py +14 -9
  71. mx_bluesky/hyperion/parameters/rotation.py +15 -6
  72. {mx_bluesky-1.4.0.dist-info → mx_bluesky-1.4.1.dist-info}/METADATA +35 -34
  73. {mx_bluesky-1.4.0.dist-info → mx_bluesky-1.4.1.dist-info}/RECORD +77 -70
  74. {mx_bluesky-1.4.0.dist-info → mx_bluesky-1.4.1.dist-info}/WHEEL +1 -1
  75. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Mapping_py3v1.py +0 -150
  76. {mx_bluesky-1.4.0.dist-info → mx_bluesky-1.4.1.dist-info}/LICENSE +0 -0
  77. {mx_bluesky-1.4.0.dist-info → mx_bluesky-1.4.1.dist-info}/entry_points.txt +0 -0
  78. {mx_bluesky-1.4.0.dist-info → mx_bluesky-1.4.1.dist-info}/top_level.txt +0 -0
@@ -5,7 +5,6 @@ This version changed to python3 March2020 by RLO
5
5
 
6
6
  import json
7
7
  import re
8
- import shutil
9
8
  import sys
10
9
  import time
11
10
  from pathlib import Path
@@ -14,25 +13,15 @@ from time import sleep
14
13
 
15
14
  import bluesky.plan_stubs as bps
16
15
  import numpy as np
17
- from blueapi.core import MsgGenerator
18
- from dodal.beamlines import i24
16
+ from bluesky.utils import MsgGenerator
19
17
  from dodal.common import inject
18
+ from dodal.devices.attenuator import ReadOnlyAttenuator
20
19
  from dodal.devices.i24.beamstop import Beamstop, BeamstopPositions
21
20
  from dodal.devices.i24.dual_backlight import BacklightPositions, DualBacklight
22
21
  from dodal.devices.i24.i24_detector_motion import DetectorMotion
23
22
  from dodal.devices.i24.pmac import PMAC, EncReset, LaserSettings
24
23
 
25
- from mx_bluesky.beamlines.i24.serial.fixed_target import (
26
- i24ssx_Chip_Mapping_py3v1 as mapping,
27
- )
28
- from mx_bluesky.beamlines.i24.serial.fixed_target import (
29
- i24ssx_Chip_StartUp_py3v1 as startup,
30
- )
31
- from mx_bluesky.beamlines.i24.serial.fixed_target.ft_utils import (
32
- ChipType,
33
- Fiducials,
34
- MappingType,
35
- )
24
+ from mx_bluesky.beamlines.i24.serial.fixed_target.ft_utils import ChipType, Fiducials
36
25
  from mx_bluesky.beamlines.i24.serial.log import (
37
26
  SSX_LOGGER,
38
27
  _read_visit_directory_from_file,
@@ -41,7 +30,6 @@ from mx_bluesky.beamlines.i24.serial.log import (
41
30
  from mx_bluesky.beamlines.i24.serial.parameters import get_chip_format
42
31
  from mx_bluesky.beamlines.i24.serial.parameters.constants import (
43
32
  CS_FILES_PATH,
44
- FULLMAP_PATH,
45
33
  LITEMAP_PATH,
46
34
  PARAM_FILE_NAME,
47
35
  PARAM_FILE_PATH_FT,
@@ -106,6 +94,9 @@ def initialise_stages(
106
94
  sleep(0.1)
107
95
  SSX_LOGGER.info("Clearing General Purpose PVs 1-120")
108
96
  for i in range(4, 120):
97
+ if i == 100:
98
+ # Do not clear visit PV
99
+ continue
109
100
  pvar = "ME14E-MO-IOC-01:GP" + str(i)
110
101
  caput(pvar, 0)
111
102
  sys.stdout.write(".")
@@ -118,6 +109,7 @@ def initialise_stages(
118
109
  @log_on_entry
119
110
  def write_parameter_file(
120
111
  detector_stage: DetectorMotion,
112
+ attenuator: ReadOnlyAttenuator,
121
113
  ) -> MsgGenerator:
122
114
  param_path: Path = PARAM_FILE_PATH_FT
123
115
  # Create directory if it doesn't yet exist.
@@ -146,6 +138,8 @@ def write_parameter_file(
146
138
  f"Requested filename ends in a number. Appended dash: {filename}"
147
139
  )
148
140
 
141
+ transmission = yield from bps.rd(attenuator.actual_transmission)
142
+
149
143
  params_dict = {
150
144
  "visit": _read_visit_directory_from_file().as_posix(), # noqa
151
145
  "directory": caget(pv.me14e_filepath),
@@ -154,12 +148,13 @@ def write_parameter_file(
154
148
  "detector_distance_mm": caget(pv.me14e_dcdetdist),
155
149
  "detector_name": str(det_type),
156
150
  "num_exposures": int(caget(NUM_EXPOSURES_PV)),
157
- "chip": chip_params.dict(),
151
+ "transmission": transmission,
152
+ "chip": chip_params.model_dump(),
158
153
  "map_type": map_type,
159
154
  "pump_repeat": pump_repeat,
160
155
  "checker_pattern": bool(caget(pv.me14e_gp111)),
161
- "laser_dwell_s": float(caget(pv.me14e_gp103)) if pump_repeat != 0 else None,
162
- "laser_delay_s": float(caget(pv.me14e_gp110)) if pump_repeat != 0 else None,
156
+ "laser_dwell_s": float(caget(pv.me14e_gp103)) if pump_repeat != 0 else 0.0,
157
+ "laser_delay_s": float(caget(pv.me14e_gp110)) if pump_repeat != 0 else 0.0,
163
158
  "pre_pump_exposure_s": float(caget(pv.me14e_gp109))
164
159
  if pump_repeat != 0
165
160
  else None,
@@ -171,11 +166,6 @@ def write_parameter_file(
171
166
  SSX_LOGGER.info("Information written to file \n")
172
167
  SSX_LOGGER.info(pformat(params_dict))
173
168
 
174
- if map_type == MappingType.Full:
175
- # This step creates some header files (.addr, .spec), containing the parameters,
176
- # that are only needed when full mapping is in use.
177
- SSX_LOGGER.info("Full mapping in use. Running start up now.")
178
- startup.run()
179
169
  yield from bps.null()
180
170
 
181
171
 
@@ -239,11 +229,11 @@ def save_screen_map() -> MsgGenerator:
239
229
  with open(litemap_path / "currentchip.map", "w") as f:
240
230
  SSX_LOGGER.debug("Printing only blocks with block_val == 1")
241
231
  for x in range(1, 82):
242
- block_str = "ME14E-MO-IOC-01:GP%i" % (x + 10)
232
+ block_str = f"ME14E-MO-IOC-01:GP{x + 10:d}"
243
233
  block_val = int(caget(block_str))
244
234
  if block_val == 1:
245
- SSX_LOGGER.info("%s %d" % (block_str, block_val))
246
- line = "%02dstatus P3%02d1 \t%s\n" % (x, x, block_val)
235
+ SSX_LOGGER.info(f"{block_str} {block_val:d}")
236
+ line = f"{x:02d}status P3{x:02d}1 \t{block_val}\n"
247
237
  f.write(line)
248
238
  yield from bps.null()
249
239
 
@@ -286,29 +276,6 @@ def upload_parameters(pmac: PMAC = inject("pmac")) -> MsgGenerator:
286
276
  yield from bps.null()
287
277
 
288
278
 
289
- @log_on_entry
290
- def upload_full(pmac: PMAC | None = None) -> MsgGenerator:
291
- if not pmac:
292
- pmac = i24.pmac()
293
-
294
- map_file: Path = FULLMAP_PATH / "currentchip.full"
295
- if not map_file.exists():
296
- raise FileNotFoundError(f"The file {map_file} has not yet been created")
297
- with open(map_file) as fh:
298
- f = fh.readlines()
299
-
300
- for _i in range(len(f) // 2):
301
- pmac_list = []
302
- for _j in range(2):
303
- pmac_list.append(f.pop(0).rstrip("\n"))
304
- writeline = " ".join(pmac_list)
305
- SSX_LOGGER.info(f"{writeline}")
306
- yield from bps.abs_set(pmac.pmac_string, writeline, wait=True)
307
- yield from bps.sleep(0.02)
308
- SSX_LOGGER.debug("Upload fullmap done")
309
- yield from bps.null()
310
-
311
-
312
279
  @log_on_entry
313
280
  def load_stock_map(map_choice: str = "clear") -> MsgGenerator:
314
281
  # TODO See https://github.com/DiamondLightSource/mx_bluesky/issues/122
@@ -553,7 +520,7 @@ def load_lite_map() -> MsgGenerator:
553
520
  break
554
521
  button_name = str(row) + str(column)
555
522
  lab_num = x * 8 + z
556
- label = "%02.d" % (lab_num + 1)
523
+ label = f"{lab_num + 1:02d}"
557
524
  btn_names[button_name] = label
558
525
  block_dict = btn_names
559
526
  else:
@@ -576,26 +543,6 @@ def load_lite_map() -> MsgGenerator:
576
543
  yield from bps.null()
577
544
 
578
545
 
579
- @log_on_entry
580
- def load_full_map() -> MsgGenerator:
581
- from matplotlib import pyplot as plt
582
-
583
- params = startup.read_parameter_file()
584
-
585
- fullmap_fid = FULLMAP_PATH / f"{caget(MAP_FILEPATH_PV)}.spec"
586
- SSX_LOGGER.info(f"Opening {fullmap_fid}")
587
- mapping.plot_file(plt, fullmap_fid, params.chip.chip_type.value)
588
- mapping.convert_chip_to_hex(fullmap_fid, params.chip.chip_type.value)
589
- shutil.copy2(fullmap_fid.with_suffix(".full"), FULLMAP_PATH / "currentchip.full")
590
- SSX_LOGGER.info(
591
- "Copying {} to {}".format(
592
- fullmap_fid.with_suffix(".full"), FULLMAP_PATH / "currentchip.full"
593
- )
594
- )
595
- SSX_LOGGER.debug("Load full map done")
596
- yield from bps.null()
597
-
598
-
599
546
  @log_on_entry
600
547
  def moveto(place: str = "origin", pmac: PMAC = inject("pmac")) -> MsgGenerator:
601
548
  SSX_LOGGER.info(f"Move to: {place}")
@@ -731,15 +678,15 @@ def fiducial(point: int = 1, pmac: PMAC = inject("pmac")) -> MsgGenerator:
731
678
  output_param_path.mkdir(parents=True, exist_ok=True)
732
679
  SSX_LOGGER.info(f"Writing Fiducial File {output_param_path}/fiducial_{point}.txt")
733
680
  SSX_LOGGER.info("MTR\tRBV\tRAW\tCorr\tf_value")
734
- SSX_LOGGER.info("MTR1\t%1.4f\t%i" % (rbv_1, mtr1_dir))
735
- SSX_LOGGER.info("MTR2\t%1.4f\t%i" % (rbv_2, mtr2_dir))
736
- SSX_LOGGER.info("MTR3\t%1.4f\t%i" % (rbv_3, mtr3_dir))
681
+ SSX_LOGGER.info(f"MTR1\t{rbv_1:1.4f}\t{mtr1_dir:d}")
682
+ SSX_LOGGER.info(f"MTR2\t{rbv_2:1.4f}\t{mtr2_dir:d}")
683
+ SSX_LOGGER.info(f"MTR3\t{rbv_3:1.4f}\t{mtr3_dir:d}")
737
684
 
738
685
  with open(output_param_path / f"fiducial_{point}.txt", "w") as f:
739
686
  f.write("MTR\tRBV\tCorr\n")
740
- f.write("MTR1\t%1.4f\t%i\n" % (rbv_1, mtr1_dir))
741
- f.write("MTR2\t%1.4f\t%i\n" % (rbv_2, mtr2_dir))
742
- f.write("MTR3\t%1.4f\t%i" % (rbv_3, mtr3_dir))
687
+ f.write(f"MTR1\t{rbv_1:1.4f}\t{mtr1_dir:d}\n")
688
+ f.write(f"MTR2\t{rbv_2:1.4f}\t{mtr2_dir:d}\n")
689
+ f.write(f"MTR3\t{rbv_3:1.4f}\t{mtr3_dir:d}")
743
690
  SSX_LOGGER.info(f"Fiducial {point} set.")
744
691
  yield from bps.null()
745
692
 
@@ -901,13 +848,13 @@ def cs_maker(pmac: PMAC = inject("pmac")) -> MsgGenerator:
901
848
  sleep(2.5)
902
849
  yield from set_pmac_strings_for_cs(pmac, {"cs1": cs1, "cs2": cs2, "cs3": cs3})
903
850
  yield from bps.trigger(pmac.to_xyz_zero)
904
- sleep(0.1)
851
+ sleep(2.5)
905
852
  yield from bps.trigger(pmac.home, wait=True)
906
- sleep(0.1)
853
+ sleep(2.5)
907
854
  SSX_LOGGER.debug(f"Chip_type is {chip_type}")
908
855
  if chip_type == 0:
909
856
  yield from bps.abs_set(pmac.pmac_string, "!x0.4y0.4", wait=True)
910
- sleep(0.1)
857
+ sleep(2.5)
911
858
  yield from bps.trigger(pmac.home, wait=True)
912
859
  else:
913
860
  yield from bps.trigger(pmac.home, wait=True)
@@ -2,13 +2,9 @@
2
2
  Startup utilities for chip
3
3
  """
4
4
 
5
- import os
6
5
  import string
7
- import time
8
6
  from pathlib import Path
9
7
 
10
- import numpy as np
11
-
12
8
  from mx_bluesky.beamlines.i24.serial.fixed_target.ft_utils import ChipType
13
9
  from mx_bluesky.beamlines.i24.serial.log import SSX_LOGGER, log_on_entry
14
10
  from mx_bluesky.beamlines.i24.serial.parameters import (
@@ -16,7 +12,6 @@ from mx_bluesky.beamlines.i24.serial.parameters import (
16
12
  get_chip_format,
17
13
  )
18
14
  from mx_bluesky.beamlines.i24.serial.parameters.constants import (
19
- HEADER_FILES_PATH,
20
15
  PARAM_FILE_NAME,
21
16
  PARAM_FILE_PATH_FT,
22
17
  )
@@ -45,31 +40,6 @@ def fiducials(chip_type: int):
45
40
  return fiducial_list
46
41
 
47
42
 
48
- def get_xy(addr: str, chip_type: ChipType):
49
- entry = addr.split("_")[-2:]
50
- R, C = entry[0][0], entry[0][1]
51
- r2, c2 = entry[1][0], entry[1][1]
52
- blockR = string.ascii_uppercase.index(R)
53
- blockC = int(C) - 1
54
- lowercase_list = list(string.ascii_lowercase + string.ascii_uppercase + "0")
55
- windowR = lowercase_list.index(r2)
56
- windowC = lowercase_list.index(c2)
57
-
58
- chip_params = get_chip_format(chip_type)
59
-
60
- x = (
61
- (blockC * chip_params.b2b_horz)
62
- + (blockC * (chip_params.x_num_steps - 1) * chip_params.x_step_size)
63
- + (windowC * chip_params.x_step_size)
64
- )
65
- y = (
66
- (blockR * chip_params.b2b_vert)
67
- + (blockR * (chip_params.y_num_steps - 1) * chip_params.y_step_size)
68
- + (windowR * chip_params.y_step_size)
69
- )
70
- return x, y
71
-
72
-
73
43
  def pathli(l_in=None, way="typewriter", reverse=False):
74
44
  if l_in is None:
75
45
  l_in = []
@@ -147,172 +117,3 @@ def get_alphanumeric(chip_type: ChipType):
147
117
  alphanumeric_list.append(block + "_" + window)
148
118
  SSX_LOGGER.info(f"Length of alphanumeric list = {len(alphanumeric_list)}")
149
119
  return alphanumeric_list
150
-
151
-
152
- @log_on_entry
153
- def get_shot_order(chip_type: ChipType):
154
- cell_format = get_chip_format(chip_type)
155
- blk_num = cell_format.x_blocks
156
- wnd_num = cell_format.x_num_steps
157
- uppercase_list = list(string.ascii_uppercase)[:blk_num]
158
- number_list = [str(x) for x in range(1, blk_num + 1)]
159
- lowercase_list = list(string.ascii_lowercase + string.ascii_uppercase + "0")[
160
- :wnd_num
161
- ]
162
-
163
- block_list = zippum([uppercase_list, "snake", 0], [number_list, "expand", 0])
164
- window_dn = zippum([lowercase_list, "expand", 0], [lowercase_list, "snake", 0])
165
- window_up = zippum([lowercase_list, "expand", 1], [lowercase_list, "snake", 0])
166
-
167
- switch = 0
168
- count = 0
169
- collect_list = []
170
- for block in block_list:
171
- if switch == 0:
172
- for window in window_dn:
173
- collect_list.append(block + "_" + window)
174
- count += 1
175
- if count == blk_num:
176
- count = 0
177
- switch = 1
178
- else:
179
- for window in window_up:
180
- collect_list.append(block + "_" + window)
181
- count += 1
182
- if count == blk_num:
183
- count = 0
184
- switch = 0
185
-
186
- SSX_LOGGER.info(f"Length of collect list = {len(collect_list)}")
187
- return collect_list
188
-
189
-
190
- @log_on_entry
191
- def write_file(
192
- location: str = "i24",
193
- suffix: str = ".addr",
194
- order: str = "alphanumeric",
195
- param_file_path: Path = PARAM_FILE_PATH_FT,
196
- save_path: Path = HEADER_FILES_PATH,
197
- ):
198
- if location == "i24":
199
- params = read_parameter_file(param_file_path)
200
- else:
201
- msg = f"Unknown location, {location}"
202
- SSX_LOGGER.error(msg)
203
- raise ValueError(msg)
204
- chip_file_path = save_path / f"chips/{params.directory}/{params.filename}{suffix}"
205
-
206
- fiducial_list = fiducials(params.chip.chip_type.value)
207
-
208
- if order == "alphanumeric":
209
- addr_list = get_alphanumeric(params.chip.chip_type)
210
- elif order == "shot":
211
- addr_list = get_shot_order(params.chip.chip_type)
212
- else:
213
- raise ValueError(f"{order=} unrecognised")
214
-
215
- with open(chip_file_path, "a") as g:
216
- for addr in addr_list:
217
- xtal_name = "_".join([params.filename, addr])
218
- (x, y) = get_xy(xtal_name, params.chip.chip_type)
219
- if addr in fiducial_list:
220
- pres = "0"
221
- else:
222
- if "rand" in suffix:
223
- pres = str(np.random.randint(2))
224
- else:
225
- pres = "-1"
226
- line = "\t".join([xtal_name, str(x), str(y), "0.0", pres]) + "\n"
227
- g.write(line)
228
-
229
- SSX_LOGGER.info(f"Write {chip_file_path} completed")
230
-
231
-
232
- @log_on_entry
233
- def check_files(
234
- location: str,
235
- suffix_list: list[str],
236
- param_file_path: Path | str = PARAM_FILE_PATH_FT,
237
- save_path: Path = HEADER_FILES_PATH,
238
- ):
239
- if location == "i24":
240
- params = read_parameter_file(param_file_path)
241
- else:
242
- msg = f"Unknown location, {location}"
243
- SSX_LOGGER.error(msg)
244
- raise ValueError(msg)
245
- chip_file_path = save_path / f"chips/{params.directory}/{params.filename}"
246
-
247
- try:
248
- os.stat(chip_file_path)
249
- except Exception:
250
- os.makedirs(chip_file_path)
251
- for suffix in suffix_list:
252
- full_fid = chip_file_path.with_suffix(suffix)
253
- if full_fid.is_file():
254
- time_str = time.strftime("%Y%m%d_%H%M%S_")
255
- timestamp_fid = ( # noqa: F841
256
- full_fid.parent / f"{time_str}_{params.filename}{full_fid.suffix}"
257
- )
258
- # FIXME hack / fix. Actually move the file
259
- SSX_LOGGER.info(f"File {full_fid} Already Exists")
260
- SSX_LOGGER.debug("Check files done")
261
- return 1
262
-
263
-
264
- @log_on_entry
265
- def write_headers(
266
- location: str,
267
- suffix_list: list[str],
268
- param_file_path: Path = PARAM_FILE_PATH_FT,
269
- save_path: Path = HEADER_FILES_PATH,
270
- ):
271
- if location == "i24":
272
- params = read_parameter_file(param_file_path)
273
- chip_file_path = save_path / f"chips/{params.directory}/{params.filename}"
274
-
275
- for suffix in suffix_list:
276
- full_fid = chip_file_path.with_suffix(suffix)
277
- with open(full_fid, "w") as g:
278
- g.write(
279
- "#23456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\n#\n"
280
- )
281
- g.write(f"#&i24\tchip_name = {params.filename}\n")
282
- g.write(f"#&i24\tvisit = {params.visit}\n")
283
- g.write(f"#&i24\tsub_dir = {params.directory}\n")
284
- g.write(f"#&i24\tn_exposures = {params.num_exposures}\n")
285
- g.write(f"#&i24\tchip_type = {params.chip.chip_type.value}\n")
286
- g.write(f"#&i24\tmap_type = {params.map_type.value}\n")
287
- g.write(f"#&i24\tpump_repeat = {params.pump_repeat.value}\n")
288
- g.write(f"#&i24\tpumpexptime = {params.laser_dwell_s}\n")
289
- g.write(f"#&i24\texptime = {params.laser_delay_s}\n")
290
- g.write(f"#&i24\tdcdetdist = {params.detector_distance_mm}\n")
291
- g.write(f"#&i24\tprepumpexptime = {params.pre_pump_exposure_s}\n")
292
- g.write(f"#&i24\tdet_Type = {params.detector_name}\n")
293
- g.write("#\n")
294
- g.write(
295
- "#XtalAddr XCoord YCoord ZCoord Present Shot Spare04 Spare03 Spare02 Spare01\n"
296
- )
297
- else:
298
- msg = f"Unknown location, {location}"
299
- SSX_LOGGER.error(msg)
300
- raise ValueError(msg)
301
- SSX_LOGGER.debug("Write headers done")
302
-
303
-
304
- def run():
305
- SSX_LOGGER.debug("Run Startup")
306
- check_files("i24", [".addr", ".shot"])
307
- SSX_LOGGER.info("Checked Files")
308
- write_headers("i24", [".addr", ".shot"])
309
- SSX_LOGGER.info("Written Headers")
310
- SSX_LOGGER.info("Writing to Files has been disabled. Headers Only")
311
- # Makes a file with random crystal positions
312
- check_files("i24", ["rando.spec"])
313
- write_headers("i24", ["rando.spec"])
314
- SSX_LOGGER.debug("StartUp Done")
315
-
316
-
317
- if __name__ == "__main__":
318
- run()
@@ -3,7 +3,6 @@ Move on click gui for fixed targets at I24
3
3
  Robin Owen 12 Jan 2021
4
4
  """
5
5
 
6
- import logging
7
6
  from collections.abc import Sequence
8
7
 
9
8
  import bluesky.plan_stubs as bps
@@ -17,10 +16,9 @@ from mx_bluesky.beamlines.i24.serial.fixed_target import (
17
16
  i24ssx_Chip_Manager_py3v1 as manager,
18
17
  )
19
18
  from mx_bluesky.beamlines.i24.serial.fixed_target.ft_utils import Fiducials
19
+ from mx_bluesky.beamlines.i24.serial.log import SSX_LOGGER
20
20
  from mx_bluesky.beamlines.i24.serial.parameters.constants import OAV1_CAM
21
21
 
22
- logger = logging.getLogger("I24ssx.moveonclick")
23
-
24
22
 
25
23
  def _get_beam_centre(oav: OAV):
26
24
  """Extract the beam centre x/y positions from the display.configuration file.
@@ -53,7 +51,7 @@ def _move_on_mouse_click_plan(
53
51
  x, y = clicked_position
54
52
  xmove = -1 * (beamX - x) * zoomcalibrator
55
53
  ymove = 1 * (beamY - y) * zoomcalibrator
56
- logger.info(f"Moving X and Y {xmove} {ymove}")
54
+ SSX_LOGGER.info(f"Moving X and Y {xmove} {ymove}")
57
55
  xmovepmacstring = "#1J:" + str(xmove)
58
56
  ymovepmacstring = "#2J:" + str(ymove)
59
57
  yield from bps.abs_set(pmac.pmac_string, xmovepmacstring, wait=True)
@@ -66,7 +64,7 @@ def onMouse(event, x, y, flags, param):
66
64
  RE = param[0]
67
65
  pmac = param[1]
68
66
  oav = param[2]
69
- logger.info(f"Clicked X and Y {x} {y}")
67
+ SSX_LOGGER.info(f"Clicked X and Y {x} {y}")
70
68
  RE(_move_on_mouse_click_plan(oav, pmac, (x, y)))
71
69
 
72
70
 
@@ -159,7 +157,7 @@ def start_viewer(oav: OAV, pmac: PMAC, RE: RunEngine, oav1: str = OAV1_CAM):
159
157
  cv.namedWindow("OAV1view")
160
158
  cv.setMouseCallback("OAV1view", onMouse, param=[RE, pmac, oav]) # type: ignore
161
159
 
162
- logger.info("Showing camera feed. Press escape to close")
160
+ SSX_LOGGER.info("Showing camera feed. Press escape to close")
163
161
  # Read captured video and store them in success and frame
164
162
  success, frame = cap.read()
165
163
 
@@ -6,8 +6,8 @@ from os import environ
6
6
  from pathlib import Path
7
7
 
8
8
  import bluesky.plan_stubs as bps
9
- from blueapi.core import MsgGenerator
10
9
  from bluesky.log import logger as bluesky_logger
10
+ from bluesky.utils import MsgGenerator
11
11
  from dodal.log import DEFAULT_GRAYLOG_PORT, ophyd_async_logger
12
12
  from dodal.log import LOGGER as dodal_logger
13
13
 
@@ -1,15 +1,19 @@
1
1
  from mx_bluesky.beamlines.i24.serial.parameters.constants import SSXType
2
2
  from mx_bluesky.beamlines.i24.serial.parameters.experiment_parameters import (
3
+ BeamSettings,
3
4
  ChipDescription,
4
5
  ExtruderParameters,
5
6
  FixedTargetParameters,
7
+ SerialAndLaserExperiment,
6
8
  )
7
9
  from mx_bluesky.beamlines.i24.serial.parameters.utils import get_chip_format
8
10
 
9
11
  __all__ = [
10
12
  "SSXType",
13
+ "BeamSettings",
11
14
  "ExtruderParameters",
12
15
  "ChipDescription",
13
16
  "FixedTargetParameters",
17
+ "SerialAndLaserExperiment",
14
18
  "get_chip_format",
15
19
  ]
@@ -10,6 +10,12 @@ class SSXType(Enum):
10
10
  EXTRUDER = "Serial Jet"
11
11
 
12
12
 
13
+ BEAM_CENTER_POS: dict[str, list] = {
14
+ "eiger": [1600.0, 1697.4],
15
+ "pilatus": [1284.7, 1308.6],
16
+ }
17
+
18
+
13
19
  OAV_CONFIG_FILES = {
14
20
  "zoom_params_file": "/dls_sw/i24/software/gda_versions/gda_9_34/config/xml/jCameraManZoomLevels.xml",
15
21
  "oav_config_json": "/dls_sw/i24/software/daq_configuration/json/OAVCentring.json",
@@ -41,7 +47,6 @@ PARAM_FILE_NAME = "parameters.json"
41
47
  PARAM_FILE_PATH = _params_file_location()
42
48
  PARAM_FILE_PATH_FT = PARAM_FILE_PATH / "fixed_target"
43
49
  LITEMAP_PATH = PARAM_FILE_PATH_FT / "litemaps"
44
- FULLMAP_PATH = PARAM_FILE_PATH_FT / "fullmaps"
45
50
  # Paths for r only
46
51
  PVAR_FILE_PATH = INTERNAL_FILES_PATH / "fixed_target/pvar_files"
47
52
  CS_FILES_PATH = INTERNAL_FILES_PATH / "fixed_target/cs"
@@ -1,14 +1,16 @@
1
1
  import json
2
+ from abc import abstractmethod
2
3
  from pathlib import Path
3
4
  from typing import Literal
4
5
 
5
- from pydantic import BaseModel, field_validator
6
+ from pydantic import BaseModel, ConfigDict, field_validator
6
7
 
7
8
  from mx_bluesky.beamlines.i24.serial.fixed_target.ft_utils import (
8
9
  ChipType,
9
10
  MappingType,
10
11
  PumpProbeSetting,
11
12
  )
13
+ from mx_bluesky.beamlines.i24.serial.parameters.constants import SSXType
12
14
 
13
15
 
14
16
  class SerialExperiment(BaseModel):
@@ -20,6 +22,7 @@ class SerialExperiment(BaseModel):
20
22
  exposure_time_s: float
21
23
  detector_distance_mm: float
22
24
  detector_name: Literal["eiger", "pilatus"]
25
+ transmission: float
23
26
 
24
27
  @field_validator("visit", mode="before")
25
28
  @classmethod
@@ -36,23 +39,38 @@ class SerialExperiment(BaseModel):
36
39
  class LaserExperiment(BaseModel):
37
40
  """Laser settings for pump probe serial collections."""
38
41
 
39
- laser_dwell_s: float | None = None # pump exposure time
40
- laser_delay_s: float | None = None # pump delay
42
+ laser_dwell_s: float = 0.0 # pump exposure time
43
+ laser_delay_s: float = 0.0 # pump delay
41
44
  pre_pump_exposure_s: float | None = None # Pre illumination, just for chip
42
45
 
43
46
 
44
- class ExtruderParameters(SerialExperiment, LaserExperiment):
45
- """Extruder parameter model."""
46
-
47
- num_images: int
48
- pump_status: bool
49
-
47
+ class SerialAndLaserExperiment(SerialExperiment, LaserExperiment):
50
48
  @classmethod
51
49
  def from_file(cls, filename: str | Path):
52
50
  with open(filename) as fh:
53
51
  raw_params = json.load(fh)
54
52
  return cls(**raw_params)
55
53
 
54
+ @property
55
+ @abstractmethod
56
+ def nexgen_experiment_type(self) -> str:
57
+ pass
58
+
59
+
60
+ class ExtruderParameters(SerialAndLaserExperiment):
61
+ """Extruder parameter model."""
62
+
63
+ num_images: int
64
+ pump_status: bool
65
+
66
+ @property
67
+ def nexgen_experiment_type(self) -> str:
68
+ return "extruder"
69
+
70
+ @property
71
+ def ispyb_experiment_type(self) -> SSXType:
72
+ return SSXType.EXTRUDER
73
+
56
74
 
57
75
  class ChipDescription(BaseModel):
58
76
  """Parameters defining the chip in use for FT collection."""
@@ -86,7 +104,7 @@ class ChipDescription(BaseModel):
86
104
  return ((self.y_num_steps - 1) * self.y_step_size) + self.b2b_vert
87
105
 
88
106
 
89
- class FixedTargetParameters(SerialExperiment, LaserExperiment):
107
+ class FixedTargetParameters(SerialAndLaserExperiment):
90
108
  """Fixed target parameter model."""
91
109
 
92
110
  num_exposures: int
@@ -96,8 +114,17 @@ class FixedTargetParameters(SerialExperiment, LaserExperiment):
96
114
  checker_pattern: bool = False
97
115
  total_num_images: int = 0 # Calculated in the code for now
98
116
 
99
- @classmethod
100
- def from_file(cls, filename: str | Path):
101
- with open(filename) as fh:
102
- raw_params = json.load(fh)
103
- return cls(**raw_params)
117
+ @property
118
+ def nexgen_experiment_type(self) -> str:
119
+ return "fixed-target"
120
+
121
+ @property
122
+ def ispyb_experiment_type(self) -> SSXType:
123
+ return SSXType.FIXED
124
+
125
+
126
+ class BeamSettings(BaseModel):
127
+ model_config = ConfigDict(frozen=True)
128
+ wavelength_in_a: float
129
+ beam_size_in_um: tuple[float, float]
130
+ beam_center_in_mm: tuple[float, float]
@@ -15,12 +15,13 @@ edm_path=$1
15
15
  # Export env variable for the stages edm to work properly
16
16
  export EDMDATAFILES="/dls_sw/prod/R3.14.12.3/support/motor/6-7-1dls14/motorApp/opi/edl"
17
17
 
18
+ # Get the directory of this script
19
+ current=$( realpath "$( dirname "$0" )" )
20
+
21
+
18
22
  if [[ $NO_PROCESERV_TEST == true ]]; then
19
23
  echo "Start the blueapi sever"
20
24
 
21
- # Get the directory of this script
22
- current=$( realpath "$( dirname "$0" )" )
23
-
24
25
  # Run script to start blueapi serve
25
26
  . $current/start_blueapi.sh
26
27
  fi
@@ -23,6 +23,8 @@ def __which__():
23
23
  print("path to pv.py: ")
24
24
 
25
25
 
26
+ requested_transmission = "BL24I-OP-ATTN-01:T2A:SETVAL1"
27
+
26
28
  # PILATUS
27
29
  pilat_filepath = "BL24I-EA-PILAT-01:cam1:FilePath"
28
30
  pilat_filename = "BL24I-EA-PILAT-01:cam1:FileName"