next up previous contents index
Next: Part III: Appendices Up: Part II: Advanced Concepts Previous: 8 User Variables

9 Control Flow

 

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  using the techniques described in Chapter 7. 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.

NOTE: If you are unfamiliar with the definition and use of macros and user variables, then you should first refer to Chapters 7 and 8 before continuing with the following sections.

9.1 IF

 

An Example of How to Use the IF Command

   

To demonstrate how to use the 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  and want to draw a box  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  that uses the panel    command to select various regions on the 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 grid. Because each of the 12 panels on the display is going to have contours  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.

                     
WIP>
define contbox    # $1=counter; uses \1.

DEFINE>
set $1 $1 + 1    # Increment plane number.
DEFINE>
panel -3 -4 $1    # Select the active panel.
DEFINE>
image myimage.img $1    # Load this image plane.
DEFINE>
contour    # Draw the contour plot.
DEFINE>
box bcstz bcstz    # Draw a simple unlabeled box.
DEFINE>
set \1 ($1 - 1) % 3    # If a left panel, \1 = 0.
DEFINE>
if (\1 < 1) box 0 nvdyz    # Label the y-axis only.
DEFINE>
set \1 ($1 - 1) 3    # If a bottom panel, \1 = 0.
DEFINE>
if (\1 < 1) box ndz 0    # Label the x-axis only.
DEFINE>
...    # Perhaps more macro commands....
DEFINE>
end    # End of the macro definition.
WIP>
autolevs 10 lin 1 10    # Set up 10 contours.
WIP>
slev P 10    # Draw the contours at every 10%.
WIP>
set \0 0    # Initialize so the first is plane 1.
WIP>
contbox \0    # Draw lower left box with plane 1.
WIP>
contbox \0    # Move right and draw plane 2.
    # Call macro contbox 9 more times.
WIP>
contbox \0    # Move right and draw the final plane (12).
WIP>
...    # Maybe more WIP commands....

In the macro definition, 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

 
DEFINE>
set \1 ($1 - 1) % 3

stores in the user variable \1 the value of (). This will only evaluate to zero when the current panel is on the left edge of the composite plot. Likewise,
 
DEFINE>
set \1 ($1 - 1) 3

performs an integer divide of by 3. This will only be zero when the current panel is along the bottom of the plot.

The use of the 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 box   command is made with only the most basic options specified (see Table 3.4 for a listing of the box command options). Then, if the current frame is located on the left edge (i.e. the value of the user variable \1 is less than 1), the command box is called again but with a NULL argument for the x-axis and a numeric labeling argument for the y-axis. If the frame is not on the left edge (i.e. the value of the user variable \1 is greater than 0), then this box command is silently ignored. In the same fashion, if the current panel is along the bottom edge, then the next if command will call box to provide a numeric label for the x-axis and a NULL argument for the y-axis; otherwise the box command will be skipped.

Other Uses of the IF Command

   

The section on if in Appendix D as well as the on-line command help if    will describe the conditional operations that are acceptable as arguments to this command. They are essentially the logical operations presented in Table 8.6.

The 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 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 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 if commands together or create a macro and have the macro name as the result of the 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:

         
WIP>
if (\1 > 0) box bcnst bcnstv
WIP>
if (\1 > 0) lstyle 4
WIP>
if (\1 > 0) move x1 0
WIP>
if (\1 > 0) draw x2 0
WIP>
if (\1 > 0) lstyle 1

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.
           
WIP>
define myifbox

DEFINE>
box bcnst bcnstv
DEFINE>
lstyle 4
DEFINE>
move x1 0
DEFINE>
draw x2 0
DEFINE>
lstyle 1
DEFINE>
end
WIP>
if (\1 > 0) myifbox    # If conditional is true, execute macro.

The IF Command with Complicated Expressions

   

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:

     
DEFINE>
set \1 ($1 - 1) % 3    # If a left panel, \1 = 0.

DEFINE>
if (\1 < 1) box 0 nvdyz    # Label the y-axis only.

This can be reduced to one command as in
   
DEFINE>
if ((($1 - 1) % 3) < 1) box 0 nvdyz

Along the same line, if the macro myifbox was defined as above, but now is only to be executed when \1 > 0 and the line style is solid, then the following command will execute the macro properly:
 
WIP>
if ((\1 > 0) && (lstyle == 1)) myifbox

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.

9.2 LOOP

 

The command loop    provides the user with the ability to execute a macro  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  to be passed to the macro (see Section 7.3).

To illustrate the use of the command loop, let us refer back to the example plot file fragment illustrated in Section 9.1. 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 (\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 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:

   
WIP>
set \0 0    # Initialize so the first plane will be 1.

WIP>
loop 12 contbox \0    # Draw all 12 contour plots.
WIP>
...    # Possibly more WIP commands....

Unlike the if   command, the loop    command may only operate on a macro (i.e. a user may not execute a single command with a loop command).gif

Up until now, nothing has been said about the required argument   to the example macro contbox (defined on page gif). Recalling the first part of the definition:

     
WIP>
define contbox    # $1=counter; uses \1.

DEFINE>
set $1 $1 + 1    # Increment plane number.
DEFINE>
...    # The rest of the definition.
DEFINE>
end    # End of the macro definition.

note the form of the set command. Because the macro was called with a simple user variable,gif (\0), the set command, when expanded by the macro processor, becomes a valid WIP command. That means that the command
WIP>
contbox \0

will produce, internally, the command
 
WIP>
set \0 \0 + 1    # Increment plane number.

Every time the macro is called, this set command will increase the value of the user variable \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 return values to the macro caller. Refer to the plot files and figures in Appendix E for further examples of this technique.



next up previous contents index
Next: Part III: Appendices Up: Part II: Advanced Concepts Previous: 8 User Variables



morgan@astro.umd.edu