Repeating scan points, specific scan class (XMCD)

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

2019-11-13