mx-bluesky 1.2.0__py3-none-any.whl → 1.4.1a0__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 (94) hide show
  1. mx_bluesky/__init__.py +8 -3
  2. mx_bluesky/__main__.py +12 -7
  3. mx_bluesky/_version.py +2 -2
  4. mx_bluesky/beamlines/i04/callbacks/murko_callback.py +14 -4
  5. mx_bluesky/beamlines/i04/thawing_plan.py +49 -11
  6. mx_bluesky/beamlines/i24/serial/__init__.py +3 -0
  7. mx_bluesky/beamlines/i24/serial/dcid.py +19 -21
  8. mx_bluesky/beamlines/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +69 -91
  9. mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/DiamondChipI24-py3v1.edl +2 -5
  10. mx_bluesky/beamlines/i24/serial/fixed_target/ft_utils.py +0 -1
  11. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +111 -143
  12. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +141 -222
  13. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_StartUp_py3v1.py +7 -216
  14. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_moveonclick.py +18 -17
  15. mx_bluesky/beamlines/i24/serial/log.py +58 -49
  16. mx_bluesky/beamlines/i24/serial/parameters/constants.py +0 -1
  17. mx_bluesky/beamlines/i24/serial/parameters/fixed_target/cs/cs_maker.json +3 -3
  18. mx_bluesky/beamlines/i24/serial/run_extruder.sh +30 -5
  19. mx_bluesky/beamlines/i24/serial/run_fixed_target.sh +30 -5
  20. mx_bluesky/beamlines/i24/serial/run_serial.py +24 -8
  21. mx_bluesky/beamlines/i24/serial/setup_beamline/ca.py +0 -2
  22. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +79 -81
  23. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_detector.py +9 -20
  24. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_zebra_plans.py +26 -28
  25. mx_bluesky/beamlines/i24/serial/write_nexus.py +11 -11
  26. mx_bluesky/common/__init__.py +0 -0
  27. mx_bluesky/common/device_setup_plans/read_hardware_for_setup.py +14 -0
  28. mx_bluesky/common/external_interaction/config_server.py +46 -0
  29. mx_bluesky/common/parameters/components.py +258 -0
  30. mx_bluesky/common/parameters/constants.py +138 -0
  31. mx_bluesky/common/parameters/gridscan.py +94 -0
  32. mx_bluesky/common/parameters/robot_load.py +16 -0
  33. mx_bluesky/common/plans/__init__.py +1 -0
  34. mx_bluesky/common/plans/do_fgs.py +121 -0
  35. mx_bluesky/common/utils/log.py +118 -0
  36. mx_bluesky/{hyperion → common/utils}/tracing.py +2 -2
  37. mx_bluesky/hyperion/__main__.py +13 -10
  38. mx_bluesky/hyperion/device_setup_plans/dcm_pitch_roll_mirror_adjuster.py +31 -26
  39. mx_bluesky/hyperion/device_setup_plans/read_hardware_for_setup.py +6 -12
  40. mx_bluesky/hyperion/device_setup_plans/setup_oav.py +6 -12
  41. mx_bluesky/hyperion/device_setup_plans/setup_panda.py +5 -6
  42. mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +49 -18
  43. mx_bluesky/hyperion/device_setup_plans/smargon.py +6 -6
  44. mx_bluesky/hyperion/device_setup_plans/utils.py +2 -2
  45. mx_bluesky/hyperion/device_setup_plans/xbpm_feedback.py +4 -4
  46. mx_bluesky/hyperion/experiment_plans/__init__.py +4 -0
  47. mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py +83 -0
  48. mx_bluesky/hyperion/experiment_plans/common/xrc_result.py +47 -0
  49. mx_bluesky/hyperion/experiment_plans/experiment_registry.py +9 -9
  50. mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +145 -161
  51. mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +56 -22
  52. mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +52 -10
  53. mx_bluesky/hyperion/experiment_plans/oav_grid_detection_plan.py +21 -20
  54. mx_bluesky/hyperion/experiment_plans/oav_snapshot_plan.py +11 -14
  55. mx_bluesky/hyperion/experiment_plans/optimise_attenuation_plan.py +2 -2
  56. mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +40 -21
  57. mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +19 -19
  58. mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +21 -21
  59. mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +51 -13
  60. mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +24 -7
  61. mx_bluesky/hyperion/experiment_plans/set_energy_plan.py +5 -6
  62. mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +1 -2
  63. mx_bluesky/hyperion/external_interaction/callbacks/common/abstract_event.py +66 -0
  64. mx_bluesky/hyperion/external_interaction/callbacks/common/ispyb_mapping.py +1 -1
  65. mx_bluesky/hyperion/external_interaction/callbacks/grid_detection_callback.py +30 -25
  66. mx_bluesky/hyperion/external_interaction/callbacks/ispyb_callback_base.py +29 -12
  67. mx_bluesky/hyperion/external_interaction/callbacks/log_uid_tag_callback.py +1 -1
  68. mx_bluesky/hyperion/external_interaction/callbacks/robot_load/ispyb_callback.py +1 -1
  69. mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +7 -4
  70. mx_bluesky/hyperion/external_interaction/callbacks/rotation/nexus_callback.py +5 -3
  71. mx_bluesky/hyperion/external_interaction/callbacks/xray_centre/ispyb_callback.py +28 -20
  72. mx_bluesky/hyperion/external_interaction/callbacks/xray_centre/nexus_callback.py +5 -4
  73. mx_bluesky/hyperion/external_interaction/config_server.py +11 -28
  74. mx_bluesky/hyperion/external_interaction/ispyb/exp_eye_store.py +1 -1
  75. mx_bluesky/hyperion/external_interaction/ispyb/ispyb_store.py +1 -1
  76. mx_bluesky/hyperion/external_interaction/nexus/nexus_utils.py +2 -2
  77. mx_bluesky/hyperion/external_interaction/nexus/write_nexus.py +1 -1
  78. mx_bluesky/hyperion/log.py +0 -84
  79. mx_bluesky/hyperion/parameters/components.py +4 -251
  80. mx_bluesky/hyperion/parameters/constants.py +22 -119
  81. mx_bluesky/hyperion/parameters/gridscan.py +35 -74
  82. mx_bluesky/hyperion/parameters/load_centre_collect.py +16 -11
  83. mx_bluesky/hyperion/parameters/rotation.py +23 -10
  84. mx_bluesky/hyperion/utils/utils.py +17 -0
  85. mx_bluesky/hyperion/utils/validation.py +5 -6
  86. {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.1a0.dist-info}/METADATA +36 -33
  87. {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.1a0.dist-info}/RECORD +91 -81
  88. {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.1a0.dist-info}/WHEEL +1 -1
  89. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Mapping_py3v1.py +0 -161
  90. mx_bluesky/example.py +0 -19
  91. mx_bluesky/hyperion/parameters/robot_load.py +0 -16
  92. {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.1a0.dist-info}/LICENSE +0 -0
  93. {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.1a0.dist-info}/entry_points.txt +0 -0
  94. {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.1a0.dist-info}/top_level.txt +0 -0
