diff --git a/src/dodal/beamlines/b07.py b/src/dodal/beamlines/b07.py index 3f712cdd500..e2b047c2fa4 100644 --- a/src/dodal/beamlines/b07.py +++ b/src/dodal/beamlines/b07.py @@ -2,13 +2,11 @@ from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline from dodal.device_manager import DeviceManager from dodal.devices.beamlines.b07 import ( + B07BSpecs150, B07SampleManipulator52B, Grating, - LensMode, ) -from dodal.devices.beamlines.b07_shared import PsuMode from dodal.devices.electron_analyser.base import EnergySource -from dodal.devices.electron_analyser.specs import SpecsDetector from dodal.devices.motors import XYZPolarStage from dodal.devices.pgm import PlaneGratingMonochromator from dodal.log import set_beamline as set_log_beamline @@ -39,13 +37,8 @@ def energy_source(pgm: PlaneGratingMonochromator) -> EnergySource: # CAM:IMAGE will fail to connect outside the beamline network, # see https://github.com/DiamondLightSource/dodal/issues/1852 @devices.factory() -def analyser(energy_source: EnergySource) -> SpecsDetector[LensMode, PsuMode]: - return SpecsDetector[LensMode, PsuMode]( - prefix=f"{B_PREFIX.beamline_prefix}-EA-DET-01:CAM:", - lens_mode_type=LensMode, - psu_mode_type=PsuMode, - energy_source=energy_source, - ) +def analyser(energy_source: EnergySource) -> B07BSpecs150: + return B07BSpecs150(f"{B_PREFIX.beamline_prefix}-EA-DET-01:CAM:", energy_source) @devices.factory() diff --git a/src/dodal/beamlines/b07_1.py b/src/dodal/beamlines/b07_1.py index a80bb89afde..a5c76ae93e3 100644 --- a/src/dodal/beamlines/b07_1.py +++ b/src/dodal/beamlines/b07_1.py @@ -2,13 +2,11 @@ from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline from dodal.device_manager import DeviceManager from dodal.devices.beamlines.b07_1 import ( + B07CSpecs150, ChannelCutMonochromator, Grating, - LensMode, ) -from dodal.devices.beamlines.b07_shared import PsuMode from dodal.devices.electron_analyser.base import EnergySource -from dodal.devices.electron_analyser.specs import SpecsDetector from dodal.devices.motors import XYZPolarAzimuthStage from dodal.devices.pgm import PlaneGratingMonochromator from dodal.log import set_beamline as set_log_beamline @@ -44,11 +42,9 @@ def energy_source(pgm: PlaneGratingMonochromator) -> EnergySource: # CAM:IMAGE will fail to connect outside the beamline network, # see https://github.com/DiamondLightSource/dodal/issues/1852 @devices.factory() -def analyser(energy_source: EnergySource) -> SpecsDetector[LensMode, PsuMode]: - return SpecsDetector[LensMode, PsuMode]( +def analyser(energy_source: EnergySource) -> B07CSpecs150: + return B07CSpecs150( prefix=f"{C_PREFIX.beamline_prefix}-EA-DET-01:CAM:", - lens_mode_type=LensMode, - psu_mode_type=PsuMode, energy_source=energy_source, ) diff --git a/src/dodal/beamlines/i09.py b/src/dodal/beamlines/i09.py index 253c5e62c28..792317ede93 100644 --- a/src/dodal/beamlines/i09.py +++ b/src/dodal/beamlines/i09.py @@ -4,10 +4,9 @@ from dodal.beamlines.i09_2_shared import devices as i09_2_shared_devices from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline from dodal.device_manager import DeviceManager -from dodal.devices.beamlines.i09.enums import LensMode, PassEnergy, PsuMode +from dodal.devices.beamlines.i09 import I09VGScientaEW4000 from dodal.devices.common_dcm import DoubleCrystalMonochromatorWithDSpacing from dodal.devices.electron_analyser.base import DualEnergySource -from dodal.devices.electron_analyser.vgscienta import VGScientaDetector from dodal.devices.fast_shutter import DualFastShutter, GenericFastShutter from dodal.devices.motors import XYZPolarAzimuthStage from dodal.devices.pgm import PlaneGratingMonochromator @@ -80,18 +79,15 @@ def dual_fast_shutter( # see https://github.com/DiamondLightSource/dodal/issues/1852 @devices.factory() def ew4000( - dual_fast_shutter: DualFastShutter, dual_energy_source: DualEnergySource, + dual_fast_shutter: DualFastShutter, source_selector: SourceSelector, -) -> VGScientaDetector[LensMode, PsuMode, PassEnergy]: - return VGScientaDetector[LensMode, PsuMode, PassEnergy]( - prefix=f"{I_PREFIX.beamline_prefix}-EA-DET-01:CAM:", - lens_mode_type=LensMode, - psu_mode_type=PsuMode, - pass_energy_type=PassEnergy, - energy_source=dual_energy_source, - shutter=dual_fast_shutter, - source_selector=source_selector, +) -> I09VGScientaEW4000: + return I09VGScientaEW4000( + f"{I_PREFIX.beamline_prefix}-EA-DET-01:CAM:", + dual_energy_source, + dual_fast_shutter, + source_selector, ) diff --git a/src/dodal/beamlines/i09_1.py b/src/dodal/beamlines/i09_1.py index 769909f5eee..d42cc7fddde 100644 --- a/src/dodal/beamlines/i09_1.py +++ b/src/dodal/beamlines/i09_1.py @@ -1,10 +1,9 @@ from dodal.beamlines.i09_1_shared import devices as i09_1_shared_devices from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline from dodal.device_manager import DeviceManager -from dodal.devices.beamlines.i09_1 import LensMode, PsuMode +from dodal.devices.beamlines.i09_1 import I091SpecsPhoibos225 from dodal.devices.common_dcm import DoubleCrystalMonochromatorWithDSpacing from dodal.devices.electron_analyser.base import EnergySource -from dodal.devices.electron_analyser.specs import SpecsDetector from dodal.devices.motors import XYZPolarAzimuthTiltStage from dodal.devices.synchrotron import Synchrotron from dodal.devices.temperture_controller import Lakeshore336 @@ -33,12 +32,9 @@ def energy_source(dcm: DoubleCrystalMonochromatorWithDSpacing) -> EnergySource: # CAM:IMAGE will fail to connect outside the beamline network, # see https://github.com/DiamondLightSource/dodal/issues/1852 @devices.factory() -def analyser(energy_source: EnergySource) -> SpecsDetector[LensMode, PsuMode]: - return SpecsDetector[LensMode, PsuMode]( - prefix=f"{PREFIX.beamline_prefix}-EA-DET-02:CAM:", - lens_mode_type=LensMode, - psu_mode_type=PsuMode, - energy_source=energy_source, +def analyser(energy_source: EnergySource) -> I091SpecsPhoibos225: + return I091SpecsPhoibos225( + f"{PREFIX.beamline_prefix}-EA-DET-02:CAM:", energy_source ) diff --git a/src/dodal/beamlines/p60.py b/src/dodal/beamlines/p60.py index d0a35b881f9..76b0318bb73 100644 --- a/src/dodal/beamlines/p60.py +++ b/src/dodal/beamlines/p60.py @@ -3,12 +3,9 @@ from dodal.devices.beamlines.p60 import ( LabXraySource, LabXraySourceReadable, - LensMode, - PassEnergy, - PsuMode, + P60VGScientaR4000, ) from dodal.devices.electron_analyser.base import DualEnergySource -from dodal.devices.electron_analyser.vgscienta import VGScientaDetector from dodal.devices.selectable_source import SourceSelector from dodal.log import set_beamline as set_log_beamline from dodal.utils import BeamlinePrefix, get_beamline_name @@ -18,13 +15,13 @@ be on the beamline network to access them so a remote `dodal connect p60` will fail. """ -devices = DeviceManager() - BL = get_beamline_name("p60") PREFIX = BeamlinePrefix(BL) set_log_beamline(BL) set_utils_beamline(BL) +devices = DeviceManager() + @devices.factory() def source_selector() -> SourceSelector: @@ -42,7 +39,7 @@ def mg_kalpha_source() -> LabXraySourceReadable: @devices.factory() -def energy_source( +def dual_energy_source( al_kalpha_source: LabXraySourceReadable, mg_kalpha_source: LabXraySourceReadable, source_selector: SourceSelector, @@ -57,13 +54,7 @@ def energy_source( # Connect will work again after this work completed # https://jira.diamond.ac.uk/browse/P60-13 @devices.factory() -def r4000( - energy_source: DualEnergySource, -) -> VGScientaDetector[LensMode, PsuMode, PassEnergy]: - return VGScientaDetector[LensMode, PsuMode, PassEnergy]( - prefix=f"{PREFIX.beamline_prefix}-EA-DET-01:CAM:", - lens_mode_type=LensMode, - psu_mode_type=PsuMode, - pass_energy_type=PassEnergy, - energy_source=energy_source, +def r4000(dual_energy_source: DualEnergySource) -> P60VGScientaR4000: + return P60VGScientaR4000( + f"{PREFIX.beamline_prefix}-EA-DET-01:CAM:", dual_energy_source ) diff --git a/src/dodal/devices/beamlines/b07/__init__.py b/src/dodal/devices/beamlines/b07/__init__.py index d1583c2a25e..3f4f53514cb 100644 --- a/src/dodal/devices/beamlines/b07/__init__.py +++ b/src/dodal/devices/beamlines/b07/__init__.py @@ -1,4 +1,20 @@ +from .analyser import ( + B07BElectronAnalyserController, + B07BSpecs150, + B07BSpecsAnalyserDriverIO, + B07BSpecsRegion, + B07BSpecsSequence, +) from .b07_motors import B07SampleManipulator52B from .enums import Grating, LensMode -__all__ = ["B07SampleManipulator52B", "Grating", "LensMode"] +__all__ = [ + "B07BElectronAnalyserController", + "B07BSpecsAnalyserDriverIO", + "B07BSpecsRegion", + "B07BSpecsSequence", + "B07BSpecs150", + "B07SampleManipulator52B", + "Grating", + "LensMode", +] diff --git a/src/dodal/devices/beamlines/b07/analyser.py b/src/dodal/devices/beamlines/b07/analyser.py new file mode 100644 index 00000000000..93dbc5457f3 --- /dev/null +++ b/src/dodal/devices/beamlines/b07/analyser.py @@ -0,0 +1,42 @@ +from dodal.devices.beamlines.b07.enums import LensMode +from dodal.devices.beamlines.b07_shared.enums import PsuMode +from dodal.devices.electron_analyser.base.base_controller import ( + ElectronAnalyserController, +) +from dodal.devices.electron_analyser.base.base_detector import ElectronAnalyserDetector +from dodal.devices.electron_analyser.base.energy_sources import EnergySource +from dodal.devices.electron_analyser.specs import ( + SpecsAnalyserDriverIO, + SpecsRegion, + SpecsSequence, +) +from dodal.devices.fast_shutter import FastShutter + +B07BSpecsRegion = SpecsRegion[LensMode, PsuMode] +B07BSpecsSequence = SpecsSequence[LensMode, PsuMode] + + +class B07BSpecsAnalyserDriverIO(SpecsAnalyserDriverIO): + def __init__(self, prefix: str, name: str = ""): + super().__init__(prefix, LensMode, PsuMode, name) + + +B07BElectronAnalyserController = ElectronAnalyserController[ + B07BSpecsAnalyserDriverIO, B07BSpecsRegion +] + + +class B07BSpecs150( + ElectronAnalyserDetector[B07BSpecsAnalyserDriverIO, B07BSpecsRegion] +): + def __init__( + self, + prefix: str, + energy_source: EnergySource, + shutter: FastShutter | None = None, + name: str = "", + ): + controller = B07BElectronAnalyserController( + B07BSpecsAnalyserDriverIO(prefix), energy_source, shutter + ) + super().__init__(controller, name) diff --git a/src/dodal/devices/beamlines/b07_1/__init__.py b/src/dodal/devices/beamlines/b07_1/__init__.py index 9ac266043a0..72fac821b2a 100644 --- a/src/dodal/devices/beamlines/b07_1/__init__.py +++ b/src/dodal/devices/beamlines/b07_1/__init__.py @@ -1,10 +1,22 @@ -from dodal.devices.beamlines.b07_1.ccmc import ( +from .analyser import ( + B07CElectronAnalyserController, + B07CSpecs150, + B07CSpecsAnalyserDriverIO, + B07CSpecsRegion, + B07CSpecsSequence, +) +from .ccmc import ( ChannelCutMonochromator, ChannelCutMonochromatorPositions, ) -from dodal.devices.beamlines.b07_1.enums import Grating, LensMode +from .enums import Grating, LensMode __all__ = [ + "B07CElectronAnalyserController", + "B07CSpecsAnalyserDriverIO", + "B07CSpecsRegion", + "B07CSpecsSequence", + "B07CSpecs150", "Grating", "LensMode", "ChannelCutMonochromator", diff --git a/src/dodal/devices/beamlines/b07_1/analyser.py b/src/dodal/devices/beamlines/b07_1/analyser.py new file mode 100644 index 00000000000..bf36c0b9e8d --- /dev/null +++ b/src/dodal/devices/beamlines/b07_1/analyser.py @@ -0,0 +1,42 @@ +from dodal.devices.beamlines.b07_1.enums import LensMode +from dodal.devices.beamlines.b07_shared.enums import PsuMode +from dodal.devices.electron_analyser.base.base_controller import ( + ElectronAnalyserController, +) +from dodal.devices.electron_analyser.base.base_detector import ElectronAnalyserDetector +from dodal.devices.electron_analyser.base.energy_sources import EnergySource +from dodal.devices.electron_analyser.specs import ( + SpecsAnalyserDriverIO, + SpecsRegion, + SpecsSequence, +) +from dodal.devices.fast_shutter import FastShutter + +B07CSpecsRegion = SpecsRegion[LensMode, PsuMode] +B07CSpecsSequence = SpecsSequence[LensMode, PsuMode] + + +class B07CSpecsAnalyserDriverIO(SpecsAnalyserDriverIO): + def __init__(self, prefix: str, name: str = ""): + super().__init__(prefix, LensMode, PsuMode, name) + + +B07CElectronAnalyserController = ElectronAnalyserController[ + B07CSpecsAnalyserDriverIO, B07CSpecsRegion +] + + +class B07CSpecs150( + ElectronAnalyserDetector[B07CSpecsAnalyserDriverIO, B07CSpecsRegion] +): + def __init__( + self, + prefix: str, + energy_source: EnergySource, + shutter: FastShutter | None = None, + name: str = "", + ): + controller = B07CElectronAnalyserController( + B07CSpecsAnalyserDriverIO(prefix), energy_source, shutter + ) + super().__init__(controller, name) diff --git a/src/dodal/devices/beamlines/i09/__init__.py b/src/dodal/devices/beamlines/i09/__init__.py index cfb2a43d07d..458ffdd0790 100644 --- a/src/dodal/devices/beamlines/i09/__init__.py +++ b/src/dodal/devices/beamlines/i09/__init__.py @@ -1,3 +1,20 @@ -from dodal.devices.beamlines.i09.enums import Grating, LensMode, PassEnergy, PsuMode +from .analyser import ( + I09ElectronAnalyserController, + I09VGScientaAnalyserDriverIO, + I09VGScientaEW4000, + I09VGScientaRegion, + I09VGScientaSequence, +) +from .enums import Grating, LensMode, PassEnergy, PsuMode -__all__ = ["Grating", "LensMode", "PsuMode", "PassEnergy"] +__all__ = [ + "I09ElectronAnalyserController", + "I09VGScientaAnalyserDriverIO", + "I09VGScientaEW4000", + "I09VGScientaRegion", + "I09VGScientaSequence", + "Grating", + "LensMode", + "PsuMode", + "PassEnergy", +] diff --git a/src/dodal/devices/beamlines/i09/analyser.py b/src/dodal/devices/beamlines/i09/analyser.py new file mode 100644 index 00000000000..748933c24d2 --- /dev/null +++ b/src/dodal/devices/beamlines/i09/analyser.py @@ -0,0 +1,60 @@ +from dodal.devices.beamlines.i09.enums import LensMode, PassEnergy, PsuMode +from dodal.devices.electron_analyser.base import DualEnergySource +from dodal.devices.electron_analyser.base.base_controller import ( + ElectronAnalyserController, +) +from dodal.devices.electron_analyser.base.base_detector import ElectronAnalyserDetector +from dodal.devices.electron_analyser.vgscienta import ( + VGScientaAnalyserDriverIO, + VGScientaRegion, + VGScientaSequence, +) +from dodal.devices.electron_analyser.vgscienta.vgscienta_driver_io import ( + VGScientaAnalyserDriverIO, +) +from dodal.devices.electron_analyser.vgscienta.vgscienta_region import ( + VGScientaRegion, + VGScientaSequence, +) +from dodal.devices.fast_shutter import DualFastShutter +from dodal.devices.selectable_source import SourceSelector + +I09VGScientaRegion = VGScientaRegion[LensMode, PassEnergy] +I09VGScientaSequence = VGScientaSequence[LensMode, PsuMode, PassEnergy] + + +class I09VGScientaAnalyserDriverIO( + VGScientaAnalyserDriverIO[LensMode, PsuMode, PassEnergy] +): + def __init__(self, prefix: str, name: str = ""): + super().__init__(prefix, LensMode, PsuMode, PassEnergy, "ELEMENT_SET", name) + + +I09ElectronAnalyserController = ElectronAnalyserController[ + I09VGScientaAnalyserDriverIO, I09VGScientaRegion +] + + +class I09VGScientaEW4000( + ElectronAnalyserDetector[I09VGScientaAnalyserDriverIO, I09VGScientaRegion] +): + """Implementation of VGScienta Electron Analyser. This model is unique for i09 + beamline because it has access to multiple energy sources and shutters. The selected + source is deterimined by the source_selector device. + """ + + def __init__( + self, + prefix: str, + dual_energy_source: DualEnergySource, + dual_fast_shutter: DualFastShutter, + source_selector: SourceSelector, + name: str = "", + ): + controller = I09ElectronAnalyserController( + I09VGScientaAnalyserDriverIO(prefix), + dual_energy_source, + dual_fast_shutter, + source_selector, + ) + super().__init__(controller, name) diff --git a/src/dodal/devices/beamlines/i09_1/__init__.py b/src/dodal/devices/beamlines/i09_1/__init__.py index b54345b1141..fc3d25d1765 100644 --- a/src/dodal/devices/beamlines/i09_1/__init__.py +++ b/src/dodal/devices/beamlines/i09_1/__init__.py @@ -1,3 +1,18 @@ +from .analyser import ( + I091ElectronAnalyserController, + I091SpecsAnalyserDriverIO, + I091SpecsPhoibos225, + I091SpecsRegion, + I091SpecsSequence, +) from .enums import LensMode, PsuMode -__all__ = ["LensMode", "PsuMode"] +__all__ = [ + "I091ElectronAnalyserController", + "I091SpecsAnalyserDriverIO", + "I091SpecsPhoibos225", + "I091SpecsRegion", + "I091SpecsSequence", + "LensMode", + "PsuMode", +] diff --git a/src/dodal/devices/beamlines/i09_1/analyser.py b/src/dodal/devices/beamlines/i09_1/analyser.py new file mode 100644 index 00000000000..bc7af96ae86 --- /dev/null +++ b/src/dodal/devices/beamlines/i09_1/analyser.py @@ -0,0 +1,41 @@ +from dodal.devices.beamlines.i09_1.enums import LensMode, PsuMode +from dodal.devices.electron_analyser.base.base_controller import ( + ElectronAnalyserController, +) +from dodal.devices.electron_analyser.base.base_detector import ElectronAnalyserDetector +from dodal.devices.electron_analyser.base.energy_sources import EnergySource +from dodal.devices.electron_analyser.specs import ( + SpecsAnalyserDriverIO, + SpecsRegion, + SpecsSequence, +) +from dodal.devices.fast_shutter import FastShutter + +I091SpecsRegion = SpecsRegion[LensMode, PsuMode] +I091SpecsSequence = SpecsSequence[LensMode, PsuMode] + + +class I091SpecsAnalyserDriverIO(SpecsAnalyserDriverIO): + def __init__(self, prefix: str, name: str = ""): + super().__init__(prefix, LensMode, PsuMode, name) + + +I091ElectronAnalyserController = ElectronAnalyserController[ + I091SpecsAnalyserDriverIO, I091SpecsRegion +] + + +class I091SpecsPhoibos225( + ElectronAnalyserDetector[I091SpecsAnalyserDriverIO, I091SpecsRegion] +): + def __init__( + self, + prefix: str, + energy_source: EnergySource, + shutter: FastShutter | None = None, + name: str = "", + ): + controller = I091ElectronAnalyserController( + I091SpecsAnalyserDriverIO(prefix), energy_source, shutter + ) + super().__init__(controller, name) diff --git a/src/dodal/devices/beamlines/p60/__init__.py b/src/dodal/devices/beamlines/p60/__init__.py index 6a25e7d0ba3..0ccdeeaa15d 100644 --- a/src/dodal/devices/beamlines/p60/__init__.py +++ b/src/dodal/devices/beamlines/p60/__init__.py @@ -1,7 +1,19 @@ +from .analyser import ( + P60ElectronAnalyserController, + P60VGScientaAnalyserDriverIO, + P60VGScientaR4000, + P60VGScientaSequence, + P60VGScientnaRegion, +) from .enums import LensMode, PassEnergy, PsuMode from .lab_xray_source import LabXraySource, LabXraySourceReadable __all__ = [ + "P60ElectronAnalyserController", + "P60VGScientaAnalyserDriverIO", + "P60VGScientaR4000", + "P60VGScientaSequence", + "P60VGScientnaRegion", "LensMode", "PsuMode", "PassEnergy", diff --git a/src/dodal/devices/beamlines/p60/analyser.py b/src/dodal/devices/beamlines/p60/analyser.py new file mode 100644 index 00000000000..a459a76c984 --- /dev/null +++ b/src/dodal/devices/beamlines/p60/analyser.py @@ -0,0 +1,56 @@ +from dodal.devices.beamlines.p60.enums import LensMode, PassEnergy, PsuMode +from dodal.devices.electron_analyser.base import AbstractEnergySource +from dodal.devices.electron_analyser.base.base_controller import ( + ElectronAnalyserController, +) +from dodal.devices.electron_analyser.base.base_detector import ElectronAnalyserDetector +from dodal.devices.electron_analyser.vgscienta import ( + VGScientaAnalyserDriverIO, + VGScientaRegion, + VGScientaSequence, +) +from dodal.devices.electron_analyser.vgscienta.vgscienta_driver_io import ( + VGScientaAnalyserDriverIO, +) +from dodal.devices.electron_analyser.vgscienta.vgscienta_region import ( + VGScientaRegion, + VGScientaSequence, +) + +P60VGScientnaRegion = VGScientaRegion[LensMode, PassEnergy] +P60VGScientaSequence = VGScientaSequence[LensMode, PsuMode, PassEnergy] + + +class P60VGScientaAnalyserDriverIO( + VGScientaAnalyserDriverIO[LensMode, PsuMode, PassEnergy] +): + def __init__(self, prefix: str, name: str = ""): + super().__init__(prefix, LensMode, PsuMode, PassEnergy, "ELEMENT_SET", name) + + +P60ElectronAnalyserController = ElectronAnalyserController[ + P60VGScientaAnalyserDriverIO, P60VGScientnaRegion +] + + +class P60VGScientaR4000( + ElectronAnalyserDetector[P60VGScientaAnalyserDriverIO, P60VGScientnaRegion] +): + """Lab specific analyser for P60 lab. It does not have any shutters connected so + will be None for this implementation. The selected_source also cannot be dynamically + changed between regions, so will also be None so regions cannot select. + """ + + def __init__( + self, + prefix: str, + energy_source: AbstractEnergySource, + name: str = "", + ): + controller = P60ElectronAnalyserController( + P60VGScientaAnalyserDriverIO(prefix), + energy_source=energy_source, + shutter=None, + source_selector=None, + ) + super().__init__(controller, name) diff --git a/src/dodal/devices/electron_analyser/base/base_driver_io.py b/src/dodal/devices/electron_analyser/base/base_driver_io.py index b266709aa82..25a3704d073 100644 --- a/src/dodal/devices/electron_analyser/base/base_driver_io.py +++ b/src/dodal/devices/electron_analyser/base/base_driver_io.py @@ -56,8 +56,6 @@ class AbstractAnalyserDriverIO( pass_energy_type (type[TPassEnergy]): Can be enum or float, depending on electron analyser model. If enum, it determines the available pass energies for this device. - energy_source: Device that can give us the correct excitation energy (in eV) - and switch sources if applicable. name (str, optional): Name of the device. """ @@ -68,6 +66,7 @@ def __init__( lens_mode_type: type[TLensMode], psu_mode_type: type[TPsuMode], pass_energy_type: type[TPassEnergy], + psu_mode_suffix: str = "PSU_MODE", name: str = "", ) -> None: self.acquisition_mode_type = acquisition_mode_type @@ -108,7 +107,7 @@ def __init__( ) # This is used by each electron analyser, however it depends on the electron # analyser type to know if is moved with region settings. - self.psu_mode = epics_signal_rw(psu_mode_type, prefix + "PSU_MODE") + self.psu_mode = epics_signal_rw(psu_mode_type, prefix + psu_mode_suffix) # This is defined in the parent class, add it as readable configuration. self.add_readables([self.acquire_time], StandardReadableFormat.CONFIG_SIGNAL) diff --git a/src/dodal/devices/electron_analyser/specs/__init__.py b/src/dodal/devices/electron_analyser/specs/__init__.py index 64819341c05..ca5ce2686cd 100644 --- a/src/dodal/devices/electron_analyser/specs/__init__.py +++ b/src/dodal/devices/electron_analyser/specs/__init__.py @@ -1,10 +1,8 @@ -from .specs_detector import SpecsDetector from .specs_driver_io import SpecsAnalyserDriverIO from .specs_enums import AcquisitionMode from .specs_region import SpecsRegion, SpecsSequence __all__ = [ - "SpecsDetector", "SpecsAnalyserDriverIO", "AcquisitionMode", "SpecsRegion", diff --git a/src/dodal/devices/electron_analyser/specs/specs_detector.py b/src/dodal/devices/electron_analyser/specs/specs_detector.py deleted file mode 100644 index 6d8eacaf515..00000000000 --- a/src/dodal/devices/electron_analyser/specs/specs_detector.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Generic - -from dodal.devices.electron_analyser.base.base_controller import ( - ElectronAnalyserController, -) -from dodal.devices.electron_analyser.base.base_detector import ElectronAnalyserDetector -from dodal.devices.electron_analyser.base.base_region import TLensMode, TPsuMode -from dodal.devices.electron_analyser.base.energy_sources import AbstractEnergySource -from dodal.devices.electron_analyser.specs.specs_driver_io import SpecsAnalyserDriverIO -from dodal.devices.electron_analyser.specs.specs_region import SpecsRegion -from dodal.devices.fast_shutter import FastShutter -from dodal.devices.selectable_source import SourceSelector - - -class SpecsDetector( - ElectronAnalyserDetector[ - SpecsAnalyserDriverIO[TLensMode, TPsuMode], - SpecsRegion[TLensMode, TPsuMode], - ], - Generic[TLensMode, TPsuMode], -): - def __init__( - self, - prefix: str, - lens_mode_type: type[TLensMode], - psu_mode_type: type[TPsuMode], - energy_source: AbstractEnergySource, - shutter: FastShutter | None = None, - source_selector: SourceSelector | None = None, - name: str = "", - ): - driver = SpecsAnalyserDriverIO[TLensMode, TPsuMode]( - prefix, lens_mode_type, psu_mode_type - ) - controller = ElectronAnalyserController[ - SpecsAnalyserDriverIO[TLensMode, TPsuMode], SpecsRegion[TLensMode, TPsuMode] - ](driver, energy_source, shutter, source_selector) - - super().__init__(controller, name) diff --git a/src/dodal/devices/electron_analyser/vgscienta/__init__.py b/src/dodal/devices/electron_analyser/vgscienta/__init__.py index c344269cc19..3b746193df0 100644 --- a/src/dodal/devices/electron_analyser/vgscienta/__init__.py +++ b/src/dodal/devices/electron_analyser/vgscienta/__init__.py @@ -1,10 +1,8 @@ -from .vgscienta_detector import VGScientaDetector from .vgscienta_driver_io import VGScientaAnalyserDriverIO from .vgscienta_enums import AcquisitionMode, DetectorMode from .vgscienta_region import VGScientaRegion, VGScientaSequence __all__ = [ - "VGScientaDetector", "VGScientaAnalyserDriverIO", "AcquisitionMode", "DetectorMode", diff --git a/src/dodal/devices/electron_analyser/vgscienta/vgscienta_detector.py b/src/dodal/devices/electron_analyser/vgscienta/vgscienta_detector.py deleted file mode 100644 index 29626b2d353..00000000000 --- a/src/dodal/devices/electron_analyser/vgscienta/vgscienta_detector.py +++ /dev/null @@ -1,46 +0,0 @@ -from typing import Generic - -from dodal.devices.electron_analyser.base.base_controller import ( - ElectronAnalyserController, -) -from dodal.devices.electron_analyser.base.base_detector import ElectronAnalyserDetector -from dodal.devices.electron_analyser.base.base_region import TLensMode, TPsuMode -from dodal.devices.electron_analyser.base.energy_sources import AbstractEnergySource -from dodal.devices.electron_analyser.vgscienta.vgscienta_driver_io import ( - VGScientaAnalyserDriverIO, -) -from dodal.devices.electron_analyser.vgscienta.vgscienta_region import ( - TPassEnergyEnum, - VGScientaRegion, -) -from dodal.devices.fast_shutter import FastShutter -from dodal.devices.selectable_source import SourceSelector - - -class VGScientaDetector( - ElectronAnalyserDetector[ - VGScientaAnalyserDriverIO[TLensMode, TPsuMode, TPassEnergyEnum], - VGScientaRegion[TLensMode, TPassEnergyEnum], - ], - Generic[TLensMode, TPsuMode, TPassEnergyEnum], -): - def __init__( - self, - prefix: str, - lens_mode_type: type[TLensMode], - psu_mode_type: type[TPsuMode], - pass_energy_type: type[TPassEnergyEnum], - energy_source: AbstractEnergySource, - shutter: FastShutter | None = None, - source_selector: SourceSelector | None = None, - name: str = "", - ): - driver = VGScientaAnalyserDriverIO[TLensMode, TPsuMode, TPassEnergyEnum]( - prefix, lens_mode_type, psu_mode_type, pass_energy_type - ) - controller = ElectronAnalyserController[ - VGScientaAnalyserDriverIO[TLensMode, TPsuMode, TPassEnergyEnum], - VGScientaRegion[TLensMode, TPassEnergyEnum], - ](driver, energy_source, shutter, source_selector) - - super().__init__(controller, name) diff --git a/src/dodal/devices/electron_analyser/vgscienta/vgscienta_driver_io.py b/src/dodal/devices/electron_analyser/vgscienta/vgscienta_driver_io.py index 3d7db84aa93..2563f0a7e37 100644 --- a/src/dodal/devices/electron_analyser/vgscienta/vgscienta_driver_io.py +++ b/src/dodal/devices/electron_analyser/vgscienta/vgscienta_driver_io.py @@ -40,6 +40,7 @@ def __init__( lens_mode_type: type[TLensMode], psu_mode_type: type[TPsuMode], pass_energy_type: type[TPassEnergyEnum], + psu_mode_suffix: str = "PSU_MODE", name: str = "", ) -> None: with self.add_children_as_readables(StandardReadableFormat.CONFIG_SIGNAL): @@ -60,6 +61,7 @@ def __init__( lens_mode_type, psu_mode_type, pass_energy_type, + psu_mode_suffix, name, ) diff --git a/tests/devices/electron_analyser/base/test_base_controller.py b/tests/devices/electron_analyser/base/test_base_controller.py index 62a353c5d56..468d06a73ff 100644 --- a/tests/devices/electron_analyser/base/test_base_controller.py +++ b/tests/devices/electron_analyser/base/test_base_controller.py @@ -13,13 +13,13 @@ ) from tests.devices.electron_analyser.helper_util import ( TEST_SEQUENCE_REGION_NAMES, - get_test_sequence, + TEST_SEQUENCES, ) @pytest.fixture def sequence(sim_detector: GenericElectronAnalyserDetector) -> GenericSequence: - return get_test_sequence(type(sim_detector)) + return TEST_SEQUENCES[type(sim_detector)]() @pytest.fixture diff --git a/tests/devices/electron_analyser/base/test_base_detector.py b/tests/devices/electron_analyser/base/test_base_detector.py index 2b0ffee8475..5fe04483994 100644 --- a/tests/devices/electron_analyser/base/test_base_detector.py +++ b/tests/devices/electron_analyser/base/test_base_detector.py @@ -108,7 +108,6 @@ def test_analyser_detector_creates_region_detectors( ) assert len(region_detectors) == len(sequence.get_enabled_regions()) for det in region_detectors: - assert det.region.enabled is True assert det.name == sim_detector.name + "_" + det.region.name diff --git a/tests/devices/electron_analyser/base/test_base_region.py b/tests/devices/electron_analyser/base/test_base_region.py index 9d53f4a5e59..a3c1a70705b 100644 --- a/tests/devices/electron_analyser/base/test_base_region.py +++ b/tests/devices/electron_analyser/base/test_base_region.py @@ -2,7 +2,8 @@ import pytest -from dodal.devices.beamlines import b07, b07_shared, i09 +from dodal.devices.beamlines.b07 import B07BSpecsRegion, B07BSpecsSequence +from dodal.devices.beamlines.i09 import I09VGScientaRegion, I09VGScientaSequence from dodal.devices.electron_analyser.base import ( AbstractBaseRegion, EnergyMode, @@ -12,25 +13,17 @@ to_binding_energy, to_kinetic_energy, ) -from dodal.devices.electron_analyser.specs import ( - SpecsRegion, - SpecsSequence, -) -from dodal.devices.electron_analyser.vgscienta import VGScientaRegion, VGScientaSequence +from dodal.devices.electron_analyser.specs import SpecsSequence +from dodal.devices.electron_analyser.vgscienta import VGScientaSequence from tests.devices.electron_analyser.helper_util import ( TEST_SEQUENCE_REGION_NAMES, - get_test_sequence, + TEST_SEQUENCES, ) -@pytest.fixture( - params=[ - SpecsSequence[b07.LensMode, b07_shared.PsuMode], - VGScientaSequence[i09.LensMode, i09.PsuMode, i09.PassEnergy], - ], -) +@pytest.fixture(params=[B07BSpecsSequence, I09VGScientaSequence]) def sequence(request: pytest.FixtureRequest) -> GenericSequence: - return get_test_sequence(request.param) + return TEST_SEQUENCES[request.param]() @pytest.fixture @@ -38,9 +31,9 @@ def expected_region_class( sequence: GenericSequence, ) -> type[AbstractBaseRegion]: if isinstance(sequence, SpecsSequence): - return SpecsRegion[b07.LensMode, b07_shared.PsuMode] + return B07BSpecsRegion elif isinstance(sequence, VGScientaSequence): - return VGScientaRegion[i09.LensMode, i09.PassEnergy] + return I09VGScientaRegion raise TypeError(f"Unknown sequence type {type(sequence)}") diff --git a/tests/devices/electron_analyser/conftest.py b/tests/devices/electron_analyser/conftest.py index 2cd1bb29e25..474a0ea17e8 100644 --- a/tests/devices/electron_analyser/conftest.py +++ b/tests/devices/electron_analyser/conftest.py @@ -3,8 +3,8 @@ import pytest from ophyd_async.core import InOut, init_devices, set_mock_value -from dodal.devices.beamlines import b07, b07_shared, i09 -from dodal.devices.beamlines.i09 import Grating +from dodal.devices.beamlines.b07 import B07BSpecs150 +from dodal.devices.beamlines.i09 import Grating, I09VGScientaEW4000 from dodal.devices.common_dcm import ( DoubleCrystalMonochromatorWithDSpacing, PitchAndRollCrystal, @@ -17,8 +17,6 @@ EnergySource, GenericElectronAnalyserDetector, ) -from dodal.devices.electron_analyser.specs import SpecsDetector -from dodal.devices.electron_analyser.vgscienta import VGScientaDetector from dodal.devices.fast_shutter import DualFastShutter, GenericFastShutter from dodal.devices.pgm import PlaneGratingMonochromator from dodal.devices.selectable_source import SourceSelector @@ -62,6 +60,16 @@ async def dual_energy_source(source_selector: SourceSelector) -> DualEnergySourc return dual_energy_source +def fast_shutter() -> GenericFastShutter: + with init_devices(mock=True): + fast_shutter = GenericFastShutter[InOut]( + pv="TEST:", + open_state=InOut.OUT, + close_state=InOut.IN, + ) + return fast_shutter + + @pytest.fixture def shutter1() -> GenericFastShutter[InOut]: with init_devices(mock=True): @@ -103,12 +111,10 @@ def dual_fast_shutter( async def b07b_specs150( single_energy_source: EnergySource, shutter1: GenericFastShutter, -) -> SpecsDetector[b07.LensMode, b07_shared.PsuMode]: +) -> B07BSpecs150: with init_devices(mock=True): - b07b_specs150 = SpecsDetector[b07.LensMode, b07_shared.PsuMode]( + b07b_specs150 = B07BSpecs150( prefix="TEST:", - lens_mode_type=b07.LensMode, - psu_mode_type=b07_shared.PsuMode, energy_source=single_energy_source, shutter=shutter1, ) @@ -122,15 +128,12 @@ async def ew4000( dual_energy_source: DualEnergySource, dual_fast_shutter: DualFastShutter, source_selector: SourceSelector, -) -> VGScientaDetector[i09.LensMode, i09.PsuMode, i09.PassEnergy]: +) -> I09VGScientaEW4000: with init_devices(mock=True): - ew4000 = VGScientaDetector[i09.LensMode, i09.PsuMode, i09.PassEnergy]( + ew4000 = I09VGScientaEW4000( prefix="TEST:", - lens_mode_type=i09.LensMode, - psu_mode_type=i09.PsuMode, - pass_energy_type=i09.PassEnergy, - energy_source=dual_energy_source, - shutter=dual_fast_shutter, + dual_energy_source=dual_energy_source, + dual_fast_shutter=dual_fast_shutter, source_selector=source_selector, ) return ew4000 @@ -139,8 +142,8 @@ async def ew4000( @pytest.fixture(params=["ew4000", "b07b_specs150"]) def sim_detector( request: pytest.FixtureRequest, - ew4000: VGScientaDetector[i09.LensMode, i09.PsuMode, i09.PassEnergy], - b07b_specs150: SpecsDetector[b07.LensMode, b07_shared.PsuMode], + ew4000: I09VGScientaEW4000, + b07b_specs150: B07BSpecs150, ) -> GenericElectronAnalyserDetector: detectors = [ew4000, b07b_specs150] for detector in detectors: diff --git a/tests/devices/electron_analyser/helper_util/__init__.py b/tests/devices/electron_analyser/helper_util/__init__.py index c3026b1e71d..da0f67f56d5 100644 --- a/tests/devices/electron_analyser/helper_util/__init__.py +++ b/tests/devices/electron_analyser/helper_util/__init__.py @@ -1,8 +1,11 @@ from .assert_func import assert_region_has_expected_values -from .sequence import TEST_SEQUENCE_REGION_NAMES, get_test_sequence +from .sequence import ( + TEST_SEQUENCE_REGION_NAMES, + TEST_SEQUENCES, +) __all__ = [ "assert_region_has_expected_values", - "get_test_sequence", "TEST_SEQUENCE_REGION_NAMES", + "TEST_SEQUENCES", ] diff --git a/tests/devices/electron_analyser/helper_util/sequence.py b/tests/devices/electron_analyser/helper_util/sequence.py index 67bf1496760..a7e5620f0c4 100644 --- a/tests/devices/electron_analyser/helper_util/sequence.py +++ b/tests/devices/electron_analyser/helper_util/sequence.py @@ -1,14 +1,13 @@ from dodal.common.data_util import load_json_file_to_class -from dodal.devices.beamlines import b07, b07_shared, i09 -from dodal.devices.electron_analyser.specs import ( - SpecsAnalyserDriverIO, - SpecsDetector, - SpecsSequence, +from dodal.devices.beamlines.b07 import ( + B07BSpecs150, + B07BSpecsAnalyserDriverIO, + B07BSpecsSequence, ) -from dodal.devices.electron_analyser.vgscienta import ( - VGScientaAnalyserDriverIO, - VGScientaDetector, - VGScientaSequence, +from dodal.devices.beamlines.i09 import ( + I09VGScientaAnalyserDriverIO, + I09VGScientaEW4000, + I09VGScientaSequence, ) from tests.devices.electron_analyser.test_data import ( TEST_SPECS_SEQUENCE, @@ -18,29 +17,22 @@ TEST_SEQUENCE_REGION_NAMES = ["New_Region", "New_Region1", "New_Region2"] -def b07_specs_test_sequence_loader() -> SpecsSequence[b07.LensMode, b07_shared.PsuMode]: - return load_json_file_to_class( - SpecsSequence[b07.LensMode, b07_shared.PsuMode], TEST_SPECS_SEQUENCE - ) +def b07_specs_test_sequence_loader() -> B07BSpecsSequence: + return load_json_file_to_class(B07BSpecsSequence, TEST_SPECS_SEQUENCE) -def i09_vgscienta_test_sequence_loader() -> VGScientaSequence[ - i09.LensMode, i09.PsuMode, i09.PassEnergy -]: - return load_json_file_to_class( - VGScientaSequence[i09.LensMode, i09.PsuMode, i09.PassEnergy], - TEST_VGSCIENTA_SEQUENCE, - ) +def i09_vgscienta_test_sequence_loader() -> I09VGScientaSequence: + return load_json_file_to_class(I09VGScientaSequence, TEST_VGSCIENTA_SEQUENCE) # Map to know what function to load in sequence an analyser driver should use. TEST_SEQUENCES = { - SpecsDetector: b07_specs_test_sequence_loader, - SpecsAnalyserDriverIO: b07_specs_test_sequence_loader, - SpecsSequence: b07_specs_test_sequence_loader, - VGScientaDetector: i09_vgscienta_test_sequence_loader, - VGScientaAnalyserDriverIO: i09_vgscienta_test_sequence_loader, - VGScientaSequence: i09_vgscienta_test_sequence_loader, + B07BSpecs150: b07_specs_test_sequence_loader, + B07BSpecsAnalyserDriverIO: b07_specs_test_sequence_loader, + B07BSpecsSequence: b07_specs_test_sequence_loader, + I09VGScientaEW4000: i09_vgscienta_test_sequence_loader, + I09VGScientaAnalyserDriverIO: i09_vgscienta_test_sequence_loader, + I09VGScientaSequence: i09_vgscienta_test_sequence_loader, } diff --git a/tests/devices/electron_analyser/specs/test_specs_detector.py b/tests/devices/electron_analyser/specs/test_specs_detector.py deleted file mode 100644 index ac91086a57a..00000000000 --- a/tests/devices/electron_analyser/specs/test_specs_detector.py +++ /dev/null @@ -1,31 +0,0 @@ -from ophyd_async.core import set_mock_value - -from dodal.devices.electron_analyser.specs import SpecsDetector - - -async def test_analyser_specs_detector_image_shape( - b07b_specs150: SpecsDetector, -) -> None: - driver = b07b_specs150.driver - prefix = driver.name + "-" - - low_energy = 1 - high_energy = 10 - slices = 4 - set_mock_value(driver.low_energy, low_energy) - set_mock_value(driver.high_energy, high_energy) - set_mock_value(driver.slices, slices) - - min_angle = 1 - max_angle = 10 - set_mock_value(driver.min_angle_axis, min_angle) - set_mock_value(driver.max_angle_axis, max_angle) - - angle_axis = await driver.angle_axis.get_value() - energy_axis = await driver.energy_axis.get_value() - - describe = await b07b_specs150.describe() - assert describe[f"{prefix}image"]["shape"] == [ - len(angle_axis), - len(energy_axis), - ] diff --git a/tests/devices/electron_analyser/specs/test_specs_driver_io.py b/tests/devices/electron_analyser/specs/test_specs_driver_io.py index 69e3fc590dc..d7287ff15dd 100644 --- a/tests/devices/electron_analyser/specs/test_specs_driver_io.py +++ b/tests/devices/electron_analyser/specs/test_specs_driver_io.py @@ -12,38 +12,33 @@ partial_reading, ) -from dodal.devices.beamlines.b07 import LensMode -from dodal.devices.beamlines.b07_shared import PsuMode +from dodal.devices.beamlines.b07.analyser import ( + B07BSpecsAnalyserDriverIO, + B07BSpecsRegion, +) from dodal.devices.electron_analyser.base import EnergyMode from dodal.devices.electron_analyser.base.base_enums import EnergyMode -from dodal.devices.electron_analyser.specs import ( - AcquisitionMode, - SpecsAnalyserDriverIO, - SpecsDetector, - SpecsRegion, -) +from dodal.devices.electron_analyser.specs import AcquisitionMode from tests.devices.electron_analyser.helper_util import ( TEST_SEQUENCE_REGION_NAMES, - get_test_sequence, + TEST_SEQUENCES, ) @pytest.fixture -async def sim_driver( - b07b_specs150: SpecsDetector[LensMode, PsuMode], -) -> SpecsAnalyserDriverIO[LensMode, PsuMode]: +async def sim_driver(b07b_specs150) -> B07BSpecsAnalyserDriverIO: return b07b_specs150.driver @pytest.fixture -def sequence(sim_driver: SpecsAnalyserDriverIO[LensMode, PsuMode]): - return get_test_sequence(type(sim_driver)) +def sequence(sim_driver: B07BSpecsAnalyserDriverIO): + return TEST_SEQUENCES[type(sim_driver)]() @pytest.mark.parametrize("region", TEST_SEQUENCE_REGION_NAMES, indirect=True) async def test_analyser_sets_region_correctly( - sim_driver: SpecsAnalyserDriverIO[LensMode, PsuMode], - region: SpecsRegion[LensMode, PsuMode], + sim_driver: B07BSpecsAnalyserDriverIO, + region: B07BSpecsRegion, run_engine: RunEngine, ) -> None: run_engine(bps.mv(sim_driver, region), wait=True) @@ -99,8 +94,8 @@ async def test_analyser_sets_region_correctly( @pytest.mark.parametrize("region", TEST_SEQUENCE_REGION_NAMES, indirect=True) async def test_analyser_sets_region_and_read_configuration_is_correct( - sim_driver: SpecsAnalyserDriverIO[LensMode, PsuMode], - region: SpecsRegion[LensMode, PsuMode], + sim_driver: B07BSpecsAnalyserDriverIO, + region: B07BSpecsRegion, run_engine: RunEngine, ) -> None: run_engine(bps.mv(sim_driver, region), wait=True) @@ -136,8 +131,8 @@ async def test_analyser_sets_region_and_read_configuration_is_correct( @pytest.mark.parametrize("region", TEST_SEQUENCE_REGION_NAMES, indirect=True) async def test_analyser_sets_region_and_read_is_correct( - sim_driver: SpecsAnalyserDriverIO[LensMode, PsuMode], - region: SpecsRegion[LensMode, PsuMode], + sim_driver: B07BSpecsAnalyserDriverIO, + region: B07BSpecsRegion, run_engine: RunEngine, ) -> None: run_engine(bps.mv(sim_driver, region), wait=True) @@ -159,8 +154,8 @@ async def test_analyser_sets_region_and_read_is_correct( @pytest.mark.parametrize("region", TEST_SEQUENCE_REGION_NAMES, indirect=True) async def test_specs_analyser_binding_energy_axis( - sim_driver: SpecsAnalyserDriverIO[LensMode, PsuMode], - region: SpecsRegion[LensMode, PsuMode], + sim_driver: B07BSpecsAnalyserDriverIO, + region: B07BSpecsRegion, run_engine: RunEngine, ) -> None: run_engine(bps.mv(sim_driver, region)) @@ -181,7 +176,7 @@ async def test_specs_analyser_binding_energy_axis( async def test_specs_analyser_energy_axis( - sim_driver: SpecsAnalyserDriverIO[LensMode, PsuMode], + sim_driver: B07BSpecsAnalyserDriverIO, run_engine: RunEngine, ) -> None: start_energy = 1 @@ -197,7 +192,7 @@ async def test_specs_analyser_energy_axis( async def test_specs_analyser_angle_axis( - sim_driver: SpecsAnalyserDriverIO[LensMode, PsuMode], + sim_driver: B07BSpecsAnalyserDriverIO, run_engine: RunEngine, ) -> None: max_angle = 21 diff --git a/tests/devices/electron_analyser/specs/test_specs_region.py b/tests/devices/electron_analyser/specs/test_specs_region.py index c26a1f27dcd..2ce1119e417 100644 --- a/tests/devices/electron_analyser/specs/test_specs_region.py +++ b/tests/devices/electron_analyser/specs/test_specs_region.py @@ -2,20 +2,20 @@ import pytest -from dodal.devices.beamlines.b07 import LensMode +from dodal.devices.beamlines.b07 import B07BSpecsSequence, LensMode from dodal.devices.beamlines.b07_shared import PsuMode from dodal.devices.electron_analyser.base import EnergyMode -from dodal.devices.electron_analyser.specs import AcquisitionMode, SpecsSequence +from dodal.devices.electron_analyser.specs import AcquisitionMode from dodal.devices.selectable_source import SelectedSource from tests.devices.electron_analyser.helper_util import ( + TEST_SEQUENCES, assert_region_has_expected_values, - get_test_sequence, ) @pytest.fixture -def sequence() -> SpecsSequence[LensMode, PsuMode]: - return get_test_sequence(SpecsSequence[LensMode, PsuMode]) +def sequence() -> B07BSpecsSequence: + return TEST_SEQUENCES[B07BSpecsSequence]() @pytest.fixture @@ -82,7 +82,7 @@ def expected_region_values() -> list[dict[str, Any]]: def test_sequence_get_expected_enabled_region_names( - sequence: SpecsSequence[LensMode, PsuMode], + sequence: B07BSpecsSequence, expected_enabled_region_names: list[str], ) -> None: assert sequence.get_enabled_region_names() == expected_enabled_region_names @@ -91,7 +91,7 @@ def test_sequence_get_expected_enabled_region_names( def test_file_loads_into_class_with_expected_values( - sequence: SpecsSequence[LensMode, PsuMode], + sequence: B07BSpecsSequence, expected_region_values: list[dict[str, Any]], ) -> None: assert len(sequence.regions) == len(expected_region_values) diff --git a/tests/devices/electron_analyser/vgscienta/test_vgscienta_detector.py b/tests/devices/electron_analyser/vgscienta/test_vgscienta_detector.py deleted file mode 100644 index 48ac964f0f6..00000000000 --- a/tests/devices/electron_analyser/vgscienta/test_vgscienta_detector.py +++ /dev/null @@ -1,25 +0,0 @@ -import numpy as np -from ophyd_async.core import set_mock_value - -from dodal.devices.beamlines.i09 import LensMode, PassEnergy, PsuMode -from dodal.devices.electron_analyser.vgscienta import ( - VGScientaDetector, -) - - -async def test_analyser_vgscienta_detector_image_shape( - ew4000: VGScientaDetector[LensMode, PsuMode, PassEnergy], -) -> None: - driver = ew4000.driver - prefix = driver.name + "-" - - energy_axis = np.array([1, 2, 3, 4, 5]) - angle_axis = np.array([1, 2]) - set_mock_value(driver.energy_axis, energy_axis) - set_mock_value(driver.angle_axis, angle_axis) - - describe = await ew4000.describe() - assert describe[f"{prefix}image"]["shape"] == [ - len(angle_axis), - len(energy_axis), - ] diff --git a/tests/devices/electron_analyser/vgscienta/test_vgscienta_driver_io.py b/tests/devices/electron_analyser/vgscienta/test_vgscienta_driver_io.py index 17e8b4fbd11..17bbdbff1c8 100644 --- a/tests/devices/electron_analyser/vgscienta/test_vgscienta_driver_io.py +++ b/tests/devices/electron_analyser/vgscienta/test_vgscienta_driver_io.py @@ -13,35 +13,31 @@ partial_reading, ) -from dodal.devices.beamlines.i09 import LensMode, PassEnergy, PsuMode -from dodal.devices.electron_analyser.base import EnergyMode -from dodal.devices.electron_analyser.vgscienta import ( - VGScientaAnalyserDriverIO, - VGScientaDetector, - VGScientaRegion, +from dodal.devices.beamlines.i09 import ( + I09VGScientaAnalyserDriverIO, + I09VGScientaRegion, ) +from dodal.devices.electron_analyser.base import EnergyMode from tests.devices.electron_analyser.helper_util import ( TEST_SEQUENCE_REGION_NAMES, - get_test_sequence, + TEST_SEQUENCES, ) @pytest.fixture -async def sim_driver( - ew4000: VGScientaDetector, -) -> VGScientaAnalyserDriverIO[LensMode, PsuMode, PassEnergy]: +async def sim_driver(ew4000) -> I09VGScientaAnalyserDriverIO: return ew4000.driver @pytest.fixture -def sequence(sim_driver: VGScientaAnalyserDriverIO[LensMode, PsuMode, PassEnergy]): - return get_test_sequence(type(sim_driver)) +def sequence(sim_driver: I09VGScientaAnalyserDriverIO): + return TEST_SEQUENCES[type(sim_driver)]() @pytest.mark.parametrize("region", TEST_SEQUENCE_REGION_NAMES, indirect=True) async def test_analyser_sets_region_correctly( - sim_driver: VGScientaAnalyserDriverIO[LensMode, PsuMode, PassEnergy], - region: VGScientaRegion[LensMode, PassEnergy], + sim_driver: I09VGScientaAnalyserDriverIO, + region: I09VGScientaRegion, run_engine: RunEngine, ) -> None: run_engine(bps.mv(sim_driver, region), wait=True) @@ -98,8 +94,8 @@ async def test_analyser_sets_region_correctly( @pytest.mark.parametrize("region", TEST_SEQUENCE_REGION_NAMES, indirect=True) async def test_analyser_sets_region_and_read_configuration_is_correct( - sim_driver: VGScientaAnalyserDriverIO[LensMode, PsuMode, PassEnergy], - region: VGScientaRegion[LensMode, PassEnergy], + sim_driver: I09VGScientaAnalyserDriverIO, + region: I09VGScientaRegion, run_engine: RunEngine, ) -> None: run_engine(bps.mv(sim_driver, region), wait=True) @@ -140,8 +136,8 @@ async def test_analyser_sets_region_and_read_configuration_is_correct( @pytest.mark.parametrize("region", TEST_SEQUENCE_REGION_NAMES, indirect=True) async def test_analyser_sets_region_and_read_is_correct( - sim_driver: VGScientaAnalyserDriverIO[LensMode, PsuMode, PassEnergy], - region: VGScientaRegion[LensMode, PassEnergy], + sim_driver: I09VGScientaAnalyserDriverIO, + region: I09VGScientaRegion, run_engine: RunEngine, ) -> None: run_engine(bps.mv(sim_driver, region), wait=True) @@ -164,8 +160,8 @@ async def test_analyser_sets_region_and_read_is_correct( @pytest.mark.parametrize("region", TEST_SEQUENCE_REGION_NAMES, indirect=True) async def test_analayser_binding_energy_is_correct( - sim_driver: VGScientaAnalyserDriverIO[LensMode, PsuMode, PassEnergy], - region: VGScientaRegion[LensMode, PassEnergy], + sim_driver: I09VGScientaAnalyserDriverIO, + region: I09VGScientaRegion, run_engine: RunEngine, ) -> None: run_engine(bps.mv(sim_driver, region), wait=True) @@ -187,7 +183,7 @@ async def test_analayser_binding_energy_is_correct( def test_driver_throws_error_with_wrong_pass_energy( - sim_driver: VGScientaAnalyserDriverIO[LensMode, PsuMode, PassEnergy], + sim_driver: I09VGScientaAnalyserDriverIO, run_engine: RunEngine, ) -> None: class PassEnergyTestEnum(StrictEnum): @@ -204,7 +200,7 @@ class PassEnergyTestEnum(StrictEnum): def test_driver_throws_error_with_wrong_detector_mode( - sim_driver: VGScientaAnalyserDriverIO[LensMode, PsuMode, PassEnergy], + sim_driver: I09VGScientaAnalyserDriverIO, run_engine: RunEngine, ) -> None: class DetectorModeTestEnum(StrictEnum): diff --git a/tests/devices/electron_analyser/vgscienta/test_vgsicenta_region.py b/tests/devices/electron_analyser/vgscienta/test_vgsicenta_region.py index 0e4fe4f88bb..a0466da2d80 100644 --- a/tests/devices/electron_analyser/vgscienta/test_vgsicenta_region.py +++ b/tests/devices/electron_analyser/vgscienta/test_vgsicenta_region.py @@ -2,29 +2,31 @@ import pytest -from dodal.devices.beamlines.i09 import LensMode, PassEnergy, PsuMode +from dodal.devices.beamlines.i09 import LensMode, PassEnergy +from dodal.devices.beamlines.i09.analyser import ( + I09VGScientaRegion, + I09VGScientaSequence, +) from dodal.devices.electron_analyser.base import EnergyMode from dodal.devices.electron_analyser.vgscienta import ( AcquisitionMode, DetectorMode, - VGScientaRegion, - VGScientaSequence, ) from dodal.devices.selectable_source import SelectedSource from tests.devices.electron_analyser.helper_util import ( + TEST_SEQUENCES, assert_region_has_expected_values, - get_test_sequence, ) @pytest.fixture -def sequence() -> VGScientaSequence[LensMode, PsuMode, PassEnergy]: - return get_test_sequence(VGScientaSequence[LensMode, PsuMode, PassEnergy]) +def sequence() -> I09VGScientaSequence: + return TEST_SEQUENCES[I09VGScientaSequence]() @pytest.fixture -def expected_region_class() -> type[VGScientaRegion[LensMode, PassEnergy]]: - return VGScientaRegion[LensMode, PassEnergy] +def expected_region_class() -> type[I09VGScientaRegion]: + return I09VGScientaRegion @pytest.fixture @@ -106,7 +108,7 @@ def expected_region_values() -> list[dict[str, Any]]: def test_sequence_get_expected_enabled_region_names( - sequence: VGScientaSequence[LensMode, PsuMode, PassEnergy], + sequence: I09VGScientaSequence, expected_enabled_region_names: list[str], ) -> None: assert sequence.get_enabled_region_names() == expected_enabled_region_names @@ -115,7 +117,7 @@ def test_sequence_get_expected_enabled_region_names( def test_file_loads_into_class_with_expected_values( - sequence: VGScientaSequence[LensMode, PsuMode, PassEnergy], + sequence: I09VGScientaSequence, expected_region_values: list[dict[str, Any]], ) -> None: assert len(sequence.regions) == len(expected_region_values)