@@ -30,38 +30,38 @@ class Loop(Command):
3030 Set `pv1` to 1, 1.5, 2, 2.5, 3, .., 9.5, 10:
3131 >>> cmd = Loop('pv1', 1, 10, 0.5)
3232
33- Set `pv1` to 10, 9, 8, 7, .., 1:
33+ Set `pv1` to 10, 9, 8, 7, .., 1, i.e. stepping down :
3434 >>> cmd = Loop('pv1', 10, 1, -1)
3535
36- At each step of the loop, perform additional commands:
36+ At each step of the loop, perform additional commands:
3737 >>> cmd = Loop('pv1', 1, 10, 1, Set('daq', 1), Delay(10), Set('daq', 0))
3838 >>> cmd = Loop('pv1', 1, 10, 1,
3939 ... body = [ Set('daq', 1), Delay(10), Set('daq', 0) ])
4040
4141 When after loop updates `pv1`, check for its readback to match, then perform commands within the loop:
4242 >>> cmd = Loop('pv1', 1, 10, 1, Set('daq', 1), Delay(10), Set('daq', 0), readback=True)
4343
44- Special behavior of nested loops. If step size is 'wrong', the loops will cycle direction:
45- >>> cmd = Loop('x', 1, 3, 1, body=[ Loop('y', 1, 3, -1 ])
46-
47- Will result in these values:
48-
49- = =
50- x y
51- = =
52- 1 1
53- 1 2
54- 1 3
55- 2 3
56- 2 2
57- 2 1
58- 3 1
59- 3 2
60- 3 3
61- = =
44+ .. _`loop-direction`:
45+
46+
47+ For nested loops, note the special handling of the step direction.
48+ Consider a normal nested loop for 'xpos' and 'ypos' both stepping from 0 to 5 with a positive step:
49+
50+ >>> cmd = Loop('xpos', 0, 5, 1, [ Loop('ypos', 0, 5, 1 ])
51+
52+ In this example, the step size for the inner loop is 'wrong'.
53+ Going from 0 to 5 ordinarily means stepping up by +1 in each loop iteration,
54+ but the step is instead provided as -1, as if this was a loop from 5 down to 0:
55+
56+ >>> cmd = Loop('xpos', 0, 5, 1, [ Loop('ypos', 0, 5, -1 ])
57+
58+ As a result, the loop will cycle its direction between +1 and -1.
59+
60+ .. image:: scan_alternate.png
6261
6362 Note how the direction of the inner loop changes.
6463 This can be useful for scanning the X/Y surface of a sample.
64+
6565 """
6666 def __init__ (self , device , start , end , step , body = None , * args , ** kwargs ):
6767 if not isinstance (device , str ):
@@ -119,6 +119,21 @@ def setTimeout(self, timeout):
119119 """
120120 self .__timeout = timeout
121121
122+ def getBody (self ):
123+ """Obtain list of body commands.
124+
125+ The Loop(..) constructor creates a safe
126+ copy of the passed 'body' to prevent side effects
127+ when that body is later changed and maybe
128+ used to construct another Loop(..) instance.
129+
130+ If there is a desire to change the loop's body
131+ (before it's submitted to the scan server),
132+ this method provides that list of commands.
133+ :return: Loop body
134+ """
135+ return self .__body
136+
122137 def genXML (self ):
123138 xml = ET .Element ('loop' )
124139
0 commit comments