@@ -2,34 +2,20 @@
2
2
  Startup utilities for chip
3
3
  """
4
4
 
5
- import logging
6
- import os
7
5
  import string
8
- import time
9
6
  from pathlib import Path
10
7
 
11
- import numpy as np
12
-
13
- from mx_bluesky.beamlines.i24.serial import log
14
8
  from mx_bluesky.beamlines.i24.serial.fixed_target.ft_utils import ChipType
9
+ from mx_bluesky.beamlines.i24.serial.log import SSX_LOGGER, log_on_entry
15
10
  from mx_bluesky.beamlines.i24.serial.parameters import (
16
11
  FixedTargetParameters,
17
12
  get_chip_format,
18
13
  )
19
14
  from mx_bluesky.beamlines.i24.serial.parameters.constants import (
20
- HEADER_FILES_PATH,
21
15
  PARAM_FILE_NAME,
22
16
  PARAM_FILE_PATH_FT,
23
17
  )
24
18
 
25
- logger = logging.getLogger("I24ssx.chip_startup")
26
-
27
-
28
- def setup_logging():
29
- # Log should now change name daily.
30
- logfile = time.strftime("i24fixedtarget_%d%B%y.log").lower()
31
- log.config(logfile)
32
-
33
19
 
34
20
  def read_parameter_file(
35
21
  param_path: Path | str = PARAM_FILE_PATH_FT,
@@ -41,44 +27,19 @@ def read_parameter_file(
41
27
  return params
42
28
 
43
29
 
44
- @log.log_on_entry
30
+ @log_on_entry
45
31
  def fiducials(chip_type: int):
46
32
  fiducial_list: list | None = None
47
33
  if chip_type in [ChipType.Oxford, ChipType.OxfordInner, ChipType.Minichip]:
48
34
  fiducial_list = []
49
35
  elif chip_type == ChipType.Custom:
50
36
  # No fiducial for custom
51
- logger.warning("No fiducials for custom chip")
37
+ SSX_LOGGER.warning("No fiducials for custom chip")
52
38
  else:
53
- logger.warning(f"Unknown chip_type, {chip_type}, in fiducials")
39
+ SSX_LOGGER.warning(f"Unknown chip_type, {chip_type}, in fiducials")
54
40
  return fiducial_list
55
41
 
56
42
 
57
- def get_xy(addr: str, chip_type: ChipType):
58
- entry = addr.split("_")[-2:]
59
- R, C = entry[0][0], entry[0][1]
60
- r2, c2 = entry[1][0], entry[1][1]
61
- blockR = string.ascii_uppercase.index(R)
62
- blockC = int(C) - 1
63
- lowercase_list = list(string.ascii_lowercase + string.ascii_uppercase + "0")
64
- windowR = lowercase_list.index(r2)
65
- windowC = lowercase_list.index(c2)
66
-
67
- chip_params = get_chip_format(chip_type)
68
-
69
- x = (
70
- (blockC * chip_params.b2b_horz)
71
- + (blockC * (chip_params.x_num_steps - 1) * chip_params.x_step_size)
72
- + (windowC * chip_params.x_step_size)
73
- )
74
- y = (
75
- (blockR * chip_params.b2b_vert)
76
- + (blockR * (chip_params.y_num_steps - 1) * chip_params.y_step_size)
77
- + (windowR * chip_params.y_step_size)
78
- )
79
- return x, y
80
-
81
-
82
43
  def pathli(l_in=None, way="typewriter", reverse=False):
83
44
  if l_in is None:
84
45
  l_in = []
@@ -118,9 +79,9 @@ def pathli(l_in=None, way="typewriter", reverse=False):
118
79
  for _ in range(25):
119
80
  long_list.append(entry)
120
81
  else:
121
- logger.warning(f"No known path, way = {way}")
82
+ SSX_LOGGER.warning(f"No known path, way = {way}")
122
83
  else:
123
- logger.warning("No list written")
84
+ SSX_LOGGER.warning("No list written")
124
85
  return long_list
125
86
 
126
87
 
@@ -154,175 +115,5 @@ def get_alphanumeric(chip_type: ChipType):
154
115
  for block in block_list:
155
116
  for window in window_list:
156
117
  alphanumeric_list.append(block + "_" + window)
157
- logger.info(f"Length of alphanumeric list = {len(alphanumeric_list)}")
118
+ SSX_LOGGER.info(f"Length of alphanumeric list = {len(alphanumeric_list)}")
158
119
  return alphanumeric_list
159
-
160
-
161
- @log.log_on_entry
162
- def get_shot_order(chip_type: ChipType):
163
- cell_format = get_chip_format(chip_type)
164
- blk_num = cell_format.x_blocks
165
- wnd_num = cell_format.x_num_steps
166
- uppercase_list = list(string.ascii_uppercase)[:blk_num]
167
- number_list = [str(x) for x in range(1, blk_num + 1)]
168
- lowercase_list = list(string.ascii_lowercase + string.ascii_uppercase + "0")[
169
- :wnd_num
170
- ]
171
-
172
- block_list = zippum([uppercase_list, "snake", 0], [number_list, "expand", 0])
173
- window_dn = zippum([lowercase_list, "expand", 0], [lowercase_list, "snake", 0])
174
- window_up = zippum([lowercase_list, "expand", 1], [lowercase_list, "snake", 0])
175
-
176
- switch = 0
177
- count = 0
178
- collect_list = []
179
- for block in block_list:
180
- if switch == 0:
181
- for window in window_dn:
182
- collect_list.append(block + "_" + window)
183
- count += 1
184
- if count == blk_num:
185
- count = 0
186
- switch = 1
187
- else:
188
- for window in window_up:
189
- collect_list.append(block + "_" + window)
190
- count += 1
191
- if count == blk_num:
192
- count = 0
193
- switch = 0
194
-
195
- logger.info(f"Length of collect list = {len(collect_list)}")
196
- return collect_list
197
-
198
-
199
- @log.log_on_entry
200
- def write_file(
201
- location: str = "i24",
202
- suffix: str = ".addr",
203
- order: str = "alphanumeric",
204
- param_file_path: Path = PARAM_FILE_PATH_FT,
205
- save_path: Path = HEADER_FILES_PATH,
206
- ):
207
- if location == "i24":
208
- params = read_parameter_file(param_file_path)
209
- else:
210
- msg = f"Unknown location, {location}"
211
- logger.error(msg)
212
- raise ValueError(msg)
213
- chip_file_path = save_path / f"chips/{params.directory}/{params.filename}{suffix}"
214
-
215
- fiducial_list = fiducials(params.chip.chip_type.value)
216
-
217
- if order == "alphanumeric":
218
- addr_list = get_alphanumeric(params.chip.chip_type)
219
- elif order == "shot":
220
- addr_list = get_shot_order(params.chip.chip_type)
221
- else:
222
- raise ValueError(f"{order=} unrecognised")
223
-
224
- with open(chip_file_path, "a") as g:
225
- for addr in addr_list:
226
- xtal_name = "_".join([params.filename, addr])
227
- (x, y) = get_xy(xtal_name, params.chip.chip_type)
228
- if addr in fiducial_list:
229
- pres = "0"
230
- else:
231
- if "rand" in suffix:
232
- pres = str(np.random.randint(2))
233
- else:
234
- pres = "-1"
235
- line = "\t".join([xtal_name, str(x), str(y), "0.0", pres]) + "\n"
236
- g.write(line)
237
-
238
- logger.info(f"Write {chip_file_path} completed")
239
-
240
-
241
- @log.log_on_entry
242
- def check_files(
243
- location: str,
244
- suffix_list: list[str],
245
- param_file_path: Path | str = PARAM_FILE_PATH_FT,
246
- save_path: Path = HEADER_FILES_PATH,
247
- ):
248
- if location == "i24":
249
- params = read_parameter_file(param_file_path)
250
- else:
251
- msg = f"Unknown location, {location}"
252
- logger.error(msg)
253
- raise ValueError(msg)
254
- chip_file_path = save_path / f"chips/{params.directory}/{params.filename}"
255
-
256
- try:
257
- os.stat(chip_file_path)
258
- except Exception:
259
- os.makedirs(chip_file_path)
260
- for suffix in suffix_list:
261
- full_fid = chip_file_path.with_suffix(suffix)
262
- if full_fid.is_file():
263
- time_str = time.strftime("%Y%m%d_%H%M%S_")
264
- timestamp_fid = ( # noqa: F841
265
- full_fid.parent / f"{time_str}_{params.filename}{full_fid.suffix}"
266
- )
267
- # FIXME hack / fix. Actually move the file
268
- logger.info(f"File {full_fid} Already Exists")
269
- logger.debug("Check files done")
270
- return 1
271
-
272
-
273
- @log.log_on_entry
274
- def write_headers(
275
- location: str,
276
- suffix_list: list[str],
277
- param_file_path: Path = PARAM_FILE_PATH_FT,
278
- save_path: Path = HEADER_FILES_PATH,
279
- ):
280
- if location == "i24":
281
- params = read_parameter_file(param_file_path)
282
- chip_file_path = save_path / f"chips/{params.directory}/{params.filename}"
283
-
284
- for suffix in suffix_list:
285
- full_fid = chip_file_path.with_suffix(suffix)
286
- with open(full_fid, "w") as g:
287
- g.write(
288
- "#23456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\n#\n"
289
- )
290
- g.write(f"#&i24\tchip_name = {params.filename}\n")
291
- g.write(f"#&i24\tvisit = {params.visit}\n")
292
- g.write(f"#&i24\tsub_dir = {params.directory}\n")
293
- g.write(f"#&i24\tn_exposures = {params.num_exposures}\n")
294
- g.write(f"#&i24\tchip_type = {params.chip.chip_type.value}\n")
295
- g.write(f"#&i24\tmap_type = {params.map_type.value}\n")
296
- g.write(f"#&i24\tpump_repeat = {params.pump_repeat.value}\n")
297
- g.write(f"#&i24\tpumpexptime = {params.laser_dwell_s}\n")
298
- g.write(f"#&i24\texptime = {params.laser_delay_s}\n")
299
- g.write(f"#&i24\tdcdetdist = {params.detector_distance_mm}\n")
300
- g.write(f"#&i24\tprepumpexptime = {params.pre_pump_exposure_s}\n")
301
- g.write(f"#&i24\tdet_Type = {params.detector_name}\n")
302
- g.write("#\n")
303
- g.write(
304
- "#XtalAddr XCoord YCoord ZCoord Present Shot Spare04 Spare03 Spare02 Spare01\n"
305
- )
306
- else:
307
- msg = f"Unknown location, {location}"
308
- logger.error(msg)
309
- raise ValueError(msg)
310
- logger.debug("Write headers done")
311
-
312
-
313
- def run():
314
- logger.debug("Run Startup")
315
- check_files("i24", [".addr", ".shot"])
316
- logger.info("Checked Files")
317
- write_headers("i24", [".addr", ".shot"])
318
- logger.info("Written Headers")
319
- logger.info("Writing to Files has been disabled. Headers Only")
320
- # Makes a file with random crystal positions
321
- check_files("i24", ["rando.spec"])
322
- write_headers("i24", ["rando.spec"])
323
- logger.debug("StartUp Done")
324
-
325
-
326
- if __name__ == "__main__":
327
- setup_logging()
328
- 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.
@@ -28,28 +26,32 @@ def _get_beam_centre(oav: OAV):
28
26
  Args:
29
27
  oav (OAV): the OAV device.
30
28
  """
