From 94ebfd7001974703ad708f1308d754c5bfd9c805 Mon Sep 17 00:00:00 2001 From: appleb_m Date: Fri, 6 Feb 2026 15:59:27 +0100 Subject: [PATCH] DAQ: smargon, added aerotech functionality --- src/aare/devices/smargon.py | 63 +++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/src/aare/devices/smargon.py b/src/aare/devices/smargon.py index 80361e08..adb99f4c 100644 --- a/src/aare/devices/smargon.py +++ b/src/aare/devices/smargon.py @@ -4,7 +4,7 @@ from time import sleep, time import requests from aare.common.beamline import MXBeamline -from aare.common.coordinate import SmargonCoordinate, Coordinate +from aare.common.coordinate import SmargonCoordinate, Coordinate, AerotechCoordinate class SmargonMode(Enum): @@ -18,6 +18,7 @@ class Smargon(object): SMARGON_HOME = SmargonCoordinate( sh_mm=Coordinate(x=0, y=0, z=18), phi_deg=0, chi_deg=0 ) + AERO_HOME = AerotechCoordinate(x=18, y=0, z=0, omega=0) def __init__(self, bl: MXBeamline): if bl == MXBeamline.X06DA: @@ -29,6 +30,7 @@ class Smargon(object): elif bl == MXBeamline.SIMULATED: self.__simulated = True self.__pos = self.SMARGON_HOME + self.__pos_aero = self.AERO_HOME else: raise Exception("unknown beamline") @@ -94,12 +96,21 @@ class Smargon(object): chi_deg=scs["CHI"], ) + @property + def readback_aerotech(self) -> AerotechCoordinate: + if self.__simulated: + return self.__pos_aero + + acs = self.gonget("readbackAEROTECH") + return AerotechCoordinate(at_mm = Coordinate(x=acs["GMX"], y = acs["GMY"], z = acs["GMZ"]), + omega_deg = acs["GMU"]) + @property def target(self) -> SmargonCoordinate: if self.__simulated: return self.__pos - scs = self.gonget("targetSCS") + scs = self.gonget("targetSCS") #targetAEROTECH, #targetOMEGA return SmargonCoordinate( sh_mm=Coordinate(x=scs["SHX"], y=scs["SHY"], z=scs["SHZ"]), phi_deg=scs["PHI"], @@ -124,6 +135,32 @@ class Smargon(object): if target_string: self.gonput(f"targetSCS?{target_string}") + @property + def target_aerotech(self) -> AerotechCoordinate: + if self.__simulated: + return self.__pos_aero + + acs = self.gonget("targetAEROTECH") #targetAEROTECH, #targetOMEGA + return AerotechCoordinate(at_mm = Coordinate(x=acs["GMX"], y = acs["GMY"], z = acs["GMZ"]), + omega_deg = acs["GMU"]) + + @target_aerotech.setter + def target_aerotech(self, coord: AerotechCoordinate): + if self.__simulated: + self.__pos_aero = coord + return + + target_string = "" + if coord.at_mm is not None: + target_string += "&GMX={:.5f}&GMY={:.5f}&GMZ={:.5f}".format( + coord.at_mm.x, coord.at_mm.y, coord.at_mm.z + ) + if coord.omega_deg is not None: + target_string += "&GMU={:.5f}".format(coord.omega_deg) + if target_string: + self.gonput(f"targetAEROTECH?{target_string}") + + def wait(self, timeout=60.0, tol=0.01, poll_time=0.01): target = self.target timeout = timeout + time() @@ -133,3 +170,25 @@ class Smargon(object): if time() > timeout: raise TimeoutError("Timed out waiting for Smargon to reach target") sleep(poll_time) + + def wait_aerotech(self, timeout=60.0, tol=0.01, poll_time=0.01): + target = self.target + timeout = timeout + time() + while time() < timeout: + if self.target_aerotech.eq(self.readback_aerotech, tol): + break + if time() > timeout: + raise TimeoutError("Timed out waiting for Aerotech to reach target") + sleep(poll_time) + + +if __name__ == "__main__": + smargon = Smargon(MXBeamline.X10SA) + x = smargon.readback_aerotech + print(x) + y = smargon.target_aerotech + smargon.target_aerotech = AerotechCoordinate(at_mm=Coordinate(x=18, y=0, z=0)) + print(y) + smargon.wait_aerotech() + print(f"aerotech reached {smargon.readback_aerotech}") +