From 38bee8c5c7806ca32db360ad6c38b25b602f8553 Mon Sep 17 00:00:00 2001 From: "gac-x01da (Resp. Clark Adam Hugh)" Date: Wed, 11 Sep 2024 13:27:35 +0200 Subject: [PATCH] Changed advanced scan to be used with energy inputs (not angle) --- debye_bec/devices/mo1_bragg.py | 52 ++++++++++++++++++----------- debye_bec/scans/mono_bragg_scans.py | 28 ++++++++-------- 2 files changed, 47 insertions(+), 33 deletions(-) diff --git a/debye_bec/devices/mo1_bragg.py b/debye_bec/devices/mo1_bragg.py index a882428..2ae766e 100644 --- a/debye_bec/devices/mo1_bragg.py +++ b/debye_bec/devices/mo1_bragg.py @@ -226,8 +226,8 @@ class ScanParameter: cycle_high: int = None start: float = None stop: float = None - t_kink: float = None p_kink: float = None + e_kink: float = None class Mo1Bragg(Device, PositionerBase): @@ -528,34 +528,51 @@ class Mo1Bragg(Device, PositionerBase): self.scan_settings.s_scan_angle_hi.put(high) self.scan_settings.s_scan_scantime.put(scan_time) - def set_advanced_xas_settings(self, low: float, high:float, scan_time: float, t_kink: float, p_kink: float) -> None: + def set_advanced_xas_settings(self, low: float, high:float, scan_time: float, p_kink: float, e_kink: float) -> None: """Set Advanced XAS parameters for upcoming scan. low (float): Low angle value of the scan in deg high (float): High angle value of the scan in deg scan_time (float): Time for a half oscillation in s - t_kink (float): Time of kink in s - p_kink (float): Position of kink in deg + p_kink (float): Position of kink in % + e_kink (float): Energy of kink in eV Args: """ - offset = low - range = high - low # total range (peak-peak) + ## TODO Change to energy only, calculation done on ACS controller + ## ACS requires energy as input, outputs angle + ## + reset bit signal, + calc done bit signal + ## In the meantime, misuse s_scan_angle/energy PVs + move_type = self.move_type.get() + if move_type == MoveType.ENERGY: + self.scan_settings.s_scan_energy_lo.put(e_kink) + time.sleep(1) + e_kink_deg = self.scan_settings.s_scan_angle_hi.get() + self.scan_settings.s_scan_energy_lo.put(low) + self.scan_settings.s_scan_energy_hi.put(high) + time.sleep(1) + low_deg = self.scan_settings.s_scan_angle_lo.get() + high_deg = self.scan_settings.s_scan_angle_hi.get() sf = 0.025 # safety factor to limit acceleration -> NEVER SET TO ZERO ! n = 41 # number of samples to generate -> Always choose uneven number, otherwise peak value will not be included degree = 3 # degree of spline, 3 works good tc = 0.0062 # time to be compensated each spline in s + pc = 0.02 # angle to add at both limits, must be same values as used on ACS controller for simple scans - if t_kink > scan_time / 2 - sf: - raise Exception("Kink time of {0:0.3f} s too big, must be < {1:0.3f} s".format(t_kink, scan_time / 2 - sf)) + # increase motion range slightly so that xas trigger signals will occur at defined energy limits + low_deg = low_deg - pc + high_deg = high_deg + pc - if p_kink > range: - raise Exception("Kink position of {0:0.3f}° deg too big, must be < {1:0.3f}° deg".format(p_kink, range)) + if p_kink < 0 or p_kink > 100: + raise Exception("Kink position not within range of [0..100%]") + + if e_kink_deg < low_deg or e_kink_deg > high_deg: + raise Exception("Kink energy not within selected energy range of scan") tc1 = sf / scan_time * tc - tc2 = t_kink / scan_time * tc + t_kink = (scan_time - tc - 2*(sf - tc1)) * p_kink/100 + (sf - tc1) - t_input = [0, sf - tc1, t_kink - tc2, scan_time - sf - tc1, scan_time - tc] - p_input = [0, 0 , p_kink , range , range ] + t_input = [0, sf - tc1, t_kink , scan_time - tc - sf + tc1, scan_time - tc ] + p_input = [0, 0 , e_kink_deg - low_deg , high_deg - low_deg , high_deg - low_deg] cv = np.stack((t_input, p_input)).T # spline coefficients max_param = len(cv) - degree @@ -567,7 +584,7 @@ class Mo1Bragg(Device, PositionerBase): j = spl(np.linspace(0,max_param,n), 3) tim, pos = p.T - pos = pos + offset + pos = pos + low_deg vel = v[:,1]/v[:,0] acc = [] @@ -588,9 +605,6 @@ class Mo1Bragg(Device, PositionerBase): self.scan_settings.a_scan_vel.put(vel) self.scan_settings.a_scan_time.put(dt) - - - def set_xrd_settings( self, enable_low: bool, @@ -755,8 +769,8 @@ class Mo1Bragg(Device, PositionerBase): low=self.scan_parameter.start, high=self.scan_parameter.stop, scan_time=self.scan_parameter.scan_time, - t_kink=self.scan_parameter.t_kink, p_kink=self.scan_parameter.p_kink, + e_kink=self.scan_parameter.e_kink, ) self.set_xrd_settings( enable_low=False, @@ -776,8 +790,8 @@ class Mo1Bragg(Device, PositionerBase): low=self.scan_parameter.start, high=self.scan_parameter.stop, scan_time=self.scan_parameter.scan_time, - t_kink=self.scan_parameter.t_kink, p_kink=self.scan_parameter.p_kink, + e_kink=self.scan_parameter.e_kink, ) self.set_xrd_settings( enable_low=self.scan_parameter.xrd_enable_low, diff --git a/debye_bec/scans/mono_bragg_scans.py b/debye_bec/scans/mono_bragg_scans.py index d0947d6..0ae9384 100644 --- a/debye_bec/scans/mono_bragg_scans.py +++ b/debye_bec/scans/mono_bragg_scans.py @@ -173,7 +173,7 @@ class XASAdvancedScan(XASSimpleScan): gui_config = { "Movement Parameters": ["start", "stop"], "Scan Parameters": ["scan_time", "scan_duration"], - "Spline Parameters": ["t_kink", "p_kink"], + "Spline Parameters": ["p_kink", "e_kink"], } def __init__( @@ -182,27 +182,27 @@ class XASAdvancedScan(XASSimpleScan): stop: float, scan_time: float, scan_duration: float, - t_kink: float, p_kink: float, + e_kink: float, motor: DeviceBase = "mo1_bragg", **kwargs, ): """The xas_advanced_scan is an oscillation motion on the mono motor. Start and Stop define the energy range for the scan, scan_time is the time for one scan cycle and scan_duration is the duration of the scan. If scan duration is set to 0, the scan will run infinitely. - t_kink and p_kink add a kink to the motion profile to slow down in the exafs region of the scan. + p_kink and e_kink add a kink to the motion profile to slow down in the exafs region of the scan. Args: start (float): Start angle for the scan. stop (float): Stop angle for the scan. scan_time (float): Time for one oscillation . scan_duration (float): Total duration of the scan. - t_kink (float): Time of the kink. p_kink (float): Position of the kink. + e_kink (float): Energy of the kink. motor (DeviceBase, optional): Motor device to be used for the scan. Defaults to "mo1_bragg". Examples: - >>> scans.xas_advanced_scan(start=9, stop=11, scan_time=0.5, scan_duration=10, t_kink=0.15, p_kink=1) + >>> scans.xas_advanced_scan(start=9, stop=11, scan_time=0.5, scan_duration=10, p_kink=0.15, e_kink=1) """ super().__init__( start=start, @@ -212,8 +212,8 @@ class XASAdvancedScan(XASSimpleScan): motor=motor, **kwargs, ) - self.t_kink = t_kink self.p_kink = p_kink + self.e_kink = e_kink class XASAdvancedScanWithXRD(XASAdvancedScan): @@ -221,7 +221,7 @@ class XASAdvancedScanWithXRD(XASAdvancedScan): gui_config = { "Movement Parameters": ["start", "stop"], "Scan Parameters": ["scan_time", "scan_duration"], - "Spline Parameters": ["t_kink", "p_kink"], + "Spline Parameters": ["p_kink", "e_kink"], "Low Energy Range": ["xrd_enable_low", "num_trigger_low", "exp_time_low", "cycle_low"], "High Energy Range": ["xrd_enable_high", "num_trigger_high", "exp_time_high", "cycle_high"], } @@ -232,8 +232,8 @@ class XASAdvancedScanWithXRD(XASAdvancedScan): stop: float, scan_time: float, scan_duration: float, - t_kink: float, p_kink: float, + e_kink: float, xrd_enable_low: bool, num_trigger_low: int, exp_time_low: float, @@ -249,15 +249,15 @@ class XASAdvancedScanWithXRD(XASAdvancedScan): with XRD triggering at low and high energy ranges. Start and Stop define the energy range for the scan, scan_time is the time for one scan cycle and scan_duration is the duration of the scan. If scan duration is set to 0, the scan will run infinitely. - t_kink and p_kink add a kink to the motion profile to slow down in the exafs region of the scan. + p_kink and e_kink add a kink to the motion profile to slow down in the exafs region of the scan. Args: start (float): Start angle for the scan. stop (float): Stop angle for the scan. scan_time (float): Time for one oscillation . scan_duration (float): Total duration of the scan. - t_kink (float): Time of the kink. - p_kink (float): Position of the kink. + p_kink (float): Position of kink. + e_kink (float): Energy of the kink. xrd_enable_low (bool): Enable XRD triggering for the low energy range. num_trigger_low (int): Number of triggers for the low energy range. exp_time_low (float): Exposure time for the low energy range. @@ -269,20 +269,20 @@ class XASAdvancedScanWithXRD(XASAdvancedScan): motor (DeviceBase, optional): Motor device to be used for the scan. Defaults to "mo1_bragg". Examples: - >>> scans.xas_advanced_scan_with_xrd(start=9, stop=11, scan_time=0.5, scan_duration=10, t_kink=0.15, p_kink=1, xrd_enable_low=True, num_trigger_low=5, cycle_low=2, exp_time_low=100, xrd_enable_high=False, num_trigger_high=3, cycle_high=1, exp_time_high=1000) + >>> scans.xas_advanced_scan_with_xrd(start=9, stop=11, scan_time=0.5, scan_duration=10, p_kink=0.15, e_kink=1, xrd_enable_low=True, num_trigger_low=5, cycle_low=2, exp_time_low=100, xrd_enable_high=False, num_trigger_high=3, cycle_high=1, exp_time_high=1000) """ super().__init__( start=start, stop=stop, scan_time=scan_time, scan_duration=scan_duration, - t_kink=t_kink, p_kink=p_kink, + e_kink=e_kink, motor=motor, **kwargs, ) - self.t_kink = t_kink self.p_kink = p_kink + self.e_kink = e_kink self.xrd_enable_low = xrd_enable_low self.num_trigger_low = num_trigger_low self.exp_time_low = exp_time_low