Skip to content
This repository has been archived by the owner on Sep 2, 2024. It is now read-only.

Commit

Permalink
(#1217) Use event from grid detect to do ispyb deposition
Browse files Browse the repository at this point in the history
* Move ispyb callback activation to before grid detect
* Fixup all the broken unit tests
* Separate descriptor constants from plan names
* Move callback activation wrapper to callback module
  • Loading branch information
rtuck99 committed Apr 23, 2024
1 parent ab757d4 commit 1192243
Show file tree
Hide file tree
Showing 27 changed files with 517 additions and 237 deletions.
8 changes: 4 additions & 4 deletions src/hyperion/device_setup_plans/read_hardware_for_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def read_hardware_for_ispyb_pre_collection(
):
LOGGER.info("Reading status of beamline for ispyb deposition, pre collection.")
yield from bps.create(
name=CONST.PLAN.ISPYB_HARDWARE_READ
name=CONST.DESCRIPTORS.ISPYB_HARDWARE_READ
) # gives name to event *descriptor* document
yield from bps.read(undulator.current_gap)
yield from bps.read(synchrotron.synchrotron_mode)
Expand All @@ -39,20 +39,20 @@ def read_hardware_for_ispyb_during_collection(
attenuator: Attenuator, flux: Flux, dcm: DCM
):
LOGGER.info("Reading status of beamline for ispyb deposition, during collection.")
yield from bps.create(name=CONST.PLAN.ISPYB_TRANSMISSION_FLUX_READ)
yield from bps.create(name=CONST.DESCRIPTORS.ISPYB_TRANSMISSION_FLUX_READ)
yield from bps.read(attenuator.actual_transmission)
yield from bps.read(flux.flux_reading)
yield from bps.read(dcm.energy_in_kev)
yield from bps.save()


def read_hardware_for_nexus_writer(detector: EigerDetector):
yield from bps.create(name=CONST.PLAN.NEXUS_READ)
yield from bps.create(name=CONST.DESCRIPTORS.NEXUS_READ)
yield from bps.read(detector.bit_depth)
yield from bps.save()


def read_hardware_for_zocalo(detector: EigerDetector):
yield from bps.create(name=CONST.PLAN.ZOCALO_HW_READ)
yield from bps.create(name=CONST.DESCRIPTORS.ZOCALO_HW_READ)
yield from bps.read(detector.odin.file_writer.id)
yield from bps.save()
1 change: 0 additions & 1 deletion src/hyperion/experiment_plans/flyscan_xray_centre_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,6 @@ def flyscan_xray_centre(
CONST.TRIGGER.ZOCALO: CONST.PLAN.DO_FGS,
"hyperion_internal_parameters": old_parameters.json(),
"activate_callbacks": [
"GridscanISPyBCallback",
"GridscanNexusFileCallback",
],
}
Expand Down
15 changes: 15 additions & 0 deletions src/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
from hyperion.external_interaction.callbacks.oav_snapshot_callback import (
OavSnapshotCallback,
)
from hyperion.external_interaction.callbacks.xray_centre.ispyb_callback import (
ispyb_activation_wrapper,
)
from hyperion.log import LOGGER
from hyperion.parameters.gridscan import GridScanWithEdgeDetect
from hyperion.parameters.plan_specific.grid_scan_with_edge_detect_params import (
Expand Down Expand Up @@ -134,6 +137,17 @@ def detect_grid_and_do_gridscan(
composite: GridDetectThenXRayCentreComposite,
parameters: GridScanWithEdgeDetectInternalParameters,
oav_params: OAVParameters,
):
yield from ispyb_activation_wrapper(
parameters,
_detect_grid_and_do_gridscan(composite, parameters, oav_params),
)


def _detect_grid_and_do_gridscan(
composite: GridDetectThenXRayCentreComposite,
parameters: GridScanWithEdgeDetectInternalParameters,
oav_params: OAVParameters,
):
assert composite.aperture_scatterguard.aperture_positions is not None
experiment_params: GridScanWithEdgeDetectParams = parameters.experiment_params
Expand Down Expand Up @@ -190,6 +204,7 @@ def run_grid_detection_plan(
parameters.hyperion_params.ispyb_params.xtal_snapshots_omega_end = (
oav_callback.snapshot_filenames[1][::-1]
)
# TODO 1217 REMOVE THIS
parameters.hyperion_params.ispyb_params.upper_left = out_upper_left

yield from bps.abs_set(composite.backlight, Backlight.OUT)
Expand Down
4 changes: 1 addition & 3 deletions src/hyperion/experiment_plans/oav_grid_detection_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from typing import TYPE_CHECKING, Tuple

import bluesky.plan_stubs as bps
import bluesky.preprocessors as bpp
import numpy as np
from blueapi.core import BlueskyContext
from dodal.devices.backlight import Backlight
Expand Down Expand Up @@ -57,7 +56,6 @@ def get_min_and_max_y_of_pin(
return min_y, max_y


@bpp.run_decorator()
def grid_detection_plan(
composite: OavGridDetectionComposite,
parameters: OAVParameters,
Expand Down Expand Up @@ -159,7 +157,7 @@ def grid_detection_plan(
yield from bps.abs_set(oav.snapshot.directory, snapshot_dir)
yield from bps.trigger(oav.snapshot, wait=True)

yield from bps.create("snapshot_to_ispyb")
yield from bps.create(CONST.DESCRIPTORS.OAV_SNAPSHOT_TRIGGERED)

yield from bps.read(oav.snapshot)
yield from bps.read(smargon)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,6 @@ def panda_flyscan_xray_centre(
CONST.TRIGGER.ZOCALO: CONST.PLAN.DO_FGS,
"hyperion_internal_parameters": parameters.json(),
"activate_callbacks": [
"GridscanISPyBCallback",
"GridscanNexusFileCallback",
],
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def robot_load():

yield from bps.wait("robot_load")

yield from bps.create(name=CONST.PLAN.ROBOT_LOAD)
yield from bps.create(name=CONST.DESCRIPTORS.ROBOT_LOAD)
yield from bps.read(composite.robot.barcode)
yield from bps.save()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ def get_xtal_snapshots(ispyb_params):

@dataclass
class GridScanInfo:
upper_left: Union[list[int], ndarray]
upper_left: Union[list[int], ndarray] # TODO REMOVE THIS
# upper_left_x: float
# upper_left_y: float
y_steps: int
y_step_size: float
101 changes: 57 additions & 44 deletions src/hyperion/external_interaction/callbacks/ispyb_callback_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,54 +92,67 @@ def activity_gated_event(self, doc: Event) -> Event:
"has no corresponding descriptor record"
)
return doc
if event_descriptor.get("name") == CONST.PLAN.ISPYB_HARDWARE_READ:
assert self._event_driven_data_collection_info
ISPYB_LOGGER.info("ISPyB handler received event from read hardware")
self._event_driven_data_collection_info.undulator_gap1 = doc["data"][
"undulator_current_gap"
]
assert isinstance(
synchrotron_mode := doc["data"]["synchrotron-synchrotron_mode"],
SynchrotronMode,
)
self._event_driven_data_collection_info.synchrotron_mode = (
synchrotron_mode.value
)
self._event_driven_data_collection_info.slitgap_horizontal = doc["data"][
"s4_slit_gaps_xgap"
]
self._event_driven_data_collection_info.slitgap_vertical = doc["data"][
"s4_slit_gaps_ygap"
]
self._sample_barcode = doc["data"]["robot-barcode"]

if event_descriptor.get("name") == CONST.PLAN.ISPYB_TRANSMISSION_FLUX_READ:
assert self._event_driven_data_collection_info
if transmission := doc["data"]["attenuator_actual_transmission"]:
# Ispyb wants the transmission in a percentage, we use fractions
self._event_driven_data_collection_info.transmission = (
transmission * 100
match event_descriptor.get("name"):
case CONST.DESCRIPTORS.ISPYB_HARDWARE_READ:
self._handle_ispyb_hardware_read(doc)
case CONST.DESCRIPTORS.OAV_SNAPSHOT_TRIGGERED:
self._handle_oav_snapshot_triggered(doc)
case CONST.DESCRIPTORS.ISPYB_TRANSMISSION_FLUX_READ:
self._handle_ispyb_transmission_flux_read(doc)

scan_data_infos = self.populate_info_for_update(
self._event_driven_data_collection_info, self.params
)
self._event_driven_data_collection_info.flux = doc["data"][
"flux_flux_reading"
]
if doc["data"]["dcm_energy_in_kev"]:
energy_ev = doc["data"]["dcm_energy_in_kev"] * 1000
self._event_driven_data_collection_info.wavelength = (
convert_eV_to_angstrom(energy_ev)
ISPYB_LOGGER.info("Updating ispyb entry.")
self.ispyb_ids = self.update_deposition(
self.params,
scan_data_infos,
self._sample_barcode,
)
ISPYB_LOGGER.info(f"Recieved ISPYB IDs: {self.ispyb_ids}")
return self._tag_doc(doc)

scan_data_infos = self.populate_info_for_update(
self._event_driven_data_collection_info, self.params
)
ISPYB_LOGGER.info("Updating ispyb entry.")
self.ispyb_ids = self.update_deposition(
self.params,
scan_data_infos,
self._sample_barcode,
def _handle_ispyb_hardware_read(self, doc):
assert self._event_driven_data_collection_info
ISPYB_LOGGER.info("ISPyB handler received event from read hardware")
self._event_driven_data_collection_info.undulator_gap1 = doc["data"][
"undulator_current_gap"
]
assert isinstance(
synchrotron_mode := doc["data"]["synchrotron-synchrotron_mode"],
SynchrotronMode,
)
self._event_driven_data_collection_info.synchrotron_mode = (
synchrotron_mode.value
)
self._event_driven_data_collection_info.slitgap_horizontal = doc["data"][
"s4_slit_gaps_xgap"
]
self._event_driven_data_collection_info.slitgap_vertical = doc["data"][
"s4_slit_gaps_ygap"
]
self._sample_barcode = doc["data"]["robot-barcode"]

def _handle_oav_snapshot_triggered(self, doc):
pass

def _handle_ispyb_transmission_flux_read(self, doc):
assert self._event_driven_data_collection_info
if transmission := doc["data"]["attenuator_actual_transmission"]:
# Ispyb wants the transmission in a percentage, we use fractions
self._event_driven_data_collection_info.transmission = transmission * 100

self._event_driven_data_collection_info.flux = doc["data"]["flux_flux_reading"]

if doc["data"]["dcm_energy_in_kev"]:
energy_ev = doc["data"]["dcm_energy_in_kev"] * 1000
self._event_driven_data_collection_info.wavelength = convert_eV_to_angstrom(
energy_ev
)
ISPYB_LOGGER.info(f"Recieved ISPYB IDs: {self.ispyb_ids}")
return self._tag_doc(doc)

def _deposit_grid_scan_info(self, doc: Event):
# TODO
pass

def update_deposition(
self,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def _run_activity_gated(self, name: str, func, doc, override=False):

def start(self, doc: RunStart) -> RunStart | None:
callbacks_to_activate = doc.get("activate_callbacks")
if callbacks_to_activate:
if callbacks_to_activate and not self.active:
activate = type(self).__name__ in callbacks_to_activate
self.active = activate
self.log.info(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ def activity_gated_descriptor(self, doc: EventDescriptor) -> EventDescriptor | N

def activity_gated_event(self, doc: Event) -> Event | None:
event_descriptor = self.descriptors.get(doc["descriptor"])
if event_descriptor and event_descriptor.get("name") == CONST.PLAN.ROBOT_LOAD:
if (
event_descriptor
and event_descriptor.get("name") == CONST.DESCRIPTORS.ROBOT_LOAD
):
assert (
self.action_id is not None
), "ISPyB Robot load callback event called unexpectedly"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,22 @@ def activity_gated_event(self, doc: Event):
"has no corresponding descriptor record"
)
return doc
if event_descriptor.get("name") == CONST.PLAN.ISPYB_TRANSMISSION_FLUX_READ:
if (
event_descriptor.get("name")
== CONST.DESCRIPTORS.ISPYB_TRANSMISSION_FLUX_READ
):
NEXUS_LOGGER.info(f"Nexus handler received event from read hardware {doc}")
data = doc["data"]
assert self.writer, "Nexus writer not initialised"
self.writer.beam, self.writer.attenuator = (
create_beam_and_attenuator_parameters(
data["dcm_energy_in_kev"],
data["flux_flux_reading"],
data["attenuator_actual_transmission"],
)
(
self.writer.beam,
self.writer.attenuator,
) = create_beam_and_attenuator_parameters(
data["dcm_energy_in_kev"],
data["flux_flux_reading"],
data["attenuator_actual_transmission"],
)
if event_descriptor.get("name") == CONST.PLAN.NEXUS_READ:
if event_descriptor.get("name") == CONST.DESCRIPTORS.NEXUS_READ:
NEXUS_LOGGER.info(f"Nexus handler received event from read hardware {doc}")
vds_data_type = vds_type_based_on_bit_depth(doc["data"]["eiger_bit_depth"])
assert self.writer is not None
Expand Down
Loading

0 comments on commit 1192243

Please sign in to comment.