1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
|
%% This file is to be included by latex in wip.tex
%
% Chapter: Control flow
%
\mylabel{c:flow}
\myfile{flow.tex}
This chapter describes methods of how to control the execution of plot
commands.
Most \wip\ commands are called once and, generally, only when the user
needs them.
If a command or group of commands are going to be called several times
the user usually creates a macro\index{Macros} using the techniques
described in Chapter~\ref{c:macros}.
If a macro or command needs to be executed a number of times or only
under certain conditions,
then tools are needed to enable the user to do this.
The following sections describe these advanced tools and provide
examples of their use.
{\sc Note}:
If you are unfamiliar with the definition and use of macros and user
variables,
then you should first refer to
Chapters~\ref{c:macros} and \ref{c:uservar}
before continuing with the following sections.
\section{IF}
\mylabel{s:if}
\subsubsection* {An Example of How to Use the IF Command}
\mylabel{sss:howtouseif}
\index{Commands!{\tt if}}
To demonstrate how to use the
{\tt if}\index{Commands!{\tt if}}\index{Macros!commands!{\tt if}}
command,
let's create a plot
where the use of the command would be the only logical way to solve the problem.
Suppose we want to draw several plots on one
view surface\index{View Surface} and want to draw a
box\index{Boxes} around each plot but only have the left most and
bottom most boxes labeled with numbers along with the tick marks.
Since we are going to draw essentially the same plot in each box,
the easy solution will be to define a macro\index{Macros} that
uses the {\tt panel}\index{Commands!{\tt panel}}%
\index{Coordinate System!commands!{\tt panel}} command
to select various regions on the view surface\index{View Surface}
and then only label select panels when drawing the box.
To make this example a bit more realistic,
suppose we have an image cube that contains 12 planes and they are to be
plotted on a $3\times4$ grid.
Because each of the 12 panels on the display is going to have
contours\index{Contour Plots} drawn in them,
it would probably be desired to have as much space available for
each plot window as possible.
Hence, it will be best to have no space between neighboring panels.
Also, remember we will
only (numerically) identify the tick marks on the left most and bottom
most panels; the other panels will be bordered and have unlabeled
tick marks.
The following fragment shows the macro definition and the commands
used to perform this task.
\begin{wiplist}%
\mylabel{e:contbox}
\index{Commands!{\tt define}}
\index{Commands!{\tt set}}
\index{Commands!{\tt panel}}
\index{Commands!{\tt image}}
\index{Commands!{\tt contour}}
\index{Commands!{\tt box}}
\index{Commands!{\tt if}}
\index{Commands!{\tt end}}
\index{Commands!{\tt autolevs}}
\index{Commands!{\tt slev}}
\item [\wipp] {\tt define contbox}\hfill\# \$1=counter; uses \esc{1}.
\samepage
\item [\wipd] {\tt set \$1 \$1 + 1}\hfill\# Increment plane number.
\item [\wipd] {\tt panel -3 -4 \$1}\hfill\# Select the active panel.
\item [\wipd] {\tt image myimage.img \$1}\hfill\# Load this image plane.
\item [\wipd] {\tt contour}\hfill\# Draw the contour plot.
\item [\wipd] {\tt box bcstz bcstz}\hfill\# Draw a simple unlabeled box.
\item [\wipd] {\tt set \esc{1} (\$1 - 1) \% 3}\hfill\# If a left panel,
\esc{1} = 0.
\item [\wipd] {\tt if (\esc{1} < 1) box 0 nvdyz}\hfill\# Label the
$y$-axis only.
\item [\wipd] {\tt set \esc{1} (\$1 - 1) \esc{\,} 3}\hfill\# If a bottom
panel, \esc{1} = 0.
\item [\wipd] {\tt if (\esc{1} < 1) box ndz 0}\hfill\# Label the
$x$-axis only.
\item [\wipd] \ldots\hfill\# Perhaps more macro commands\ldots.
\item [\wipd] {\tt end}\hfill\# End of the macro definition.
\item [\wipp] {\tt autolevs 10 lin 1 10}\hfill\# Set up 10 contours.
\item [\wipp] {\tt slev P 10}\hfill\# Draw the contours at every 10\%.
\item [\wipp] {\tt set \esc{0} 0}\hfill\# Initialize so the first is plane 1.
\item [\wipp] {\tt contbox \esc{0}}\hfill\# Draw lower left box with plane 1.
\item [\wipp] {\tt contbox \esc{0}}\hfill\# Move right and draw plane 2.
\item [$\vdots$] \ \hfill\# Call macro {\tt contbox} 9 more times.
\item [\wipp] {\tt contbox \esc{0}}\hfill\# Move right and draw
the final plane (12).
\item [\wipp] \ldots\hfill\# Maybe more \wip\ commands\ldots.
\end{wiplist}
In the macro definition, user variables\index{User Variables} are used
to keep track of the current plane number and the current panel frame.
Furthermore, this index is used to determine whether or not the current
frame is located along the bottom or the left side of the composite picture.
The line
\begin{wiplist}%
\index{Commands!{\tt set}}
\item [\wipd] {\tt set \esc{1} (\$1 - 1) \% 3}
\end{wiplist}
stores in the user variable \esc{1} the value of ($(plane - 1) \bmod 3$).
This will only evaluate to zero when the current panel is on the
left edge of the composite plot.
Likewise,
\begin{wiplist}%
\index{Commands!{\tt set}}
\item [\wipd] {\tt set \esc{1} (\$1 - 1) \esc{\,} 3}
\end{wiplist}
performs an integer divide of $(plane - 1)$ by 3.
This will only be zero when the current panel is along the bottom of the plot.
The use of the {\tt if} command should now become more apparent.
Prior to testing whether the current panel is on either the left or
bottom edges, a call to the
{\tt box}\index{Commands!{\tt box}}\index{Boxes!commands!{\tt box}}
command is made with only the most basic options specified
(see Table~\ref{t:box} for a listing of the {\tt box} command options).
Then, if the current frame is located on the left edge
(\ie the value of the user variable \esc{1} is less than 1),
the command {\tt box} is called again but with a {\sc Null} argument for
the $x$-axis and a numeric labeling argument for the $y$-axis.
If the frame is not on the left edge
(\ie the value of the user variable \esc{1} is greater than 0),
then this {\tt box} command is silently ignored.
In the same fashion, if the current panel is along the bottom edge, then
the next {\tt if} command will call {\tt box} to provide a numeric
label for the $x$-axis and a {\sc Null} argument for the $y$-axis;
otherwise the {\tt box} command will be skipped.
\subsubsection* {Other Uses of the IF Command}
\mylabel{sss:moreif}
\index{Commands!{\tt if}}
The section on {\tt if} in Appendix~\ref{a:cmdname} as well as the
on-line command
{\tt help if}\index{Help!commands!{\tt help}}%
\index{Help!commands!{\tt if}}
will describe the conditional operations that are acceptable as
arguments to this command.
They are essentially the logical operations presented in
Table~\ref{t:twoop}.
The {\tt if} command can also permit the user
to leave a macro before the last command defined in it is reached.
For example, if a macro is drawing points on a plot and the user only
wants certain symbol types to be drawn, then an {\tt if} command could
allow the user to exit the macro (gracefully) before reaching the undesired
plot commands.
Another example might be to check for boundary limits before executing
further steps in a macro.
It should be noted that the {\tt if} conditional will only apply to the
command or macro that follows on the same line.
Furthermore, only one command or macro
may be present on a single line.
To have one conditional result in several commands being executed either
chain several {\tt if} commands together or create a macro and have the
macro name as the result of the {\tt if} command.
For example, if the user had a situation where there were only certain
conditions that a labeled box should be drawn along with a dotted line
at $y = 0$, then the user could use
the following group of commands:
\begin{wiplist}%
\index{Commands!{\tt if}}
\index{Commands!{\tt box}}
\index{Commands!{\tt lstyle}}
\index{Commands!{\tt move}}
\index{Commands!{\tt draw}}
\item {\tt if (\esc{1} > 0) box bcnst bcnstv}
\item {\tt if (\esc{1} > 0) lstyle 4}
\item {\tt if (\esc{1} > 0) move x1 0}
\item {\tt if (\esc{1} > 0) draw x2 0}
\item {\tt if (\esc{1} > 0) lstyle 1}
\end{wiplist}
Writing the conditional commands this way is useful
only if the conditional commands are used once
or if the number of conditional commands are few.
The next listing will produce the same results as the example before
except that a macro is used.
This listing is not much more compact than the previous example but
would be far easier to enhance and maintain than the previous example.
In addition, it groups all the commands that are affected by the
conditional command in one place.
\begin{wiplist}%
\index{Commands!{\tt define}}
\index{Commands!{\tt box}}
\index{Commands!{\tt lstyle}}
\index{Commands!{\tt move}}
\index{Commands!{\tt draw}}
\index{Commands!{\tt if}}
\item [\wipp] {\tt define myifbox}
\samepage
\item [\wipd] {\tt box bcnst bcnstv}
\item [\wipd] {\tt lstyle 4}
\item [\wipd] {\tt move x1 0}
\item [\wipd] {\tt draw x2 0}
\item [\wipd] {\tt lstyle 1}
\item [\wipd] {\tt end}
\item [{$\vdots$}]
\item [\wipp] {\tt if (\esc{1} > 0) myifbox}\hfill\# If conditional is true,
execute macro.
\end{wiplist}
\subsubsection* {The IF Command with Complicated Expressions}
\mylabel{sss:hardif}
\index{Commands!{\tt if}}
All of the above examples have shown only one argument on each side of
the conditional operation.
Also, only one conditional operation was present.
The entire conditional expression, however, can be made arbitrarily complex.
For example, in the example that started this section, a test was made to
determine if the current panel was on the left edge and if so, draw a
labeled box.
The two commands used to perform this action were:
\begin{wiplist}%
\index{Commands!{\tt set}}
\index{Commands!{\tt if}}
\index{Commands!{\tt box}}
\item [\wipd] {\tt set \esc{1} (\$1 - 1) \% 3}\hfill\# If a left panel,
\esc{1} = 0.
\samepage
\item [\wipd] {\tt if (\esc{1} < 1) box 0 nvdyz}\hfill\# Label the
$y$-axis only.
\end{wiplist}
This can be reduced to one command as in
\begin{wiplist}%
\index{Commands!{\tt if}}
\index{Commands!{\tt box}}
\item [\wipd] {\tt if (((\$1 - 1) \% 3) < 1) box 0 nvdyz}
\end{wiplist}
Along the same line, if the macro {\tt myifbox} was defined as above, but
now is only to be executed when {\tt \esc{1} > 0} {\em and}
the line style is solid,
then the following command will execute the macro
properly:
\begin{wiplist}%
\index{Commands!{\tt if}}
\item [\wipp] {\tt if ((\esc{1} > 0) \&\& (lstyle == 1)) myifbox}
\end{wiplist}
However, as these commands become more complex, they may be more
difficult to understand the meaning or intent and also are more
difficult to track down when errors appear.
\section{LOOP}
\mylabel{s:loop}
The command
{\tt loop}\index{Commands!{\tt loop}}%
\index{Macros!commands!{\tt loop}}
provides the user with the ability to execute a macro\index{Macros}
several times with only one call.
This command has two required arguments:
(1) the number of times the named macro should be executed, and
(2) the macro to execute.
Any other parameters present with the command are considered as
arguments\index{Macros!passing arguments}
to be passed to the macro (see Section~\ref{s:macarguments}).
To illustrate the use of the command {\tt loop}, let us refer
back to the example plot file fragment illustrated in Section~\ref{s:if}.
To review, a macro was defined which will display several
contour plots on one plot labeling only the left and bottom most panels.
After the macro was defined, the image counter (\esc{0}) was initialized
such that the first plane (and first panel) was correctly set when the
macro was called.
Next, the macro was called twelve (12) times and then some other
\wip\ plotting commands were possibly issued.
Instead of calling the macro twelve times,
the command {\tt loop} might have been used to perform the same function.
Hence, the commands that appear after the macro definition
in that example may be replaced with the \wip\ commands shown
in the following code fragment:
\begin{wiplist}%
\index{Commands!{\tt set}}
\index{Commands!{\tt loop}}
\item [\wipp] {\tt set \esc{0} 0}\hfill\# Initialize so the first
plane will be 1.
\samepage
\item [\wipp] {\tt loop 12 contbox \esc{0}}\hfill\# Draw all 12 contour plots.
\item [\wipp] \ldots\hfill\# Possibly more \wip\ commands\ldots.
\end{wiplist}
Unlike
the {\tt if}\index{Commands!{\tt if}}\index{Macros!commands!{\tt if}}
command,
the {\tt loop}\index{Commands!{\tt loop}}%
\index{Macros!commands!{\tt loop}}
command may only operate on a macro
(\ie a user may not execute a single command with a {\tt loop}
command).\footnote{A very simple solution to this would be to define a
macro with only the one command needed and then use {\tt loop} to
execute it repetitively.}
Up until now, nothing has been said about the required
argument\index{Macros!passing arguments}\index{Macros!iterative counters}
to the example macro {\tt contbox} (defined on page~\pageref{e:contbox}).
Recalling the first part of the definition:
\begin{wiplist}%
\index{Commands!{\tt define}}
\index{Commands!{\tt set}}
\index{Commands!{\tt end}}
\item [\wipp] {\tt define contbox}\hfill\# \$1=counter; uses \esc{1}.
\samepage
\item [\wipd] {\tt set \$1 \$1 + 1}\hfill\# Increment plane number.
\item [\wipd] \ldots\hfill\# The rest of the definition.
\item [\wipd] {\tt end}\hfill\# End of the macro definition.
\end{wiplist}
note the form of the {\tt set} command.
Because the macro was called with
a simple user variable,\footnote{Note that calling this macro with
a vector, string variable, or function
is an error and will cause the macro to abort.}
(\esc{0}), the {\tt set} command, when expanded by the macro processor,
becomes a valid \wip\ command.
That means that the command
\begin{wiplist}%
\item {\tt contbox \esc{0}}
\end{wiplist}
will produce, internally, the command
\begin{wiplist}%
\index{Commands!{\tt set}}
\item {\tt set \esc{0} \esc{0} + 1}\hfill\# Increment plane number.
\end{wiplist}
Every time the macro is called, this {\tt set} command
will increase the value of the user variable \esc{0} by 1.
This technique permits macro users to iterate with the same macro but with
different counters.
This also, in essence, provides a way to
{\em return} values to the macro caller.
Refer to the plot files and figures in Appendix~\ref{a:samples}
for further examples of this technique.
|