31
- return oav.parameters.beam_centre_i, oav.parameters.beam_centre_j
29
+ beam_x = yield from bps.rd(oav.beam_centre_i)
30
+ beam_y = yield from bps.rd(oav.beam_centre_j)
31
+ return beam_x, beam_y
32
32
 
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)
36
+ currentzoom = yield from bps.rd(oav.zoom_controller.percentage) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
37
37
  zoomcalibrator = 1.547 - (0.03 * currentzoom) + (0.0001634 * currentzoom**2)
38
38
  return zoomcalibrator
39
39
 
40
40
 
41
41
  def _move_on_mouse_click_plan(
42
- oav: OAV, pmac: PMAC, beam_centre: Sequence[int], clicked_position: Sequence[int]
42
+ oav: OAV,
43
+ pmac: PMAC,
44
+ clicked_position: Sequence[int],
43
45
  ):
44
46
  """A plan that calculates the zoom calibrator and moves to the clicked \
45
47
  position coordinates.
46
48
  """
47
49
  zoomcalibrator = yield from _calculate_zoom_calibrator(oav)
48
- beamX, beamY = beam_centre
50
+ beamX, beamY = yield from _get_beam_centre(oav)
49
51
  x, y = clicked_position
50
52
  xmove = -1 * (beamX - x) * zoomcalibrator
