next up previous contents
Next: Answers to Frequently Asked Up: Processing Flows with SU Previous: A typical SU processing   Contents

Extending SU by shell programming

Shell programming can be used to greatly extend the reach of SU without writing C code. See, for example, CvStack, FilterTest, FirstBreak, and Velan in su/examples.

It is a sad fact that the UNIX shell is not a high level programming language--consequently, effective shell coding often involves arcane tricks. In this section, we'll provide some useful templates for some of the common UNIX shell programming idioms.

We use CvStack as an illustration. The core of this shell is a double loop over velocities and cdps that produces velocity panels--a concept not contained in any single SU program.

Remark: For most of us, writing a shell like CvStack from scratch is a time-consuming affair. To cut down the development time, your authors excerpt from existing shells to make new ones even when we don't quite remember what every detail means. We suggest that you do the same!

We won't comment on the lines already explained in our previous two shell code examples (see Sections 8.2.1 and 8.2.3), but instead focus on the new features used in CvStack.

#! /bin/sh
# Constant-velocity stack of a range of cmp gathers
# Authors: Jack, Ken
# NOTE: Comment lines preceding user input start with  #!#
set -x

#!# Set input/output file names and data parameters
cdpmin=601 cdpmax=610
space=1         # 1 null trace between panels

#!# Determine velocity sampling.
vmin=1500   vmax=3000   dv=150

### Determine ns and dt from data (for sunull)
nt=`sugethw ns <$input | sed 1q | sed 's/.*ns=//'`                [1]
dt=`sugethw dt <$input | sed 1q | sed 's/.*dt=//'`

### Convert dt to seconds from header value in microseconds
dt=`bc -l <<END                                                   [2]
        $dt / 1000000

### Do the velocity analyses.
>$stackdata  # zero output file                                   [3]
while [ $v -le $vmax ]                                            [4]
        while [ $cdp -le $cdpmax ]                                [5]
                suwind <$input \                                  [6]
                        key=cdp min=$cdp max=$cdp count=$fold |
                sunmo cdp=$cdp vnmo=$v tnmo=0.0 |
                sustack >>$stackdata
                cdp=`bc -l <<END                                  [7]                               
                        $cdp + 1
        sunull ntr=$space nt=$nt dt=$dt >>$stackdata              [8]
        v=`bc -l <<END
                $v + $dv

### Plot the common velocity stacked data
ncdp=`bc -l <<END
d2=`bc -l <<END
        $dv/($ncdp + $space)                                      [9]

sugain <$stackdata tpow=2.0 |

suximage perc=99 f2=$f2 d2=$d2 \
        title="File: $input  Constant-Velocity Stack " \
        label1="Time (s)"  label2="Velocity (m/s)" & 

exit                                                              [10]
Discussion of numbered lines:

  1. This elaborate construction gets some information from the first trace header of the data set. The program sugethw lists the values of the specified keys in the successive traces. For example,
    % suplane | sugethw tracl ns
     tracl=1            ns=64       
     tracl=2            ns=64       
     tracl=3            ns=64       
     tracl=4            ns=64       
     tracl=5            ns=64       
     tracl=6            ns=64    
    Although sugethw is eager to give the values for every trace in the data set, we only need it once. The solution is to use the UNIX stream editor (sed). In fact, we use it twice. By default, sed passes along its input to its output. Our first use is merely to tell sed to quit after it puts the first line in the pipe. The second pass through sed strips off the unwanted material before the integer. In detail, the second sed command reads: replace (or substitute) everything up to the characters ns= with nothing, i.e., delete those characters.

  2. We are proud of this trick. The Bourne shell does not provide floating point arithmetic. Where this is needed, we use the UNIX built-in bc calculator program with the ``here document'' facility. Here, we make the commonly needed conversion of sampling interval which is given in micro-seconds in the SEG-Y header, but as seconds in SU codes. Note carefully the backquotes around the entire calculation--we assign the result of this calculation to the shell variable on the left of the equal sign, here dt. The calculation may take several lines. We first set the number of decimal places with scale=4 and then do the conversion to seconds. The characters END that follow the here document redirection symbol << are arbitrary, the shell takes its input from the text in the shell file until it comes to a line that contains the same characters again. For more information about bc:
    % man bc

  3. As the comment indicates, this is a special use of the output redirection symbol that has the effect of destroying any pre-existing file of the same name or opening a new file with that name. In fact, this is what > always does as its first action--it's a dangerous operator! If you intend to append, then, as mentioned earlier, use >>.

  4. This is the outer loop over velocities. Another warning about spaces--the spaces around the bracket symbols are essential.

    Caveat: The bracket notation is a nice alternative to the older clunky test notation:

    while test $v -le $vmax
    Because the bracket notation is not documented on the typical sh manual page, we have some qualms about using it. But, as far as we know, all modern sh commands support it--please let us know if you find one that doesn't.

    WARNING! OK, now you know that there is a UNIX command called test. So don't use the name ``test'' for one of your shell (or C) programs--depending on your $PATH setting, you could be faced with seemingly inexplicable output.

  5. This is the inner loop over cdps.

  6. Reminder: No spaces or tabs after the line continuation symbol!

  7. Notice that we broke the nice indentation structure by putting the final END against the left margin. That's because the sh manual page says that the termination should contain only the END (or whatever you use). In fact, most versions support indentation. We didn't think the added beautification was worth the risk in a shell meant for export. Also note that we used bc for an integer arithmetic calculation even though integer arithmetic is built into the Bourne shell--why learn two arcane rituals, when one will do? See man expr, if you are curious.

    Figure: Output of the CvStack shell program.
    \begin{figure}\epsfysize 300pt

  8. sunull is a program I (Jack) wrote to create all-zero traces to enhance displays of the sort produced by CvStack. Actually, I had written this program many times, but this was the first time I did it on purpose. (Yes, that was an attempt at humor.)

  9. An arcane calculation to get velocity labeling on the trace axis. Very impressive! I wonder what it means? (See last item.)

  10. The exit statement is useful because you might want to save some ``spare parts'' for future use. If so, just put them after the exit statement and they won't be executed.

Figure 8.2 shows an output generated by CvStack.

next up previous contents
Next: Answers to Frequently Asked Up: Processing Flows with SU Previous: A typical SU processing   Contents
John Stockwell 2007-04-10