Skip to content

Commit

Permalink
Read aperture size in serialisable format (#549)
Browse files Browse the repository at this point in the history
- Add a Converter and method to convert SingleAperturePosition
- Add a util to get beam size x and y from the above
  • Loading branch information
dperl-dls authored May 20, 2024
1 parent e06ae81 commit 729be13
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 13 deletions.
Empty file.
16 changes: 16 additions & 0 deletions src/dodal/beamline_specific_utils/i03.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from dataclasses import dataclass

from dodal.devices.aperturescatterguard import SingleAperturePosition

I03_BEAM_HEIGHT_UM = 20


@dataclass
class BeamSize:
x_um: float | None
y_um: float | None


def beam_size_from_aperture(position: SingleAperturePosition):
aperture_size = position.radius_microns
return BeamSize(aperture_size, I03_BEAM_HEIGHT_UM if aperture_size else None)
26 changes: 19 additions & 7 deletions src/dodal/devices/aperturescatterguard.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import asyncio
from collections import OrderedDict, namedtuple
from dataclasses import dataclass
from dataclasses import asdict, dataclass

from bluesky.protocols import Movable
from bluesky.protocols import Movable, Reading
from ophyd_async.core import AsyncStatus, SignalR, StandardReadable
from ophyd_async.core.soft_signal_backend import SoftSignalBackend
from ophyd_async.core.soft_signal_backend import SoftConverter, SoftSignalBackend

from dodal.devices.aperture import Aperture
from dodal.devices.scatterguard import Scatterguard
Expand Down Expand Up @@ -114,18 +114,30 @@ def __init__(self, prefix: str = "", name: str = "") -> None:
self.aperture = Aperture(prefix + "-MO-MAPT-01:")
self.scatterguard = Scatterguard(prefix + "-MO-SCAT-01:")
self.aperture_positions: AperturePositions | None = None
self.selected_aperture = self.SelectedAperture(
backend=SoftSignalBackend(
SingleAperturePosition, AperturePositions.UNKNOWN
),
self.TOLERANCE_STEPS = 3 # Number of MRES steps
aperture_backend = SoftSignalBackend(
SingleAperturePosition, AperturePositions.UNKNOWN
)
aperture_backend.converter = self.ApertureConverter()
self.selected_aperture = self.SelectedAperture(backend=aperture_backend)
self.set_readable_signals(
read=[
self.selected_aperture,
]
)
super().__init__(name)

class ApertureConverter(SoftConverter):
# Ophyd-async #311 should add a default converter for dataclasses to do this
def reading(
self, value: SingleAperturePosition, timestamp: float, severity: int
) -> Reading:
return Reading(
value=asdict(value),
timestamp=timestamp,
alarm_severity=-1 if severity > 2 else severity,
)

class SelectedAperture(SignalR):
async def read(self, *args, **kwargs):
assert isinstance(self.parent, ApertureScatterguard)
Expand Down
11 changes: 5 additions & 6 deletions tests/devices/unit_tests/test_aperture_scatterguard.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from dataclasses import asdict
from typing import Sequence
from unittest.mock import MagicMock, call

Expand Down Expand Up @@ -262,9 +263,8 @@ async def test_given_aperture_not_set_through_device_but_motors_in_position_when
):
selected_aperture = await aperture_in_medium_pos.read()
assert isinstance(selected_aperture, dict)
assert (
selected_aperture["test_ap_sg-selected_aperture"]["value"]
== aperture_positions.MEDIUM
assert selected_aperture["test_ap_sg-selected_aperture"]["value"] == asdict(
aperture_positions.MEDIUM
)


Expand All @@ -273,9 +273,8 @@ async def test_when_aperture_set_and_device_read_then_position_returned(
):
await aperture_in_medium_pos.set(aperture_positions.MEDIUM)
selected_aperture = await aperture_in_medium_pos.read()
assert (
selected_aperture["test_ap_sg-selected_aperture"]["value"]
== aperture_positions.MEDIUM
assert selected_aperture["test_ap_sg-selected_aperture"]["value"] == asdict(
aperture_positions.MEDIUM
)


Expand Down
30 changes: 30 additions & 0 deletions tests/devices/unit_tests/util/test_beamline_specific_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import pytest

from dodal.beamline_specific_utils.i03 import (
I03_BEAM_HEIGHT_UM,
beam_size_from_aperture,
)
from dodal.devices.aperturescatterguard import (
ApertureFiveDimensionalLocation,
SingleAperturePosition,
)

RADII_AND_SIZES = [
(None, (None, None)),
(123, (123, I03_BEAM_HEIGHT_UM)),
(23.45, (23.45, I03_BEAM_HEIGHT_UM)),
(888, (888, I03_BEAM_HEIGHT_UM)),
]


def get_single_ap(radius):
return SingleAperturePosition(
"", "", radius, ApertureFiveDimensionalLocation(0, 0, 0, 0, 0)
)


@pytest.mark.parametrize(["aperture_radius", "beam_size"], RADII_AND_SIZES)
def test_beam_size_from_aperture(aperture_radius, beam_size):
beamsize = beam_size_from_aperture(get_single_ap(aperture_radius))
assert beamsize.x_um == beam_size[0]
assert beamsize.y_um == beam_size[1]

0 comments on commit 729be13

Please sign in to comment.