Skip to content

Commit

Permalink
Fixes for ophyd async types mega merge (#858)
Browse files Browse the repository at this point in the history
* Remove get_processing_result()
* Remove composite results signal
* Changes to support extracting the results from the event
* Fix InvocationError due to usage of missing attribute centres_of_mass
* Misc enum fixes, remove timeout from expected call args
* Re-enable disabled test now that naming is fixed
* Fix panda instantiations
* Make private signals public
* Change PMAC string signals to Movable devices
* Fix enum type for fluorescence detector
* Fix AperturePositions enum
* Fix more panda uri/prefix changes, beamstop enum
* Fix PMAC to use new Reference wrapper
* Fix Thawer to use new Reference wrapper
* Fix OAV to redis forwarder signal types
* Allow I10 devices to accept float64 from bluesky scan() plan
* Revert panda uri changes back to prefix
* Misc I10 fixes for ophyd-async type changes
* Revert uri/prefix mangling in device_instantiation()
* Fix I10 unit tests by flattening devices
* Remove nonsensical fgs counter mock set
* Fix connection issue due to typing on xspress3
* Document the aperturescatterguard radius. Make the attenuator fields private again.
* Make mirror voltage attribs private again
* Remove unneeded lint ignore
* Make zebra shutter manual_position_setpoint private again
* Update comment with reference to the correct ophyd-async issue
* Remove superfluous calls to add_children_as_readables() in i10 devices where the children were all instances of Reference
* Fix typo in zebra_controlled_shutter pydoc. Pin ophyd-async to v0.8.0a2
* Fixes for OAV changes
* Fix OAV changes to work with ophyd-async typing changes
  • Loading branch information
rtuck99 authored Nov 5, 2024
1 parent 8640900 commit 2e58d4e
Show file tree
Hide file tree
Showing 62 changed files with 437 additions and 423 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ description = "Ophyd devices and other utils that could be used across DLS beaml
dependencies = [
"click",
"ophyd",
"ophyd-async>=0.7.0a1,<0.8",
"ophyd-async==0.8.0a2",
"bluesky",
"pyepics",
"dataclasses-json",
Expand Down
3 changes: 1 addition & 2 deletions src/dodal/common/beamlines/beamline_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ def device_instantiation(
fake: bool whether to fake with ophyd.sim
post_create: Callable (optional) a function to be run on the device after
creation
bl_prefix: bool if true, add the beamline prefix when instantiating, if
false the complete PV prefix must be supplied.
bl_prefix: bool if true, add the beamline prefix when instantiating
Returns:
The instance of the device.
"""
Expand Down
24 changes: 10 additions & 14 deletions src/dodal/common/signal_utils.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
from collections.abc import Callable, Coroutine
from typing import Any, TypeVar
from typing import Any

from bluesky.protocols import Reading
from ophyd_async.core import SignalR, SoftSignalBackend
from ophyd_async.core._soft_signal_backend import SignalMetadata
from ophyd_async.core import SignalDatatypeT, SignalR, SoftSignalBackend

T = TypeVar("T")


class HarwareBackedSoftSignalBackend(SoftSignalBackend[T]):
class HardwareBackedSoftSignalBackend(SoftSignalBackend[SignalDatatypeT]):
def __init__(
self,
get_from_hardware_func: Callable[[], Coroutine[Any, Any, T]],
get_from_hardware_func: Callable[[], Coroutine[Any, Any, SignalDatatypeT]],
*args,
**kwargs,
) -> None:
Expand All @@ -20,20 +17,20 @@ def __init__(

async def _update_value(self):
new_value = await self.get_from_hardware_func()
await self.put(new_value)
await self.put(new_value, True)

async def get_reading(self) -> Reading:
await self._update_value()
return await super().get_reading()

async def get_value(self) -> T:
async def get_value(self) -> SignalDatatypeT:
await self._update_value()
return await super().get_value()


def create_hardware_backed_soft_signal(
datatype: type[T],
get_from_hardware_func: Callable[[], Coroutine[Any, Any, T]],
datatype: type[SignalDatatypeT],
get_from_hardware_func: Callable[[], Coroutine[Any, Any, SignalDatatypeT]],
units: str | None = None,
precision: int | None = None,
):
Expand All @@ -45,9 +42,8 @@ def create_hardware_backed_soft_signal(
the signal is currently read only. See https://github.com/bluesky/ophyd-async/issues/525
for a more full solution.
"""
metadata = SignalMetadata(units=units, precision=precision)
return SignalR(
backend=HarwareBackedSoftSignalBackend(
get_from_hardware_func, datatype, metadata=metadata
backend=HardwareBackedSoftSignalBackend(
get_from_hardware_func, datatype, units=units, precision=precision
)
)
24 changes: 18 additions & 6 deletions src/dodal/devices/aperturescatterguard.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from __future__ import annotations

import asyncio
from enum import Enum

from bluesky.protocols import Movable
from ophyd_async.core import (
AsyncStatus,
HintedSignal,
StandardReadable,
StrictEnum,
)
from pydantic import BaseModel, Field

Expand All @@ -22,12 +22,24 @@ class InvalidApertureMove(Exception):


class AperturePosition(BaseModel):
"""
Represents one of the available positions for the Aperture-Scatterguard.
Attributes:
aperture_x: The x position of the aperture component in mm
aperture_y: The y position of the aperture component in mm
aperture_z: The z position of the aperture component in mm
scatterguard_x: The x position of the scatterguard component in mm
scatterguard_y: The y position of the scatterguard component in mm
radius: Radius of the selected aperture. When in the Robot Load position, the
radius is defined to be 0
"""

aperture_x: float
aperture_y: float
aperture_z: float
scatterguard_x: float
scatterguard_y: float
radius: float | None = Field(json_schema_extra={"units": "µm"}, default=None)
radius: float = Field(json_schema_extra={"units": "µm"}, default=0.0)

@property
def values(self) -> tuple[float, float, float, float, float]:
Expand All @@ -54,7 +66,7 @@ def tolerances_from_gda_params(
@staticmethod
def from_gda_params(
name: ApertureValue,
radius: float | None,
radius: float,
params: GDABeamlineParameters,
) -> AperturePosition:
return AperturePosition(
Expand All @@ -67,7 +79,7 @@ def from_gda_params(
)


class ApertureValue(str, Enum):
class ApertureValue(StrictEnum):
"""Maps from a short usable name to the value name in the GDA Beamline parameters"""

ROBOT_LOAD = "ROBOT_LOAD"
Expand All @@ -81,7 +93,7 @@ def load_positions_from_beamline_parameters(
) -> dict[ApertureValue, AperturePosition]:
return {
ApertureValue.ROBOT_LOAD: AperturePosition.from_gda_params(
ApertureValue.ROBOT_LOAD, None, params
ApertureValue.ROBOT_LOAD, 0, params
),
ApertureValue.SMALL: AperturePosition.from_gda_params(
ApertureValue.SMALL, 20, params
Expand Down Expand Up @@ -172,7 +184,7 @@ async def _get_current_aperture_position(self) -> ApertureValue:

raise InvalidApertureMove("Current aperture/scatterguard state unrecognised")

async def _get_current_radius(self) -> float | None:
async def _get_current_radius(self) -> float:
current_value = await self._get_current_aperture_position()
return self._loaded_positions[current_value].radius

Expand Down
4 changes: 2 additions & 2 deletions src/dodal/devices/apple2_undulator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import abc
import asyncio
from dataclasses import dataclass
from enum import Enum
from typing import Any

import numpy as np
Expand All @@ -11,6 +10,7 @@
ConfigSignal,
HintedSignal,
StandardReadable,
StrictEnum,
soft_signal_r_and_setter,
wait_for_value,
)
Expand All @@ -20,7 +20,7 @@
from dodal.log import LOGGER


class UndulatorGateStatus(str, Enum):
class UndulatorGateStatus(StrictEnum):
open = "Open"
close = "Closed"

Expand Down
6 changes: 2 additions & 4 deletions src/dodal/devices/areadetector/plugins/CAM.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
from enum import Enum

from ophyd_async.core import StandardReadable
from ophyd_async.core import StandardReadable, StrictEnum
from ophyd_async.epics.signal import epics_signal_r, epics_signal_rw


class ColorMode(str, Enum):
class ColorMode(StrictEnum):
"""
Enum to store the various color modes of the camera. We use RGB1.
"""
Expand Down
7 changes: 3 additions & 4 deletions src/dodal/devices/backlight.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
from asyncio import sleep
from enum import Enum

from bluesky.protocols import Movable
from ophyd_async.core import AsyncStatus, StandardReadable
from ophyd_async.core import AsyncStatus, StandardReadable, StrictEnum
from ophyd_async.epics.signal import epics_signal_rw


class BacklightPower(str, Enum):
class BacklightPower(StrictEnum):
ON = "On"
OFF = "Off"


class BacklightPosition(str, Enum):
class BacklightPosition(StrictEnum):
IN = "In"
OUT = "Out"

Expand Down
6 changes: 2 additions & 4 deletions src/dodal/devices/cryostream.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
from enum import Enum

from ophyd_async.core import StandardReadable
from ophyd_async.core import StandardReadable, StrictEnum
from ophyd_async.epics.signal import epics_signal_r, epics_signal_rw


class InOut(str, Enum):
class InOut(StrictEnum):
IN = "In"
OUT = "Out"

Expand Down
6 changes: 2 additions & 4 deletions src/dodal/devices/detector/detector_motion.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from enum import Enum

from ophyd_async.core import Device
from ophyd_async.core import Device, StrictEnum
from ophyd_async.epics.motor import Motor
from ophyd_async.epics.signal import epics_signal_r, epics_signal_rw


class ShutterState(str, Enum):
class ShutterState(StrictEnum):
CLOSED = "Closed"
OPEN = "Open"

Expand Down
5 changes: 2 additions & 3 deletions src/dodal/devices/diamond_filter.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from enum import Enum
from typing import Generic, TypeVar

from ophyd_async.core import StandardReadable
from ophyd_async.core import StandardReadable, StrictEnum
from ophyd_async.epics.motor import Motor
from ophyd_async.epics.signal import epics_signal_rw


class _Filters(str, Enum):
class _Filters(StrictEnum):
pass


Expand Down
10 changes: 4 additions & 6 deletions src/dodal/devices/fluorescence_detector_motion.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
from enum import Enum

from ophyd_async.core import StandardReadable
from ophyd_async.core import StandardReadable, StrictEnum
from ophyd_async.epics.signal import epics_signal_r


class FluorescenceDetectorControlState(Enum):
OUT = 0
IN = 1
class FluorescenceDetectorControlState(StrictEnum):
OUT = "Out"
IN = "In"


class FluorescenceDetector(StandardReadable):
Expand Down
9 changes: 4 additions & 5 deletions src/dodal/devices/focusing_mirror.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from enum import Enum

from ophyd_async.core import (
AsyncStatus,
ConfigSignal,
Device,
DeviceVector,
HintedSignal,
StandardReadable,
StrictEnum,
observe_value,
soft_signal_r_and_setter,
)
Expand All @@ -25,20 +24,20 @@
DEFAULT_SETTLE_TIME_S = 60


class MirrorType(str, Enum):
class MirrorType(StrictEnum):
"""See https://manual.nexusformat.org/classes/base_classes/NXmirror.html"""

SINGLE = "single"
MULTI = "multi"


class MirrorStripe(str, Enum):
class MirrorStripe(StrictEnum):
RHODIUM = "Rhodium"
BARE = "Bare"
PLATINUM = "Platinum"


class MirrorVoltageDemand(str, Enum):
class MirrorVoltageDemand(StrictEnum):
N_A = "N/A"
OK = "OK"
FAIL = "FAIL"
Expand Down
7 changes: 3 additions & 4 deletions src/dodal/devices/hutch_shutter.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from enum import Enum

from bluesky.protocols import Movable
from ophyd_async.core import (
DEFAULT_TIMEOUT,
AsyncStatus,
StandardReadable,
StrictEnum,
wait_for_value,
)
from ophyd_async.epics.signal import epics_signal_r, epics_signal_w
Expand All @@ -16,13 +15,13 @@ class ShutterNotSafeToOperateError(Exception):
pass


class ShutterDemand(str, Enum):
class ShutterDemand(StrictEnum):
OPEN = "Open"
CLOSE = "Close"
RESET = "Reset"


class ShutterState(str, Enum):
class ShutterState(StrictEnum):
FAULT = "Fault"
OPEN = "Open"
OPENING = "Opening"
Expand Down
Loading

0 comments on commit 2e58d4e

Please sign in to comment.