mx-bluesky 0.0.1__py3-none-any.whl → 0.3.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 (82) hide show
  1. mx_bluesky/__main__.py +1 -2
  2. mx_bluesky/_version.py +14 -2
  3. mx_bluesky/example.py +4 -4
  4. mx_bluesky/i04/__init__.py +3 -0
  5. mx_bluesky/i04/callbacks/murko_callback.py +45 -0
  6. mx_bluesky/i04/thawing_plan.py +84 -0
  7. mx_bluesky/i24/serial/__init__.py +49 -0
  8. mx_bluesky/i24/serial/blueapi_config.yaml +12 -0
  9. mx_bluesky/{I24 → i24}/serial/dcid.py +53 -41
  10. mx_bluesky/{I24 → i24}/serial/extruder/EX-gui-edm/DetStage.edl +1 -2
  11. mx_bluesky/{I24 → i24}/serial/extruder/EX-gui-edm/DiamondExtruder-I24-py3v1.edl +28 -32
  12. mx_bluesky/{I24 → i24}/serial/extruder/EX-gui-edm/microdrop_alignment.edl +0 -1
  13. mx_bluesky/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +513 -0
  14. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/CustomChip_py3v1.edl +1 -2
  15. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/DetStage.edl +1 -2
  16. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/DiamondChipI24-py3v1.edl +46 -41
  17. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/ME14E-GeneralPurpose.edl +0 -1
  18. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/MappingLite-oxford_py3v1.edl +10 -11
  19. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/PMAC_Command.edl +0 -1
  20. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/Shutter_Control.edl +0 -1
  21. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/microdrop_alignment.edl +0 -1
  22. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/nudgechip.edl +0 -1
  23. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/pumpprobe-py3v1.edl +300 -119
  24. mx_bluesky/i24/serial/fixed_target/FT-gui-edm/short1-laser.png +0 -0
  25. mx_bluesky/i24/serial/fixed_target/FT-gui-edm/short2-laser.png +0 -0
  26. mx_bluesky/{I24 → i24}/serial/fixed_target/ft_utils.py +24 -1
  27. mx_bluesky/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +798 -0
  28. mx_bluesky/{I24 → i24}/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +374 -408
  29. mx_bluesky/{I24 → i24}/serial/fixed_target/i24ssx_Chip_Mapping_py3v1.py +34 -40
  30. mx_bluesky/i24/serial/fixed_target/i24ssx_Chip_StartUp_py3v1.py +325 -0
  31. mx_bluesky/{I24 → i24}/serial/fixed_target/i24ssx_moveonclick.py +40 -45
  32. mx_bluesky/i24/serial/log.py +156 -0
  33. mx_bluesky/i24/serial/parameters/__init__.py +15 -0
  34. mx_bluesky/i24/serial/parameters/constants.py +47 -0
  35. mx_bluesky/i24/serial/parameters/experiment_parameters.py +124 -0
  36. mx_bluesky/i24/serial/parameters/fixed_target/cs/cs_maker.json +9 -0
  37. mx_bluesky/{I24 → i24}/serial/parameters/fixed_target/cs/motor_direction.txt +1 -1
  38. mx_bluesky/{I24 → i24}/serial/parameters/fixed_target/pvar_files/minichip-oxford.pvar +1 -1
  39. mx_bluesky/i24/serial/parameters/utils.py +40 -0
  40. mx_bluesky/i24/serial/run_extruder.sh +19 -0
  41. mx_bluesky/i24/serial/run_fixed_target.sh +22 -0
  42. mx_bluesky/i24/serial/run_serial.py +36 -0
  43. mx_bluesky/{I24 → i24}/serial/set_visit_directory.sh +6 -1
  44. mx_bluesky/{I24 → i24}/serial/setup_beamline/pv.py +1 -62
  45. mx_bluesky/{I24 → i24}/serial/setup_beamline/pv_abstract.py +6 -7
  46. mx_bluesky/{I24 → i24}/serial/setup_beamline/setup_beamline.py +90 -269
  47. mx_bluesky/{I24 → i24}/serial/setup_beamline/setup_detector.py +47 -40
  48. mx_bluesky/i24/serial/setup_beamline/setup_zebra_plans.py +459 -0
  49. mx_bluesky/i24/serial/start_blueapi.sh +28 -0
  50. mx_bluesky/i24/serial/write_nexus.py +102 -0
  51. mx_bluesky/parameters/__init__.py +31 -0
  52. mx_bluesky/parameters/components.py +200 -0
  53. {mx_bluesky-0.0.1.dist-info → mx_bluesky-0.3.1.dist-info}/METADATA +37 -26
  54. mx_bluesky-0.3.1.dist-info/RECORD +67 -0
  55. {mx_bluesky-0.0.1.dist-info → mx_bluesky-0.3.1.dist-info}/WHEEL +1 -1
  56. mx_bluesky-0.3.1.dist-info/entry_points.txt +4 -0
  57. mx_bluesky/I24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +0 -476
  58. mx_bluesky/I24/serial/fixed_target/FT-gui-edm/ME14E-motors.edl +0 -1874
  59. mx_bluesky/I24/serial/fixed_target/__init__.py +0 -0
  60. mx_bluesky/I24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +0 -695
  61. mx_bluesky/I24/serial/fixed_target/i24ssx_Chip_StartUp_py3v1.py +0 -463
  62. mx_bluesky/I24/serial/log.py +0 -101
  63. mx_bluesky/I24/serial/parameters/__init__.py +0 -5
  64. mx_bluesky/I24/serial/parameters/constants.py +0 -39
  65. mx_bluesky/I24/serial/parameters/fixed_target/cs/cs_maker.json +0 -9
  66. mx_bluesky/I24/serial/parameters/fixed_target/cs/fiducial_1.txt +0 -4
  67. mx_bluesky/I24/serial/parameters/fixed_target/cs/fiducial_2.txt +0 -4
  68. mx_bluesky/I24/serial/parameters/fixed_target/litemaps/currentchip.map +0 -81
  69. mx_bluesky/I24/serial/parameters/fixed_target/parameters.txt +0 -13
  70. mx_bluesky/I24/serial/run_serial.py +0 -52
  71. mx_bluesky/I24/serial/write_nexus.py +0 -113
  72. mx_bluesky-0.0.1.dist-info/RECORD +0 -58
  73. mx_bluesky-0.0.1.dist-info/entry_points.txt +0 -4
  74. /mx_bluesky/{I24 → i24}/__init__.py +0 -0
  75. /mx_bluesky/{I24/serial → i24/serial/extruder}/__init__.py +0 -0
  76. /mx_bluesky/{I24/serial/extruder → i24/serial/fixed_target}/__init__.py +0 -0
  77. /mx_bluesky/{I24 → i24}/serial/parameters/fixed_target/pvar_files/oxford.pvar +0 -0
  78. /mx_bluesky/{I24 → i24}/serial/run_ssx.sh +0 -0
  79. /mx_bluesky/{I24 → i24}/serial/setup_beamline/__init__.py +0 -0
  80. /mx_bluesky/{I24 → i24}/serial/setup_beamline/ca.py +0 -0
  81. {mx_bluesky-0.0.1.dist-info → mx_bluesky-0.3.1.dist-info}/LICENSE +0 -0
  82. {mx_bluesky-0.0.1.dist-info → mx_bluesky-0.3.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,513 @@
1
+ """
2
+ Extruder data collection
3
+ This version in python3 new Feb2021 by RLO
4
+ - March 21 added logging and Eiger functionality
5
+ """
6
+
7
+ import json
8
+ import logging
9
+ import re
10
+ import shutil
11
+ import sys
12
+ import time
13
+ from datetime import datetime
14
+ from pathlib import Path
15
+ from pprint import pformat
16
+ from time import sleep
17
+
18
+ import bluesky.plan_stubs as bps
19
+ import bluesky.preprocessors as bpp
20
+ from blueapi.core import MsgGenerator
21
+ from dodal.common import inject
22
+ from dodal.devices.hutch_shutter import HutchShutter, ShutterDemand
23
+ from dodal.devices.i24.aperture import Aperture
24
+ from dodal.devices.i24.beamstop import Beamstop
25
+ from dodal.devices.i24.dcm import DCM
26
+ from dodal.devices.i24.dual_backlight import DualBacklight
27
+ from dodal.devices.i24.i24_detector_motion import DetectorMotion
28
+ from dodal.devices.zebra import DISCONNECT, SOFT_IN3, Zebra
29
+
30
+ from mx_bluesky.i24.serial import log
31
+ from mx_bluesky.i24.serial.dcid import DCID
32
+ from mx_bluesky.i24.serial.parameters import ExtruderParameters, SSXType
33
+ from mx_bluesky.i24.serial.parameters.constants import PARAM_FILE_NAME, PARAM_FILE_PATH
34
+ from mx_bluesky.i24.serial.setup_beamline import Pilatus, caget, caput, pv
35
+ from mx_bluesky.i24.serial.setup_beamline import setup_beamline as sup
36
+ from mx_bluesky.i24.serial.setup_beamline.setup_detector import (
37
+ UnknownDetectorType,
38
+ get_detector_type,
39
+ )
40
+ from mx_bluesky.i24.serial.setup_beamline.setup_zebra_plans import (
41
+ GATE_START,
42
+ TTL_EIGER,
43
+ TTL_PILATUS,
44
+ arm_zebra,
45
+ disarm_zebra,
46
+ open_fast_shutter,
47
+ reset_zebra_when_collection_done_plan,
48
+ set_shutter_mode,
49
+ setup_zebra_for_extruder_with_pump_probe_plan,
50
+ setup_zebra_for_quickshot_plan,
51
+ )
52
+ from mx_bluesky.i24.serial.write_nexus import call_nexgen
53
+
54
+ usage = "%(prog)s command [options]"
55
+ logger = logging.getLogger("I24ssx.extruder")
56
+
57
+ SAFE_DET_Z = 1480
58
+
59
+
60
+ def setup_logging():
61
+ logfile = time.strftime("i24extruder_%d%B%y.log").lower()
62
+ log.config(logfile)
63
+
64
+
65
+ def flush_print(text):
66
+ sys.stdout.write(str(text))
67
+ sys.stdout.flush()
68
+
69
+
70
+ @log.log_on_entry
71
+ def initialise_extruder(
72
+ detector_stage: DetectorMotion = inject("detector_motion"),
73
+ ) -> MsgGenerator:
74
+ setup_logging()
75
+ logger.info("Initialise Parameters for extruder data collection on I24.")
76
+
77
+ visit = caget(pv.ioc12_gp1)
78
+ logger.info(f"Visit defined {visit}")
79
+
80
+ # Define detector in use
81
+ det_type = yield from get_detector_type(detector_stage)
82
+
83
+ caput(pv.ioc12_gp2, "test")
84
+ caput(pv.ioc12_gp3, "testrun")
85
+ caput(pv.ioc12_gp4, "100")
86
+ caput(pv.ioc12_gp5, "0.01")
87
+ caput(pv.ioc12_gp6, 0)
88
+ caput(pv.ioc12_gp8, 0) # status PV do not reuse gp8 for something else
89
+ caput(pv.ioc12_gp9, 0)
90
+ caput(pv.ioc12_gp10, 0)
91
+ caput(pv.ioc12_gp15, det_type.name)
92
+ caput(pv.pilat_cbftemplate, 0)
93
+ logger.info("Initialisation complete.")
94
+ yield from bps.null()
95
+
96
+
97
+ @log.log_on_entry
98
+ def laser_check(
99
+ mode: str,
100
+ zebra: Zebra = inject("zebra"),
101
+ detector_stage: DetectorMotion = inject("detector_motion"),
102
+ ) -> MsgGenerator:
103
+ """Plan to open the shutter and check the laser beam from the viewer by pressing \
104
+ 'Laser On' and 'Laser Off' buttons on the edm.
105
+
106
+ The 'Laser on' button sets the correct OUT_TTL pv for the detector in use to \
107
+ SOFT_IN1 and the shutter mode to auto.
108
+ The 'Laser off' button disconnects the OUT_TTL pv set by the previous step and \
109
+ resets the shutter mode to manual.
110
+
111
+ WARNING. When using the laser with the extruder, some hardware changes need to be made.
112
+ Because all four of the zebra ttl outputs are in use in this mode, when the \
113
+ detector in use is the Eiger, the Pilatus cable is repurposed to trigger the light \
114
+ source, and viceversa.
115
+ """
116
+ setup_logging()
117
+ logger.debug(f"Laser check: {mode}")
118
+
119
+ det_type = yield from get_detector_type(detector_stage)
120
+
121
+ LASER_TTL = TTL_EIGER if isinstance(det_type, Pilatus) else TTL_PILATUS
122
+ if mode == "laseron":
123
+ yield from bps.abs_set(zebra.output.out_pvs[LASER_TTL], SOFT_IN3)
124
+ yield from set_shutter_mode(zebra, "auto")
125
+
126
+ if mode == "laseroff":
127
+ yield from bps.abs_set(zebra.output.out_pvs[LASER_TTL], DISCONNECT)
128
+ yield from set_shutter_mode(zebra, "manual")
129
+
130
+
131
+ @log.log_on_entry
132
+ def enter_hutch(
133
+ detector_stage: DetectorMotion = inject("detector_motion"),
134
+ ) -> MsgGenerator:
135
+ """Move the detector stage before entering hutch."""
136
+ setup_logging()
137
+ yield from bps.mv(detector_stage.z, SAFE_DET_Z)
138
+ logger.debug("Detector moved.")
139
+
140
+
141
+ @log.log_on_entry
142
+ def write_parameter_file(detector_stage: DetectorMotion):
143
+ """Writes a json parameter file that can later be parsed by the model."""
144
+ param_file: Path = PARAM_FILE_PATH / PARAM_FILE_NAME
145
+ logger.debug(f"Writing Parameter File to: {param_file}\n")
146
+
147
+ det_type = yield from get_detector_type(detector_stage)
148
+ logger.warning(f"DETECTOR TYPE: {det_type}")
149
+ filename = caget(pv.ioc12_gp3)
150
+ # If file name ends in a digit this causes processing/pilatus pain.
151
+ # Append an underscore
152
+ if det_type.name == "pilatus":
153
+ m = re.search(r"\d+$", filename)
154
+ if m is not None:
155
+ # Note for future reference. Appending underscore causes more hassle and
156
+ # high probability of users accidentally overwriting data. Use a dash
157
+ filename = filename + "-"
158
+ logger.info(
159
+ f"Requested filename ends in a number. Appended dash: {filename}"
160
+ )
161
+
162
+ pump_status = bool(caget(pv.ioc12_gp6))
163
+ pump_exp = float(caget(pv.ioc12_gp9)) if pump_status else None
164
+ pump_delay = float(caget(pv.ioc12_gp10)) if pump_status else None
165
+
166
+ params_dict = {
167
+ "visit": log._read_visit_directory_from_file().as_posix(), # noqa
168
+ "directory": caget(pv.ioc12_gp2),
169
+ "filename": filename,
170
+ "exposure_time_s": float(caget(pv.ioc12_gp5)),
171
+ "detector_distance_mm": float(caget(pv.ioc12_gp7)),
172
+ "detector_name": str(det_type),
173
+ "num_images": int(caget(pv.ioc12_gp4)),
174
+ "pump_status": pump_status,
175
+ "laser_dwell_s": pump_exp,
176
+ "laser_delay_s": pump_delay,
177
+ }
178
+ with open(param_file, "w") as f:
179
+ json.dump(params_dict, f, indent=4)
180
+
181
+ logger.info("Parameters \n")
182
+ logger.info(pformat(params_dict))
183
+ yield from bps.null()
184
+
185
+
186
+ @log.log_on_entry
187
+ def main_extruder_plan(
188
+ zebra: Zebra,
189
+ aperture: Aperture,
190
+ backlight: DualBacklight,
191
+ beamstop: Beamstop,
192
+ detector_stage: DetectorMotion,
193
+ shutter: HutchShutter,
194
+ dcm: DCM,
195
+ parameters: ExtruderParameters,
196
+ dcid: DCID,
197
+ start_time: datetime,
198
+ ) -> MsgGenerator:
199
+ # Setting up the beamline
200
+ logger.debug("Open hutch shutter")
201
+ yield from bps.abs_set(shutter, ShutterDemand.OPEN, wait=True)
202
+
203
+ yield from sup.setup_beamline_for_collection_plan(
204
+ aperture, backlight, beamstop, wait=True
205
+ )
206
+
207
+ yield from sup.move_detector_stage_to_position_plan(
208
+ detector_stage, parameters.detector_distance_mm
209
+ )
210
+
211
+ # For pixel detector
212
+ filepath = parameters.collection_directory.as_posix()
213
+ logger.debug(f"Filepath {filepath}")
214
+ logger.debug(f"Filename {parameters.filename}")
215
+
216
+ if parameters.detector_name == "pilatus":
217
+ logger.info("Using pilatus mini cbf")
218
+ caput(pv.pilat_cbftemplate, 0)
219
+ logger.info(f"Pilatus quickshot setup: filepath {filepath}")
220
+ logger.info(f"Pilatus quickshot setup: filepath {parameters.filename}")
221
+ logger.info(
222
+ f"Pilatus quickshot setup: number of images {parameters.num_images}"
223
+ )
224
+ logger.info(
225
+ f"Pilatus quickshot setup: exposure time {parameters.exposure_time_s}"
226
+ )
227
+
228
+ if parameters.pump_status:
229
+ logger.info("Pump probe extruder data collection")
230
+ logger.info(f"Pump exposure time {parameters.laser_dwell_s}")
231
+ logger.info(f"Pump delay time {parameters.laser_delay_s}")
232
+ sup.pilatus(
233
+ "fastchip",
234
+ [
235
+ filepath,
236
+ parameters.filename,
237
+ parameters.num_images,
238
+ parameters.exposure_time_s,
239
+ ],
240
+ )
241
+ yield from setup_zebra_for_extruder_with_pump_probe_plan(
242
+ zebra,
243
+ parameters.detector_name,
244
+ parameters.exposure_time_s,
245
+ parameters.num_images,
246
+ parameters.laser_dwell_s,
247
+ parameters.laser_delay_s,
248
+ pulse1_delay=0.0,
249
+ wait=True,
250
+ )
251
+ else:
252
+ logger.info("Static experiment: no photoexcitation")
253
+ sup.pilatus(
254
+ "quickshot",
255
+ [
256
+ filepath,
257
+ parameters.filename,
258
+ parameters.num_images,
259
+ parameters.exposure_time_s,
260
+ ],
261
+ )
262
+ yield from setup_zebra_for_quickshot_plan(
263
+ zebra, parameters.exposure_time_s, parameters.num_images, wait=True
264
+ )
265
+
266
+ elif parameters.detector_name == "eiger":
267
+ logger.info("Using Eiger detector")
268
+
269
+ logger.warning(
270
+ """TEMPORARY HACK!
271
+ Running a Single image pilatus data collection to create directory."""
272
+ ) # See https://github.com/DiamondLightSource/mx_bluesky/issues/45
273
+ num_shots = 1
274
+ sup.pilatus(
275
+ "quickshot-internaltrig",
276
+ [filepath, parameters.filename, num_shots, parameters.exposure_time_s],
277
+ )
278
+ logger.debug("Sleep 2s waiting for pilatus to arm")
279
+ sleep(2.5)
280
+ caput(pv.pilat_acquire, "0") # Disarm pilatus
281
+ sleep(0.5)
282
+ caput(pv.pilat_acquire, "1") # Arm pilatus
283
+ logger.debug("Pilatus data collection DONE")
284
+ sup.pilatus("return to normal", None)
285
+ logger.info("Pilatus back to normal. Single image pilatus data collection DONE")
286
+
287
+ caput(pv.eiger_seqID, int(caget(pv.eiger_seqID)) + 1)
288
+ logger.info(f"Eiger quickshot setup: filepath {filepath}")
289
+ logger.info(f"Eiger quickshot setup: filepath {parameters.filename}")
290
+ logger.info(f"Eiger quickshot setup: number of images {parameters.num_images}")
291
+ logger.info(
292
+ f"Eiger quickshot setup: exposure time {parameters.exposure_time_s}"
293
+ )
294
+
295
+ if parameters.pump_status:
296
+ logger.info("Pump probe extruder data collection")
297
+ logger.debug(f"Pump exposure time {parameters.laser_dwell_s}")
298
+ logger.debug(f"Pump delay time {parameters.laser_delay_s}")
299
+ sup.eiger(
300
+ "triggered",
301
+ [
302
+ filepath,
303
+ parameters.filename,
304
+ parameters.num_images,
305
+ parameters.exposure_time_s,
306
+ ],
307
+ )
308
+ yield from setup_zebra_for_extruder_with_pump_probe_plan(
309
+ zebra,
310
+ parameters.detector_name,
311
+ parameters.exposure_time_s,
312
+ parameters.num_images,
313
+ parameters.laser_dwell_s,
314
+ parameters.laser_delay_s,
315
+ pulse1_delay=0.0,
316
+ wait=True,
317
+ )
318
+ else:
319
+ logger.info("Static experiment: no photoexcitation")
320
+ sup.eiger(
321
+ "quickshot",
322
+ [
323
+ filepath,
324
+ parameters.filename,
325
+ parameters.num_images,
326
+ parameters.exposure_time_s,
327
+ ],
328
+ )
329
+ yield from setup_zebra_for_quickshot_plan(
330
+ zebra, parameters.exposure_time_s, parameters.num_images, wait=True
331
+ )
332
+ else:
333
+ err = f"Unknown Detector Type, det_type = {parameters.detector_name}"
334
+ logger.error(err)
335
+ raise UnknownDetectorType(err)
336
+
337
+ # Do DCID creation BEFORE arming the detector
338
+ dcid.generate_dcid(
339
+ visit=parameters.visit.name,
340
+ image_dir=parameters.collection_directory.as_posix(),
341
+ start_time=start_time,
342
+ num_images=parameters.num_images,
343
+ exposure_time=parameters.exposure_time_s,
344
+ pump_exposure_time=parameters.laser_dwell_s,
345
+ pump_delay=parameters.laser_delay_s or 0,
346
+ pump_status=int(parameters.pump_status),
347
+ )
348
+
349
+ # Collect
350
+ logger.info("Fast shutter opening")
351
+ yield from open_fast_shutter(zebra)
352
+ if parameters.detector_name == "pilatus":
353
+ logger.info("Pilatus acquire ON")
354
+ caput(pv.pilat_acquire, 1)
355
+ elif parameters.detector_name == "eiger":
356
+ logger.info("Triggering Eiger NOW")
357
+ caput(pv.eiger_trigger, 1)
358
+
359
+ dcid.notify_start()
360
+
361
+ if parameters.detector_name == "eiger":
362
+ wavelength = yield from bps.rd(dcm.wavelength_in_a)
363
+ logger.debug("Call nexgen server for nexus writing.")
364
+ call_nexgen(None, start_time, parameters, wavelength, "extruder")
365
+
366
+ timeout_time = time.time() + parameters.num_images * parameters.exposure_time_s + 10
367
+
368
+ yield from arm_zebra(zebra)
369
+ sleep(GATE_START) # Sleep for the same length of gate_start, hard coded to 1
370
+ i = 0
371
+ text_list = ["|", "/", "-", "\\"]
372
+ while True:
373
+ line_of_text = "\r\t\t\t Waiting " + 30 * (f"{text_list[i % 4]}")
374
+ flush_print(line_of_text)
375
+ sleep(0.5)
376
+ i += 1
377
+ zebra_arm_status = yield from bps.rd(zebra.pc.arm.armed)
378
+ if zebra_arm_status == 0: # not zebra.pc.is_armed():
379
+ # As soon as zebra is disarmed, exit.
380
+ # Epics updates this PV once the collection is done.
381
+ logger.info("Zebra disarmed - Collection done.")
382
+ break
383
+ if time.time() >= timeout_time:
384
+ logger.warning(
385
+ """
386
+ Something went wrong and data collection timed out. Aborting.
387
+ """
388
+ )
389
+ raise TimeoutError("Data collection timed out.")
390
+
391
+ logger.debug("Collection completed without errors.")
392
+
393
+
394
+ @log.log_on_entry
395
+ def collection_aborted_plan(
396
+ zebra: Zebra, detector_name: str, dcid: DCID
397
+ ) -> MsgGenerator:
398
+ """A plan to run in case the collection is aborted before the end."""
399
+ logger.warning("Data Collection Aborted")
400
+ yield from disarm_zebra(zebra) # If aborted/timed out zebra still armed
401
+ if detector_name == "pilatus":
402
+ caput(pv.pilat_acquire, 0)
403
+ elif detector_name == "eiger":
404
+ caput(pv.eiger_acquire, 0)
405
+ sleep(0.5)
406
+ end_time = datetime.now()
407
+ dcid.collection_complete(end_time, aborted=True)
408
+
409
+
410
+ @log.log_on_entry
411
+ def tidy_up_at_collection_end_plan(
412
+ zebra: Zebra,
413
+ shutter: HutchShutter,
414
+ parameters: ExtruderParameters,
415
+ dcid: DCID,
416
+ ) -> MsgGenerator:
417
+ """A plan to tidy up at the end of a collection, successful or aborted.
418
+
419
+ Args:
420
+ zebra (Zebra): The Zebra device.
421
+ shutter (HutchShutter): The HutchShutter device.
422
+ parameters (ExtruderParameters): Collection parameters.
423
+ """
424
+ yield from reset_zebra_when_collection_done_plan(zebra)
425
+
426
+ # Clean Up
427
+ if parameters.detector_name == "pilatus":
428
+ sup.pilatus("return-to-normal", None)
429
+ elif parameters.detector_name == "eiger":
430
+ sup.eiger("return-to-normal", None)
431
+ logger.debug(f"{parameters.filename}_{caget(pv.eiger_seqID)}")
432
+ logger.debug("End of Run")
433
+ logger.debug("Close hutch shutter")
434
+ yield from bps.abs_set(shutter, ShutterDemand.CLOSE, wait=True)
435
+
436
+ dcid.notify_end()
437
+
438
+
439
+ @log.log_on_entry
440
+ def collection_complete_plan(
441
+ collection_directory: Path, detector_name: str, dcid: DCID
442
+ ) -> MsgGenerator:
443
+ if detector_name == "pilatus":
444
+ logger.info("Pilatus Acquire STOP")
445
+ caput(pv.pilat_acquire, 0)
446
+ elif detector_name == "eiger":
447
+ logger.info("Eiger Acquire STOP")
448
+ caput(pv.eiger_acquire, 0)
449
+ caput(pv.eiger_ODcapture, "Done")
450
+
451
+ sleep(0.5)
452
+
453
+ end_time = datetime.now()
454
+ dcid.collection_complete(end_time, aborted=False)
455
+ logger.info(f"End Time = {end_time.ctime()}")
456
+
457
+ # Copy parameter file
458
+ shutil.copy2(
459
+ PARAM_FILE_PATH / PARAM_FILE_NAME,
460
+ collection_directory / PARAM_FILE_NAME,
461
+ )
462
+ yield from bps.null()
463
+
464
+
465
+ def run_extruder_plan(
466
+ zebra: Zebra = inject("zebra"),
467
+ aperture: Aperture = inject("aperture"),
468
+ backlight: DualBacklight = inject("backlight"),
469
+ beamstop: Beamstop = inject("beamstop"),
470
+ detector_stage: DetectorMotion = inject("detector_motion"),
471
+ shutter: HutchShutter = inject("shutter"),
472
+ dcm: DCM = inject("dcm"),
473
+ ) -> MsgGenerator:
474
+ setup_logging()
475
+ start_time = datetime.now()
476
+ logger.info(f"Collection start time: {start_time.ctime()}")
477
+
478
+ yield from write_parameter_file(detector_stage)
479
+ parameters = ExtruderParameters.from_file(PARAM_FILE_PATH / PARAM_FILE_NAME)
480
+
481
+ # DCID - not generated yet
482
+ dcid = DCID(
483
+ emit_errors=False,
484
+ ssx_type=SSXType.EXTRUDER,
485
+ detector=parameters.detector_name,
486
+ )
487
+
488
+ yield from bpp.contingency_wrapper(
489
+ main_extruder_plan(
490
+ zebra=zebra,
491
+ aperture=aperture,
492
+ backlight=backlight,
493
+ beamstop=beamstop,
494
+ detector_stage=detector_stage,
495
+ shutter=shutter,
496
+ dcm=dcm,
497
+ parameters=parameters,
498
+ dcid=dcid,
499
+ start_time=start_time,
500
+ ),
501
+ except_plan=lambda e: (
502
+ yield from collection_aborted_plan(zebra, parameters.detector_name, dcid)
503
+ ),
504
+ else_plan=lambda: (
505
+ yield from collection_complete_plan(
506
+ parameters.collection_directory, parameters.detector_name, dcid
507
+ )
508
+ ),
509
+ final_plan=lambda: (
510
+ yield from tidy_up_at_collection_end_plan(zebra, shutter, parameters, dcid)
511
+ ),
512
+ auto_raise=False,
513
+ )
@@ -690,7 +690,7 @@ botShadowColor index 11
690
690
  font "arial-medium-r-18.0"
691
691
  numCmds 1
692
692
  command {
693
- 0 "python SCRIPTS_LOCATION/fixed_target/i24ssx_Chip_Manager_py3v1.py cs_reset"
693
+ 0 "blueapi -c CONFIG_LOCATION controller run cs_reset"
694
694
  }
695
695
  endObjectProperties
696
696
 
@@ -830,4 +830,3 @@ value {
830
830
  }
831
831
  autoSize
832
832
  endObjectProperties
833
-
@@ -113,7 +113,7 @@ font "arial-medium-r-18.0"
113
113
  buttonLabel "Move Stage"
114
114
  numCmds 1
115
115
  command {
116
- 0 "python SCRIPTS_LOCATION/setup_beamline/setup_detector.py \"Serial Fixed\""
116
+ 0 "blueapi -c CONFIG_LOCATION controller run setup_detector_stage '\{\"expt_type\":\"Serial Fixed\"\}'"
117
117
  }
118
118
  endObjectProperties
119
119
 
@@ -136,4 +136,3 @@ value {
136
136
  }
137
137
  autoSize
138
138
  endObjectProperties
139
-