Skip to content
Open
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
06b0c49
create i05-shared and move pgm there
Jul 30, 2025
db2bf55
change names to snake case
Jul 30, 2025
7a22f71
minor import change
Jul 30, 2025
49c2eb5
create base mirror
Jul 30, 2025
81166cb
add m1 mirror
Jul 30, 2025
a6bb6f1
add XY and XYZ collimating mirrrors
Jul 31, 2025
6e7a533
fix i10
Jul 31, 2025
ed3592b
add piezo mirror
Jul 31, 2025
1c292b6
add more mirrors
Jul 31, 2025
56e074b
move i05-shared to beamline specific utils
Jul 31, 2025
ba7f819
amend beamlines init file
Jul 31, 2025
b89e69a
move i05-shared to beamline specific utils
Jul 31, 2025
0c889cb
amend beamlines init file
Jul 31, 2025
d7a226e
Merge branch 'create-i05-shared-beamline-module' into common-mirror
Villtord Jul 31, 2025
6b57679
remove XY coll mirror - will be a separate issue
Jul 31, 2025
2cfcce8
Merge remote-tracking branch 'origin/main' into common-mirror
Aug 1, 2025
ca52f00
rename mirror class
Aug 1, 2025
fdce221
move xyzpitchyawroll to motors
Aug 1, 2025
ccf8b5a
rename pgm
Aug 1, 2025
2a97a79
add explicit parameters to child classes
Aug 1, 2025
2d0bd84
Merge branch 'main' into common-mirror
Villtord Aug 1, 2025
80422f0
make common mirror classes generic of strictenum
Aug 4, 2025
0cc78a0
Merge branch 'main' into common-mirror
Villtord Aug 4, 2025
5dc0c0d
Merge branch 'main' into common-mirror
Villtord Aug 5, 2025
c6046b7
add mirrors controls and docstring
Aug 5, 2025
64eff2b
Merge branch 'main' into common-mirror
Villtord Aug 6, 2025
e322968
Merge branch 'main' into common-mirror
Villtord Aug 18, 2025
0710b47
make all new classes depend on Stage only
Aug 19, 2025
7642ffa
Merge branch 'main' into common-mirror
Villtord Aug 19, 2025
559937b
Merge branch 'main' into common-mirror
Villtord Sep 5, 2025
b979135
Merge branch 'main' into common-mirror
Villtord Sep 10, 2025
9fdfcfd
relocate common_mirror to I05 devices
Sep 10, 2025
08322a2
Merge branch 'main' into common-mirror
Villtord Sep 11, 2025
a0cfb59
add comment on mirrors connection
Sep 11, 2025
74045b9
make mirrors locatable and stoppable, fix typos
Sep 19, 2025
c6be37c
Merge branch 'main' into common-mirror
Villtord Sep 19, 2025
67e180e
Merge branch 'main' into common-mirror
Villtord Dec 1, 2025
8d00f21
fix merge
Dec 1, 2025
b752967
fix merge
Dec 1, 2025
5388298
fix test
Dec 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion src/dodal/beamline_specific_utils/i05_shared.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,41 @@
from ophyd_async.core import StrictEnum

from dodal.common.beamlines.beamline_utils import device_factory
from dodal.devices.i05.enums import Grating
from dodal.devices.i05.common_mirror import XYZPiezoSwitchingMirror
from dodal.devices.motors import XYZPitchYawRollStage
from dodal.devices.pgm import PGM
from dodal.utils import BeamlinePrefix

PREFIX = BeamlinePrefix("i05", "I")


class M3MJ6Mirror(StrictEnum):
UNKNOWN = "Unknown"
MJ6 = "MJ6"
M3 = "M3"
REFERENCE = "Reference"


class Grating(StrictEnum):
PT_400 = "400 lines/mm"
C_1600 = "C 1600 lines/mm"
RH_1600 = "Rh 1600 lines/mm"
PT_800 = "B 800 lines/mm"


@device_factory()
def pgm() -> PGM:
return PGM(prefix=f"{PREFIX.beamline_prefix}-OP-PGM-01:", grating=Grating)


@device_factory()
def m1_collimating_mirror() -> XYZPitchYawRollStage:
return XYZPitchYawRollStage(prefix=f"{PREFIX.beamline_prefix}-OP-COL-01:")