51
- ymove = -1 * (beamY - y) * zoomcalibrator
52
- logger.info(f"Moving X and Y {xmove} {ymove}")
53
+ ymove = 1 * (beamY - y) * zoomcalibrator
54
+ SSX_LOGGER.info(f"Moving X and Y {xmove} {ymove}")
53
55
  xmovepmacstring = "#1J:" + str(xmove)
54
56
  ymovepmacstring = "#2J:" + str(ymove)
55
57
  yield from bps.abs_set(pmac.pmac_string, xmovepmacstring, wait=True)
@@ -62,14 +64,13 @@ def onMouse(event, x, y, flags, param):
62
64
  RE = param[0]
63
65
  pmac = param[1]
64
66
  oav = param[2]
65
- beamX, beamY = _get_beam_centre(oav)
66
- logger.info(f"Clicked X and Y {x} {y}")
67
- RE(_move_on_mouse_click_plan(oav, pmac, (beamX, beamY), (x, y)))
67
+ SSX_LOGGER.info(f"Clicked X and Y {x} {y}")
68
+ RE(_move_on_mouse_click_plan(oav, pmac, (x, y)))
68
69
 
69
70
 
70
- def update_ui(oav, frame):
71
+ def update_ui(oav, frame, RE):
71
72
  # Get beam x and y values
