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

Commit

Permalink
Merge tidy-ups
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Willemsen committed Nov 10, 2023
1 parent 2812e00 commit a27463b
Show file tree
Hide file tree
Showing 14 changed files with 117 additions and 54 deletions.
5 changes: 1 addition & 4 deletions deploy/deploy_hyperion.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from git import Repo
from packaging.version import Version

recognised_beamlines = ["dev", "i03", "i02-1", "i04"]ain
recognised_beamlines = ["dev", "i03", "i02-1", "i04"]


class repo:
Expand Down Expand Up @@ -67,13 +67,10 @@ def get_hyperion_release_dir_from_args(repo: repo) -> str:
if args.beamline == "dev":
print("Running as dev")
return "/tmp/hyperion_release_test/bluesky"
<<<<<<< HEAD
elif args.beamline == "i03":
return f"/dls_sw/{args.beamline}/software/bluesky"
elif args.beamline == "i02-1":
return f"/dls_sw/{args.beamline}/software/bluesky"
=======
>>>>>>> origin/main
else:
return f"/dls_sw/{args.beamline}/software/bluesky"

Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ install_requires =
xarray
doct
databroker
dls-dodal @ git+https://github.com/DiamondLightSource/dodal.git@9adc9ee996ff70a1e3f340def3f85e10a318af82
dls-dodal @ git+https://github.com/DiamondLightSource/dodal.git@39084723b73adec1df9199b9fe601d68242eeb3d
pydantic<2.0 # See https://github.com/DiamondLightSource/hyperion/issues/774
scipy

Expand Down
22 changes: 16 additions & 6 deletions src/hyperion/experiment_plans/vmxm_flyscan_xray_centre_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,12 @@
)

import hyperion.log
from hyperion.device_setup_plans.setup_zebra import (
set_zebra_shutter_to_manual,
)
from hyperion.exceptions import WarningException
from hyperion.external_interaction.callbacks.xray_centre.callback_collection import (
VmxmFastGridScanCallbackCollection,
)
from hyperion.parameters import external_parameters
from hyperion.parameters.constants import ISPYB_PLAN_NAME, SIM_BEAMLINE
from hyperion.parameters.constants import ISPYB_HARDWARE_READ_PLAN, SIM_BEAMLINE
from hyperion.tracing import TRACER
from hyperion.utils.context import device_composite_from_context, setup_context

Expand Down Expand Up @@ -76,7 +73,7 @@ def wait_for_gridscan_valid(fgs_motors: FastGridScan2D, timeout=0.5):

def tidy_up_plans(fgs_composite: VmxmFlyScanXRayCentreComposite):
hyperion.log.LOGGER.info("Tidying up Zebra")
yield from set_zebra_shutter_to_manual(fgs_composite.zebra)
yield from tidyup_vmxm_zebra_after_gridscan(fgs_composite.zebra)

Check warning on line 76 in src/hyperion/experiment_plans/vmxm_flyscan_xray_centre_plan.py

View check run for this annotation

Codecov / codecov/patch

src/hyperion/experiment_plans/vmxm_flyscan_xray_centre_plan.py#L75-L76

Added lines #L75 - L76 were not covered by tests


@bpp.set_run_key_decorator("run_gridscan")
Expand All @@ -90,7 +87,7 @@ def run_gridscan(
):
fgs_motors = fgs_composite.fast_grid_scan

Check warning on line 88 in src/hyperion/experiment_plans/vmxm_flyscan_xray_centre_plan.py

View check run for this annotation

Codecov / codecov/patch

src/hyperion/experiment_plans/vmxm_flyscan_xray_centre_plan.py#L88

Added line #L88 was not covered by tests

yield from bps.create(name=ISPYB_PLAN_NAME)
yield from bps.create(name=ISPYB_HARDWARE_READ_PLAN)
yield from bps.read(fgs_composite.synchrotron.machine_status.synchrotron_mode)
yield from bps.save()

Check warning on line 92 in src/hyperion/experiment_plans/vmxm_flyscan_xray_centre_plan.py

View check run for this annotation

Codecov / codecov/patch

src/hyperion/experiment_plans/vmxm_flyscan_xray_centre_plan.py#L90-L92