@device_factory()
def m3mj6_switching_mirror() -> XYZPiezoSwitchingMirror:
return XYZPiezoSwitchingMirror(
prefix=f"{PREFIX.beamline_prefix}-OP-SWTCH-01:",
mirrors=M3MJ6Mirror,
)
47 changes: 44 additions & 3 deletions src/dodal/beamlines/i05.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
from dodal.beamline_specific_utils.i05_shared import pgm as i05_pgm
from ophyd_async.core import StrictEnum

from dodal.beamline_specific_utils.i05_shared import (
m1_collimating_mirror,
m3mj6_switching_mirror,
pgm,
)
from dodal.common.beamlines.beamline_utils import device_factory
from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline
from dodal.devices.i05.common_mirror import XYZPiezoSwitchingMirror, XYZSwitchingMirror
from dodal.devices.motors import XYZPitchYawRollStage
from dodal.devices.pgm import PGM
from dodal.devices.synchrotron import Synchrotron
from dodal.log import set_beamline as set_log_beamline
Expand All @@ -17,6 +25,39 @@ def synchrotron() -> Synchrotron:
return Synchrotron()


# BL05 shared devices


@device_factory()
def pgm_i05() -> PGM:
return pgm()


@device_factory()
def m1() -> XYZPitchYawRollStage:
return m1_collimating_mirror()


# will connect after https://jira.diamond.ac.uk/browse/I05-731
@device_factory()
def m3mj6() -> XYZPiezoSwitchingMirror:
return m3mj6_switching_mirror()


# beamline specific devices


# will connect after https://jira.diamond.ac.uk/browse/I05-731
class M4M5Mirror(StrictEnum):
UNKNOWN = "Unknown"
MJ6 = "M4"
M3 = "M5"
REFERENCE = "Reference"


@device_factory()
def pgm() -> PGM:
return i05_pgm()
def m4m5() -> XYZSwitchingMirror:
return XYZSwitchingMirror(
prefix=f"{PREFIX.beamline_prefix}-OP-RFM-01:",
mirrors=M4M5Mirror,
)
51 changes: 46 additions & 5 deletions src/dodal/beamlines/i05_1.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
from dodal.beamline_specific_utils.i05_shared import pgm as i05_pgm
from ophyd_async.core import StrictEnum

from dodal.beamline_specific_utils.i05_shared import (
m1_collimating_mirror,
m3mj6_switching_mirror,
pgm,
)
from dodal.common.beamlines.beamline_utils import device_factory
from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline
from dodal.devices.i05.common_mirror import XYZPiezoSwitchingMirror
from dodal.devices.motors import XYZPitchYawRollStage
from dodal.devices.pgm import PGM
from dodal.devices.synchrotron import Synchrotron
from dodal.log import set_beamline as set_log_beamline
Expand All @@ -13,10 +21,43 @@


@device_factory()
def pgm() -> PGM:
return i05_pgm()
def synchrotron() -> Synchrotron:
return Synchrotron()


# BL05 shared devices


@device_factory()
def pgm_i05() -> PGM:
return pgm()


@device_factory()
def synchrotron() -> Synchrotron:
return Synchrotron()
def m1() -> XYZPitchYawRollStage:
return m1_collimating_mirror()


@device_factory()
def m3mj6() -> XYZPiezoSwitchingMirror:
return m3mj6_switching_mirror()


# beamline specific devices


# will connect after https://jira.diamond.ac.uk/browse/I05-731
class Mj7j8Mirror(StrictEnum):
UNKNOWN = "Unknown"
MJ6 = "MJ8"
M3 = "MJ7"
REFERENCE = "Reference"


# will connect after https://jira.diamond.ac.uk/browse/I05-731
@device_factory()
def mj7j8() -> XYZPiezoSwitchingMirror:
return XYZPiezoSwitchingMirror(
prefix=f"{PREFIX.beamline_prefix}-OP-RFM-01:",
mirrors=Mj7j8Mirror,
)
8 changes: 6 additions & 2 deletions src/dodal/devices/i05/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
from dodal.devices.i05.enums import Grating
from dodal.devices.i05.common_mirror import (
XYZPiezoCollimatingMirror,
XYZPiezoSwitchingMirror,
XYZSwitchingMirror,
)

__all__ = ["Grating"]
__all__ = ["XYZSwitchingMirror", "XYZPiezoCollimatingMirror", "XYZPiezoSwitchingMirror"]
120 changes: 120 additions & 0 deletions src/dodal/devices/i05/common_mirror.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
from typing import Generic, TypeVar

from ophyd_async.core import StrictEnum
from ophyd_async.epics.core import epics_signal_rw, epics_signal_x

