diff --git a/src/dodal/beamlines/i02_1.py b/src/dodal/beamlines/i02_1.py index 5daa4b3b01..0c27d4b82e 100644 --- a/src/dodal/beamlines/i02_1.py +++ b/src/dodal/beamlines/i02_1.py @@ -10,16 +10,19 @@ I02_1FilterTwoSelections, ) from dodal.devices.beamlines.i02_1.fast_grid_scan import ZebraFastGridScanTwoD +from dodal.devices.beamlines.i02_1.flux import Flux from dodal.devices.beamlines.i02_1.sample_motors import SampleMotors +from dodal.devices.common_dcm import DoubleCrystalMonochromatorBase, StationaryCrystal from dodal.devices.eiger import EigerDetector +from dodal.devices.slits import Slits from dodal.devices.synchrotron import Synchrotron +from dodal.devices.undulator import UndulatorInKeV from dodal.devices.zebra.zebra import Zebra from dodal.devices.zebra.zebra_constants_mapping import ( ZebraMapping, ZebraSources, ZebraTTLOutputs, ) -from dodal.devices.zocalo import ZocaloResults from dodal.log import set_beamline as set_log_beamline from dodal.utils import BeamlinePrefix, get_beamline_name @@ -30,7 +33,7 @@ DAQ_CONFIGURATION_PATH = "/dls_sw/i02-1/software/daq_configuration" I02_1_ZEBRA_MAPPING = ZebraMapping( - outputs=ZebraTTLOutputs(TTL_EIGER=2, TTL_XSPRESS3=3, TTL_FAST_SHUTTER=1), + outputs=ZebraTTLOutputs(TTL_EIGER=4), sources=ZebraSources(), ) @@ -41,9 +44,18 @@ EigerDetector, prefix=f"{PREFIX.beamline_prefix}-EA-EIGER-01:", wait=False ) def eiger(eiger: EigerDetector) -> EigerDetector: + eiger.detector_id = 101 return eiger +@devices.factory() +def undulator(daq_configuration_path: str) -> UndulatorInKeV: + return UndulatorInKeV( + prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-01:", + id_gap_lookup_table_path=f"{daq_configuration_path}/lookup/BeamLine_Undulator_toGap.txt", + ) + + @devices.factory() def zebra_fast_grid_scan() -> ZebraFastGridScanTwoD: return ZebraFastGridScanTwoD( @@ -65,15 +77,33 @@ def zebra() -> Zebra: ) -# Device not needed after https://github.com/DiamondLightSource/mx-bluesky/issues/1299 @devices.factory() -def zocalo() -> ZocaloResults: - return ZocaloResults() +def dcm() -> DoubleCrystalMonochromatorBase: + return DoubleCrystalMonochromatorBase( + f"{PREFIX.beamline_prefix}-MO-DCM-01:", + xtal_1=StationaryCrystal, + xtal_2=StationaryCrystal, + ) + + +@devices.fixture +def daq_configuration_path() -> str: + return DAQ_CONFIGURATION_PATH @devices.factory() +def s4_slit_gaps() -> Slits: + return Slits(f"{PREFIX.beamline_prefix}-AL-SLITS-04:") + + +@devices.factory(use_factory_name=False) def goniometer() -> SampleMotors: - return SampleMotors(f"{PREFIX.beamline_prefix}-MO-SAMP-01:") + return SampleMotors(f"{PREFIX.beamline_prefix}-MO-", name="gonio") + + +@devices.factory() +def flux() -> Flux: + return Flux(f"{PREFIX.beamline_prefix}-EA-FLUX-01:") @devices.factory() diff --git a/src/dodal/devices/beamlines/i02_1/fast_grid_scan.py b/src/dodal/devices/beamlines/i02_1/fast_grid_scan.py index 70ebbf755b..310887522f 100644 --- a/src/dodal/devices/beamlines/i02_1/fast_grid_scan.py +++ b/src/dodal/devices/beamlines/i02_1/fast_grid_scan.py @@ -1,5 +1,5 @@ from ophyd_async.core import SignalR, derived_signal_r, soft_signal_r_and_setter -from ophyd_async.epics.core import epics_signal_rw_rbv +from ophyd_async.epics.core import epics_signal_r, epics_signal_rw_rbv from dodal.devices.fast_grid_scan import ( FastGridScanCommon, @@ -20,7 +20,7 @@ class ZebraFastGridScanTwoD(FastGridScanCommon[ZebraGridScanParamsTwoD]): """i02-1's EPICS interface for the 2D FGS differs slightly from the standard 3D version: - No Z steps, Z step sizes, or Y2 start positions, or Z2 start - - No scan valid PV - see https://github.com/DiamondLightSource/mx-bluesky/issues/1203 + - Scan valid PV needs to end with RBV - No program_number - see https://github.com/DiamondLightSource/mx-bluesky/issues/1203 """ # noqa D415 @@ -34,6 +34,8 @@ def __init__( # See https://github.com/DiamondLightSource/mx-bluesky/issues/1203 self.dwell_time_ms = epics_signal_rw_rbv(float, f"{full_prefix}EXPOSURE_TIME") + self.status = epics_signal_r(int, f"{full_prefix}SCAN_STATUS_RBV") + self._movable_params["dwell_time_ms"] = self.dwell_time_ms def _create_expected_images_signal(self): diff --git a/src/dodal/devices/beamlines/i02_1/flux.py b/src/dodal/devices/beamlines/i02_1/flux.py new file mode 100644 index 0000000000..26ac8dde39 --- /dev/null +++ b/src/dodal/devices/beamlines/i02_1/flux.py @@ -0,0 +1,16 @@ +from ophyd_async.core import ( + StandardReadable, + StandardReadableFormat, +) +from ophyd_async.epics.core import epics_signal_r + + +class Flux(StandardReadable): + """i02-1 currently don't have a PV for the flux at the sample position. for now, XBPM3 flux is sufficient + for reading and sending the flux to ispyb during gridscans. + """ + + def __init__(self, prefix: str, name="") -> None: + with self.add_children_as_readables(StandardReadableFormat.HINTED_SIGNAL): + self.flux_reading = epics_signal_r(float, prefix + "XBPM-03") + super().__init__(name=name) diff --git a/src/dodal/devices/beamlines/i02_1/sample_motors.py b/src/dodal/devices/beamlines/i02_1/sample_motors.py index c0e49b27c1..323881fbb1 100644 --- a/src/dodal/devices/beamlines/i02_1/sample_motors.py +++ b/src/dodal/devices/beamlines/i02_1/sample_motors.py @@ -13,7 +13,8 @@ def __init__( # See https://github.com/DiamondLightSource/mx-bluesky/issues/1212 # regarding a potential motion issue with omega with self.add_children_as_readables(): - self.x = Motor(f"{prefix}X") - self.z = Motor(f"{prefix}Z") - self.omega = Motor(f"{prefix}OMEGA") + self.x = Motor(f"{prefix}SAMP-01:X") + self.z = Motor(f"{prefix}SAMP-01:Z") + self.y = Motor(f"{prefix}GONJK-01:HEIGHT") + self.omega = Motor(f"{prefix}SAMP-01:OMEGA") super().__init__(name=name)