Macro hooks examples

This chapter consists of a series of examples demonstrating how to define hookable macros and how to programmatically attach hooks to macros.

  1##############################################################################
  2##
  3# This file is part of Sardana
  4##
  5# http://www.sardana-controls.org/
  6##
  7# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
  8##
  9# Sardana is free software: you can redistribute it and/or modify
 10# it under the terms of the GNU Lesser General Public License as published by
 11# the Free Software Foundation, either version 3 of the License, or
 12# (at your option) any later version.
 13##
 14# Sardana is distributed in the hope that it will be useful,
 15# but WITHOUT ANY WARRANTY; without even the implied warranty of
 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17# GNU Lesser General Public License for more details.
 18##
 19# You should have received a copy of the GNU Lesser General Public License
 20# along with Sardana.  If not, see <http://www.gnu.org/licenses/>.
 21##
 22##############################################################################
 23
 24"""This module contains macros that demonstrate the usage of hooks"""
 25
 26__all__ = ["captain_hook", "captain_hook2", "loop", "hooked_scan",
 27           "hooked_dummyscan"]
 28
 29__docformat__ = 'restructuredtext'
 30
 31from sardana.macroserver.macro import Macro, Type, Hookable, ExecMacroHook
 32
 33
 34class loop(Macro, Hookable):
 35    """A macro that executes a for loop. It accepts hooks.
 36    This macro is part of the examples package. It was written for
 37    demonstration purposes"""
 38
 39    hints = {'allowsHooks': ('pre-move', 'post-move', 'pre-acq', 'post-acq')}
 40
 41    param_def = [['start', Type.Integer, None, 'start point'],
 42                 ['stop', Type.Integer, None, 'end point'],
 43                 ['step', Type.Integer, 1, 'step']]
 44
 45    def run(self, start, stop, step):
 46        self.info("Starting loop")
 47        for i in range(start, stop, step):
 48            self.output("At step %d" % i)
 49            self.flushOutput()
 50            for hook, hints in self.hooks:
 51                self.info("running hook with hints=" + repr(hints))
 52                hook()
 53        self.info("Finished loop")
 54
 55
 56class captain_hook(Macro):
 57    """A macro that executes a loop macro. A hook was attached so that in each
 58    step of the loop this hook is executed.
 59    This macro is part of the examples package. It was written for
 60    demonstration purposes"""
 61
 62    param_def = [['start', Type.Integer, None, 'start point'],
 63                 ['stop', Type.Integer, None, 'end point'],
 64                 ['step', Type.Integer, 1, 'step']]
 65
 66    def hook(self):
 67        self.info("\thook execution")
 68
 69    def run(self, start, stop, step):
 70        loop_macro, _ = self.createMacro("loop", start, stop, step)
 71        loop_macro.hooks = [(self.hook, ["pre-acq"])]
 72        self.runMacro(loop_macro)
 73
 74
 75class captain_hook2(Macro):
 76    """A macro that executes a loop macro. A hook was attached so that in each
 77    step of the loop this hook is executed.
 78    This macro is part of the examples package. It was written for
 79    demonstration purposes"""
 80
 81    param_def = [['start', Type.Integer, None, 'start point'],
 82                 ['stop', Type.Integer, None, 'end point'],
 83                 ['step', Type.Integer, 1, 'step']]
 84
 85    def hook(self):
 86        self.execMacroStr(["lsm"])
 87
 88    def run(self, start, stop, step):
 89        loop_macro, _ = self.createMacro("loop", start, stop, step)
 90        #h = self.createExecMacroHook(["lsm"])
 91        # it gives the "pre-acq" hint to the hook
 92        loop_macro.hooks = [self.hook]
 93        self.runMacro(loop_macro)
 94
 95
 96class hooked_scan(Macro):
 97    """An example on how to attach hooks to the various hook points of a scan.
 98    This macro is part of the examples package. It was written for
 99    demonstration purposes"""
