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).