Skip to content

Conversation

@srishtysajeev
Copy link
Contributor

@srishtysajeev srishtysajeev commented Dec 4, 2025

Fixes #1489

Requires DiamondLightSource/dodal#1757

To test:

  • Confirm tests pass

@DominicOram DominicOram added the i04 Changes relating to I04 label Dec 9, 2025
Copy link
Contributor

@DominicOram DominicOram left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly reminders to myself that I will fix but would like an answer on the question around when we optimise transmission

for zoom in zoom_levels:
LOGGER.info(f"Moving to zoom level {zoom}")
yield from bps.abs_set(oav.zoom_controller, zoom, wait=True)
yield from bps.sleep(1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should: Why do we have a sleep here and in the zoom device? I think probably just having one in the zoom device is better

Comment on lines 240 to 273
zoom_level_to_dict = {
"7.5x": [
oav.zoom_controller.x_placeholder_zoom_7,
oav.zoom_controller.y_placeholder_zoom_7,
],
"1.0x": [
oav.zoom_controller.x_placeholder_zoom_1,
oav.zoom_controller.y_placeholder_zoom_1,
],
"1.5x": [
oav.zoom_controller.x_placeholder_zoom_2,
oav.zoom_controller.y_placeholder_zoom_2,
],
"2.0x": [
oav.zoom_controller.x_placeholder_zoom_3,
oav.zoom_controller.y_placeholder_zoom_3,
],
"2.5x": [
oav.zoom_controller.x_placeholder_zoom_4,
oav.zoom_controller.y_placeholder_zoom_4,
],
"3.0x": [
oav.zoom_controller.x_placeholder_zoom_5,
oav.zoom_controller.y_placeholder_zoom_5,
],
"5.0x": [
oav.zoom_controller.x_placeholder_zoom_6,
oav.zoom_controller.y_placeholder_zoom_6,
],
"10.0x": [
oav.zoom_controller.x_placeholder_zoom_8,
oav.zoom_controller.y_placeholder_zoom_8,
],
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be stored on the device

LOGGER.info(f"Moving to zoom level {zoom}")
yield from bps.abs_set(oav.zoom_controller, zoom, wait=True)
yield from bps.sleep(1)
if zoom == "7.5x" or zoom == "1.0x":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should: Why do we want to optimise transmission at specifically these zooms? Maybe a question for @olliesilvester or @aragaod

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was a bit arbitrary. We definitely wanted to optimise transmission for zoom 7.5 because it's apparently the most important zoom level and then we noticed that this transmission wasn't as good for the low zooms so we also decided to run the optimisation for zoom 1 too during testing.

@codecov
Copy link

codecov bot commented Dec 16, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.36%. Comparing base (327c161) to head (ef5cabf).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1496      +/-   ##
==========================================
+ Coverage   92.29%   92.36%   +0.06%     
==========================================
  Files         142      142              
  Lines        8094     8168      +74     
==========================================
+ Hits         7470     7544      +74     
  Misses        624      624              
Components Coverage Δ
i24 SSX 78.56% <ø> (ø)
hyperion 97.93% <ø> (ø)
other 98.12% <100.00%> (+0.04%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@DominicOram DominicOram changed the title 1489 automated oav centring post testing Add plan for automatically finding the beam centre on the OAV Dec 16, 2025
@DominicOram DominicOram marked this pull request as ready for review December 16, 2025 14:49
@DominicOram DominicOram requested a review from a team as a code owner December 16, 2025 14:49
@olliesilvester olliesilvester self-assigned this Dec 18, 2025
@olliesilvester
Copy link
Contributor

Notes after testing

  • Gives bad center on zoom 1 due to background ring. This should get fixed by using ROI (this logic is in another branch)
  • The binary search is a bit overkill. We can relax this by doing something like: At the beginning of a new iteration, check how much we're going to change the transmission. If it's less than x%, then we just end it there and use that transmission
  • XBPM trigger PV seems a bit dodgy - we think it isn't waiting long enough
  • Should use string enums for the zooms in initial params rather than strings. Also maybe throw an error if

Copy link
Contributor

@olliesilvester olliesilvester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This worked as-is on the beamline, but the main things to address are:

  • Better validation if you typo the parameters
  • Less strict binary search (but we can put that into a new issue)
  • Address dodgy xbpm feedback. Could add sleeps in for now, or chase up with controls

defaults are always correct.
"""

LOGGER.info("prearing beamline")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LOGGER.info("prearing beamline")
LOGGER.info("Preparing beamline to take scintillator images...")

initial_wait_group,
)

LOGGER.info("setting transmission")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LOGGER.info("setting transmission")

if image_name is None:
image_name = f"{time.time_ns()}ATT{transmission * 100}"

LOGGER.info(f"using image name {image_name}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LOGGER.info(f"using image name {image_name}")
LOGGER.info(f"Using image name {image_name}")

) -> MsgGenerator:
"""
Prepares the beamline for oav image by making sure the pin is NOT mounted and
Prepares the beamline for oav image by making sure the pin is not mounted and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could: mention in docstring that we're also opening shutter here

return (yield from bps.rd(max_pixel.max_pixel_val))


def optimise_transmission_with_oav(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notes from testing:

  • Occasionally this would hit the StopIteration for various reasons: We are being overly precise; there is an issue with i04's xbpm PV which is causing us to not wait for long enough,;the error margin on the transmission device is much higher than the PV suggests.
    We should keep the binary search, but either increase the tolerence, or call it "done" as soon as the next iteration would involve moving the transmission by <x%

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to put this part into a separate issue

Comment on lines +245 to +246
zoom_levels_to_centre: list[str] | None = None,
zoom_levels_to_optimise_transmission: list[str] | None = None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should: These should default to ["1.0x", "7.5x"] and ["1.0x", "7.5x"] respectively, then the if None part on lines 261 and 264 can be removed.

Also, we should use a string enum for the accepted zoom levels so that we can get proper validation. Right now there is no obvious error if someone typo's the zoom level parameters, the plan just ends up hanging somewhere.

xbpm_feedback: XBPMFeedback,
transmission: float,
):
yield from bps.trigger(xbpm_feedback, wait=True)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During testing we ended up adding a sleep after triggering xbpm feedback. This real fix is to address the issues with the PV though

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

i04 Changes relating to I04

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Automated OAV Centring: Create a plan that sets the beam centres for different zooms

4 participants