This section describes how to run a scan repeating the measurement at each point a given number of times. The user can define what should be done before any measurement is performed.
The general macro for repeating points is called:
ascan_repeat
and is available at each beamline.
The arguments of this macro are the same as for ascan except the last one, which indicates the number of times should be measured at each point. Ex.
p09/door/haso111tb [68]: %ascan_repeat exp_mot01 1 10 5 1 2 ScanDir is not defined. This operation will not be stored persistently. Use Use "expconf" (or "senv ScanDir <abs directory>") to enable it Scan #12 started at Thu Mar 5 09:59:25 2015. It will take at least 0:02:23.294805 Moving to start positions... #Pt No exp_mot01 exp_t01 Position dt 0 1 1 1 1.1593 1 1 1 1 3.43973 2 3 1 3 5.93795 3 3 1 3 8.43999 4 5 1 5 10.9357 5 5 1 5 13.4416 6 6 1 6 15.9429 7 6 1 6 18.4389 8 8 1 8 20.9424 9 8 1 8 23.4402 10 10 1 10 25.9409 11 10 1 10 28.441 Scan #12 ended at Thu Mar 5 09:59:55 2015, taking 0:00:29.792336.Dead time 59.7% (motion dead time 46.1%)
where each point is repeated twice.
The actions to be performed between the measurements at each point have to be defined in a hook of the ascan_repeat macro. A template macro showing hos to implement this, ascan_repeat_example, is provided with the rest of the macros, and can be found in the file scan_repeatpoints_user.py in the macros directory.
""" Macro library containning user macros using the scan_repeat macro. Available Macros are: ascan_repeat_example """ __all__ = ["ascan_repeat_example"] __docformat__ = 'restructuredtext' import os import copy import datetime import numpy from sardana.macroserver.msexception import UnknownEnv from sardana.macroserver.macro import * from sardana.macroserver.scan import * from sardana.util.motion import Motor, MotionPath rep_counter = 0 class HookPars: pass def hook_pre_acq(self, hook_pars): global rep_counter self.output(str(rep_counter)) # Implement actions depending on the rep_counter value: 0 -> first time of this position, 1 -> second time ... For example, for an action that depends on rep_counter being odd oder even: if rep_counter % 2 == 0: self.output("switch magnet to 'North'") else: self.output("switch magnet to 'South'") if rep_counter < (hook_pars.nb_repeat - 1): rep_counter = rep_counter + 1 else: rep_counter = 0 class ascan_repeat_example(Macro): param_def = [ ['motor', Type.Moveable, None, 'Moveable to move'], ['start_pos', Type.Float, None, 'Scan start position'], ['final_pos', Type.Float, None, 'Scan final position'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'], ['nb_repeat', Type.Integer, None, 'Number of repetitions per point'] ] def run(self, motor, start_pos, final_pos, nr_interv, integ_time, nb_repeat): macro, pars = self.createMacro('ascan_repeat', motor, start_pos, final_pos, nr_interv, integ_time, nb_repeat) # parameters for scan hook function hook_pars = HookPars() hook_pars.nb_repeat = nb_repeat f = lambda : hook_pre_acq(self, hook_pars) macro.hooks = [ (f, ["pre-acq"]), ] self.runMacro(macro)
In the function hook_pre_acq the users can define any action, based on the
number of the repeatition is needed (variable rep_counter).