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", "hooked_dummyscan"]
 27
 28__docformat__ = "restructuredtext"
 29
 30from sardana.macroserver.macro import ExecMacroHook, Hookable, Macro, Type
 31
 32
 33class loop(Macro, Hookable):
 34    """A macro that executes a for loop. It accepts hooks.
 35    This macro is part of the examples package. It was written for
 36    demonstration purposes"""
 37
 38    hints = {"allowsHooks": ("pre-move", "post-move", "pre-acq", "post-acq")}
 39
 40    param_def = [
 41        ["start", Type.Integer, None, "start point"],
 42        ["stop", Type.Integer, None, "end point"],
 43        ["step", Type.Integer, 1, "step"],
 44    ]
 45
 46    def run(self, start, stop, step):
 47        self.info("Starting loop")
 48        for i in range(start, stop, step):
 49            self.output("At step %d" % i)
 50            self.flushOutput()
 51            for hook, hints in self.hooks:
 52                self.info("running hook with hints=" + repr(hints))
 53                hook()
 54        self.info("Finished loop")
 55
 56
 57class captain_hook(Macro):
 58    """A macro that executes a loop macro. A hook was attached so that in each
 59    step of the loop this hook is executed.
 60    This macro is part of the examples package. It was written for
 61    demonstration purposes"""
 62
 63    param_def = [
 64        ["start", Type.Integer, None, "start point"],
 65        ["stop", Type.Integer, None, "end point"],
 66        ["step", Type.Integer, 1, "step"],
 67    ]
 68
 69    def hook(self):
 70        self.info("\thook execution")
 71
 72    def run(self, start, stop, step):
 73        loop_macro, _ = self.createMacro("loop", start, stop, step)
 74        loop_macro.hooks = [(self.hook, ["pre-acq"])]
 75        self.runMacro(loop_macro)
 76
 77
 78class captain_hook2(Macro):
 79    """A macro that executes a loop macro. A hook was attached so that in each
 80    step of the loop this hook is executed.
 81    This macro is part of the examples package. It was written for
 82    demonstration purposes"""
 83
 84    param_def = [
 85        ["start", Type.Integer, None, "start point"],
 86        ["stop", Type.Integer, None, "end point"],
 87        ["step", Type.Integer, 1, "step"],
 88    ]
 89
 90    def hook(self):
 91        self.execMacroStr(["lsm"])
 92
 93    def run(self, start, stop, step):
 94        loop_macro, _ = self.createMacro("loop", start, stop, step)
 95        # h = self.createExecMacroHook(["lsm"])
 96        # it gives the "pre-acq" hint to the hook
 97        loop_macro.hooks = [self.hook]
 98        self.runMacro(loop_macro)
 99
100
101class hooked_scan(Macro):
102    """An example on how to attach hooks to the various hook points of a scan.
103    This macro is part of the examples package. It was written for
104    demonstration purposes"""
105
106    param_def = [
107        ["motor", Type.Moveable, None, "Motor to move"],
108        ["start_pos", Type.Float, None, "Scan start position"],
109        ["final_pos", Type.Float, None, "Scan final position"],
110        ["nr_interv", Type.Integer, None, "Number of scan intervals"],
111        ["integ_time", Type.Float, None, "Integration time"],
112    ]
113
114    def hook1(self):
115        self.info("\thook1 execution")
116
117    def hook2(self):
118        self.info("\thook2 execution")
119
120    def hook3(self):
121        self.info("\thook3 execution")
122
123    def hook4(self):
124        self.info("\thook4 execution")
125
126    def hook5(self):
127        self.info("\thook5 execution")
128
129    def hook6(self):
130        self.info("\thook6 execution")
131
132    def run(self, motor, start_pos, final_pos, nr_interv, integ_time):
133        ascan, pars = self.createMacro(
134            "ascan", motor, start_pos, final_pos, nr_interv, integ_time
135        )
136        ascan.hooks = [
137            (self.hook1, ["pre-acq"]),
138            (self.hook2, ["pre-acq", "post-acq", "pre-move", "post-move", "aaaa"]),
139            self.hook3,
140            (self.hook4, ["pre-scan"]),
141            (self.hook5, ["pre-scan", "post-scan"]),
142            (self.hook6, ["post-step"]),
143        ]
144        self.runMacro(ascan)
145
146
147class hooked_scan_with_macro(Macro):
148    """An example on how to attach macro (in this case without parameters)
149    as a hook to the various hook points of a scan.
150
151    This macro is part of the examples package. It was written for
152    demonstration purposes"""
153
154    param_def = [
155        ["motor", Type.Moveable, None, "Motor to move"],
156        ["start_pos", Type.Float, None, "Scan start position"],
157        ["final_pos", Type.Float, None, "Scan final position"],
158        ["nr_interv", Type.Integer, None, "Number of scan intervals"],
159        ["integ_time", Type.Float, None, "Integration time"],
160        ["macro", Type.Macro, None, "Macro to be used as hook"],
161        [
162            "hook_places",
163            [["hook_place", Type.String, None, "Hook place"]],
164            None,
165            "Hook places where macro will be called",
166        ],
167    ]
168
169    def run(
170        self, motor, start_pos, final_pos, nr_interv, integ_time, macro, hook_places
171    ):
172        ascan, _ = self.createMacro(
173            "ascan", motor, start_pos, final_pos, nr_interv, integ_time
174        )
175        macro_hook = ExecMacroHook(self, "umv", [["mot01", 1]])
176        ascan.hooks = [(macro_hook, hook_places)]
177        self.runMacro(ascan)
178
179
180class hooked_dummyscan(Macro):
181    """An example on how to attach hooks to the various hook points of a scan.
182    This macro is part of the examples package. It was written for
183    demonstration purposes"""
184
185    param_def = [
186        ["start_pos", Type.Float, None, "Scan start position"],
187        ["final_pos", Type.Float, None, "Scan final position"],
188        ["nr_interv", Type.Integer, None, "Number of scan intervals"],
189        ["integ_time", Type.Float, None, "Integration time"],
190    ]
191
192    def hook1(self):
193        self.info("\thook1 execution")
194
195    def hook2(self):
196        self.info("\thook2 execution")
197
198    def hook3(self):
199        self.info("\thook3 execution")
200
201    def run(self, start_pos, final_pos, nr_interv, integ_time):
202        dummyscan, pars = self.createMacro(
203            "dummyscan", start_pos, final_pos, nr_interv, integ_time
204        )
205        dummyscan.hooks = [
206            (self.hook1, ["pre-scan"]),
207            (self.hook2, ["pre-acq", "post-acq", "pre-move", "post-move", "aaaa"]),
208            (self.hook3, ["post-scan"]),
209        ]
210        self.runMacro(dummyscan)