-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
470 Full experiment plan to replace execute request #538
base: main
Are you sure you want to change the base?
Changes from all commits
334114c
ce1faa5
273bf43
35c78b6
bd24559
a4c44ca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import dataclasses | ||
|
||
from blueapi.core import BlueskyContext | ||
from dodal.devices.oav.oav_parameters import OAVParameters | ||
|
||
from mx_bluesky.hyperion.experiment_plans.robot_load_then_centre_plan import ( | ||
RobotLoadThenCentreComposite, | ||
robot_load_then_centre, | ||
) | ||
from mx_bluesky.hyperion.experiment_plans.rotation_scan_plan import ( | ||
RotationScanComposite, | ||
multi_rotation_scan, | ||
) | ||
from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect | ||
from mx_bluesky.hyperion.utils.context import device_composite_from_context | ||
|
||
|
||
@dataclasses.dataclass | ||
class LoadCentreCollectComposite(RobotLoadThenCentreComposite, RotationScanComposite): | ||
"""Composite that provides access to the required devices.""" | ||
|
||
pass | ||
|
||
|
||
def create_devices(context: BlueskyContext) -> LoadCentreCollectComposite: | ||
"""Create the necessary devices for the plan.""" | ||
return device_composite_from_context(context, LoadCentreCollectComposite) | ||
|
||
|
||
def load_centre_collect_full_plan( | ||
composite: LoadCentreCollectComposite, | ||
params: LoadCentreCollect, | ||
oav_params: OAVParameters | None = None, | ||
): | ||
"""Attempt a complete data collection experiment, consisting of the following: | ||
* Load the sample if necessary | ||
* Move to the specified goniometer start angles | ||
* Perform optical centring, then X-ray centring | ||
* If X-ray centring finds a diffracting centre then move to that centre and | ||
* do a collection with the specified parameters. | ||
""" | ||
if not oav_params: | ||
oav_params = OAVParameters(context="xrayCentring") | ||
Comment on lines
+42
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we need to refactor the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
yield from robot_load_then_centre(composite, params.robot_load_then_centre) | ||
|
||
yield from multi_rotation_scan(composite, params.multi_rotation_scan, oav_params) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -147,6 +147,15 @@ class WithOptionalEnergyChange(BaseModel): | |
|
||
class WithVisit(BaseModel): | ||
visit: str = Field(min_length=1) | ||
zocalo_environment: str = Field(default=CONST.ZOCALO_ENV) | ||
beamline: str = Field(default=CONST.I03.BEAMLINE, pattern=r"BL\d{2}[BIJS]") | ||
det_dist_to_beam_converter_path: str = Field( | ||
default=CONST.PARAM.DETECTOR.BEAM_XY_LUT_PATH | ||
) | ||
insertion_prefix: str = Field( | ||
default=CONST.I03.INSERTION_PREFIX, pattern=r"SR\d{2}[BIJS]" | ||
) | ||
detector_distance_mm: float | None = Field(default=None, gt=0) | ||
Comment on lines
+150
to
+158
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another reminder to myself to write an issue cleaning this up There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
|
||
class DiffractionExperiment( | ||
|
@@ -157,16 +166,7 @@ class DiffractionExperiment( | |
file_name: str | ||
exposure_time_s: float = Field(gt=0) | ||
comment: str = Field(default="") | ||
beamline: str = Field(default=CONST.I03.BEAMLINE, pattern=r"BL\d{2}[BIJS]") | ||
insertion_prefix: str = Field( | ||
default=CONST.I03.INSERTION_PREFIX, pattern=r"SR\d{2}[BIJS]" | ||
) | ||
det_dist_to_beam_converter_path: str = Field( | ||
default=CONST.PARAM.DETECTOR.BEAM_XY_LUT_PATH | ||
) | ||
zocalo_environment: str = Field(default=CONST.ZOCALO_ENV) | ||
trigger_mode: TriggerMode = Field(default=TriggerMode.FREE_RUN) | ||
detector_distance_mm: float | None = Field(default=None, gt=0) | ||
run_number: int | None = Field(default=None, ge=0) | ||
selected_aperture: ApertureValue | None = Field(default=None) | ||
transmission_frac: float = Field(default=0.1) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
from typing import TypeVar | ||
|
||
from pydantic import BaseModel, model_validator | ||
|
||
from mx_bluesky.hyperion.parameters.components import ( | ||
HyperionParameters, | ||
WithSample, | ||
WithVisit, | ||
) | ||
from mx_bluesky.hyperion.parameters.gridscan import ( | ||
RobotLoadThenCentre, | ||
) | ||
from mx_bluesky.hyperion.parameters.rotation import MultiRotationScan | ||
|
||
T = TypeVar("T", bound=BaseModel) | ||
|
||
|
||
def construct_from_values(parent_context: dict, key: str, t: type[T]) -> T: | ||
values = dict(parent_context) | ||
values |= values[key] | ||
return t(**values) | ||
|
||
|
||
class LoadCentreCollect(HyperionParameters, WithVisit, WithSample): | ||
"""Experiment parameters to perform the combined robot load, | ||
pin-tip centre and rotation scan operations.""" | ||
|
||
robot_load_then_centre: RobotLoadThenCentre | ||
multi_rotation_scan: MultiRotationScan | ||
|
||
@model_validator(mode="before") | ||
@classmethod | ||
def validate_model(cls, values): | ||
allowed_keys = ( | ||
LoadCentreCollect.model_fields.keys() | ||
| RobotLoadThenCentre.model_fields.keys() | ||
| MultiRotationScan.model_fields.keys() | ||
) | ||
disallowed_keys = values.keys() - allowed_keys | ||
assert ( | ||
disallowed_keys == set() | ||
), f"Unexpected fields found in LoadCentreCollect {disallowed_keys}" | ||
|
||
values["robot_load_then_centre"] = construct_from_values( | ||
values, "robot_load_then_centre", RobotLoadThenCentre | ||
) | ||
values["multi_rotation_scan"] = construct_from_values( | ||
values, "multi_rotation_scan", MultiRotationScan | ||
) | ||
return values |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should: I think in general it's preferable to use https://nsls-ii.github.io/bluesky/generated/bluesky.preprocessors.finalize_wrapper.html as it better handles the
GeneratorExit
case for when theRE
wants to interrupt a plan to pause/stop. We don't do this currently but might as well think bear it in mind.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will look at doing this for the multipin changes as I will need to move that anyway