-
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
(#475) Xray-centre and collect on multiple centres #553
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #553 +/- ##
==========================================
+ Coverage 78.21% 78.58% +0.37%
==========================================
Files 92 94 +2
Lines 6797 6943 +146
==========================================
+ Hits 5316 5456 +140
- Misses 1481 1487 +6
|
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.
Thank you! This is great, we will see how it goes on Monday. Some comments in code, think a few places where we should probably all talk it through together.
Additionally, for multipin tests we're also probably going to need something that gives us the top result in each segment e.g. for a 100 box long multipin with 5 samples in we would want the top result in 0-20, 20-40 etc. We can do this on the beamline for the tests next week and then maybe pull it into a better defined issue.
pass | ||
|
||
|
||
def change_aperture_then_centre( |
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 centre
here is misleading as upon first reading it I thought it meant you were about to do a pin tip/xrc. Maybe change_aperture_and_move_to_crystal
?
from mx_bluesky.hyperion.tracing import TRACER | ||
|
||
|
||
class CentringComposite(Protocol): |
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.
Could: Feels like a composite might be overkill here, we could just have change_aperture_then_centre
take a ApertureScatterguard and a Smargon
|
||
|
||
@dataclasses.dataclass | ||
class FlyscanResult: |
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: It's more a XRCResult than flyscan result. We could do a XRC as a step scan and produce these results.
@@ -112,26 +116,27 @@ def sample_motors(self) -> Smargon: | |||
return self.smargon | |||
|
|||
|
|||
class FlyscanEventHandler: |
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: For other events we use CallbackBase
. I can't see why you can't here and would be good to keep consistency.
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 think it's overkill for what should just be a simple event handler. What does it give us?
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) |
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: It looks weird to me to take args/kwargs when they're never used
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 think that's a leftover from when I first started off inheriting from DocumentRouter and decided it was too much faff
@@ -242,6 +262,38 @@ def run_gridscan_and_move( | |||
yield from bps.wait() | |||
|
|||
|
|||
def _xrc_result_to_flyscan_result( |
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 it is cleaner, and more idiomatic of bluesky, to move this calculation to the FlyscanEventHandler
. It should be able to get everything it needs for the calculation by the events produced throughout the plan. This would reduce the complexity of the plans themselves and change _fire_flyscan_result_event
to just be a bps.read(zocalo)
Probably needs a discussion.
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 started doing this and have run into complications with unit tests as now ThreeDGridscan
needs to be injected in lots of places. Also I think I have run into additional complications due to #220 which previously wasn't an issue because the tests either didn't need to account for this bug or did it both ways which cancelled each other out.
selection_params = params.select_centres | ||
selection_func = getattr(flyscan_result, selection_params.name) # type: ignore | ||
assert callable(selection_func) |
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 don't think letting the user provide a function name like this is very good. It's quite brittle to name changes/argument changes and I don't think we need this much flexibility right now anyway.
for hit in hits: | ||
LOGGER.info(f"Performing rotations for {hit}") | ||
yield from change_aperture_then_centre(hit, composite) | ||
yield from multi_rotation_scan( | ||
composite, params.multi_rotation_scan, oav_params | ||
) |
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.
Must: I think what we actually want to do is take all the hits and wrap them up in one call to multi_rotation_scan
with different x/y/z starts. Otherwise we're going to get the detector re-arming between them all etc. For a first pass this probably means just stay at the same aperture for each of them, which is fine.
@@ -105,15 +111,27 @@ def pin_tip_centre_then_xray_centre( | |||
oav_config_file: str = OAV_CONFIG_JSON, | |||
) -> MsgGenerator: | |||
"""Starts preparing for collection then performs the pin tip centre and xray centre""" | |||
# TODO listen for flyscan results and then centre |
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: We're doing this, no need for the comment
pin_centre_then_xray_centre_plan(composite, parameters, oav_config_file), | ||
group=CONST.WAIT.GRID_READY_FOR_DC, | ||
) | ||
flyscan_event_handler = FlyscanEventHandler() |
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: This pattern is used quite a bit now, I think it's probably worth making a wrapper of something like:
def do_plan_and_move_to_xrc_result(plan):
"""Do the specified plan then move to whatever result XRC gives back"""
yield from bpp.subs_wrapper(plan, flyscan_event_handler := FlyscanEventHandler())
flyscan_results = flyscan_event_handler.flyscan_results
assert (
flyscan_results
), "Flyscan result event not received or no crystal found and exception not raised"
yield from change_aperture_then_centre(flyscan_results[0], composite)
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 didn't partly as we are ultimately removing most of the places where it's used anyway
Fix system tests, unit tests
928a917
to
646e46f
Compare
Implements #475
See also DiamondLightSource/dodal#814
This implements multiple rotations on multiple centres for the
load_centre_collect_full_plan
.The behaviour of other plans should remain unchanged, with moving to a single centre.
By default load_centre_collect also only does a single centre.
To specify multiple centres, include the following in the request parameters:
where n is however many centres to select