Added lines #L90 - L92 were not covered by tests

Expand Down Expand Up @@ -135,6 +132,19 @@ def setup_vmxm_zebra_for_gridscan(
yield from bps.wait(group)

Check warning on line 132 in src/hyperion/experiment_plans/vmxm_flyscan_xray_centre_plan.py

View check run for this annotation

Codecov / codecov/patch

src/hyperion/experiment_plans/vmxm_flyscan_xray_centre_plan.py#L131-L132

Added lines #L131 - L132 were not covered by tests


def tidyup_vmxm_zebra_after_gridscan(
zebra: Zebra, group="tidyup_vmxm_zebra_after_gridscan", wait=False
): # note: VMXm-specific
vmxm_zebra_input = 4
vmxm_zebra_output = 36
yield from bps.abs_set(

Check warning on line 140 in src/hyperion/experiment_plans/vmxm_flyscan_xray_centre_plan.py

View check run for this annotation

Codecov / codecov/patch

src/hyperion/experiment_plans/vmxm_flyscan_xray_centre_plan.py#L138-L140

Added lines #L138 - L140 were not covered by tests
zebra.output.out_pvs[vmxm_zebra_input], vmxm_zebra_output, group=group
)

if wait:
yield from bps.wait(group)

Check warning on line 145 in src/hyperion/experiment_plans/vmxm_flyscan_xray_centre_plan.py

View check run for this annotation

Codecov / codecov/patch

src/hyperion/experiment_plans/vmxm_flyscan_xray_centre_plan.py#L144-L145

Added lines #L144 - L145 were not covered by tests


@bpp.set_run_key_decorator("run_gridscan_and_move")
@bpp.run_decorator(md={"subplan_name": "run_gridscan_and_move"})
def run_gridscan_and_move(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ def event(self, doc: dict):
"flux_flux_reading", 0.0
)

LOGGER.info("Creating ispyb entry.")
self.ispyb_ids = self.ispyb.begin_deposition()
LOGGER.info(f"Recieved ISPYB IDs: {self.ispyb_ids}")
LOGGER.info("Creating ispyb entry.")
self.ispyb_ids = self.ispyb.begin_deposition()
LOGGER.info(f"Recieved ISPYB IDs: {self.ispyb_ids}")

def stop(self, doc: dict):
"""Subclasses must check that they are recieving a stop document for the correct
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from hyperion.external_interaction.callbacks.rotation.zocalo_callback import (
RotationZocaloCallback,
)
from hyperion.external_interaction.nexus.nexus_utils import create_i03_goniometer_axes

if TYPE_CHECKING:
from hyperion.parameters.plan_specific.rotation_scan_internal_params import (
Expand All @@ -25,15 +26,19 @@
@dataclass(frozen=True, order=True)
class RotationCallbackCollection(AbstractPlanCallbackCollection):
"""Groups the callbacks for external interactions for a rotation scan.
Cast to a list to pass it to Bluesky.preprocessors.subs_decorator()."""
Cast to a list to pass it to Bluesky.preprocessors.subs_decorator().
Note: specific to i03."""

nexus_handler: RotationNexusFileCallback
ispyb_handler: RotationISPyBCallback
zocalo_handler: RotationZocaloCallback

@classmethod
def from_params(cls, parameters: RotationInternalParameters):
nexus_handler = RotationNexusFileCallback()
nexus_handler = RotationNexusFileCallback(
create_goniometer_axes=create_i03_goniometer_axes
)
ispyb_handler = RotationISPyBCallback(parameters)
zocalo_handler = RotationZocaloCallback(
parameters.hyperion_params.zocalo_environment, ispyb_handler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

from bluesky.callbacks import CallbackBase

from hyperion.external_interaction.nexus.write_nexus import NexusWriter
from hyperion.external_interaction.nexus.write_nexus import (
CreateGoniometerProtocol,
NexusWriter,
)
from hyperion.log import LOGGER
from hyperion.parameters.plan_specific.rotation_scan_internal_params import (
RotationInternalParameters,
Expand All @@ -24,10 +27,11 @@ class RotationNexusFileCallback(CallbackBase):
Usually used as part of a RotationCallbackCollection.
"""

def __init__(self):
def __init__(self, create_goniometer_axes: CreateGoniometerProtocol):
self.run_uid: str | None = None
self.parameters: RotationInternalParameters | None = None
self.writer: NexusWriter | None = None
self.create_goniometer_axes = create_goniometer_axes

def start(self, doc: dict):
if doc.get("subplan_name") == "rotation_scan_with_cleanup":
Expand All @@ -42,5 +46,6 @@ def start(self, doc: dict):
self.parameters,
self.parameters.get_scan_points(),
self.parameters.get_data_shape(),
create_goniometer_func=self.create_goniometer_axes,
)
self.writer.create_nexus_file()
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
from hyperion.external_interaction.callbacks.xray_centre.zocalo_callback import (
XrayCentreZocaloCallback,
)
from hyperion.external_interaction.nexus.nexus_utils import (
create_i03_goniometer_axes,
create_vmxm_goniometer_axes,
)

if TYPE_CHECKING:
from hyperion.parameters.internal_parameters import InternalParameters
Expand All @@ -25,15 +29,17 @@
class XrayCentreCallbackCollection(AbstractPlanCallbackCollection):
"""Groups the callbacks for external interactions in the fast grid scan, and
connects the Zocalo and ISPyB handlers. Cast to a list to pass it to
Bluesky.preprocessors.subs_decorator()."""
Bluesky.preprocessors.subs_decorator().
Note: currently specific to i03 as it creates i03's goniometer axes."""

nexus_handler: GridscanNexusFileCallback
ispyb_handler: GridscanISPyBCallback
zocalo_handler: XrayCentreZocaloCallback

@classmethod
def from_params(cls, parameters: InternalParameters):
nexus_handler = GridscanNexusFileCallback()
nexus_handler = GridscanNexusFileCallback(create_i03_goniometer_axes)
ispyb_handler = GridscanISPyBCallback(parameters)
zocalo_handler = XrayCentreZocaloCallback(parameters, ispyb_handler)
callback_collection = cls(
Expand All @@ -46,14 +52,16 @@ def from_params(cls, parameters: InternalParameters):

@dataclass(frozen=True, order=True)
class VmxmFastGridScanCallbackCollection(AbstractPlanCallbackCollection):
"""Like XRayCentreCallbackCollection, but without zocalo."""
"""Like XRayCentreCallbackCollection, but without zocalo.
Note: currently specific to VMXm as it creates VMXm's goniometer axes."""

nexus_handler: Gridscan2DNexusFileCallback
ispyb_handler: GridscanISPyBCallback

@classmethod
def from_params(cls, parameters: InternalParameters):
nexus_handler = Gridscan2DNexusFileCallback()
nexus_handler = Gridscan2DNexusFileCallback(create_vmxm_goniometer_axes)
ispyb_handler = GridscanISPyBCallback(parameters)
callback_collection = cls(

Check warning on line 66 in src/hyperion/external_interaction/callbacks/xray_centre/callback_collection.py

View check run for this annotation

Codecov / codecov/patch

src/hyperion/external_interaction/callbacks/xray_centre/callback_collection.py#L64-L66

Added lines #L64 - L66 were not covered by tests
nexus_handler=nexus_handler,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

from bluesky.callbacks import CallbackBase

from hyperion.external_interaction.nexus.write_nexus import NexusWriter
from hyperion.external_interaction.nexus.write_nexus import (
CreateGoniometerProtocol,
NexusWriter,
)
from hyperion.log import LOGGER
from hyperion.parameters.constants import ISPYB_HARDWARE_READ_PLAN
from hyperion.parameters.plan_specific.gridscan_internal_params import (
Expand All @@ -29,11 +32,12 @@ class GridscanNexusFileCallback(CallbackBase):
Usually used as part of an FGSCallbackCollection.
"""

def __init__(self) -> None:
def __init__(self, create_goniometer_func: CreateGoniometerProtocol) -> None:
self.parameters: GridscanInternalParameters | None = None
self.run_start_uid: str | None = None
self.nexus_writer_1: NexusWriter | None = None
self.nexus_writer_2: NexusWriter | None = None
self.create_goniometer_func = create_goniometer_func

def start(self, doc: dict):
if doc.get("subplan_name") == "run_gridscan_move_and_tidy":
Expand All @@ -57,9 +61,14 @@ def descriptor(self, doc):
nexus_data_1 = self.parameters.get_nexus_info(1)
LOGGER.info(f"Nexus data 1: {nexus_data_1}")
nexus_data_2 = self.parameters.get_nexus_info(2)
self.nexus_writer_1 = NexusWriter(self.parameters, **nexus_data_1)
self.nexus_writer_1 = NexusWriter(
self.parameters,
create_goniometer_func=self.create_goniometer_func,
**nexus_data_1,
)
self.nexus_writer_2 = NexusWriter(
self.parameters,
create_goniometer_func=self.create_goniometer_func,
**nexus_data_2,
vds_start_index=nexus_data_1["data_shape"][0],
)
Expand All @@ -70,10 +79,11 @@ def descriptor(self, doc):
class Gridscan2DNexusFileCallback(CallbackBase):
"""Similar to above, but for a 2D gridscan"""

def __init__(self) -> None:
def __init__(self, create_goniometer_func: CreateGoniometerProtocol) -> None:
self.parameters: GridscanInternalParameters | None = None
self.run_start_uid: str | None = None
self.nexus_writer: NexusWriter | None = None
self.create_goniometer_func = create_goniometer_func

Check warning on line 86 in src/hyperion/external_interaction/callbacks/xray_centre/nexus_callback.py

View check run for this annotation

Codecov / codecov/patch

src/hyperion/external_interaction/callbacks/xray_centre/nexus_callback.py#L83-L86

Added lines #L83 - L86 were not covered by tests

def start(self, doc: dict):
if doc.get("subplan_name") == "run_gridscan_move_and_tidy":
Expand All @@ -85,7 +95,7 @@ def start(self, doc: dict):
self.run_start_uid = doc.get("uid")

Check warning on line 95 in src/hyperion/external_interaction/callbacks/xray_centre/nexus_callback.py

View check run for this annotation

Codecov / codecov/patch

src/hyperion/external_interaction/callbacks/xray_centre/nexus_callback.py#L93-L95

Added lines #L93 - L95 were not covered by tests

def descriptor(self, doc):
if doc.get("name") == ISPYB_PLAN_NAME:
if doc.get("name") == ISPYB_HARDWARE_READ_PLAN:
assert (

Check warning on line 99 in src/hyperion/external_interaction/callbacks/xray_centre/nexus_callback.py

View check run for this annotation

Codecov / codecov/patch

src/hyperion/external_interaction/callbacks/xray_centre/nexus_callback.py#L98-L99

Added lines #L98 - L99 were not covered by tests
self.parameters is not None
), "Nexus callback did not receive parameters before being asked to write!"
Expand All @@ -96,5 +106,9 @@ def descriptor(self, doc):
LOGGER.info("Initialising nexus writer")
nexus_data = self.parameters.get_nexus_info(1)
LOGGER.info(f"Nexus data: {nexus_data}")
self.nexus_writer = NexusWriter(self.parameters, **nexus_data)
self.nexus_writer = NexusWriter(

Check warning on line 109 in src/hyperion/external_interaction/callbacks/xray_centre/nexus_callback.py

View check run for this annotation

Codecov / codecov/patch

src/hyperion/external_interaction/callbacks/xray_centre/nexus_callback.py#L106-L109

Added lines #L106 - L109 were not covered by tests
self.parameters,
create_goniometer_func=self.create_goniometer_func,
**nexus_data,
)
self.nexus_writer.create_nexus_file()

Check warning on line 114 in src/hyperion/external_interaction/callbacks/xray_centre/nexus_callback.py

View check run for this annotation

Codecov / codecov/patch

src/hyperion/external_interaction/callbacks/xray_centre/nexus_callback.py#L114

Added line #L114 was not covered by tests
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from hyperion.external_interaction.callbacks.xray_centre.nexus_callback import (
GridscanNexusFileCallback,
)
from hyperion.external_interaction.nexus.nexus_utils import create_i03_goniometer_axes
from hyperion.parameters.constants import ISPYB_HARDWARE_READ_PLAN
from hyperion.parameters.external_parameters import from_file as default_raw_params
from hyperion.parameters.plan_specific.gridscan_internal_params import (
Expand Down Expand Up @@ -36,7 +37,7 @@ def test_writers_not_setup_on_plan_start_doc(
nexus_writer: MagicMock,
dummy_params: GridscanInternalParameters,
):
nexus_handler = GridscanNexusFileCallback()
nexus_handler = GridscanNexusFileCallback(create_i03_goniometer_axes)
nexus_writer.assert_not_called()
nexus_handler.start(
{
Expand All @@ -51,7 +52,7 @@ def test_writers_dont_create_on_init_but_do_on_ispyb_event(
nexus_writer: MagicMock,
dummy_params: GridscanInternalParameters,
):
nexus_handler = GridscanNexusFileCallback()
nexus_handler = GridscanNexusFileCallback(create_i03_goniometer_axes)

assert nexus_handler.nexus_writer_1 is None
assert nexus_handler.nexus_writer_2 is None
Expand Down Expand Up @@ -85,7 +86,7 @@ def test_writers_do_create_one_file_each_on_start_doc_for_run_gridscan(
):
nexus_writer.side_effect = [MagicMock(), MagicMock()]

nexus_handler = GridscanNexusFileCallback()
nexus_handler = GridscanNexusFileCallback(create_i03_goniometer_axes)
nexus_handler.start(
{
"subplan_name": "run_gridscan_move_and_tidy",
Expand Down Expand Up @@ -113,7 +114,7 @@ def test_writers_do_create_one_file_each_on_start_doc_for_run_gridscan(
def test_sensible_error_if_writing_triggered_before_params_received(
nexus_writer: MagicMock, dummy_params
):
nexus_handler = GridscanNexusFileCallback()
nexus_handler = GridscanNexusFileCallback(create_i03_goniometer_axes)
with pytest.raises(AssertionError) as excinfo:
nexus_handler.descriptor(
{
Expand Down
15 changes: 1 addition & 14 deletions src/hyperion/external_interaction/nexus/nexus_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@
from datetime import datetime, timedelta

from dodal.devices.detector import DetectorParams
from dodal.utils import get_beamline_name
from nexgen.nxs_utils import Attenuator, Axis, Beam, Detector, EigerDetector, Goniometer
from nexgen.nxs_utils.Axes import TransformationType

from hyperion.external_interaction.ispyb.ispyb_dataclass import IspybParams

BL = get_beamline_name(None)


def create_i03_goniometer_axes(
omega_start: float,
Expand Down Expand Up @@ -72,7 +69,7 @@ def create_vmxm_goniometer_axes(
omega_start: float,
scan_points: dict | None,
x_y_z_increments: tuple[float, float, float] = (0.0, 0.0, 0.0),
):
) -> Goniometer:
"""Returns a Nexgen 'Goniometer' object with the dependency chain of I03's Smargon
goniometer. If scan points is provided these values will be used in preference to
those from the params object.
Expand Down Expand Up @@ -117,16 +114,6 @@ def create_vmxm_goniometer_axes(
return Goniometer(gonio_axes, scan_points)

Check warning on line 114 in src/hyperion/external_interaction/nexus/nexus_utils.py

View check run for this annotation

Codecov / codecov/patch

src/hyperion/external_interaction/nexus/nexus_utils.py#L114

Added line #L114 was not covered by tests


if BL == "i03":
create_goniometer_axes = create_i03_goniometer_axes
elif BL == "i02-1":
create_goniometer_axes = create_vmxm_goniometer_axes
else:

def create_goniometer_axes(*a, **k):
raise ValueError("Cannot create goniometer axes on unknown beamline")


def get_start_and_predicted_end_time(time_expected: float) -> tuple[str, str]:
time_format = r"%Y-%m-%dT%H:%M:%SZ"
start = datetime.utcfromtimestamp(time.time())
Expand Down
Loading

0 comments on commit a27463b

Please sign in to comment.