72
- beamX, beamY = _get_beam_centre(oav)
73
+ beamX, beamY = RE(_get_beam_centre(oav)).plan_result
73
74
 
74
75
  # Overlay text and beam centre
75
76
  cv.ellipse(
@@ -156,7 +157,7 @@ def start_viewer(oav: OAV, pmac: PMAC, RE: RunEngine, oav1: str = OAV1_CAM):
156
157
  cv.namedWindow("OAV1view")
157
158
  cv.setMouseCallback("OAV1view", onMouse, param=[RE, pmac, oav]) # type: ignore
158
159
 
159
- logger.info("Showing camera feed. Press escape to close")
160
+ SSX_LOGGER.info("Showing camera feed. Press escape to close")
160
161
  # Read captured video and store them in success and frame
161
162
  success, frame = cap.read()
162
163
 
@@ -164,7 +165,7 @@ def start_viewer(oav: OAV, pmac: PMAC, RE: RunEngine, oav1: str = OAV1_CAM):
164
165
  while success:
165
166
  success, frame = cap.read()
166
167
 
167
- update_ui(oav, frame)
168
+ update_ui(oav, frame, RE)
168
169
 
169
170
  k = cv.waitKey(1)
170
171
  if k == 113: # Q
@@ -212,7 +213,7 @@ def start_viewer(oav: OAV, pmac: PMAC, RE: RunEngine, oav1: str = OAV1_CAM):
212
213
 
213
214
 
214
215
  if __name__ == "__main__":
215
- RE = RunEngine()
216
+ RE = RunEngine(call_returns_result=True)
216
217
  # Get devices out of dodal
217
218
  oav: OAV = i24.oav()
218
219
  pmac: PMAC = i24.pmac()
@@ -1,39 +1,30 @@
1
1
  import functools
2
2
  import logging
3
3
  import logging.config
4
+ import time
4
5
  from os import environ
5
6
  from pathlib import Path
6
7
 
7
- from dodal.log import (
8
- ERROR_LOG_BUFFER_LINES,
9
- integrate_bluesky_and_ophyd_logging,
10
- set_up_all_logging_handlers,
11
- )
8
+ import bluesky.plan_stubs as bps
9
+ from bluesky.log import logger as bluesky_logger
10
+ from bluesky.utils import MsgGenerator
11
+ from dodal.log import DEFAULT_GRAYLOG_PORT, ophyd_async_logger
12
12
  from dodal.log import LOGGER as dodal_logger
13
13
 
14
- VISIT_PATH = Path("/dls_sw/i24/etc/ssx_current_visit.txt")
15
-
16
-
17
- class OphydDebugFilter(logging.Filter): # NOTE yet to be fully tested
18
- """Do not send ophyd debug log messages to stream handler."""
14
+ from mx_bluesky.common.utils.log import do_default_logging_setup
19
15
 
20
- def filter(self, record):
21
- return "ophyd" not in record.getMessage().lower()
16
+ VISIT_PATH = Path("/dls_sw/i24/etc/ssx_current_visit.txt")
22
17
 
23
18
 
24
19
  # Logging set up
25
- logger = logging.getLogger("I24ssx")
26
- logger.addHandler(logging.NullHandler())
27
- logger.parent = dodal_logger
20
+ SSX_LOGGER = logging.getLogger("I24serial")
21
+ SSX_LOGGER.addHandler(logging.NullHandler())
22
+ SSX_LOGGER.parent = dodal_logger
23
+
28
24
 
29
25
  logging_config = {
30
26
  "version": 1,
31
27
  "disable_existing_loggers": False,
32
- "filters": {
33
- "ophyd_filter": {
34
- "()": OphydDebugFilter,
35
- }
36
- },
37
28
  "formatters": {
38
29
  "default": {
39
30
  "class": "logging.Formatter",
@@ -42,18 +33,17 @@ logging_config = {
42
33
  },
43
34
  "handlers": {
44
35
  "console": {
45
- "level": "DEBUG",
36
+ "level": "INFO",
46
37
  "class": "logging.StreamHandler",
47
38
  "formatter": "default",
48
- "filters": ["ophyd_filter"],
49
39
  "stream": "ext://sys.stdout",
50
40
  }
51
41
  },
52
42
  "loggers": {
53
- "I24ssx": {
43
+ "I24serial": {
54
44
  "handlers": ["console"],
55
45
  "level": "DEBUG",
56
- "propagate": True,
46
+ "propagate": False,
57
47
  }
58
48
  },
59
49
  }
@@ -68,10 +58,8 @@ def _read_visit_directory_from_file() -> Path:
68
58
 
69
59
 
70
60
  def _get_logging_file_path() -> Path:
71
- """Get the path to write the artemis log files to.
72
- If on a beamline, this will be written to the according area depending on the
73
- BEAMLINE envrionment variable. If no envrionment variable is found it will default
74
- it to the tmp/dev directory.
61
+ """Get the path to write the serial experiment specific log file to.
62
+ If on a beamline, this will be written to the tmp folder in the current visit.
75
63
  Returns:
76
64
  logging_path (Path): Path to the log file for the file handler to write to.
77
65
  """
@@ -87,24 +75,11 @@ def _get_logging_file_path() -> Path:
87
75
  return logging_path
88
76
 
89
77
 
90
- def default_logging_setup(dev_mode: bool = False):
91
- """ Default log setup for i24 serial.
92
-
93
- - Set up handlers for parent logger (from dodal)
94
- - integrate bluesky and ophyd loggers
95
- - Remove dodal stream handler to avoid double messages (for now, use only the \
96
- i24ssx default stream to keep the output expected by the scientists.)
97
- """
98
- handlers = set_up_all_logging_handlers( # noqa: F841
99
- dodal_logger,
100
- _get_logging_file_path(),
101
- "dodal.log",
102
- dev_mode,
103
- ERROR_LOG_BUFFER_LINES,
104
- )
105
- integrate_bluesky_and_ophyd_logging(dodal_logger)
106
- # Remove dodal StreamHandler to avoid duplication of messages above debug
107
- dodal_logger.removeHandler(dodal_logger.handlers[0])
78
+ def _integrate_bluesky_logs(parent_logger: logging.Logger):
79
+ # Integrate only bluesky and ophyd_async logger
80
+ for log in [bluesky_logger, ophyd_async_logger]:
81
+ log.parent = parent_logger
82
+ log.setLevel(logging.DEBUG)
108
83
 
109
84
 
110
85
  def config(
@@ -124,7 +99,15 @@ def config(
124
99
  dev_mode (bool, optional): If true, will log to graylog on localhost instead \
125
100
  of production. Defaults to False.
126
101
  """
127
- default_logging_setup(dev_mode=dev_mode)
102
+ do_default_logging_setup(
103
+ "mx-bluesky.log",
104
+ DEFAULT_GRAYLOG_PORT,
105
+ dev_mode=dev_mode,
106
+ integrate_all_logs=False,
107
+ )
108
+ # Remove dodal StreamHandler to avoid duplication of messages above debug
109
+ dodal_logger.removeHandler(dodal_logger.handlers[0])
110
+ _integrate_bluesky_logs(dodal_logger)
128
111
 
129
112
  if logfile:
130
113
  logs = _get_logging_file_path() / logfile
@@ -135,14 +118,40 @@ def config(
135
118
  FH = logging.FileHandler(logs, mode=write_mode, encoding="utf-8", delay=delayed)
136
119
  FH.setLevel(logging.DEBUG)
137
120
  FH.setFormatter(fileFormatter)
138
- logger.addHandler(FH)
121
+ SSX_LOGGER.addHandler(FH)
139
122
 
140
123
 
141
124
  def log_on_entry(func):
142
125
  @functools.wraps(func)
143
126
  def decorator(*args, **kwargs):
144
127
  name = func.__name__
145
- logger.debug(f"Running {name} ")
128
+ SSX_LOGGER.debug(f"Running {name} ")
146
129
  return func(*args, **kwargs)
147
130
 
148
131
  return decorator
132
+
133
+
134
+ def setup_collection_logs(expt: str, dev_mode: bool = False) -> MsgGenerator:
135
+ """A small plan to set up the logging from blueapi on start up as we're running \
136
+ on procserv.
137
+ This setup will likely change once the beamline has a cluster.
138
+ """
139
+ if (
140
+ expt == "Serial Fixed"
141
+ ): # SSXType.FIXED: See https://github.com/DiamondLightSource/mx-bluesky/issues/608
142
+ logfile = time.strftime("i24fixedtarget_%d%B%y.log").lower()
143
+ else:
144
+ logfile = time.strftime("i24extruder_%d%B%y.log").lower()
145
+
146
+ config(logfile, dev_mode=dev_mode)
147
+ yield from bps.null()
148
+
149
+
150
+ def clean_up_log_config_at_end() -> MsgGenerator:
151
+ """A small plan for blueapi to tidy up logging configuration."""
152
+ # See https://github.com/DiamondLightSource/mx-bluesky/issues/609
153
+ for handler in SSX_LOGGER.handlers:
154
+ SSX_LOGGER.removeHandler(handler)
155
+ for handler in dodal_logger.handlers:
156
+ dodal_logger.removeHandler(handler)
157
+ yield from bps.null()
@@ -41,7 +41,6 @@ PARAM_FILE_NAME = "parameters.json"
41
41
  PARAM_FILE_PATH = _params_file_location()
42
42
  PARAM_FILE_PATH_FT = PARAM_FILE_PATH / "fixed_target"
43
43
  LITEMAP_PATH = PARAM_FILE_PATH_FT / "litemaps"
44
- FULLMAP_PATH = PARAM_FILE_PATH_FT / "fullmaps"
45
44
  # Paths for r only
46
45
  PVAR_FILE_PATH = INTERNAL_FILES_PATH / "fixed_target/pvar_files"
47
46
  CS_FILES_PATH = INTERNAL_FILES_PATH / "fixed_target/cs"
@@ -1,8 +1,8 @@
1
1
  {
2
- "scalex": 10004.0,
3
- "scaley": 10005.2,
2
+ "scalex": 10004.7,
3
+ "scaley": 10004.4,
4
4
  "scalez": 10000.0,
5
- "skew": -0.01,
5
+ "skew": 0.120,
6
6
  "Sx_dir": 1,
7
7
  "Sy_dir": 1,
8
8
  "Sz_dir": 1
@@ -1,19 +1,44 @@
1
1
  #!/bin/bash
2
2
 
3
+ NO_PROCESERV_TEST=false
4
+
5
+ case "$2" in
6
+ -t | --test)
7
+ echo "Will run serial in test mode without procserv."
8
+ NO_PROCESERV_TEST=true
9
+ ;;
10
+ esac
11
+
12
+
3
13
  # Get edm path from input
4
14
  edm_path=$1
5
15
 
6
16
  # Get the directory of this script
7
17
  current=$( realpath "$( dirname "$0" )" )
8
18
 
9
- # Run script to start blueapi serve
10
- . $current/start_blueapi.sh
19
+ if [[ $NO_PROCESERV_TEST == true ]]; then
20
+ echo "Start the blueapi sever"
21
+
22
+ # Run script to start blueapi serve
23
+ . $current/start_blueapi.sh
24
+ fi
25
+
26
+ echo "Set up logging configuration"
27
+ blueapi -c "${current}/blueapi_config.yaml" controller run setup_collection_logs '{"expt":"Serial Jet"}'
11
28
 
12
29
  # Open the edm screen for an extruder serial collection
13
30
  echo "Starting extruder edm screen."
14
31
  edm -x "${edm_path}/EX-gui/DiamondExtruder-I24-py3v1.edl"
15
32
 
16
- echo "Edm screen closed, bye!"
33
+ echo "Edm screen closed"
34
+
35
+ echo "Clean up log configuration"
36
+ blueapi -c "${current}/blueapi_config.yaml" controller run clean_up_log_config_at_end
37
+
38
+ if [[ $NO_PROCESERV_TEST == true ]]; then
39
+ # In this case blueapi server needs to be killed.
40
+ pgrep blueapi | xargs kill
41
+ echo "Blueapi process killed"
42
+ fi
17
43
 
18
- pgrep blueapi | xargs kill
19
- echo "Blueapi process killed"
44
+ echo "All done, bye!"
@@ -1,5 +1,14 @@
1
1
  #!/bin/bash
2
2
 
3
+ NO_PROCESERV_TEST=false
4
+
5
+ case "$2" in
6
+ -t | --test)
7
+ echo "Will run serial in test mode without procserv."
8
+ NO_PROCESERV_TEST=true
9
+ ;;
10
+ esac
11
+
3
12
  # Get edm path from input
4
13
  edm_path=$1
5
14
 
@@ -9,14 +18,30 @@ export EDMDATAFILES="/dls_sw/prod/R3.14.12.3/support/motor/6-7-1dls14/motorApp/o
9
18
  # Get the directory of this script
10
19
  current=$( realpath "$( dirname "$0" )" )
11
20
 
12
- # Run script to start blueapi serve
13
- . $current/start_blueapi.sh
21
+
22
+ if [[ $NO_PROCESERV_TEST == true ]]; then
23
+ echo "Start the blueapi sever"
24
+
25
+ # Run script to start blueapi serve
26
+ . $current/start_blueapi.sh
27
+ fi
28
+
29
+ echo "Set up logging configuration"
30
+ blueapi -c "${current}/blueapi_config.yaml" controller run setup_collection_logs '{"expt":"Serial Fixed"}'
14
31
 
15
32
  # Open the edm screen for a fixed target serial collection
16
33
  echo "Starting fixed target edm screen."
17
34
  edm -x "${edm_path}/FT-gui/DiamondChipI24-py3v1.edl"
18
35
 
19
- echo "Edm screen closed, bye!"
36
+ echo "Edm screen closed"
37
+
38
+ echo "Clean up log configuration"
39
+ blueapi -c "${current}/blueapi_config.yaml" controller run clean_up_log_config_at_end
40
+
41
+ if [[ $NO_PROCESERV_TEST == true ]]; then
42
+ # In this case blueapi server needs to be killed.
43
+ pgrep blueapi | xargs kill
44
+ echo "Blueapi process killed"
45
+ fi
20
46
 
21
- pgrep blueapi | xargs kill
22
- echo "Blueapi process killed"
47
+ echo "All done, bye!"