100
101    param_def = [
102        ['motor',      Type.Moveable, None, 'Motor to move'],
103        ['start_pos',  Type.Float,   None, 'Scan start position'],
104        ['final_pos',  Type.Float,   None, 'Scan final position'],
105        ['nr_interv',  Type.Integer, None, 'Number of scan intervals'],
106        ['integ_time', Type.Float,   None, 'Integration time']
107    ]
108
109    def hook1(self):
110        self.info("\thook1 execution")
111
112    def hook2(self):
113        self.info("\thook2 execution")
114
115    def hook3(self):
116        self.info("\thook3 execution")
117
118    def hook4(self):
119        self.info("\thook4 execution")
120
121    def hook5(self):
122        self.info("\thook5 execution")
123
124    def hook6(self):
125        self.info("\thook6 execution")
126
127    def run(self, motor, start_pos, final_pos, nr_interv, integ_time):
128        ascan, pars = self.createMacro(
129            "ascan", motor, start_pos, final_pos, nr_interv, integ_time)
130        ascan.hooks = [(self.hook1, ["pre-acq"]),
131                       (self.hook2, ["pre-acq", "post-acq",
132                                     "pre-move", "post-move", "aaaa"]),
133                       self.hook3,
134                       (self.hook4, ["pre-scan"]),
135                       (self.hook5, ["pre-scan", "post-scan"]),
136                       (self.hook6, ["post-step"])]
137        self.runMacro(ascan)
138
139
140class hooked_scan_with_macro(Macro):
141    """An example on how to attach macro (in this case without parameters)
142    as a hook to the various hook points of a scan.
143
144    This macro is part of the examples package. It was written for
145    demonstration purposes"""
146
147    param_def = [
148        ['motor', Type.Moveable, None, 'Motor to move'],
149        ['start_pos', Type.Float,   None, 'Scan start position'],
150        ['final_pos', Type.Float,   None, 'Scan final position'],
151        ['nr_interv', Type.Integer, None, 'Number of scan intervals'],
152        ['integ_time', Type.Float,   None, 'Integration time'],
153        ['macro', Type.Macro, None, 'Macro to be used as hook'],
154        ['hook_places', [['hook_place', Type.String, None, 'Hook place']],
155            None, 'Hook places where macro will be called']
156    ]
157
158    def run(self, motor, start_pos, final_pos, nr_interv, integ_time, macro,
159            hook_places):
160        ascan, _ = self.createMacro(
161            "ascan", motor, start_pos, final_pos, nr_interv, integ_time)
162        macro_hook = ExecMacroHook(self, "umv", [["mot01", 1]])
163        ascan.hooks = [(macro_hook, hook_places)]
164        self.runMacro(ascan)
165
166
167class hooked_dummyscan(Macro):
168    """An example on how to attach hooks to the various hook points of a scan.
169    This macro is part of the examples package. It was written for
170    demonstration purposes"""
171
172    param_def = [
173        ['start_pos',  Type.Float,   None, 'Scan start position'],
174        ['final_pos',  Type.Float,   None, 'Scan final position'],
175        ['nr_interv',  Type.Integer, None, 'Number of scan intervals'],
176        ['integ_time', Type.Float,   None, 'Integration time']
177    ]
178
179    def hook1(self):
180        self.info("\thook1 execution")
181
182    def hook2(self):
183        self.info("\thook2 execution")
184
185    def hook3(self):
186        self.info("\thook3 execution")
187
188    def run(self, start_pos, final_pos, nr_interv, integ_time):
189        dummyscan, pars = self.createMacro(
190            "dummyscan", start_pos, final_pos, nr_interv, integ_time)
191        dummyscan.hooks = [(self.hook1, ["pre-scan"]), (self.hook2, ["pre-acq",
192                                                                     "post-acq", "pre-move", "post-move", "aaaa"]), (self.hook3, ["post-scan"])]
193        self.runMacro(dummyscan)