from dodal.devices.motors import _X, _Y, _Z, XYZPitchYawRollStage

TMirror = TypeVar("TMirror", bound=StrictEnum)


class XYZSwitchingMirror(XYZPitchYawRollStage, Generic[TMirror]):
"""
Set of mirrors on a hexapod with x,y,z and yaw, pitch, roll motors.
To change mirror one need to set mirror enum and trigger mirror change.
"""

def __init__(
self,
prefix: str,
mirrors: type[TMirror],
name: str = "",
x_infix: str = _X,
y_infix: str = _Y,
z_infix: str = _Z,
pitch_infix: str = "PITCH",
yaw_infix: str = "YAW",
roll_infix: str = "ROLL",
mirror_read_suffix: str = "MIRCTRL:RBV:MIRROR",
mirror_write_suffix: str = "MIRCTRL:DMD:MIRROR",
mirror_change_suffix: str = "MIRCTRL:SEQ:CHNG:MIRROR.PROC",
mirror_abort_suffix: str = "MIRCTRL:DMD:ABORT.PROC",
):
with self.add_children_as_readables():
self.mirror = epics_signal_rw(
mirrors,
read_pv=prefix + mirror_read_suffix,
write_pv=prefix + mirror_write_suffix,
)

self.mirror_change = epics_signal_x(write_pv=prefix + mirror_change_suffix)
self.mirror_abort = epics_signal_x(write_pv=prefix + mirror_abort_suffix)

super().__init__(
prefix, name, x_infix, y_infix, z_infix, pitch_infix, yaw_infix, roll_infix
)


class XYZPiezoCollimatingMirror(XYZPitchYawRollStage):
"""
Collimating mirror on a hexapod with x,y,z and yaw, pitch, roll motors.
In addition there is a fine pitch piezo motor.
"""

def __init__(
self,
prefix: str,
name: str = "",
x_infix: str = _X,
y_infix: str = _Y,
z_infix: str = _Z,
pitch_infix: str = "PITCH",
yaw_infix: str = "YAW",
roll_infix: str = "ROLL",
fpitch_read_suffix: str = "FPITCH:RBV",
fpitch_write_suffix: str = "FPITCH:DMD",
):
with self.add_children_as_readables():
self.fine_pitch = epics_signal_rw(
float,
read_pv=prefix + fpitch_read_suffix,
write_pv=prefix + fpitch_write_suffix,
)
super().__init__(
prefix, name, x_infix, y_infix, z_infix, pitch_infix, yaw_infix, roll_infix
)


class XYZPiezoSwitchingMirror(XYZPitchYawRollStage, Generic[TMirror]):
"""
Set of mirrors on a hexapod with x,y,z and yaw, pitch, roll motors.
To change mirror one need to set mirror enum and trigger mirror change.
In addition there is a fine pitch piezo motor.
"""

def __init__(
self,
prefix: str,
mirrors: type[TMirror],
name: str = "",
x_infix: str = _X,
y_infix: str = _Y,
z_infix: str = _Z,
pitch_infix: str = "PITCH",
yaw_infix: str = "YAW",
roll_infix: str = "ROLL",
fpitch_read_suffix: str = "FPITCH:RBV",
fpitch_write_suffix: str = "FPITCH:DMD",
mirror_read_suffix: str = "MIRCTRL:RBV:MIRROR",
mirror_write_suffix: str = "MIRCTRL:DMD:MIRROR",
mirror_change_suffix: str = "MIRCTRL:SEQ:CHNG:MIRROR.PROC",
mirror_abort_suffix: str = "MIRCTRL:DMD:ABORT.PROC",
):
with self.add_children_as_readables():
self.fine_pitch = epics_signal_rw(
float,
read_pv=prefix + fpitch_read_suffix,
write_pv=prefix + fpitch_write_suffix,
)
self.mirror = epics_signal_rw(
mirrors,
read_pv=prefix + mirror_read_suffix,
write_pv=prefix + mirror_write_suffix,
)

self.mirror_change = epics_signal_x(write_pv=prefix + mirror_change_suffix)
self.mirror_abort = epics_signal_x(write_pv=prefix + mirror_abort_suffix)

super().__init__(
prefix, name, x_infix, y_infix, z_infix, pitch_infix, yaw_infix, roll_infix
)
8 changes: 0 additions & 8 deletions src/dodal/devices/i05/enums.py

This file was deleted.

Loading