66
77import bluesky .plan_stubs as bps
88import bluesky .preprocessors as bpp
9- import numpy as np
109from bluesky .protocols import Readable
1110from bluesky .utils import FailedStatus , MsgGenerator
12- from dodal .common . beamlines . commissioning_mode import read_commissioning_mode
11+ from dodal .devices . eiger import EigerDetector
1312from dodal .devices .fast_grid_scan import (
1413 FastGridScanCommon ,
1514 FastGridScanThreeD ,
1615 GridScanInvalidError ,
1716)
18- from dodal .devices .zocalo import ZocaloResults
19- from dodal .devices .zocalo .zocalo_results import (
20- XrcResult ,
21- get_full_processing_results ,
22- )
2317
2418from mx_bluesky .common .experiment_plans .inner_plans .do_fgs import (
25- ZOCALO_STAGE_GROUP ,
2619 kickoff_and_complete_gridscan ,
2720)
2821from mx_bluesky .common .experiment_plans .inner_plans .read_hardware import (
2922 read_hardware_plan ,
3023)
3124from mx_bluesky .common .parameters .constants import (
3225 DocDescriptorNames ,
33- GridscanParamConstants ,
3426 PlanGroupCheckpointConstants ,
3527 PlanNameConstants ,
3628)
3729from mx_bluesky .common .parameters .device_composites import FlyScanEssentialDevices
3830from mx_bluesky .common .parameters .gridscan import SpecifiedThreeDGridScan
3931from mx_bluesky .common .utils .exceptions import (
40- CrystalNotFoundError ,
4132 SampleError ,
4233)
4334from mx_bluesky .common .utils .log import LOGGER
4435from mx_bluesky .common .utils .tracing import TRACER
45- from mx_bluesky .common .xrc_result import XRayCentreResult
4636
4737
4838@dataclasses .dataclass
@@ -55,26 +45,19 @@ class BeamlineSpecificFGSFeatures:
5545 ..., MsgGenerator
5646 ] # Eventually replace with https://github.com/DiamondLightSource/mx-bluesky/issues/819
5747 read_during_collection_plan : Callable [..., MsgGenerator ]
58- get_xrc_results_from_zocalo : bool
59-
6048
61- def generic_tidy (xrc_composite : FlyScanEssentialDevices , wait = True ) -> MsgGenerator :
62- """Tidy Zocalo and turn off Eiger dev/shm. Ran after the beamline-specific tidy plan"""
6349
64- LOGGER .info ("Tidying up Zocalo" )
65- group = "generic_tidy"
66- # make sure we don't consume any other results
67- yield from bps .unstage (xrc_composite .zocalo , group = group )
50+ def tidy_eiger (eiger : EigerDetector ) -> MsgGenerator :
51+ """Turn off Eiger dev/shm. Ran after the beamline-specific tidy plan"""
6852
6953 # Turn off dev/shm streaming to avoid filling disk, see https://github.com/DiamondLightSource/hyperion/issues/1395
7054 LOGGER .info ("Turning off Eiger dev/shm streaming" )
7155 # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855)
7256 yield from bps .abs_set (
73- xrc_composite . eiger .odin .fan .dev_shm_enable , # type: ignore # until https://github.com/DiamondLightSource/mx-bluesky/issues/1076
57+ eiger .odin .fan .dev_shm_enable , # type: ignore # until https://github.com/DiamondLightSource/mx-bluesky/issues/1076
7458 0 ,
75- group = group ,
59+ wait = True ,
7660 )
77- yield from bps .wait (group )
7861
7962
8063def construct_beamline_specific_fast_gridscan_features (
@@ -84,7 +67,6 @@ def construct_beamline_specific_fast_gridscan_features(
8467 fgs_motors : FastGridScanCommon ,
8568 signals_to_read_pre_flyscan : Sequence [Readable ],
8669 signals_to_read_during_collection : Sequence [Readable ],
87- get_xrc_results_from_zocalo : bool = False ,
8870) -> BeamlineSpecificFGSFeatures :
8971 """Construct the class needed to do beamline-specific parts of the XRC FGS
9072
@@ -104,9 +86,6 @@ def construct_beamline_specific_fast_gridscan_features(
10486
10587 signals_to_read_during_collection (Callable): Signals which will be read and saved as a bluesky event
10688 document whilst the gridscan motion is in progress
107-
108- get_xrc_results_from_zocalo (bool): If true, fetch grid scan results from zocalo after completion, as well as
109- update the ispyb comment field with information about the results. See _fetch_xrc_results_from_zocalo
11089 """
11190 read_pre_flyscan_plan = partial (
11291 read_hardware_plan ,
@@ -127,7 +106,6 @@ def construct_beamline_specific_fast_gridscan_features(
127106 fgs_motors ,
128107 read_pre_flyscan_plan ,
129108 read_during_collection_plan ,
130- get_xrc_results_from_zocalo ,
131109 )
132110
133111
@@ -159,7 +137,7 @@ def common_flyscan_xray_centre(
159137
160138 def _overall_tidy ():
161139 yield from beamline_specific .tidy_plan ()
162- yield from generic_tidy (composite )
140+ yield from tidy_eiger (composite . eiger )
163141
164142 def _decorated_flyscan ():
165143 @bpp .set_run_key_decorator (PlanNameConstants .GRIDSCAN_OUTER )
@@ -181,81 +159,16 @@ def run_gridscan_and_tidy(
181159 yield from beamline_specific .setup_trigger_plan (fgs_composite , parameters )
182160
183161 LOGGER .info ("Starting grid scan" )
184- yield from bps .stage (
185- fgs_composite .zocalo , group = ZOCALO_STAGE_GROUP
186- ) # connect to zocalo and make sure the queue is clear
187162 yield from run_gridscan (fgs_composite , params , beamline_specific )
188163
189164 LOGGER .info ("Grid scan finished" )
190165
191- if beamline_specific .get_xrc_results_from_zocalo :
192- yield from _fetch_xrc_results_from_zocalo (composite .zocalo , parameters )
193-
194166 yield from run_gridscan_and_tidy (composite , parameters , beamline_specific )
195167
196168 composite .eiger .set_detector_parameters (parameters .detector_params )
197169 yield from _decorated_flyscan ()
198170
199171
200- def _fetch_xrc_results_from_zocalo (
201- zocalo_results : ZocaloResults ,
202- parameters : SpecifiedThreeDGridScan ,
203- ) -> MsgGenerator :
204- """
205- Get XRC results from the ZocaloResults device which was staged during a grid scan,
206- and store them in XRayCentreEventHandler.xray_centre_results by firing an event.
207-
208- The RunEngine must be subscribed to XRayCentreEventHandler for this plan to work.
209- """
210-
211- LOGGER .info ("Getting X-ray center Zocalo results..." )
212-
213- yield from bps .trigger (zocalo_results , wait = True )
214- LOGGER .info ("Zocalo triggered and read, interpreting results." )
215- xrc_results = yield from get_full_processing_results (zocalo_results )
216- LOGGER .info (f"Got xray centres, top 5: { xrc_results [:5 ]} " )
217- filtered_results = [
218- result
219- for result in xrc_results
220- if result ["total_count" ]
221- >= GridscanParamConstants .ZOCALO_MIN_TOTAL_COUNT_THRESHOLD
222- ]
223- discarded_count = len (xrc_results ) - len (filtered_results )
224- if discarded_count > 0 :
225- LOGGER .info (f"Removed { discarded_count } results because below threshold" )
226- if filtered_results :
227- flyscan_results = [
228- _xrc_result_in_boxes_to_result_in_mm (xr , parameters )
229- for xr in filtered_results
230- ]
231- else :
232- commissioning_mode = yield from read_commissioning_mode ()
233- if commissioning_mode :
234- LOGGER .info ("Commissioning mode enabled, returning dummy result" )
235- flyscan_results = [_generate_dummy_xrc_result (parameters )]
236- else :
237- LOGGER .warning ("No X-ray centre received" )
238- raise CrystalNotFoundError ()
239- yield from _fire_xray_centre_result_event (flyscan_results )
240-
241-
242- def _generate_dummy_xrc_result (params : SpecifiedThreeDGridScan ) -> XRayCentreResult :
243- com = [params .x_steps / 2 , params .y_steps / 2 , params .z_steps / 2 ]
244- max_voxel = [round (p ) for p in com ]
245- return _xrc_result_in_boxes_to_result_in_mm (
246- XrcResult (
247- centre_of_mass = com ,
248- max_voxel = max_voxel ,
249- bounding_box = [max_voxel , [p + 1 for p in max_voxel ]],
250- n_voxels = 1 ,
251- max_count = 10000 ,
252- total_count = 100000 ,
253- sample_id = params .sample_id ,
254- ),
255- params ,
256- )
257-
258-
259172def run_gridscan (
260173 fgs_composite : FlyScanEssentialDevices ,
261174 parameters : SpecifiedThreeDGridScan ,
@@ -296,49 +209,3 @@ def run_gridscan(
296209 # in a GDA-happy state.
297210 if isinstance (beamline_specific .fgs_motors , FastGridScanThreeD ):
298211 yield from bps .abs_set (beamline_specific .fgs_motors .z_steps , 0 , wait = False )
299-
300-
301- def _xrc_result_in_boxes_to_result_in_mm (
302- xrc_result : XrcResult , parameters : SpecifiedThreeDGridScan
303- ) -> XRayCentreResult :
304- fgs_params = parameters .fast_gridscan_params
305- xray_centre = fgs_params .grid_position_to_motor_position (
306- np .array (xrc_result ["centre_of_mass" ])
307- )
308- # A correction is applied to the bounding box to map discrete grid coordinates to
309- # the corners of the box in motor-space; we do not apply this correction
310- # to the xray-centre as it is already in continuous space and the conversion has
311- # been performed already
312- # In other words, xrc_result["bounding_box"] contains the position of the box centre,
313- # so we subtract half a box to get the corner of the box
314- return XRayCentreResult (
315- centre_of_mass_mm = xray_centre ,
316- bounding_box_mm = (
317- fgs_params .grid_position_to_motor_position (
318- np .array (xrc_result ["bounding_box" ][0 ]) - 0.5
319- ),
320- fgs_params .grid_position_to_motor_position (
321- np .array (xrc_result ["bounding_box" ][1 ]) - 0.5
322- ),
323- ),
324- max_count = xrc_result ["max_count" ],
325- total_count = xrc_result ["total_count" ],
326- sample_id = xrc_result ["sample_id" ],
327- )
328-
329-
330- def _fire_xray_centre_result_event (results : Sequence [XRayCentreResult ]):
331- def empty_plan ():
332- return iter ([])
333-
334- yield from bpp .set_run_key_wrapper (
335- bpp .run_wrapper (
336- empty_plan (),
337- md = {
338- PlanNameConstants .FLYSCAN_RESULTS : [
339- dataclasses .asdict (r ) for r in results
340- ]
341- },
342- ),
343- PlanNameConstants .FLYSCAN_RESULTS ,
344- )
0 commit comments