Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
➲ Quick Start 5
➲ Overview of a ProMAX Process 6
➲ Creating your own Directory Hierarchy 7
➲ Writing a Menu 8
➲ Installing the Menu 9
➲ Overriding the Default ProMAX Files 10
➲ Writing a ProMAX Program 12
➲ Viewing Online Documentation 13
➲ Writing Helpfiles 14
➲ Self-guided Tutorial 15
➲ Support Documentation 17
➲ System Overview 19
➲ Your Development Directory 20
➲ Tool Anatomy 21
➲ Programming Exercises: Simple Tools (amp_ratio) 22
➲ amp_ratio Exercise 1: Adding Trace Headers 23
➲ Menus 24
➲ Global Parameters 24
➲ amp_ratio Exercise 2: ordered parameter files 24
➲ amp_ratio Exercise 3: time gates and tables 25
➲ Debugging 26
➲ C Programming Environment 27
➲ Tool Types 28
➲ Programming Exercise: Ensemble Tools (AVO) 29
➲ Programming Exercise: Panel Tools 31
➲ Programming Exercise: Input Tools 32
➲ Programming Exercise: IPC Tools 33
➲ System Overview 35
➲ ProMAX Organization: Areas, Lines, and Flows 36
➲ The User Interface: The Flow Builder 38
➲ Menu Files 39
➲ Flow Execution 40
➲ Super Executive 40
➲ Executive 41
➲ Executive 53
➲ System Architecture 54
➲ Headers and Global Variables 55
➲ Input Tools 56
➲ Re-entrancy 57
➲ Common Blocks and Parms Structures 58
➲ Executive Functions 60
➲ Communication between Tools 61
➲ OPF Database 62
➲ Make System 63
➲ Working with ProMAX Systems 64
➲ Getting Started 65
➲ System Administrator Setup 65
➲ User Setup 66
➲ Converting to the New System 71
➲ Understanding the Directory Structure 72
➲ $PROMAX_HOME/port/include/make/ 72
➲ $PROMAX_HOME/port/bin/ 75
➲ $PROMAX_HOME/sys/bin/ 76
➲ $PROMAX_HOME/port/src/exe/exec/ 77
➲ Customizing the System 78
➲ Toggling Products: .promax 79
➲ Adding a New Tool 83
➲ Making Your New Executable 86
➲ Incorporating New Functionality 89
➲ Creating Menus 90
➲ Adding a ProMAX Menu 91
➲ Changing Files 93
➲ Understanding the Makefile System 96
➲ C++ Template Instantiation 96
➲ Terms and Variable Descriptions 96
➲ Makefile Techniques 118
➲ C Environment 137
➲ Menus 251
➲ Overview of ProMAX Menus and Landmark Lisp 252
➲ Parts of a ProMAX menu 253
➲ Menu Heading 254
➲ Parameter Specifications 254
➲ exec_data 256
➲ Rules 257
➲ Tips on Writing Menus 260
➲ Use Examples 260
➲ Keep it Simple 260
➲ Usable Lisp Functions 261
➲ Lisp Primitives 261
➲ Access & Assignment Functions 264
➲ ProMAX Lisp Extentions 266
➲ Parameter Menu System 268
➲ Parameter Keywords 269
➲ Parameter Types and Attributes 269
➲ Including Other Menus 280
➲ Rules and Context Sensitivity 280
➲ pwin 290
➲ Example Macro: Display Shots with AGC 292
➲ Helpfiles 297
➲ How Helpfiles Are Accessed 298
➲ FrameMaker-formatted Helpfiles 299
➲ sine_wave.inc 472
➲ sine_wave.f 473
➲ sineWave.c 479
➲ Index 685
ProMAX Developer’s
Programming Guide
Introduction
Organization
We divided this manual into chapters and sections that discuss
the key processes of the ProMAX system. In general, this
consists of:
Documentation Conventions
We use the following documentation conventions in this
manual:
Example
Quick Start
• the menu
• the program
• the helpfile
The menu is the window that the User Interface pops up to let a
user enter parameters for your program. The program is the
code that actually runs. The helpfile hopefully tells people how
to use your process without them having to call you too much.
There are two types of inline flow tools: IPC tools and executive
tools. IPC tools used to be called socket tools. This Quick Start
chapter will only show you how to write an IPC tool. This is an
approach which we recommend for many applications,
especially if you are just getting started. Developing IPC tools
is significantly quicker and simpler than developing non-IPC
tools, at little performance cost. If you are an expert—for
example, if you have taken a ProMAX programming course—
you may decide to write inline flow tools using executive tools.
Writing a Menu
Once you have written a menu that you are happy with, you
have to install it in the ProMAX list of menus that appears in the
User Interface. We recommend that you copy the file
$PROMAX_HOME/port/menu/promax/Processes to
~/$PROMAX_HOME/port/menu/promax/Processes, which is
the 2D list of menus. The 3D list lives in
$PROMAX_HOME/port/menu/promax3d. Now add your menu
to the appropriate category. It should be straight forward how to
do this by looking at the file. Be sure you do not use the .menu
suffix.
You need to tell the User Interface where to find your personal
ProMAX files: your new Processes file, menu, executable, and
helpfile. Edit or create a .promax file in your home directory to
look like this (replace your home directory for /mnt/stof):
(quote
((:product
; This is a comment
("P" "2D ProMAX"
".:/mnt/stof/promax/1998.6/linux/exe"\
; executables
"/mnt/stof/promax/1998.6/port/menu/promax:\
promax" ; menus
"/mnt/stof/promax/1998.6/port/menu/promax
/Processes" ; Processes file
"promax:/mnt/stof/promax/1998.6/port/help\
/promax" ; helpfiles
"" ; miscellaneous files (use default)
"" ; data area (use default)
t)
("3" "3D ProMAX"
".:/mnt/stof/promax/1998.6/linux/exe"
"/mnt/stof/promax/1998.6/port/menu/promax3d:\
promax3d"
"/mnt/stof/promax/1998.6/port/menu/promax3d\
/Processes"
"promax3d"
""
""
t)
))
)
you must use promax. Thus, this search path above looks first in
your home directory, and then in the master location.
/usr/bin/make
which should compile and link the sample code. The executable
produced by this make will reside in
~/$PROMAX_HOME/linux/exe. For more information on the
Make System, refer Make System chapter. For more description
on IPC tools or stand-alone programs, see the Tool Types
chapter.
$PROMAX_HOME/port/bin/aman tblToMatrix
aman c_promax
or
aman fortran_promax
Writing Helpfiles
Self-guided Tutorial
To use this tutorial, simply read through each section and follow
the reading and programming exercise assignments. The
specific reading and exercise assignments are highlighted as
follows:
➱ Now do this.
Before you get started, please note that this chapter refers to the
environmental variable $PROMAX_HOME, which is the path
name of the directory under which ProMAX is installed. Ask
your system administrator for help in setting up your ProMAX
environment if he or she has not already done so.
Support Documentation
aman tblCopy
from the command line of the computer. Your path must include
$PROMAX_HOME/port/bin.
aman -k tbl
aman c_promax
aman fortran_promax
System Overview
Tool Anatomy
➱ Read the Executive Tools section of the Tool Types chapter. You do
not need to read beyond this section, since the remainder of the
chapter will be assigned later in the tutorial.
This assigned reading section provides an overview of the
structure of most ProMAX processes, including the processes in
the programming exercises in this tutorial.
➱ Next you will need to copy the menu files into your personal menu
directory. To do this, go to your own menu directory by typing:
cd ~/$PROMAX_HOME/port/menu/promax
cp $PROMAX_HOME/port/src/lib/maxtool/amp_ratio/*.menu .
➱ Set the permissions so that you can edit the files by typing:
chmod 644 *.menu
Menus
A ProMAX menu is a file which controls how menu parameters
appear to the user.
cp $PROMAX_HOME/port/menu/EXAMPLE.menu .
Global Parameters
There are many numerical variables that are related to a dataset,
such as the number of samples per trace and the number of trace
headers that exist for each trace. ProMAX has a global include
file that you can access to easily get this information.
➱ Read the Parameter Tables chapter. You can find additional informa-
tion can be found in a chapter with the same name in the ProMAX
Reference Manual.
➱ Edit amp_ratio3.f or ampRatio3.c; use ProMAX parameter tables to
limit the time window for which the first break is searched. Edit the
menu to allow the option to use the time gates and to get the time
gates from the database.
Debugging
C Programming Environment
Tool Types
➱ Read the Tool Types chapter. Pay particular attention to the respon-
sibilities that each tool has in both the init and exec subroutines,
such as setting global variables and trace header values that the
trace executive uses.
Intercept of
LSF Line
Amplitude
Sample amplitude
at an offset
Offset
A single data trace is output for each CDP gather that is input to
the routine. The sample value at time T on an output trace is
either the slope or the zero-offset intercept of the least squares
curve shown in the figure above. A menu parameter allows the
user to select either slope or intercept as the output.
Note that the tool type is panel. This is because ensemble tools
have the same calling arguments as panel tools and are inserted
in the same part of the toolcall.f file.
Recall from the Tool Types chapter that panel tools are used to
process 2D arrays of traces that are too large to fit into memory
at one time. The 2D array is processed in pieces and then
blended back together by the trace executive. The next
programming example is a panel tool in which a 2D panel of
traces is given to the exec subroutine. The exec subroutine sets
the value of each sample in the input array to a constant value;
for example, all sample values are set to 2.0. The sample values
of the next panel input are set to a value that is 1.0 more than the
previous panel. The input from the menu controls how large a
panel will be and how many edge traces will be blended with
adjacent panels. This lets you experiment with panel parameters
and see the result on the screen. When using Screen Display or
Trace Display to see the data, use the Entire Screen option for
scaling the data traces so that the differences in trace amplitudes
can be seen.
➱ Go to your maxtool directory and copy the panel directory from the
main system maxtool directory via the following commands:
cd ~/$PROMAX_HOME/port/src/lib/maxtool
cp -r $PROMAX_HOME/port/src/lib/maxtool/panel .
$PROMAX_HOME/port/src/lib/maxtool/sine_wave
➱ Copy the sine_wave directory to your own maxtool directory (see the
previous examples on how to copy a directory). Edit sine_wave1.f or
sineWave1.c and fill in the missing code where the comments indi-
cate code needs to be added.
The entry in the tools_to_add file looks like this:
name = c_socket
➱ Make the IPC tool by simply typing gmake in the directory where
Makefile resides. Run the program by putting an entry in the Pro-
cesses file for the path to the menu.
You can see another example of an IPC tool in
$PROMAX_HOME/port/src/exe/ampRatio for C programmers,
or in $PROMAX_HOME/port/src/exe/amp_ratio for
FORTRAN programmers. These examples show the amp_ratio
program in the form of IPC tools. The Makefiles and menus are
included and can be compiled and used in a processing flow.
System Overview
Menu Files
Flow Execution
Super Executive
The preceeding shell command launches the Super Executive,
or superExec for short. The flow builder executes this Super
Executive shell immediately, unless the job was submitted to a
queue. The Super Executive supplies the command line with the
path to the packet file and the name of the host on which the
flow builder is running. The Super Executive is, in a sense,
similar to the flow builder—it is restricted in purpose and has no
notion of geophysics built into it. It is responsible for seeing
that the intended processing actually happens so the flow
builder can go off and do something else, like build another
flow.
Executive
The preceeding command launches the Executive, or exec for
short. The Executive supplies the command line with the path to
the packet file, the name of the host on which the flow builder is
running, and the process ID of the Super Executive. If the
processing flow contains stand-alone or other special tools, the
correct path to the process which was specified in the menu file
is substituted for exec.exe. The full path to the process can vary
with release and may also be controlled by the user via the
Alternate Executive directive.
You will see the terms exec and Executive used frequently in
this document. They are often used interchangeably, but we will
restrict the term exec to refer literally to the program named
exec.exe, and the term Executive to refer to the body of
software that surrounds the actual processing tools and handles
the flow of data within the pipeline.
Each processing tool that is linked into the Executive must have
two parts: an initialization routine and an execution routine. The
initialization routine checks the input parameters for validity,
sets global parameters (if appropriate), creates header entries,
allocates memory, and other miscellaneous tasks that must be
performed before traces can be processed. The execution
routine is ideally a narrow-minded routine that simply processes
the traces and headers. Both routines are surrounded by the
Executive, which does everything it can to make life easy for
the initialization and execution routines.
/exe
exec.exe /sdi
superExec /(3rd party )
*.exe
/lib
libxxxxx.so
/menu
promax
promax3d
promaxvsp
/misc
*.rgb (colormaps)
ProMAX defaults
/etc
config_file
product
pvmhosts
qconfig
PROMAX_DATA_HOME
17968042TVEL /flow1
317490267TGAT DescName (ASCII)
22783694TFBP TypeName (ASCII)
Parameter Tables 36247238TMUT job.output (ASCII)
packet.job (Binary)
job.output (Binary)
/flow2
Flow
/OPF.CDP (CDP)
#s0_OPF_CDP.GEOMETRY.C_S
#s0_OPF_CDP.GEOMETRY.ELE
/OPF.CHN (Channel)
Ordered Parameter OPF60_CHN
Files database OPF60_CHN.GEOMETRY.FOLD
OPF60_CHN.GEOMETRY.SLOOKUP
/OPF.ILN (Inline-3D)
/OPF.LIN (Line)
/OPF.OFB
/OPF.PAT (Pattern)
/OPF.SIN (Source)
/OPF.SRF (Surface Station)
/OPF.TRC (Trace)
/OPF.XLN (Crossline)
/OPF.XLN (Crossline-3D)
Traces Trace
Headers
Misc.
Map
Dataset Components
Line Trace
Units FB Pick
X Ref Offset
Y Ref Static
Lo Cut etc.
Hi Cut
Total # of CDP’s
etc. Surface Location
Fold
Source X Coord
Y Coord
X Coord Static
Y Coord Datum Vel
Chans etc.
Uphole
Static
Elevation
etc. Channel
Static
CDP Amplitude Com
etc.
Fold
X Coord
Y Coord Offset
Elev
Nearest SRF Bin Center
Elev Static Mean Offset
etc. etc.
Velocities Etc....
Parameter Tables
Flow
Directory
Flow Components
Job Builder
(promax.exe)
Batch
Queue
Super Executive
(superExec)
Stand-alone Executive
Programs (exec.exe)
NMO Filter
Line Database
Information
(datasets, parameter tables, Packet File
ordered database files, etc.)
System Overview
Line: YYYYYY
Flow: ZZZZZZ
Window
Overlay
Seismic Datasets Parameter Tables
Flow Builder
Input
Data
FK Filter
Gain
Running Mix
Mute
Stack
NMO
Output
Data
Processing Pipeline
Executive
System Architecture
Input Tools
Re-entrancy
Not only do you need to use the SAVE1z and END1z variables,
you also need to get the size of your saved parameters
computed, and this is accomplished at the end of your
initialization phase. Here is an example:
C ..... Set the number of words that need to be saved for re-entrancy.
C ..... Note that CALC_LENSAV is a macro that uses END1z and SAVE1z
C ..... to calculate the common block length
LEN_SAV = CALC_LENSAV
BEGINPARMS
int ngate, use_gate, ih_ratio_max, ih_ratio_time, load_hdr, load_db,
ih_pkey, ih_skey, iformat_pkey, iformat_skey;
float *scratch;
void *gate_tbl;
void *db_trc, *dbPtr1,*dbPtr2;
ENDPARMS(parms)
.
.
.
/* Set the number of words that need to be saved for re-entrancy. */
Executive Functions
OPF Database
Make System
Getting Started
atopdir := /Landmark/ProMAX/2003.12.1
utopdir := $(HOME)/Landmark/ProMAX/2003.12.1
• linux
• linux64
Automount Users
If your development directories tend to be automounted, the
makefile system sometimes has difficulty in determining what
atopdir really is. It figures this out via the lines:
atopdir := /promax/2003.12.1
User Setup
The following sections describe the User setup.
export PATH=”$PATH:/promax/2003.12.1/sys/bin:\
/promax/2003.12.1/port/bin)”
csh/tcsh users:
ksh/sh/zsh users:
alias gmake='/usr/bin/make \
-I$PROMAX_HOME/port/include/make'
alias Makeexec='$PROMAX_HOME/port/bin/Makeexec \
-I$PROMAX_HOME/port/include/make'
When you run Makeexec for the first time, the Makefile in your
utopdir/port/src/exe/exec directory finds the Makefile in your
utopdir/port/src/lib/maxtool, cd’s to that directory, and does a
gmake. Because you do not have a libmaxtoolc.so library in
your utopdir tree, the Makefile in utopdir/port/src/lib/maxtool
will create this library for you. Unless you have a large number
of customized new tools to build, this will complete reasonably
quickly.
First-time compilation
Unlike the Master version of
$PROMAX_HOME/port/src/lib/maxtool/, your User version
does not (yet) contain any source code. Therefore, the Makefile
first builds libmaxtoolc.so with any new tools you have defined
in utopdir/port/src/lib/maxtool/ or, if none are yet defined,
simply uses the ProMAX installation stub library
libmaxtoolc.so. After your own libmaxtoolc.so library has
been built, your toolcall.f or toolcall.c will be created and
compiled to create your personal version of libtoolcall.so and
your exec.exe will be generated. The toolcall is created by the
script $PROMAX_HOME/port/bin/buildtoolcall. This script looks
at the file $PROMAX_HOME/port/src/exe/exec/tools.db, then
deletes any entries found in
utopdir/port/src/exe/exec/tools_to_delete, then adds any tools
found in utopdir/port/src/exe/exec/tools_to_add.
Nth-time compilation
You can run Makeexec from anywhere within your
utopdir/port/src/ hierarchy. In particular, you can run it inside
your utopdir/port/src/lib/maxtool/xxx/ directory, where you
have just finished modifying the source code for your latest and
greatest new tool.
For new exec tools, you must specify the source files for each
new tool in the newsrcs variable in your
utopdir/port/src/maxtool/Makefile.
• $PROMAX_HOME/port/include/make/
• $PROMAX_HOME/port/bin/
• $PROMAX_HOME/sys/bin/
• $PROMAX_HOME/port/src/exe/exec
$PROMAX_HOME/port/include/make/
This directory contains the makefile header files which are used
to set up for various possible configurations. It also contains
sample makefiles for a library or stand-alone executables. The
following table summarizes these files.
$PROMAX_HOME/port/include/make/ Files
File Description
master.make This is the file which is responsible for setting up the basic variable structures
representing the client’s directory structure. This file can be included instead
of advance.make if all you need from your makefile include are variables
containing paths to advance things. In this respect, it serves as a lightweight
header include.
advance.make This header file includes master.make and sets up anything which is constant
among all platforms such as Canned Command Sequences. It also includes
$machtype.make to import its platform dependent information.
$machtype.make This represents the header file containing the platform dependent information
such as preprocessing, compiling, and link commands. As this varies
dramatically from system to system, Landmark provides some reasonable
defaults. Even so, clients installing ProMAX will probably need to modify
this file to reflect their particular system setup. Some examples are linux.make
and linux64.make.
simple.make A simple makefile used to compile one or more executables into the current
directory.
libmaxtool.example An example user makefile for the maxtoolc library. This file is used by
Makeadvance to create a user environment.
Makefile_example_* Sample makefiles for creating new modules under the bin, exe, and lib user
port/src development subdirectories.
Example: simple.make
This makefile example uses simple.make to compile into the
current directory.
1. cd $HOME
2. mkdir simpletest
3. cd simpletest
c_() {printf(“c()\n”);}
PROGRAM D
CALL D
END
Example: compile.test
This makefile example uses compile.test.
1. cd $HOME
2. mkdir compiletest
3. cd compiletest
$PROMAX_HOME/port/bin/
This directory contains portable scripts which can be run from
the command line. The following table summarizes these
scripts.
$PROMAX_HOME/port/bin/ Files
Script Description
Auto_test A script which automates quality control testing on various platforms.
makewhatis A script which is used to make the whatis/windex for man pages. Must be
executed from the man directory.
checkin2 A script which is used to check in a previously checked out Landmark sccs file.
pvmcleanup A script which kills and cleans up after stray pvm daemons.
pvmdbx.sh A script which is invoked by an xterm by the generic debugger script. It starts
the debugger and waits when it exits to prevent the window from closing.
Makelink A script which is used to create a link from a file in a user’s directory to the
corresponding file in the $PROMAX_HOME directory.
$PROMAX_HOME/sys/bin/
This directory contains non-portable binary commands which
can be run from the command line. The following table
describes these scripts.
$PROMAX_HOME/sys/bin/ Files
Script Description
amakedepend Landmark’s version of makedepend. Generates dependencies for use with the
Makefile system.
ctar A program similar to UNIX tar except that it understands the notion of
secondary storage. It uses the advance tape catalog optionally.
ll Lisp listener. A lisp interpreter implementing Landmark’s lisp. Useful for rule
writers wanting to check syntax.
nmapmgr NQS tool for building and maintaining the machine ID database.
nqs_promax The ProMAX accounting daemon which may also be used as an alternative to
rsh (if rsh is not available).
pixmap A program used to build pixmaps. Useful if you are using the agX libraries.
tamsh A tcl/motif interpreter/shell. This allows the creation of tcl scripts which contain
motif widgets. This is a powerful homegrown version based upon Jan
Newmarch’s TclMotif.
tcat A program used to manage the tape catalog system.
$PROMAX_HOME/port/src/exe/exec/
The directory contains the executive’s makefile as well as
listings of base tools, tools to add, and tools to delete. The
following table summarizes this directory’s contents.
$PROMAX_HOME/port/src/exe/exec/ Files
Item Description
Makefile The makefile for the executive.
tools.db A base listing of inline tools which will be incorporated into the executive.
tools_to_add A listing of inline tools to add to the executive. Users may, and should, have a
personalized version of this file.
tools_to_delete A listing of inline tools to delete from the executive. Users may streamline their
personal version of the executive with this file.
Note that the rules are the same regardless of whether the file is
an ordinary file or a directory (even though intuition might
suggest that the environmental variable should end in _PATH
for ordinary files, instead of _HOME). Some of the important
ProMAX environmental variables are:
• PROMAX_HOME
• PROMAX_DATA_HOME
• PROMAX_PORT_MENU_HOME
• PROMAX_PORT_MENU_PROCESSES_HOME
• PROMAX_SYS_EXE_HOME
• PROMAX_ETC_CONFIG_FILE_HOME
• PROMAX_QUEUES_HOME
• PROMAX_ETC_PVMHOSTS_HOME
• PROMAX_SCRATCH_HOME
• PROMAX_SCRATCHX1_HOME
• PROMAX_SCRATCHX2_HOME
• ...
Parts of the system can also be customized via the .promax file
in the user’s home directory. This method allows customization
by product and facilitates toggling between products without
exiting the Flow Builder. The Flow Builder will build a .promax
file in your home directory the first time you exit the User
Interface.
For the programmer, the .promax file is the best way to control
the development environment. A search path mechanism—for
executables, menus, and help files—directs the flow builder to
use the files in your personal directories before searching in the
standard installation or other directories. In this way, you can
maintain your own parallel ProMAX system. To override the
standard paths, the ~/.promax file must contain a stanza of the
following form:
(:product
("P" "ProMAX 2D" "entry3" "entry4" "entry5" "entry6" \
"entry7" "entry8" "entry9" t)
("3" "ProMAX 3D" "entry3" "entry4" "entry5" "entry6" \
"entry7" "entry8" "entry9" t)
("4" "ProMAX 4D" "entry3" "entry4" "entry5" "entry6" \
"entry7" "entry8" "entry9" t) )
"~/[$PROMAX_HOME]/linux/exe/:[$PROMAX_HOME]/linux/exe"
This entry will cause a search of your exe directory for exec.exe
(or other executables) and the system exe directory next. For
this specific case you could use:
"~/[$PROMAX_HOME]/linux/exe/:."
"~/[$PROMAX_HOME]/‘[$PROMAX_HOME]/port/bin/Machtype‘/exe
:."
which allows the return of the machine type (linux64or linux) into
the stanza so that you do not need to worry about which
machine you are working on; therefore, the correct executable
will be used.
"~/[$PROMAX_HOME]/port/menu/promax/:\
[$PROMAX_HOME]/port/menu/promax"
or
"~/[$PROMAX_HOME]/port/menu/promax/:promax"
"~/[$PROMAX_HOME]/port/menu/promax/Processes:\
promax/Processes"
"~/[$PROMAX_HOME]/port/help/promax/:promax"
This entry will cause a search of your help directory for custom
helps and the system help directory next.
Standard:
(:product ("P" "ProMAX" "" "promax" "promax/Processes"\
"promax" "" "" "" t)
("v" "ProMAXVSP" "" "promaxvsp" "promaxvsp/Processes"\
"promaxvsp" "" "" "" t) )
Custom:
% cd ~/$PROMAX_HOME/port/src/lib/maxtool
% mkdir amp_ratio (creates a subdirectory for
new 'amp_ratio' tool)
% cd amp_ratio
% cp $PROMAX_HOME/port/src/lib/maxtool\
/amp_ratio/amp_ratio1.f .
% cp $PROMAX_HOME/port/src/lib/maxtool/amp_ratio\
/amp_ratio1.inc .
% cd ~/$PROMAX_HOME/port/menu/promax
% cp $PROMAX_HOME/port/src/lib/maxtool/amp_ratio\
/amp_ratio1.menu .
% cd ~/$PROMAX_HOME/port/src/lib/maxtool
% [edit] Makefile
newsrcs :=amp_ratio/amp_ratio1.f
(Path is relative to Makefile subdirectory)
[exit editor, saving Makefile]
% cd ~/$PROMAX_HOME/port/src/exe/exec
% more tools.db (Toolcall database. Just look,
don’t touch.)
% [edit] tools_to_add
AMP_RATIO same simple internal
[save file]
% cd ~/$PROMAX_HOME/port/src
% Makeexec (Builds toolcall.f. Compiles it)
or
% cd ~/$PROMAX_HOME/port/menu/promax
% cp $PROMAX_HOME/port/menu/promax/Processes .
% [edit] Processes
% [edit] ~/$PROMAX_HOME/port/src/lib/maxtool\
/amp_ratio/amp_ratio1.f
% Makeexec
[Try it out in ProMAX]
After you add new functionality, you must be sure that you can
make the exec. The following AMP_RATIO example
demonstrates the steps to complete to accomplish this:
% cd ~/$PROMAX_HOME/port/src/lib/maxtool
% mkdir amp_ratio
% cd amp_ratio
% cp $PROMAX_HOME/port/src/lib/maxtool/amp_ratio\
/amp_ratio1.f .
% cp $PROMAX_HOME/port/src/lib/maxtool/amp_ratio\
/amp_ratio1.inc .
% chmod +rw *
% [edit] ~/$PROMAX_HOME/port/src/exe/exec/\
tools_to_add
Note that the source code file name, amp_ratio1.f, and the
subroutine name, amp_ratio, may be different. Be sure the
name listed in the tools_to_add file truly reflects the name
of the init and exec phases.
% [edit] ~/$PROMAX_HOME/port/src/lib/maxtool/\
Makefile
Search for newsrcs and add another line listing the new
.f file so that the file looks like this (do not forget the
backslash continuation mark):
newsrcs := \
amp_ratio/amp_ratio1.f
or:
% cd ~/$PROMAX_HOME/port/src/exe/exec
% gmake [language=C](build and compile toolcall.f or .c)
The Details
The following things happened when you typed Makeexec:
2. ~/$PROMAX_HOME/port/src/exe/exec/Makefile
included the master version of this Makefile to be executed.
This ensures that your local Makefile always reflects the
changes made to the master version
$PROMAX_HOME/port/src/exe/exec/Makefile.
3. $PROMAX_HOME/port/src/exe/exec/Makefile decides
that this is a User make. It checks the following directories
• ~/$PROMAX_HOME/port/src/lib/maxtool
• ~/$PROMAX_HOME/port/src/lib/maxutil
• ~/$PROMAX_HOME/port/src/lib/maxexec
• ~/$PROMAX_HOME/port/src/lib/uiutils
• ~/$PROMAX_HOME/port/src/lib/agfc
The flow builder reads and interprets the menu files at runtime
(they are not compiled). However, before the flow builder can
know what menu files to read, it must read a list of available
menus in what is known as the Processes file. The Processes
file is product specific and is located in
$PROMAX_HOME/port/menu/[product]/. You will need a
custom copy of the Processes file in order to reference your new
tools without altering the production system and to avoid
interfering with other developers.
Creating Menus
% $PROMAX_HOME/sys/bin/promenu testtool.menu
% cd
% cp $PROMAX_HOME/port/menu/promax/Processes\
~/$PROMAX_HOME/port/menu/promax/Processes
% chmod +w ~/$PROMAX_HOME/port/menu/promax/Processes
% [edit] ~/advance/port/menu/promax/Processes
You must also add a directive in your flow to alert the flow
builder to use your new exec.exe instead of the standard,
production version. This can be done by adding the tool
“Alternate Executive” anywhere in the flow.
Parameterization is simply entering an explicit path to
exec.exe, typically:
~/promax/2003.12.1/[linux,sgi,or...]/exe/exec.exe
Changing Files
Several things must be done each time a new tool is added to the
ProMAX system. The following illustrations show files within
the ProMAX directory tree that need to be changed when a new
tool is added. The files that are changed frequently during the
development of a new tool are circled with a solid line; files that
are changed infrequently are circled with a dotted line. Other
files are shown, but if they are not circled you do not change
them. For example, the source code for an inline tool is found in
the directory path:
~/$PROMAX_HOME/port/src/lib/maxtool/your_tool
Processes
your_menu.menu
exe *.exe
linux
lib system libraries (libmaxtool*.so)
.c, .f
. promax src exe your_stand_alone
port
menu
~/ $PROMAX_ Makefile
HOME promax
Processes
your_menu.menu
exe * .exe
linuxklk
lib system libraries (libmaxutill*.so)
Terms
Term Description
Canned Command A canned command sequence can be thought of as a predefined set of
Sequence commands. It is actually a recursively expanded variable which can span many
lines. As a result, automatic variables such as $@, $^ and so forth, expand to fit
the context in which they are used. For the sake of brevity, Canned Command
Sequences will be refered to as CCR’s throughout this document.
Rule A set of targets, dependencies and commands which describe how to create the
target(s). The make will look up and evaluate the rules for each of the
dependencies before evaluating the commands which the target(s) depend(s) on.
For a more detailed explanation of this, please refer to the GNU Make document
by Richard M. Stallman and Roland McGrath.
Example:
foo : bar1.o bar2.o
$(CC) $^ -o $@
Terms (Continued)
Term Description
Variable A location in memory which contains information which may be used by rules,
CCS’s or other variables. In general, the use of variables will increase the
porability of your makefiles. Variables may be set from the command line via
calls to the make utility. For example: ‘gmake var1:=foo var2=var‘ Refer to the
GNU Make document for further information.
Boolean Variable A variable which may contain the string “yes” or “no”. It is used to figure out
exactly how the user wants certain things to be made.
Command Variable A variable which contains a command. An example might be $(AR) which
might be /bin/ar on one platform and /usr/bin/ar on another. $(AR) can be thus
be used without regard to what platform the make is being run on.
Library Variable A variable which contains the path to a library. The path may vary depending on
the context of the make.
CCS Rule Variable A canned command sequence which assumes that it is called in a rule. As a
result, it may assume that certain automatic variable which are set in rules, are
set. (Ex: $@, $^, $(<D) etc...).
Example:
target : dependencies...
$(CCS_RULE_VARIABLE)
CCS Function A canned command sequence which returns a value. It may also assume that
Variable certain values were set prior to calling the CCS Function Variable. These can be
thought of as the function arguments. For example:
function_results :=\ $(CCS_FUNCTION_VARIABLE)
Recursively A variable which is assigned via “=”. Any variable references contained within it
Expanded Variable are defined later. A recursively expanded variable can not be defined in terms of
itself.
Example: The Makefile
foo := foo
foobar = $(foo) $(bar)
bar := bar
all :
@echo “FOOBAR: $(foobar)
Terms (Continued)
Term Description
Simply Expanded A variable whose assignment is performed at the time the assignment is found. It
Variable can be defined in terms of itself.
Example: The Makefile:
foo := foo
foobar1 := $(foo) $(bar)
bar := bar
foobar2 := $(foo) $(bar)
all :
@echo “FOOBAR1: $(foobar1)”
@echo “FOOBAR2: $(foobar2)”
Command Line Variables are by default, command line overridable. This means that when a
Overridable Variable variable is set from the command line, it takes the command line value and
ignores the makefile’s attempts to initialize or augment it. Unless stated
otherwise, it can be assumed that any given variable is command line
overridable.
Example: The Makefile:
# var is a simply expanded command line
# overwritable variable.
var := $(var) “Makefile Value”
all:
@echo “VAR: $(var)”
Command Line A variable which will be augmented instead of overridden when set from the
Augmentable command line.
Variable Example:
# var is a simply expanded, command line
# augmentable variable.
override var := $(var) “Makefile Value”
all:
@echo “VAR: $(var)”
Conventions
The following list describes Makefile conventions.
[KRC|C|F|CXX|AMD|Y|LEX]foo
we can assume:
Variable Prefixes
Prefix Meaning
This says:
Variables
The following table describes the important makefile variables.
Makefile Variables
Variable Type Explanation
debug Boolean Variable. When set to yes, debug mode is
turned on.
[a|m|]srcdir Directory Variable. The top level directory for all the
$path/port/src/. portable source code.
libagfc Library Variable. $path\ The library containing the old cwp
/sys/lib/libagfc.a. routines used by the various
modules in the system.
define_ugincs
AMAKEDEPEND CCS Rule Variable. A CCS which will figure out what
the header file dependencies are
and output them to a file defined by
$(depend_include). It is include
file path is defined by
AMDPPFLAGS and the options
given to it can be augmented via
setting AMDFLAGS.
Makefile Techniques
The following tips illustrate how the makefile system can be
used to solve common problems.
gmake exe=./myexe
gmake ul=no
This will cause the C only toolcall to be created and link via the
C compiler.
gmake clink:=yes
This is how you can make from here on out. The utc is
necessary the first time only.
gmake utc
gmake SYSLIBS:=”libfoo.so”
gmake SYSXXLIBS:=”libC++foo.so”
This causes your make to output what it would have done to the
file “file”. You can now edit this file, adding and deleting
options to help figure out just why your make is failing.
This option may be -show in the latest SGI compilers. This will
cause the compiler/linker to go verbose helping you isolate
exactly which phase is going wrong.
Nmgrep
Nmgrep trace
gmake CC=/usr/bin/cc
gmake CC=”/usr/bin/cc” CXX:=”/usr/bin/CC”
Directory Structure
Directory Hierarchy
$PROMAX_HOME
. . bin/
. . exe/
. . lib/
. . obj/
. . . bin/
. . . exe/
. . . lib/
. . nodist/
. . . lib/
. port/
. . bin/
. . misc/
. . menu/
. . . promax/
. . . promaxvsp/
. . . promax3d/
. . . promax4d/
. . help/
. . . promax/
. . . promaxvsp/
. . . promax3d/
. . . promax4d/
. . man/
. . include/
. . src/
. . . bin/
. . . exe/
. . . lib/
. . nodist/
. . . include/
. etc/
Machine-dependent Directories
Product-dependent Subdirectories
Some files with the same names are different for different
products. For example, the menu and help files for ProMAX
2D, ProMAX VSP, and ProMAX 3D differ. To distinguish
among different files for different products, the last subdirectory
sometimes reflects the product name. For example, agc.menu
appears in menu/promax/, menu/promaxvsp/, and
menu/promax3d/. The ProMAX flow builder takes advantage of
this structure to find and use the appropriate files, depending on
which product is being used.
libmaxtool*.so ProMAX tools for exec.exe only. Most programmers will be adding code to the
library called libmaxtoolc.so. Multiple libraries are used to reduce the time
required to update them.
libmaxexec.so ProMAX utility functions called by tools and exec.exe only. Link with this and
you will get an executable as big as the exec.exe.
libmaxutil.so ProMAX utility functions used by any ProMAX program or tool . Stand-alone
programs typically need this library, but DO NOT need libmaxexec.so.
Third-party Software
Makefile Rules
Makefile Options
Makeexec debug=yes
Clients with their own Master version will also need access to
numerous files from Landmark’s version of the software.
Therefore, when Makefiles search for include files or libraries,
the precedence of the three versions goes as you might expect—
User, Master, and Landmark, in that order—so that anything
that is not contained in the User or Master versions will be
picked up from the Landmark version.
Reference:
Stallman, R. M., and McGrath, R., 1991. GNU Make: a
program for directing recompilation. Free Software Foundation.
C Environment
C Process Components
• a menu
• an init_ subroutine
• an exec_ subroutine
• included files
• an entry in the toolcall source file (toolcall.c or toolcall.f)
• an entry in the Processes list
The entry of your new tool in the toolcall.c or toolcall.f file tells
the trace Executive about the existence of your new processing
tool.
Note that:
Note that the C subroutine has an “_” at the end of the name.
This is required if a C subroutine is going to be called from a
FORTRAN routine. Another requirement if a C routine is to be
called from FORTRAN is that the calling arguments of the C
routine must be call-by-reference; in other words, the
arguments must be pointers rather than just values. Given these
rules and the fact that all ProMAX modules get called from the
FORTRAN subroutines in toolcall.f or analogous C routines in
the equivalent toolcall.c, the initialization routine in a C module
must be named
In other words, the “_” must follow the tool name and all
arguments must be pointers. In this example, the exec_ calling
arguments are for a simple tool.
Global Parameters
globalRuntime->samprat
ProMAX trace header routines for C all start with the three
letters “hdr” followed by other letters; for example, hdrIndex is
a function that returns the index of a trace header, the index
appropriate for the C programming language. The index for
standard headers can be found in the stdHdr structure defined in
$PROMAX_HOME/port/include/cglobal.h. Note that the
header index values in stdHdr are for FORTRAN arrays since
the stdHdr structure points to the same place in memory as the
trace executive’s standard header common block STD_HDRcz
(defined in $PROMAX_HOME/port/include/header.inc). C
programmers can use the macro STDHDR(x) to subtract 1 from
the value of the standard header, or the C programmer can
simply subtract 1 from the standard header to obtain the correct
C header array index.
Re-Entrancy
ProMAX modules handle re-entrancy by putting the permanent
variables in structure called parms by using the following
syntax. ProMAX FORTRAN modules handle re-entrancy by
keeping permanent variables in the common block
SAVED_PARMS. The Executive copies the variables out of
SAVED_PARMS to a private storage area after each routine is
called to avoid a conflict between variables of two separate calls
of the same module in a flow. The variables are then copied
back before the routine is called again.
BEGINPARMS
int int1, anotherInt;
float aFloat, anotherFloat;
Tbl *vel_tbl;
ENDPARMS(parms);
The variables are then referenced in init_ and exec_ using the
standard C syntax for accessing a member of a pointer to
structure:
parms->int1, or parms->aFloat;
*len_sav = NPARMS(parms);
Tool Types
Executive Tools
init Subroutine
The init routines are responsible for:
• reserving any memory that would be held for the entire job.
For example, memory buffers of the size of a few traces
would be considered too small to bother allocating and de-
allocating in the exec phase. Buffers the size of a shot
gather would normally be allocated in the exec phase and
de-allocated after each group of traces exited the tool.
In short, the init subroutine does things that need to be done just
once during the execution of a particular processing tool.
The init phase routine for all tool types has the same calling
arguments, those of LEN_SAV and ITOOLTYPE. The
following is the subroutine definition for the Amp Ratio
exercise (see Simple Tool Examples appendix).
exec Subroutine
The exec subroutine is the subroutine that actually processes
data. The processing parameters are passed to the subroutine
through the saved parameters. The exec subroutine is normally
called multiple times within a processing flow since it processes
a natural grouping of traces and then passes those traces along
to tools that are further down the flow. The exec subroutine of a
band-pass filter program, for example, would be called each
time a new trace is passed down the pipeline to be filtered.
Since the exec routine is called multiple times, it is good
programming practice to deallocate memory that is allocated
within the exec subroutine before the routine returns control to
the trace executive.
Simple Tools
Simple tools are designed for those numerous seismic data
processing tools that only require a single trace at a time.
Scaling, bandpass filtering, spiking decon, NMO correction,
static shifting, and geometry installation are all examples. The
simple tool assumes a single trace will be input, the tool will
process the trace, and then output the processed trace to be
picked up by the trace executive routine. No buffering or special
directives to the Executive are required.
The exec phase routine for the Amp Ratio simple tool has the
following calling arguments:
Ensemble Tools
The next most common bundle size for traces is an ensemble,
where data is collected as shots, CDP’s, receivers, offsets, etc.
Ensemble tools pass an ensemble of traces in and out of the
exec routines. Two dimensional filtering, such as FK, is a good
example of such processing. An ensemble tool must input and
output one ensemble in each call of the exec routine; however,
the number of traces in the output ensemble can be different
than the input.
The input trace and header arrays are two dimensional in the
sense that there are multiple traces and headers in each array. A
FORTRAN program can dimension the TRACES array as
The input trace and header buffers may not be completely filled
if the current ensemble is not the largest ensemble in the
dataset. The NSTORED (*nStored in C ) argument passes the
number of traces in the current ensemble. If the number of
traces in the ensemble is changed (that is, more or less than
NSTORED will be output), then NSTORED must be reset
accordingly prior to exit from the exec subroutine. The
Executive allocates the required memory and starts
accumulating traces just prior to calling the exec ensemble
routine. When an end-of-ensemble flag is found in a trace
header, indicating the end of the current ensemble, the
Executive calls your exec routine and passes the ensemble of
traces and headers. Your only responsibility is to return an
ensemble. You are at liberty to change the ensemble size, even
to one in the case of stacking, but the ensemble flag in the trace
headers must be properly set upon exiting. Of course, if you
change the ensemble size by stacking or interpolating traces,
you are responsible for changing the runtime, MAXDTRz
(globalRuntime->maxdtr in C), to reflect this change.
Remember that MAXDTRz or globlaRuntime->maxdtr must be
changed in the init_ subroutine, NOT in the exec subroutine.
You might wonder what the Executive would do for the buffer
size of TRACES if MAXDTRz was doubled for trace
interpolation. The input buffer will be filled with the original set
of, for example, shot traces, but the buffer would be
dimensioned large enough to accommodate the larger output
ensemble size. It is also worth pointing out again that the
Executive is allocating and de-allocating these input and output
buffers automatically as traces drop through the flow.
Panel Tools
Panel tools are designed to handle situations in which a 2D
processing step is to be applied to a dataset but there is not
OOOOOOOOOXXX
XXXOOOOOOXXX
XXXOOOOOOOOO
OOOOOOOOOMXX
XX MOOOOOOMXX
XXMOOOOOOOOO
OOOOOOOOOMMM
MMMOOOOOOMMM
MMMOOOOOOOOO
Note that the mix traces are a subset of the panel edge;
therefore, the number of mix traces must be less than or equal to
the number of edge traces. If the init subroutine of a panel tool
does not call EX_PANEL_PARMS, then the tool defaults to an
ensemble tool and the advantages of the panel tool are lost.
The exec phase routine for a panel tool has the same calling
arguments as the ensemble tool:
for C.
traces
time
Time padding
A padded 2D array
For single buffer tools, a third routine in addition to the init and
exec routines must be written. This routine, called the flow
routine, accumulates traces in a buffer one at a time checking
each time for the execute condition. When the proper condition
is met for processing and output, the NOUTPUT calling
argument is set to the number of traces intended to be output
from the exec routine. This will signal the Executive to stop
accumulating traces and to make a call to the exec phase.
Single buffer tools (and double buffer tools) require the usual
init and exec routines plus a flow routine. The init phase must
set ITOOLTYPE to ISNL_BUFFpz in FORTRAN and
ISNL_BUFF in C. FORTRAN routines must also make a call to
EX_BUFF_PARMS before leaving the init routine to set the
maximum buffer size, in traces, for the input or output buffer.
The analogous routine in C is exBuffParms. This call also
specifies the time and space padding parameters for the input
buffer (similar to panel tools).
Input arguments
Input arguments consist of:
criteria
for processing. In that case, you will be given the last trace
again,
without incrementing NSTORED, and must react
accordingly.
Output arguments
Output arguments consist of:
NOUTPUT: number of traces that the tool will output from the
exec
subroutine. This argument must be set to a value of 1 or
greater for
the exec subroutine to be called.
NOVERLAP: number of input traces to include in the next
buffer that
is accumulated. The last NOVERLAP traces in the current
buffer
will be the first NOVERLAP traces in the next buffer that
is
accumulated in the flow routine.
The exec phase routine for an single buffer tool has the
following calling arguments in FORTRAN:
This is the same as ensemble and panel tools, with the addition
of the parameter NTR_BUFF. NTR_BUFF is the size, in traces,
of the TRACES buffer and is set to the maximum of NSTORED
or NOUTPUT. If the number to be output is greater than the
number of traces stored, then the number of data traces that are
actually in the buffer to be processed must be sent to the exec
subroutine via the saved parameters.
buffer, and that the next NOVERLAP traces are saved at the
beginning of the buffer to start the next call of the flow routine.
When the flow tool is called again, the buffer will have the
NOVERLAP saved traces plus the next trace coming down the
pipe.
Double buffer tools require the usual init and exec routines plus
a flow routine. The init phase must set ITOOLTYPE to
IDBL_BUFFpz in FORTRAN and IDBL_BUFF in C, and must
also make a call to EX_BUFF_PARMS (or exBuffParms) to set
buffer size and padding. The flow routine for the double buffer
tool is identical to the single buffer tool.
The exec phase routine for a double buffer tool has the
following calling arguments
Complex Tools
If none of the of the multi-trace tool types handle your needs for
trace bundling, you must finally resort to the complex tool
which offers the ultimate in multi-trace I/O flexibility. This
flexibility comes at a price. You must now handle trace
buffering and block your code into logical units for buffer filling
and flushing. Most tasks can be accomplished without resorting
to complex tools, but, if the need arises, this style of multi-trace
processing is only slightly more difficult.
Like simple tools, one trace is input or output from the exec
routine at a time. Unlike simple tools, complex tools can declare
their state to be filling (only receiving), flushing (only giving),
or both (pipe: input and output in same call, same as a simple
tool). The exec phase of complex tools must declare their state
prior to exiting the routine. The options are described in the
following table:
FILL Set by a call to EX_FILLMODE. This tells the Executive that the tool is not supplying a trace
upon exit, but that it expects to receive one on the next call. Presumably you are filling a buffer
of traces for future processing. Note that in the very first call to the exec routine, a trace is
passed in and either kept or output depending on the mode (FILL, etc) set before exit. One
slight quirk of the system is that there is no mechanism to know if the trace you just received
and stored is the last trace to be input to the flow. If the trace is the last input trace and the tool
remains in fill mode, the Executive will pass the tool a dummy trace in the next call that has
the trace header entry EOJ set to 1. The tool’s cleanup flag will not be set (which terminates
the tool from the flow) because the Executive knows that traces are buffered and will be
released later. You are responsible for checking this flag and responding by processing the
traces that have been saved in the routine and then outputting them, primarily by using
FLUSH mode. The EOJ flag appears only ONCE when a tool is in FILL mode, so if there are
traces to dump after the EOJ trace appears, it is a good idea to keep a saved parameter stating
that the EOJ trace has been seen.
FLUSH Set by a call to EX_FLUSHMODE. This tells the Executive that the tool is supplying
(outputting) traces to the flow upon exit, one trace per call, and that it will not receive a new
trace on the next call. This mode is for flushing traces from a buffer after processing.
PIPE Set by a call to EX_PIPEMODE. This tells the Executive that a trace will be supplied to the
flow upon exit, and that a trace is expected to be input on the next call. If the last valid trace
has been input to a tool and it asks for another trace in pipe mode, the Executive sets the
cleanup flag to TRUE which terminates the flow for this tool. A complex tool that is always in
pipe mode behaves as a simple tool; in other words, the Executive assumes that the trace being
input is the same trace that is being output and that there are no traces buffered within the tool.
This is not always a valid assumption; however, EX_PUSHMODE alleviates this problem.
When shifting from fill to flush modes, there will be a single call to pipe mode when you are
flushing the last trace in a buffer and expect to start filling the buffer again on next call.
A very important point regarding the EOJ flag is that only ONE trace will be passed to the
exec_ subroutine in which the EOJ trace header is set to 1; thus, the have_seen_EOJ_flag
variable is set in the preceeding pseudo-code.
QUIT Set by a call to EX_QUITMODE. This tells the Trace Executive that the exec subroutine
flushed the last trace in the flow on the previous call to the exec subroutine by using
EX_FLUSHMODE. EX_QUITMODE is called when the exec subroutine is called and:
- it finds that it has no more traces to pass to the trace executive,
- there are no more traces to come, and
- it is time to set the cleanup flag and have the flow terminated for this tool
This is appropriate for the case where the entire stack line was filled, processed, and flushed.
You know you are done when the last trace in the buffer is gone.
Stand-alone Tools
exec_data: (“STAND_ALONE”
(“SPECIAL”
(“TOOLTYPE” implicit: “STAND_ALONE”)
(“PATHNAME” implicit: “poststack.exe”)
)
(“GENERAL”
(“LABEL” implicit: (value ’LABEL))
)
)
IPC Tools
While most inline flow tools reside in a giant program called the
executive, IPC tools are separate programs that pass data via
sockets. As traces come down the processing flow, they are sent
at the appropriate place from the Executive to the IPC tool.
After the processing of each individual trace or group of traces,
the IPC tool sends them back into the Executive where they
continue down the flow. All the communication and associated
bookkeeping is hidden by input and output routines. To the
programmer, this tool is compiled similar to a stand alone
program. To the user, the IPC tool looks like any ProMAX tool.
module. IPC tools are also easy to trade since you do not need
to trade the entire executive.
The IPC tool is designed mainly for C programs but can be used
with FORTRAN programs. Some wrappers for the C routines
may need to be written.
When you set DEBUG to 3, the IPC tool is started but then halts
waiting for you to attach the debugger to it. You give the
command dbx -a 1542, where 1542 is the process ID of the IPC
tool. You can get the process ID of the IPC tools from the
printout (see the View button), or you can get it via the ps
command. After you attach the debugger, you can continue
running the program with the next or cont command. You have
about 5 minutes to attach the debugger before the program
aborts. With this approach, you do not have to specify the
packet file name.
Global Parameters
The global parameters are initialized at run time and are defined
in the global.inc file. Notice that parameters are grouped into
common blocks by similar characteristics and that they all end
with a z suffix.
GLOBAL_CHARcz (FORTRAN) These are global character parameters that are supplied to the
globalChar (C) packet file (binary flow) by the flow builder at run-time. These
variables are extracted from packet file by the Executive.
GLOBAL_RUNTIMEcz (FORTRAN) These are the global run time parameters. These parameters
globalRuntime (C) are dataset dependent and, as such, are stored with each trace
dataset. These variables are read from disk at run time by the
input tool, if the input is a ProMAX dataset. If the input tool is
reading a foreign dataset (non-ProMAX format) or creating
traces (modeling), the tool must supply values for the
following subset of the run time variables
SAMPRATz
NUMSMPz
IPSORTz
MAXDTRz
IDTYPz
IPKEYz
ISKEYz
IDOMAINz
IGEOM_MATCHz
ITRNO_VALIDz
The remaining run time variables are either set by the
Executive or flow builder:
NTHz
MODEz
IOUNITz
IDATEz
INIT_ONLYz
CLEANUPz
IERRORz
GLOBAL_COORDcz (FORTRAN) These are the global parameters related to coordinates and are
globalCoord (C) stored in the LINE Ordered Database file. Prior to geometry
installation, these values are set to either INULLpz or
RNULLpz. These variables are read from disk at run time by
the input tool. After geometry installation, most of these have
valid entries.
GLOBAL_AQUIScz (FORTRAN) These are the global variables related to acquisition and are
globalAcquis (C) stored in the LINE Ordered Database file. Prior to geometry
installation, these values are set to either INULLpz or
RNULLpz. These variables are read from disk at run time by
the input tool. In practice, few of these parameters are ever
assign non-null values.
In addition to common block definition, the global.inc defines
what are referred to as global parameters. These constants end
in pz rather than z and are used instead of arbitrary numbers
(like 7) primarily for code readability. For example, the
primary sort flag may be set to IOFFSETpz instead of 4 for
offset sorted data. Beware that this is accomplished via
substitution by the C pre-processor, so adhere to the
upper/lower case mix.
For C coding, the COMMON blocks are replaced by
equivalent C structures and the same set of global constants
are defined without the pz extension. These definitions are
performed in the cglobal.h header file located in
$PROMAX_HOME/port/include.
• LIN (line)
• SIN (source index number)
• SRF (surface location)
• CDP (Common Depth Points)
• CHN (channel)
• TRC (trace)
• OFB (offset bin)
• ILN (3D inline number)
• XLN (3D crossline number)
ORDER ELEMENTS
1 2 3 4 5 .... .... N
PARM 1
PARM 2
PARM 3
PARM 4
PARM 5
The quick sort from disk using the MAP file, as described in the
preceeding paragraph, depends on the trace numbers (in the
trace headers) being valid; that is, they are unique and
associated to a column in the TRC Order. If this is not the case,
the dataset will be flagged as such (run-time variable
ITRNO_VALIDz=0), and the sort will be performed using trace
headers.
Standard Orders
Standard Orders
Order Description
LIN Order The LIN Order contains information that is unique to the LINE, such as:
Geometry:
EXDATUMz - Final datum elevation (if not variable)
IUNITSz - Type of units
ISRCTYPz - Source type
NSHOTSz - Total number of live shots
NUMCDPz - Total number of CDPs
Etc.
TRC Order The TRC Order contains information that is unique to each trace, such as:
Geometry:
SIN - Shot index numbers of every trace
SRF - Receiver surface location number of every trace
CDP - CDP bin number of every trace
CHN - Channel number of every trace
OFFSET - Source-receiver offset of every trace
SIN_LTBL - SIN look-up table
SRF_LTBL - Receiver surface location look-up table
OFB_LTBL - OFB look-up table
CDP_LTBL - CDP look-up table
ILN_LTBL - ILN look-up table
XLN_LTBL - XLN look-up table
User parameters:
First break pick times
Trim statics
Source-receiver offsets
Etc.
SRF Order The SRF Order contains information that is unique to each surface location, such as:
Geometry:
FOLD - Receiver fold of every surface location
X_COORD - X coordinate of every surface location
Y_COORD - Y coordinate of every surface location
ELEV - Elevation of every surface location
SLOOKUP - Starting address in SRF look-up table for every surface location
Plus user parameters:
Surface location statics
Etc.
Surface locations are surveyed positions where either a shot or receiver may be placed.
For 2D data, surface locations are generally equivalent to stations. However, 3D data
generally have separate locations for shots and receivers resulting in stations locations
being the super-set of all shot and receiver positions. Receiver locations are therefore
subset and not a suitable order.
XLN Order The XLN Order contains information that is unique to each XLN bin, such as:
Geometry:
FOLD - Fold of every XLN
SLOOKUP - Starting address in XLN look-up table for every XLN
OFB Order The OFB Order contains information that is unique to each OFB bin, such as:
Geometry:
OFB_CNTR - Offset bin center
MEAN_OFF - Mean offset within the bin
FOLD - Fold of every OFB
SLOOKUP - Starting address in OFB look-up table for every OFB
Plus user parameters:
Offset amplitude adjustment
Etc.
CHN Order The CHN Order contains information that is unique to each channel, such as:
Channel gain constants
Channel statics (if appropriate)
Etc.
Trace Headers
in a prior flow. But any tool can create new trace header entries.
The decision to create a new header entry is left entirely in the
hands of the applications programmers whenever some piece of
information should be passed downstream in the processing
flow to other tools.
Trace headers are passed from tool to tool in an array, but the
format of the individual entries can vary. Currently supported
formats are integer, real, double precision real (seldom used),
logical (seldom used), and character (stuffed into integers).
Each header entry can actually be an array of values, although
the length must be a whole number of words. Complicated
entities such as C structures can also be included in the trace
headers.
Any tool may access the trace header entries that were added by
tools that occur earlier in the flow, but first the tool must know
where to find the entries and what their lengths and formats are.
This information is provided by the routine HDR_NAMINFO
(or hdrInfo in C), which returns the description, length, format,
and index of a trace header entry that was specified by name.
The routine HDR_INDINFO (or hdrIndexInfo in C) returns the
name, description, length, and format of a trace header entry
that was specified by index.
Guaranteed Headers
Name Description Initial Values
The initial values are the values to which the headers are
initialized before some tool in the flow changes them. The
initial values for other (non-guaranteed) header entries must be
explicitly set in the execution phase by the tool that created
them. If the tool does not supply values, the Executive will
insert system-wide null values (INULLpz or RNULLpz in
FORTRAN and INULL and RNULL in C). This does not
necessarily indicate that a bug is present. For example, if new
header entries are created in one side of a branched flow, the
header entries will be defined in the other side of the flow, but
their values will be null.
during the current flow. Since this use is widespread, the indices
of the standard headers is placed in a C structure or FORTRAN
COMMON block for easy access. Use of any of these function
requires inclusion of header.inc or cglobal.h. C programmers
should note that the array index values provided for the standard
headers in cglobal.h point to the same place in memory as the
FORTRAN common block and that the array index values are
appropriate for FORTRAN. A value of 1 must therefore be
subtracted from a standard header index value to be correctly
used in a ProMAX module written in C. The following macro is
defined in cpromax.h to aid in making code clear when using
standard headers in C:
Headers can be deleted from the flow via a two step process in
the Executive. In the init phase, the header entry is removed
using EX_HDR_DELETE, but no traces are processed until the
exec phase. HDR_DELETE_UPDATE actually deletes the trace
header in the exec routine.
The use of the trace header routines is not restricted to tools that
are linked into the exec. Stand-alone programs can use them in
exactly the same way.
System-Related Headers
# Header Name Type Description
1 END_ENS End-of-ensemble integer An ensemble is defined within the exec as
flag* any collection of traces which (normally)
share the same primary sort key. Typical
examples are shot records, CDP gathers,
and common-receiver gathers. All of the
traces within an ensemble have ENS_ENS
set to false (NLASTpz), except the last
trace, where it is set to true (LASTTRpz).
The global variable MAXDTRz is the
maximum number of traces per ensemble
which must concur with the number of
contiguous traces that have ENS_ENS set to
NLASTpz.
3 EOJ End of job flag* integer The header entry EOJ is set to false
(NLASTpx) for every trace in a flow, except
under certain circumstances when complex
tools will receive a dummy trace (and trace
header) with EOJ set to true (LASTTRpz).
The dummy trace (and trace header) should
not be returned by the complex tool.
6 LINE_NO Line number (hashed integer Represents the hashed line (or survey) name
line name)* to uniquely identify lines. (Individual
inlines and crosslines of a 3D survey are
part of the same survey and would have the
same LINE_NO.) LINE_NO is used in
operations that involve processing or
storage of data from multiple lines.
LINE_NO is over-ridden by the GeoQuest
IES Input tool to reflect the hashed line
name of the IES line. In that case, each
version number of each inline or crossline
receives a different LINE_NO.
7 FRN_TRNO Foreign trace- integer Used to store trace numbers from non-
number-within line ProMAX sources (such as the GeoQuest
IES System or SeisWorks) to distinguish
between traces with a common LINE_NO.
8 LSEG_END Line segment end* integer A line segment is defined as a portion of the
data in a flow (including all of the data) that
should be processed as a continuous piece.
For example, if two different lines were read
into the same flow and a runmix were
applied, LSEG_END would be used to
ensure that data was not smeared from one
line into the next. LSEG_END is set to false
(NLASTpz) for all traces except the last
trace in a segment, where it is set to true
(LASTTRpz). When multiple lines are
imported via the GeoQuest IES Input tool,
the LSEG_END entry is set to true for the
last trace of each inline, crossline, time
slice, reconstruction cut, or 2D line.
9 LSEG_SEQ Line segment integer The sequence number of the current line
sequence number* segment in a processing flow. See
discussion of LSEG_END.
11 TRC_TYPE Trace type (data, aux, integer Used most commonly to distinguish
etc.) between live traces, dead traces, and aux
traces. Other valid trace types include
dummy, time break, uphole, sweep, timing,
water break, and unknown (other).
13 TR_FOLD Actual trace fold real The number of traces that were summed to
form the current trace. TR_FOLD should
reflect the actual number of traces that were
summed, even if the theoretical fold is
different (in a process such as a weighted
stack). Note that TR_FOLD is NOT an
integer.
Input-Related Headers
# Header Name Type Description
14 DISKITER Disk Data Input integer If Disk Data Input (or Tape Data Input)
iteration* reads through the data multiple times (for
the benefit of tools such as autostatics),
DISKITER will reflect the current iteration
number.
16 SEQ_DISK Trace sequence integer Reflects the actual sequence number that a
number from disk trace was read from tape or disk, if the input
tool was Disk Data Input or Tape Data
Input. SEQ_DISK is unique for every input
trace, even in the case of multiple iterations
or multiple datasets. For example, if a
dataset containing 10 traces was read twice,
on the second iteration the first trace would
have SEQ_DISK equal to 11.
Geometry-Related Headers
# Header Name Type Description
17 SOURCE Live source number integer Assigned by the user when the geometry is
(usr-defined) written and installed, and represents a
number that the user wishes to use to refer
to a given record. SINs that are not assigned
a SOURCE number are not part of the live
data and have SOURCE set equal to
INULLpz.
18 FFID Field file ID number integer The FFID of each SIN is extracted from the
headers of the field data and stored in the
parameter database for user reference. It is
largely unused because it (unfortunately)
cannot be assumed to be unique.
19 CHAN Recording channel integer The CHAN of each trace is extracted from
number the headers of the field data. CHAN is one
of the few headers for which the values from
the field data are trusted (although they can
be corrected if in error). CHAN numbers
can be used to reference the CHN ordered
parameter file in the parameter database if
the global parameter IGEOM_MATCHz is
true (=1).
20 NCHANS Number of channels integer The number of channels found within the
of source SIN to which the current trace belongs. This
is a seldom-used header entry.
22 RCDP Real/alias CDP bin real This is a floating point version of CDP for
number use with the TBL2 table routines.
23 SG_CDP Supergather Bin integer The center CDP location of this supergather,
Number typically used with various velocity analysis
programs.
24 CDP_NFLD Number of traces in integer The fold of the CDP to which the trace
CDP bin belongs (as defined by the global geometry
for the line). This is a seldom-used header
entry.
26 R_LINE Receiver line number integer The receiver line this trace was recorded on.
27 S_LINE Swath or sail line integer The sail line this trace was recorded on.
number
28 SOU_SLOC External source integer Typically the field station number assigned
location number to sources. It may or may not be on a similar
station grid as the receivers.
29 SRF_SLOC External receiver integer Typically the field station number assigned
location number to receiver positions. It may or may not be
on a similar station grid as the sources.
30 REC_NFLD Receiver fold integer The fold of the receiver gather at which the
current trace was recorded. This is a
seldom-used header entry.
31 CDP_SLOC External CDP integer Typically the field station number assigned
location number to CDP locations. It may or may not be on a
similar station grid as the sources and
receivers.
34 REC_ELEV Receiver elevation real Should reflect the actual receiver elevation
and NOT the elevation of the surface at the
receiver X,Y (if the receiver is in a
borehole). For marine shooting, the
REC_ELEV should reflect the water depth
of the cable (and should be a negative
number). See further discussion of
coordinates under REC_X.
35 SOU_X Source X coordinate real Always the actual coordinates, not the
coordinates of the nearest surfloc. All
coordinates are relative to reference
coordinates in the parameter database
(XREFz and YREFz).
37 SOU_ELEV Source elevation real The elevation of the SURFACE at the X,Y
of the source (and does NOT reflect a hole
depth; see DEPTH), except that for marine
shooting SOU_ELEV should reflect the
water depth of the source (and should be a
negative number). See further discussion of
coordinates under SOU_X.
38 DEPTH Source depth real The HOLE depth of the source. It should be
defined as 0.0 if no hole exists. DEPTH
should be 0.0 for marine shooting,
regardless of the water depth of the source.
39 UPHOLE Source uphole time real The uphole time observed for a buried
source.
40 REC_H2OD Water depth at real In marine shooting, the water depth at the
receiver X,Y of the receiver (not routinely assigned).
41 SOU_H2OD Water depth at source real In marine shooting, the water depth at the
X,Y of the source (not routinely assigned).
47 OFB_NO Offset bin number integer The sequential bin number of offset bins
that are created during geometry
installation. OFB_NO can be used to
reference the OFB ordered parameter file in
the parameter database if the global variable
IGEOM_MATCHz is true (=1).
48 OFB_CNTR Offset bin center real The offset of the center of an offset bin. See
discussion of OFB_NO.
51 SRC_DEP Source depth below real For borehole sources, SRC_DEP is the
surface depth of the source below the surface.
52 REC_DEP Receiver depth below real For borehole receivers, REC_DEP is the
surface depth of the receiver below the surface.
55 RILINE_N Real/alias 3D inline real The floating point version of ILINE_NO for
number use typically with parameter table routines.
Statics-Related Headers
# Header Name Type Description
58 NA_STAT Portion of static not real Statics are normally not fully applied
applied* within ProMAX, except to the nearest
whole sample interval (for efficiency, and
to avoid the effects of multiple
interpolations). NA_STAT represents the
fractional sample portion of the static that
is not applied. NA_STAT is applied
during NMO in normal processing, but
must also be applied by any application
that is sensitive to small static shifts (such
as velocity analysis). The Apply Fraction
Statics tool can also be used for this
purpose, either by users or in a menu
macro process.
59 N_DATUM Elevation of floating real The elevation of the floating datum at this
datum CDP. Typically added by the module
Datum Statics Apply. This trace is
datumed at this elevation.
60 TOT_STAT Total static for this real Represents the total static that SHOULD
trace* be applied to the trace (minus NA_STAT).
TOT_STAT can be used to remove
previously applied statics.
61 NMO_STAT NMO datum static real The static that WAS applied to move from
(do not apply) NO datum (the original data) to the NMO
datum.
62 FNL_STAT Static to move to real The static that will be (or was) applied to
final datum move from the NMO datum to the final
datum. This is typically applied after CDP
stack by the stacking tool.
63 SKEWSTAT Multiplex skew static real The multiplex skew static (channel static
due to differential delays in older
recording systems) that is assigned during
input of the field data.
65 SOU_STAT Total static for source real The total portion of TOT_STAT that is
attributed to the source (from elevation
statics).
67 CR_STAT Corr. autostatics real The receiver static that was computed by
recvr static a correlation autostatics program. See
also CS_STAT. CR_STAT was dropped
for Releases 5.0+ (see AR_STAT).
68 PS_STAT Power autostatics real The source static that was computed by a
source static power autostatics program. It exists for
convenience during parameterization of
the process that applies autostatics
solutions to the data. PS_STAT was
dropped for releases 5.0+ (see
AS_STAT).
69 PR_STAT Power autostatics real The receiver static that was computed by
recvr static a power autostatics program. See also
PS_STAT. PR_STAT was dropped for
releases 5.0+ (see AR_STAT).
70 TRIMSTAT Trim static real The static that was computed by a trim
statics (non-surface consistent) program.
71 FB_PICK First break pick time real The first break pick time of the trace.
72 WB_TIME Water bottom time at real The time of the water bottom at this CDP.
mid-point There are several programs which use this
for things such as adjusting time window
start and end times.
Mute-Related Headers
# Header Name Type Description
73 TLIVE_S Start time of live real The time of the first live (non-zero)
samples sample, if a top mute was applied. The
difference between TFULL_S and
TLIVE_S indicates the taper length of a
top mute, if one was applied. The value of
TLIVE_S does NOT enter the equation
for conversion from sample number to
time, or vice versa (it is NOT a recording
delay time).
74 TFULL_S Start time of full real The time of the first full untapered
samples sample, whose amplitude is totally
unaffected by a top mute if one was
applied. The difference between
TFULL_S and TLIVE_S indicates the
taper length of a top mute, if one was
applied.
75 TFULL_E End time of full real The time of the last full untapered sample,
samples whose amplitude is totally unaffected by a
bottom mute if one was applied. The
difference between TLIVE_E and
TFULL_E indicates the taper length of a
bottom mute, if one was applied.
76 TLIVE_E End time of live real The time of the last live (non-zero)
samples sample, if a bottom mute was applied.
The difference between TLIVE_E and
TFULL_E indicates the taper length of a
bottom mute, if one was applied.
77 LEN_SURG Length of surgical real The length of the taper of a surgical mute
mute taper if one was applied. If multiple surgical
mutes were applied with different taper
lengths (which is discouraged),
LEN_SURG will represent the last
applied.
78 PAD_TRC Artificially padded integrer The value of this header word is 1 if this
trace trace was padded, otherwise the value is
0.
79 AVO_ATTR AVO Attribute integer The value of this number indicates the
number particular computes AVO attribute, like
slope or gradient.
83 DMOOFF Offset bin for DMO real The offset of a common offset bin that is
created for purposes common offset DMO.
84 SLC_TIME Time of time slice real The time in milliseconds of this 3D time
slice sample.
Non-Standard Headers
# Header Name Type Description
85 AS_STAT Autostatics source real The source static that was computed by an
static autostatics program. It exists for
convenience during parameterization of the
process that applies autostatics solutions to
the data. AS_STAT replaces PS_STAT and
CS_STAT.
86 AR_STAT Autostatics receiver real The receiver static that was computed by an
static autostatics program. See also AS_STAT.
NOTE: AS_STAT replaces PR_STAT and
CR_STAT.
87 TZERO Time of zero of time real Given a time series samples an a constant
series interval, this is time values within that series
which represents time zero, say for an
autocorrelation function.
89 CDP_XD X coordinate of CDP real*8 The bin center (not the center of mass of the
(double) contributing traces). All coordinates are
relative to reference coordinates in the
parameter database (XREFz and YREFz).
Parameter Tables
X1
X2
X1
Surface locations of
CDP bins
X2
Table Rules
Some important rules about the structure of tables are as
follows:.
Table Interpolation
The following figure shows a set of scattered points in the
X1, X2 plane of a ProMAX table. These points might be
surface locations in a 3D seismic survey or points in any other
reference frame that is appropriate for a ProMAX table.
Assume that a set of parameters have been picked for each of
these points; in other words, there are Z values stored at Y
locations at each point in the plane. Also in the plane is a point
marked P, which is at coordinates (X1p, X2p). No parameters
have been picked at P; the goal of interpolation will be to
approximate values for Z(X1p, X2p, Y) based on the points that
are near to P. The question that is then raised is, “Which of the
points that are near to P should be used for the interpolation?”
X1
P(X1p, X2p)
X2
X1
X2
X1
B
X2
P
A C
(X1a, X2a, Y)
A plane can now be formed in X1, X2, Z space that contains the
points (X1a, X2a, Za), (X1b, X2b, Zb), and (X1c, X2c, Zc), as
is shown in the following figure. The value of Z(X1p, X2p, Y)
is then calculated at the point where the line parallel to Y that
intersects P also intersects the plane.
X1
B
X2
P
A C
(X1a, X2a, Z)
X Values in Tables
The primary use of tables is for interpolation of parameters in
2D and 3D seismic data processing. The parameters that are
interpolated are frequently associated with some integer
ensemble number, such as CDP bin number or Source Index
Number (SIN). Both CDP and SIN can be associated with
spatial locations on the ground such as the CDP bin location or
the source location.
can also be done with the routine tblInterpZ which uses X1, X2
pairs to describe the location at which interpolation is to be
done. Tables can be built and used via either or both methods. In
the internals of the code, the tables are referenced by the X1, X2
values, so mapping goes on between X and X1, X2.
All the previous parameter table routines still exist and are
functional, but their precison in primary key and XY
coordinates is limted to values that can be stuffed into 32-bit
floating point numbers. These routines have names like
TBL_SOMETHING in Fortran and tblSomething in C. The
new 64-bit parameter table routines are almost identical to the
32-bit routines except they are named like
TBL2_SOMETHING for Fortran and tbl2Something for C.
Table Extrapolation
The preceeding discussion of value interpolation assumed that
there were points bracketing the location for which
interpolation was being done. In cases where a value is beyond
the limit of known table values, the new value must be
extrapolated from values within the table.
X1
Requested point
• interpolation routines
aman -k tbl
aman tblCountX.
If you look at a list of the table routines you may notice that
there is a large number of routine names which begin with the
letters tbl or TBL. Many of these routines are used for working
with data that can be stored in the 2D tables. Many of the tbl
routines actually call other routines that work directly with data
in the underlying 3D data structure. These direct access routines
have names that begin with tb3. Direct access to the underlying
3D data structure can be gained by first calling the routine
tblFetchTb3 from C, which returns a pointer to the location of
the table which can be used with the tb3 routines. There is not a
set of FORTRAN routine names that begin with the letters tb3,
and there currently is no direct access to the underlying C
structures from FORTRAN. Direct access to the underlying C
structures is not necessary, however, since FORTRAN routines
are provided that access the tables via X1 and X2 arguments.
Example 1
The first FORTRAN example comes from the subroutine
INIT_AMP_RATIO, which can be found in the example source
code amp_ratio.f. This code is actually altered slightly from the
original amp_ratio.f to minimize code that is extraneous to this
discussion.
In this example, a table that holds start and end times for a time
gate is read from the database. The table DB_TBL_GET
allocates memory for the table and loads the table values into
that memory. The routine returns an argument called
ITBL_HANDLE. This is a numerical value that should not be
changed, as it is the memory location of the table. This value of
ITBL_HANDLE is the way in which the table is referenced.
Any subroutines that make use of the table will pass
ITBL_HANDLE to the routine so that the table can be uniquely
identified.
C ..... Get the name of the time gate file from the menu
CALL EX_CGETPARM( 'GATENAME', 1, CGATENAME,
NCHARS )
After checking to be sure that there are only two times, a start
and end time, stored in the table, the code gets the trace header
index and format of the primary and secondary keys by use of
the header routine called HDR_NAMINFO.
Example 2
In order to create a new ProMAX table, the user must have first
created a table name while working in the user interface. The
program that will fill the table with data must get the name of
the table into which the table data will be written. The name of
the table is acquired with the routine EX_CGETPARM in the
INIT_ subroutine, as is shown in the previous example. Note
that the name of the table that is acquired from a call to
EX_CGETPARM is the 8-character label (or hash name) which
is generated from the table description input by the user. In
order write to the table, you must find the descriptive name by
use of the routine TBL_DESC_FROM_DB. Memory must then
be allocated for the table, which is done using
TBL_ALLOCATE.
C-------------------------------------------------------
-----------------------
C
C Description:
C Standard initialization routine
C
C Output arguments:
C LEN_SAVE - number of 4-byte words to save
for\ re-entrancy
C ITOOLTYPE - processing tool type
C
C-------------------------------------------------------
-----------------------
#include "dummya.inc"
C ..... Set the tool type to simple (one trace in, one\
trace out)
ITOOLTYPE = ISIMPLEpz
RETURN
END
C-------------------------------------------------------
-----------------------
C
C Description:
C Standard execution routine
C
C Input/output arguments:
C TRACE - array of trace samples
C ITHDR - trace header (as integer)
C RTHDR - trace header (as floating point)
C
C-------------------------------------------------------
-----------------------
#include "dummya.inc"
IF ( CLEANUPz ) THEN
CALL TBL_TO_DATABASE( ID_TABLE, 'VEL', IERR )
C ......... We don't want control to pass into the main\
body
RETURN
ENDIF
RETURN
END
C-------------------------------------------------------
-----------------------
C Include file for DUMMYA
C-------------------------------------------------------
-----------------------
IMPLICIT NONE
#include "global.inc"
INTEGER ID_TABLE
C Code Examples
This section contains two examples of C table routines.
Example 1
The first C example comes from the subroutine
init_amp_ratio_, which can be found in the example source
code ampRatio.c. This code is actually altered slightly from the
original ampRatio.c to minimize code that is extraneous to this
discussion.
In this example, a table that holds start and end times for a time
gate is read from the database. The table database allocates
memory for the table and loads the table values into that
memory. The routine returns a (void*) pointer to the table
/* Get the name of the time gate file from the menu */
exParGetString( "TBLNAME", tblName );
After the table is read into memory, the names of the X and Y
axes are retrieved using tlbDescX and tblDescY. The header
array indices for the X and Y keys are also retrieved using
hdrIndex. The number of Z values (times) is checked using
tblCountZ to be sure that it is exactly two (a start and end time),
otherwise this would be an invalid table for this operation.
Next we see where the table that is created above is used in the
subroutine exec_amp_ratio, which can also be found in the
example code file ampRatio.c. The subroutine exec_amp_ratio
is given one data trace at a time to process, and the time gate is
interpolated for that trace, which is referred to as the current
trace in the following discussion.
skeyVal = rthdr[yIndex];
if( hdrFormat( yKeyName ) == HDRINT ) skeyVal =\
(float)ithdr[yIndex];
Example 2
In order to create a new ProMAX table, the user must have first
created a table name while working in the user interface. The
program that will fill the table with data must get the name of
the table into which the data will be written. The name of the
table is acquired with the routine exParGetString in the init_
subroutine, as shown in the previous example. The name of the
table that is acquired from a call to exParGetString is the 8-
character label (or hash name) which is generated from the table
description input by the user. In order write to the table, you
must find the descriptive name by use of the routine
tblDescFromDatabase. Memory must then be allocated for the
table, which is done using tblAllocate.
void *tblPntr;
ENDPARMS(parms)
/***----------------------------------------------------
---------------
Description:
Standard initialization routine
output arguments:
len_save - number of 4-byte words to save for\
re-entrancy
itooltype - processing tool type
--------------------------------------------------------
-------------***/
void
init_dummya_(int *len_sav, int *itooltype)
{
/* local variabes */
char *tblDesc; /* user-given descriptive table name
*/
/*******************************************************
**************
*
* Description:
* Standard execution routine
*
* Input/output arguments:
* trace - array of trace samples
* ithdr - trace header (as integer)
* rthdr - trace header (as floating [point)
*
********************************************************
**************/
if( globalRuntime->cleanup ){
Memory Management
C Memory Management
• multi-dimensional arrays
• deques
• heaps
• queues
• stacks
Multi-dimensional Arrays
The array memory management functions are intended to
simplify manipulation of multi-dimensional arrays in scientific
programming in C. These functions are useful only because true
multi-dimensional arrays in C cannot have variable dimensions
(as in FORTRAN). For example, the following function IS NOT
valid in C:
void badFunc(a,n1,n2)
float a[n2][n1];
{
a[n2-1][n1-1] = 1.0;
}
void goodFunc(a,n1,n2)
float **a;
{
a[n2-1][n1-1] = 1.0;
}
a[i2][i1]
a = memAlloc2(n1,n2,sizeof(float));
zeroFloatArray(n1*n2,a[0]);
• _mem
• alloc
• deque
_mem
Routine names that begin with _mem have the name and line
number of the subroutine from which the _mem routine is being
called as calling arguments. If a memory error occurs, then the
subroutine and line number at which the error occurred will be
reported. The _mem routines have _memFree routines to free
the allocated memory.
alloc
Routine names that begin with alloc allocate multi-dimensional
arrays without error messages if there is a memory error (such
as if there is insufficient memory to satisfy the request). Routine
names that begin with ealloc are routines that call the alloc
routines, but they also provide error messages and a graceful
exit from the program if there is a memory allocation error.
Memory allocated with alloc and ealloc routines is freed using
the routine names that begin with free.
deque
Routine names that begin with deque are used for creating and
using a deque. A deque is a double-ended queue; in other
words, entries can be inserted and extracted from either end of
the queue.
Heap
Routine names that begin with the heap are used for creating
and using a heap. A heap is an ordered, balanced binary tree in
which the value of the node at the root of any subtree is less
than or equal to the value of either of its children. There is no
implied relationship between siblings. Because the tree is
balanced, an array implementation is possible. With the array
implementation, if the root of a subtree is at position i in the
array, the left child will be at position 2*i+1 and the right child
at position 2*i+2, for a tree beginning with the (C convention)
position 0.
A heap can contain any size data type, but all the data in any
heap must be the same size and should be the same type.
Linked Lists
Routine names that begin with the ll are used for creating and
using linked lists. A singly-linked list is a data structure in
which the memory location of the next data node is stored as
part of the current data node.
Priority Queues
A priority queue is a limited interface to a heap data structure. It
is defined as a queue because as items are added, they are
automatically positioned appropriately, depending on their
relative priority to items already in the queue. Items are always
deleted from the front of a priority queue. This implementation
is based upon a heap data structure.
A priority queue can contain any size data type, but all the data
in any priority queue must be the same size, and should be the
same type.
Promax
Routine names that begin with promax are memory allocation,
freeing, and reallocation routines for 1D arrays. The routines
also provide the benefit of checking the ends of arrays to be
certain that they have not been overwritten. This is
accomplished through use of the routine promaxCheckmem().
Queues
Routine names that begin with queue are for allocation and use
of standard queues. The first entry input to the queue is the first
entry taken from the queue.
Memory reallocation
Routine names that begin with realloc are for use with the alloc
and ealloc routines. These routines allow arrays that were
allocated with alloc and ealloc routines to be resized.
Stack
Routine names that begin with stack are for allocation and
manipulation of data in a stack. A stack is a data structure in
which the last data value input to the structure is the first one
that can be retrieved from the structure.
References
Esakov, J., and Weiss, T., 1989. Data structures: an advanced
approach using C. Prentice Hall, p. 260-267.
mem.inc
Three memory arrays are declared in the file
$PROMAX_HOME/port/include/mem.inc. One of these arrays
is the RSPACEz array, which is managed memory in the sense
that array bounds checking is provided by the ProMAX system.
Any array boundary that is overwritten due to a programming
mistake will be caught by the ProMAX system and the program
terminated with an error message. The array RSPACEz is used
for storing and accessing REAL (floating point) numbers. There
is also an array called ISPACEz for integer numbers. RSPACEz
and ISPACEz are equivalenced in memory. They occupy the
same space in memory, and the bit patterns in memory are
interpreted as being an INTEGER or REAL number depending
on which array you access; that is, RSPACEz or ISPACEz.
PTRDIFF_T IX_FREQS
The routine names begin with the letters bv for C routines and
BV for FORTRAN routines (BV stands for Big Vector). The bv
routines generally use disk space as a type of slow memory. The
advantage of these routines is that they reduce the
programmer’s burden of opening, closing, and accessing disk
files.
Overview of gdb
This chapter is not a tutorial on the use of gdb. You can learn
about these by typing man gdb from the command line or
through the manuals provided with your computer hardware.
This chapter provides a tutorial on how to use gdb to debug a
ProMAX module.
System Review
$PROMAX_DATA_HOME/Area/Line/Flow/packet.job
where
Job Builder
(promax)
Batch
Queue
Super Executive
(superExec)
Stand-alone Executive
Programs (exec.exe)
Tool Caller
NMO Filter
Line Database
Information
(datasets, parameter tables, Packet File
ordered database files, etc.)
When you click the Execute button to start the ProMAX job, the
packet file is written and a program called superExec (or Super
Executive) reads the packet file, expands menus that are
Macros, and determines which lines in the packet file are
processing steps and which lines are not. For example, an
Alternate Executive card in the flow is not a processing step.
The Super Executive then determines which executable code
will be run to complete the job; that is, either a standalone
executable or a version of exec.exe. The Super Executive then
passes the processed packet.job file to the executive where the
processing is performed.
The following basic steps for debugging ProMAX exec and IPC
tools are described in the next subsections.
Many of the steps in debugging exec and IPC tools are identical.
("P"
"ProMAX 2D Testing"
"~/promax/2003.12/sys/exe:."
"~/promax/2003.12/port/menu/promax:promax"
"~/promax/2003.12/port/menu/promax/Processes:promax/Proc
esses"
""
""
""
"~/promax/2003.12/sys/lib:."
t )
Starting and debugging a ProMAX exec job from the command line
This method of starting a ProMAX exec job for debugging
purposes assumes you have a working menu, and this menu in
included in your personal Processes list, and you have built a
working flow from the ProMAX UI using this menu. Here are
the steps used to do this:
2. Copy or link the packet.job file from the flow you built to a
convenient location.
#!/bin/ksh
# This script is called DebugPromaxExec
export MY_PROMAX_HOME=/promax/2003.12
export \
PROMAX_HOME=/products/landmark/ProMAX/Linux/v2003.12.1/P
roMAX
export \
PROMAX_DATA_HOME=/network/integra/export/d02/genew/proma
x_data/ProMAGICclass
export \
PROMAX_SCRATCH_HOME=/network/integra/export/d02/scratch
export LM_LICENSE_FILE=2013@ora1
export \
LD_LIBRARY_PATH=$HOME$MY_PROMAX_HOME/sys/lib:$PROMAX_HOM
E/sys/lib:$PROMAX_HOME/sys/lib/syslibs
export PROMAX_AMP_RATIO_DEBUG=t
path=$PROMAX_HOME/port/bin:$PROMAX_HOME/sys/bin:$PROMAX_
HOME/sys/exe:$path
export path
$PROMAX_HOME/sys/exe/exec.exe $1 &
Note that the library paths are set to search the personal
development environment first where the newly created
libraries are located, then the production location.
n_trc = 0;
AttachDebugger("PROMAX_AMP_RATIO_DEBUG");
.
.
.
At this point you would type the following at the command line:
((gdb) where
#0 0x41f137dc in __nanosleep_nocancel () from
/lib/tls/libc.so.6
#1 0x41f135ff in sleep () from /lib/tls/libc.so.6
#2 0x40c40fca in AttachDebugger () from
/export/d01/apps/2003.19.1/ProMAX/sys/lib/libmaxutil.so
#3 0x000066c7 in ?? ()
#4 0x40c40f3a in AttachDebugger () from
/export/d01/apps/2003.19.1/ProMAX/sys/lib/libmaxutil.so
#5 0x0000003c in ?? ()
#6 0x4002eee3 in init_amp_ratio_ (len_sav=0x8149aac,
itooltype=0x8149b24)
at
/lair/genew/promax/2003.19.1/port/src/lib/maxtool/amp_ra
tio/ampRatio.c:45
#7 0x40026cfa in init_toolcall_ (ctool=0x812e1e0,
len_sav_=0x8149aac, itype=0x8149b24,
__g77_length_ctool=16)
at
/lair/genew/promax/2003.19.1/port/src/exe/exec/toolcall.
f:1057
(gdb) step
Single stepping until exit from function
__nanosleep_nocancel,
which has no line number information.
[Switching to Thread 1106929792 (LWP 26311)]
0x41f135ff in sleep () from /lib/tls/libc.so.6
(gdb) step
Single stepping until exit from function sleep,
which has no line number information.
0x40c40fca in AttachDebugger () from
/export/d01/apps/2003.19.1/ProMAX/sys/lib/libmaxutil.so
(gdb) step
Single stepping until exit from function AttachDebugger,
which has no line number information.
init_amp_ratio_ (len_sav=0x8149aac, itooltype=0x8149b24)
at
/lair/genew/promax/2003.19.1/port/src/lib/maxtool/amp_ra
tio/ampRatio.c:48
48 gatelen=-1.0;
(gdb)
parameter: DEBUG
text: "Do you want to execute the program from gdb?"
type: boolean:
value: nil
mouse_text: "If ’Yes’, you must execute this program
yourself from gdb."
exec_data:
("SOCKET_TOOL"
("GENERAL"
; The following four variables are needed by
;init_stand_alone() to
; run the stand alone program. They are described
;below.
("program" implicit: "ampRatio.exe" )
("machine" implicit: "" )
("DEBUG" implicit: ( if (value ’DEBUG) 2 1) )
; variables after here are user parameters
("P"
"ProMAX 2D Testing"
"~/promax/2003.12/sys/exe:."
"~/promax/2003.12/port/menu/promax:promax"
"~/promax/2003.12/port/menu/promax/Processes:promax/Proc
esses"
""
""
""
"~/promax/2003.12/sys/lib:."
t )
5. Build a flow which has your IPC tool and debug turned on.
8. List the ampRatio.exe source code and set the first break
point.
(gdb) list
26 void *opf_trc, *opfPtr1, *opfPtr2;
27
28 float gatelen;
29 char *cgatename;
30
31 float *trace;
32 int *ithdr;
33 float *rthdr;
34
35 initStandAlone (ac, av, "SOCKET_TOOL");
(gdb) break 35
Starting and debugging a ProMAX exec job from the command line
#!/bin/ksh
#
# ExecutePromaxFlowIPC.sh
#
export MY_PROMAX_HOME=/promax/2003.12
export PROMAX_HOME=/apps/2003.12/ProMAX
export PROMAX_DATA_HOME=/data
export PROMAX_SCRATCH_HOME=/scratch
export LM_LICENSE_FILE=2013@ora1
export \
LD_LIBRARY_PATH=$HOME$MY_PROMAX_HOME/sys/lib:$PROMAX_HOM
E/sys/lib:$PROMAX_HOME/sys/lib/syslibs
export \
PROMAX_SYS_EXE_HOME=$HOME$MY_PROMAX_HOME/sys/exe:$PROMAX
_HOME/sys/exe
export \
path=$PROMAX_HOME/port/bin:$PROMAX_HOME/sys/bin:$PROMAX_
HOME/sys/exe:$path
$PROMAX_HOME/sys/exe/$1 $2 &
Run the script and pass the exec.exe and path to the packet file.
For Example:
.
.
.
_______________________________________________________
Menus
• Menu Heading
• Parameter Specifications
• exec_data
• rules
'(
name: PROGRAM_NAME
label: "Sample ProMAX Menu" Menu Heading
value_tab: 48
parameter: NUMTO_DO
text: "Input the number of traces to process"
type: int:
value: 3
mouse_text: "Type in number of traces to process." Parameter
parameter: PARM_VAL Specifications
text: " Input the processing parameter value"
type: typein:
type_desc: ( float: 6 nil 999999. )
value: 4.
mouse_text: "Input the parameter value "
exec_data: ("PROGRAM_NAME"
("GENERAL"
("NUMTO_DO " implicit: (value 'NUMTO_DO))
("PARM_VAL" implicit: (value 'PARM_VAL)) Exec_data
)
)
rules: (
(rule1 ( > ( value 'NUMTO_DO ) 3 )
(do_show 'PARM_VAL) Rules
(do_not_show 'PARM_VAL))
)
)
Menu Heading
The menu heading has three important features plus two
optional feature. The first important feature is the '( which is
actually the first two characters in the file. Lisp makes heavy
use of parentheses to group related syntax together. There is a
corresponding ) at the end of the menu. The single quote mark
just before the parenthesis signals the Lisp interpreter to just
read the string that follows (the menu code), but to not evaluate
it.
The second line in the Menu Heading section is the name of the
program to which the menu belongs. This line is actually
optional, but it is a good idea to include it so that you can see
which program the menu belongs to without searching the rest
of the menu.
The third line is the label. This is the name that will appear in
the ProMAX processes list in the user interface. This string
should match the string in the Processes file (the file that
contains a list of menus and where they reside), or else a
harmless error will be issued in the window from which
ProMAX was started.
Parameter Specifications
This section is used to specify names, types, and other attributes
of menu parameters. In the preceeding example menu, there are
two parameters, each of which has its own set of attributes.
The next attribute is text:, which is the character string that will
appear on the ProMAX menu to the left of the box where data is
input.
The next attribute is type, which describes the kind of thing that
will appear in the menu for data input. The type of parameter in
NUMTO_DO is int, which tells the Lisp interpreter to put up a
box in the menu that will accept integer input from the
keyboard. The type of PARM_VAL is typein:, which tells the
Lisp interpreter that the data input box is to accept numerical
input from the keyboard and to look for more information about
the type in the attribute called type_desc.
The default value for the parameter is set using the value:
attribute. This is the value that will appear on the screen when
the menu is first placed into a processing flow.
exec_data
The first line in the exec_data section is
exec_data: ("PROGRAM_NAME"
Rules
The rules section is the part of the menu file that controls,
among other things, which parameters are hidden from the user
when they are not needed.
The rules section begins with the string “rules( “ and ends with
a closing parenthesis. The rules themselves are of the form
The type of evaluation is >, <, =, etc. The thing being evaluated
is some attribute of a parameter, such as its value; the
comparison value can be a constant or some expression, such as
the sum of two other parameters.
( = ( value 'NUMTO_DO ) 3 ).
In the preceeding menu file example, the only rule in the file
states that PARM_VAL is to be shown to the user on the menu
when NUMTO_DO is greater than 3.
rules:(
(rule1
(and
( = (value 'PARM1 ) 1 )
(and
(= (value 'PARM2 ) (value 'PARM1) )
(= (value 'PARM3 ) (+(value'PARM1) (value\
'PARM2)) )
)
)
(do_show 'SHOW_PAR)
(do_not_show 'SHOW_PAR)
)
)
Rules may also be made unconditional by specifying t for the
condition. Such rules are initializations and run only once.
Use Examples
Unlike the source code for ProMAX modules, you have access
to all of the ProMAX menus. Study and copy those files
liberally. It is likely that somewhere within the existing menus
there is a menu file that does something similar to what you
would like to do in your new menu.
Keep it Simple
Complex conditional statements can be difficult to debug (as in
any other programming language) but there are no debugging
tools such as dbx or gdb to debug Lisp code.
Lisp Primitives
We do not document the Lisp primitives in this manual; instead,
we direct you to two references:
The following table lists the Lisp primitives. Please note that:
Lisp Primitives
Lisp Primitive Common Lisp Reference
cdr Yes 1
car Yes 1
length Yes 1
first Yes 1
second Yes 1
third Yes 1
fourth Yes 1
fifth Yes 2
sixth Yes 2
seventh Yes 2
nth Yes 2
nthcdr Yes 1
last Yes 1
list Yes 1
append Yes 1
cons Yes 1
nconc Yes 1
push Yes 1
rplaca Yes 2
pushend No destructive (setq a '(1 2 3)) (pushend 4 a) a=>1 2 3 4)
copy-list Yes 1
eq Yes 1
equal Yes 1
= Yes 1
>= Yes 2
< Yes 2
<= Yes 2
member Almost 1, :test fixed as equal (see memq)
atom Yes 1
numberp Yes 1
listp Yes 1
symbolp Yes 1
and Yes 1
or Yes 1
null Yes 1
not Yes 1
boundp Yes 2
eval Yes 1
print Yes 1
makunbound Yes 2
+ Yes 1
- Yes 1
* Yes 1
/ Yes 1
quote Yes 1
' Yes 1
if Yes 1
cond Yes 1
setq Yes 1
do Yes 1
load Yes 1
set_value parm sexp Set contents of value: attribute of parameter named parm to sexp.
set_type parm type_kwd Set contents of type: attribute of parameter named parm to one of the
supported type keywords.
set_text parm string Set contents of text: attribute of parameter named parm to string.
set_selected_item parm sexp Set contents of selected_item: attribute of parameter named parm to
sexp.
set_mouse_text parm string Set contents of mouse_text: attribute of parameter named parm to
string.
delete_error parm string Deletes error from error_list: attribute of parameter named parm
with text of string.
add_warning parm string Adds warning to warning_list: attribute of parameter named parm
with text of string.
delete_warning parm string Deletes warning from warning_list: attribute of parameter named
parm with text of string.
set_value_tab parm integer Set contents of value_tab: attribute of parameter named parm to
integer.
do_not_show parm Set contents of showp: attribute of parameter named parm to nil.
Database Functions
Function Description
(dataset_list) Argumentless function that returns a list of three elements, the third of
which is a list of the UNIX names of available datasets. The first two
elements should not be depended upon as they are used internally by
the menu system.
(header_list) Argumentless function that returns a list of three elements, the third of
which is a list of the header words available. The first two elements
should not be depended upon as they are used internally by the menu
system.
Database Functions
Function Description
(parm_list parm_type) This function returns a list of three elements, the third of which is a list
of the UNIX names of available parameter files. The first two elements
should not be depended upon as they are used internally by the menu
system. One string argument is required, such as "MUT", "VEL", etc.,
for the various types of parametric data.
(db_parmget_line var_string) Returns the value of a line level variable named in var_string. For
example, (db_parmget_line "IUNITSz") returns IENGLISHpz,
ISECARCpz, or IMETRICpz, depending on the units of measurement
for this line in the database. (Used in menu defaulting rules.)
(string_shorten var) Remove extra white space and return the result.
(string_concatinate var1 ... varN) (Yes that’s how it’s spelled.) Returns the concatenation of its string
arguments as one long string.
(count_string var token) Returns the number of occurences of the second argument string in
the first argument string.
(system var) Executes the Unix command line in the argument string and return
the command’s output.
(xsystem var) Execute the Unix command line in the argument string, which is
assumed to invoke some X Window application, and return the
command’s output.
(where_promax_is) Returns the name of the host on which the ProMAX UI is running.
(set_environment var value) Set an environment variable to the given string value.
(unset_environment var) Unset the specified environment variable
type: choose:
:type choose:
:type :choose
type: :choose
We suggest that you use the last form; that is, to use the postfix
notation for process and parameter attributes and the prefix
notation for keyword values. The remainder of this document
uses this notation, although it is possible that this notation is not
used in early examples that you might have encountered. The
choice is arbitrary and completely up to the menu author.
Three KVPs are always first in the MDF: name, label, and
value_tab. The plot_label specification should appear with that
group as well. The exec_data and rules KVPs may appear
anywhere.
Keywords
Keyword Value Type Default Definition
rules: list NONE List of Lisp production rules used to provide context
sensitivity.
Parameter Keywords
Each parameter keyword is followed by a name symbol and
defines a new parameter. These appear one below another on the
menu. Each parameter has a number of attributes associated
with it that are also set using KVPs. The KVPs immediately
following a parameter-KVP establish the initial settings for that
parameter and may appear in any order. However, if the same
keyword is repeated before the next parameter keyword is read,
the last occurrence takes precedence. The parameter and
attribute KVPs are as follows:
Parameter Keywords
Parameter Keyword Default Definition
Value Type
Type-ins
The following table describes implicit Type-ins.
Implicit Type-in
Type Description
type: :int User allowed to type in any integer into 8 character field. No upper or lower
or type: :integer bounds applied.
or type: :fixnum
type: :real User allowed to type in any real into 10 character field. No upper or lower
or type: :float bounds applied.
or type: :flonum
type: :string User allowed to type in any string into 40 character field
Specified Type-in
In this example, the value typed in is placed in the value
attribute of the parameter, and selected_item is not used. One or
both of bounds may be omitted, which would allow the field
width to be set without any restriction on the value. To specify
an upper bound and no lower bound, set lower bound to nil.
type: :typein
type_desc: ( typein_type field_width typein_lower_bound\
typein_upper_bound )
where- typein_type is from the list of implicit\
typein types above
field_width is an integer number of characters\
to provide for entering values.
typein_lower_bound is the lowest numerical\
value allowed to be entered (ignored for\
:string type)
typein_upper_bound is the highest numerical\
value allowed to be entered (ignored for\
:string type)
Editor Type-in
In this example, the editor pops up when the visible field
(show_always_width) is clicked on. The editor and the help
windows are scroll-enabled, so neither needs to be as large as
the maximum expected entry. Again, the value typed-in is
type: :edit
type_desc: (show_always_width editor_width\
editor_height help_string )
where- show_always_width is the width of a mouse\
sensitive\
field that contains the first width non-blank\
characters of the string in the value\
attribute
editor_width is the width in chars of the popup\
editor
editor_height is the height in lines of popup\
text editor
help_string is a string of text which will\
appear at the bottom of the editor.
Choose Type
In this example, if you want to have the list of choices appear
when no item is selected, you must set selected_item to the
keyword :none.
type: :choose
type_desc: ( item [item] [item] ... )
where- item = string
or item = ( string sexp mouse_help )
or item = :return
selected_item: an item from type_desc or :none
Items may be:
string - -String will appear on list of choices
-selected_item is the string to highlight\
and is set when the user clicks button\
1 on it
-value will be set to selected_item string
list - -String will appear on list of choices
-selected_item is set to entire list with\
user click
-value set to (eval sexp) mouse_text string
-will appear on mouse-help line when user\
is pointing at this specific choice
:return --repeatable keyword which will not appear\
on list of choices but instead causes\
choices that follow to be placed on a\
new line beneath previous choices
Defaults;
selected_item-defaults to (first type_desc). If\
specified it must be a 'member' of\
type_desc list or it will be set to (first\
type_desc).
value -defaults to selected_item if selected_item\
is a string or to (eval (second\
selected_item)) if selected_item is a list.
Pop_Choose List
Pop_choose presents a single mouse sensitive item
(selected_item) to the user that, when clicked on, pops up the
entire list specified in type_desc.
type: :pop_choose
Circular List
Circular lists are just like pop_choose in that they present to the
user only the selected_item element of type_desc in a mouse
sensitive field. However, instead of popping up the entire list
when clicked on by the user, the selected_item circulates to the
next item in type_desc.
type: :circular
Boolean
Boolean type presents a list of two items to the user, Yes and
No. The value attribute is set to t if Yes is selected and to nil if
No is selected.
type: :boolean
selected_item:always one of the two lists ("Yes " t) or \
("No" nil)
defaults to ("Yes " t)
Boolean is a shorthand fortype: :choose
type_desc: ( ("Yes " t) ("No" nil) )
Multiple Choose
Multiple choose work like the choose type except that any
number of the options (including none) may be selected. The
value is this case is a list containing as members the
corresponding value that the ordinary choose would have
returned for a given selected item.
type: :multiple_choose
Action Lists
Action lists are a shorthand type exactly equivalent to choose-
type with selected_item: set to :none. Both permit lists of
choices to appear without any item selected by default, so a rule
might be fired when it is detected that selected_item does not
equal :none.
Function Type
The function type is a specialized type for access to three major
components of the ProMAX database.
type: :function
type_desc: function_call_list
where function_call_list is (dataset_list datasets)
or (header_list headers)
or ((parm_list string) parms)
where string is "MUT", "VEL", "GAT" or one of\
the other three letter strings for each type of\
parametric data allowed in the ProMAX database.
value_tab: integer
parameter: foo
type: :choose
type_desc: ("Mouse sensitive text at left side of menu")
selected_item: :none
value_tab: 0
text: :none
Text Attribute
The text attribute specifies the parameter text to appear or the
menu.
Showp Attribute
The showp attribute is a predicate that controls the visibility of
the parameter on the menu.
showp: Attribute
If set to nil, the parameter will still exist, but will not appear at
all on the menu. Being a predicate, if set to any other value
except nil, the parameter will appear (the default case). It is
possible to have parameters which never show, but this
predicate is usually manipulated by the rules which affect the
set of parameters that will be visible, based on other user-
specified parameter values. This, along with the computational
power of rules, is how context sensitivity is achieved.
mouse_text: string
Plot_label Attribute
The plot_label attribute is a predicate that controls the visibility
of the parameter on the sidelabel history of hardopy plots.
plot_label: Attribute
If set to nil (the default case), the parameter will still exist, but
will not appear at all on the plot sidelabel history. Being a
predicate, if set to any other value except nil, the parameter will
appear. In addition to being an attribute, the plot_label:
predicate is used at the beginning of the menu as a keyword to
control whether any individual parameters appear on the plot
sidelabel. (If omitted, the first plot_label: attribute determines
this global menu setting.) In any event the name of the process
being run appears on the sidelabel history.
exec_data: packet_list
or
exec_data: ( packet_list [packet_list] ... )
where
-packet_list = ( tool_namestring group_list\
[group_list] ...
-group_list = ( group_namestring parameter_list\
[parameter_list] ... )
-parameter_list = ( parameter_namestring\
output_form value_sexp )
where
-output_form = :implicit
or :string
or (:string nwords) where nwords causes
nwords * 4 chars to be output padding\
with blanks or truncating as necessary
or :real or :float or :flonum
or :int or :integer or :fixnum
-value_sexp = a Lisp form that will be eval'ed to\
get the value to output to the packet or coerced\
with output_form.
(:string num) string String padded with blanks or truncated to num 4 byte
words
(:string num) not a string String padded with blanks or truncated to num 4 byte
words
(:int and :fixnum are synonyms for :integer, :float and :flonum
are synonyms for :real)
exec_data Example
The exec_data: KVP from the AGC menu is:
exec_data:("AGC"
("GENERAL"
("MODE_AMP" implicit: (value 'MODE_AMP))
("AGCLEN" implicit: (value 'AGCLEN))
("MODE_WIN" implicit: (value 'MODE_WIN))
("MODEZERO" implicit: (if(value 'mode_option)1\
0 ))
)
)
The values output to the packet file, for the first three of these
parameters, is whatever was held in the value attribute type and
contents of the similarly named parameter in the menu system
at the time the packet file was saved. In the last case,
MODEZERO parameter in the packet file will always contain
an integer of value 0 (zero) or 1 (one), depending on whether
the value attribute of the menu system parameter mode_option
was nil or non-nil at the time the packet file was saved.
exec_data: (
("AGC"
("GENERAL"
("MODE_AMP" :implicit (value 'MODE_AMP))
("AGCLEN" :implicit (value 'AGCLEN))
("MODE_WIN" :implicit (value 'MODE_WIN))
("MODEZERO"::implicit ( if (value 'mode_option)\
1 0 ))
)
)
("FILTER"
("GENERAL"
("FLT_TYPE" :implicit (value 'FLT_TYPE))
("PHASE" :implicit 1 ) ;
("PHASE" :implicit (value 'PHASE))
("PCT_PAD" :implicit (value 'PCT_PAD))
("FLT_FREQ" :implicit (value 'FLT_FREQ))
("FLT_PARM" :implicit (value 'FLT_PARM))
("F_NOTCH" :implicit (if (value 'notch_option) \
(value 'F_NOTCH) 0.0 ))
("N_F_WIDE" :implicit (value 'N_F_WIDE))
("GATENAME" :implicit (if (value 'db_option)\
(value 'GATENAME) "NONE" ))
("PRIM_KEY" :implicit (value 'PRIM_KEY))
("SCND_KEY" :implicit (value 'SCND_KEY))
("FLT_GATE" :implicit (value 'FLT_GATE))
Example
As an example, consider the following scenario. A menu is on
the screen and the change_list is nil (the empty list). This menu
has one parameter called framus, of type integer, and an initial
value of 2:
parameter: framus
type: :integer
value: 2
There is one rule, i.e:
rules: ( ;start of rule list
( framus_rule;rule name start of rule
( (value framus) )
When the user types in a new value for integer framus, the value
attribute of framus is changed to that new value, and the
state_variable '(value framus) is pushed onto the end of the
change_list. The change_list is now:
( (value framus) )
)
)
((value framus))
( (value framus) )
Initialization Rules
In the event that the if-condition is t, the rule is unconditional
and termed an initialization rule. Such rules are run once and
only once immediately after menu parameter attributes are set
when the menu is first invoked. Initializations in included
menus are run after all initialization in the including menu have
been run, irrespective of where the :include parameters appear
on the displayed menu.
(visibility_of_parm3
(= (value 'parm1) 1)
(if (= (value 'parm2) 1)
(do_show 'parm3)
(do_not_show 'parm3)
)
)
There are two possible fixes to this problem. The first fix is the
same as title of this section: avoid conditionals in action
clauses. This rule should be written:
(visibility_of_parm3
(and
(= (value 'parm1) 1)
(= (value 'parm2) 1)
)
(do_show 'parm3)
(do_not_show 'parm3)
)
A corollary between the “think THEN, then IF” rule and the
“avoid conditionals in action clauses” rule is: if_clauses are
likely to be more complicated expressions than action clauses.
This is because the simplest actions sometimes require
complicated and strict conditions; that is, the heavy use of
if_clauses. You can overdo pushing complexity into if_clauses,
which leads to our next rule.
These four rules, each with the same simple action clause(s),
are much easier to comprehend than a single rule with an
if_clause as complicated as the earlier example. (There are, of
pwin
pwin is a program that you can use to develop new menus. You
can execute pwin to see how the menu will appear on the
ProMAX screen; you do not have to put the menu into the
processes list and start ProMAX. Additionally, you can change
the menu file and immediately see the effect on the menu
behavior.
Before you execute pwin, make sure that your menu file is not
read-only and that the following environment variables, which
are also needed to run ProMAX, are set:
pwin menuName.menu
This will pop the menu up onto the screen along with an emacs
editor window in which you can make changes to the menu. To
see the behavior of the menu, place the mouse pointer in the
menu itself. To change the menu, click on the part of the screen
that contains the source code. After the change, move the mouse
pointer back into the menu to see the effect of the change.
pwin menuName.menu -t
This will bring up the menu without the emacs part of the
window. Resize the window so that it does not occupy the entire
screen, and start your favorite editor in or from another window.
You can then make changes to the file in the editor window, and
observe their effects in the menu window when you move the
'(
name: DISKREAD
label: "Display Shots with AGC"
value_tab: 28
parameter: LABEL
text: "Select trace data file"
type: function:
type_desc: (dataset_list datasets)
value: "no entry"
;selected_item: "* No Datasets Found *"
selected_item: "INVALID"
mouse_text: "Use Mouse Button 1 to select a dataset file\
description from the DATASETS menu."
parameter: KEYLIST
text: " SOURCE list to display"
type: edit:
type_desc: (25 80 5 " FORMAT: Shot1-
ShotN,ShotM,ShotI,etc/
EXAMPLES: 1,5,9,13,27,30-40,47/ 1-10/ 11-20(2)/ \
1-10000(50),1005/
HELP: EMACS Editor Widget (scroll with down/up arrow\
keys)
CURSOR MOVEMENT: Use the arrow keys:->,<-,etc.;Point\
the mouse cursor,click B1
parameter: AGCLEN
text: "AGC operator length"
type: typein:
type_desc: ( real: 7 1.0e-5 nil )
value: 500.0
mouse_text: "Amplitude estimation operator length in\
milliseconds for sliding gate AGC."
parameter: X_SERVER
text: "Select display DEVICE"
type: :typein
type_desc: (:string 32)
:value "This Screen"
mouse_text: "'This Screen' for current display or type\
in a display name to override the current display
default."
exec_data: (
("DISKREAD"
("SPECIAL"
("TOOLTYPE" implicit: "INPUT")
)
("GENERAL"
("version" implicit: "@(#)display_shots.menu
\
50.4 9/8/93" )
("VERSION" implicit: 0.1)
("LABEL" implicit: (value 'LABEL))
("SORTOPT" implicit: 1 )
("PKEYNAM" implicit: "SOURCE " )
("SKEYNAM" implicit: "NONE " )
("TKEYNAM" implicit: "NONE " )
("KEYLIST" implicit: (value 'KEYLIST))
("THDRONLY" implicit: 0 )
("SAMPRATE" implicit: 0.0 )
)
)
("AGC"
("GENERAL"
("MODE_AMP" implicit: 1 )
("AGCLEN " implicit: (value 'AGCLEN))
("MODE_WIN" implicit: 2 )
("MODEZERO" implicit: 1 )
)
)
("TR_DISPLAY"
("GENERAL"
("X_SERVER" implicit:
(if (= (value 'X_SERVER) "This Screen")
(where_promax_displays)
(value 'X_SERVER)))
("TSTART" implicit: 0.0 )
("TEND" implicit: 8000.0 )
("NTR_SCRN" implicit: 0 )
("NEN_SCRN" implicit: 1 )
("GAP" implicit: 0 )
("SCROLL" implicit: 0 )
("XMAGNIFY" implicit: 1.0 )
("YMAGNIFY" implicit: 1.0 )
("DISPMODE" implicit: 2 )
("VARBIAS" implicit: 0.0 )
("AUTOSAVE" implicit: 1 )
("NIMAGES" implicit: 2 )
("NBATCH" implicit: 1 )
("DIRECT" implicit: 1 )
("POLARITY" implicit: 1.0 )
("TIMELINE" implicit: 100 )
("TIMEBOLD" implicit: 1000 )
("TIMEANN" implicit: 500 )
("LKEYNAM1" implicit: "SOURCE " )
("LABLMOD1" implicit: 3 )
("LABLINC1" implicit: 5 )
("LKEYNAM2" implicit: "CHAN " )
("LABLMOD2" implicit: 2 )
("LABLINC2" implicit: 5 )
("POSITION" implicit: 0 )
("CLIP" implicit: 2.0 )
("MODSCALE" implicit: 1 )
("ASCALAR" implicit: 1.0 )
("SCALEOPT" implicit: 1 )
("LMFRDATA" implicit: 0 )
("SCRN_MIN" implicit: -10.0 )
("SCRN_MAX" implicit: 10.0 )
("INTERP" implicit: 1 )
("SPLT_ENS" implicit: 1 )
)
)
)
rules: (
(test_host_name (NOT (= (value 'X_SERVER) "This
Screen"))
(progn
(setq temp (host_valid_p (value
'X_SERVER)))
(if temp
(add_error 'X_SERVER temp)
(set_error_list 'X_SERVER temp)))
(set_error_list 'X_SERVER nil)
)
)
)
Helpfiles
("Amplitude ___________________________________"
("Automatic Gain Control" "agc")
("Time-Variant Scaling" "tvs")
The name agc is passed to the PromaxHelp script, and then the
script searches your development trees and the production trees
looking for this file name with various extensions, then starts
the appropriate helpfile viewer when a file is found with the
appropriate extension. If the file agc.html is located, then
netscape is started and displays the agc.html file.
FrameMaker-formatted Helpfiles
Starting FrameMaker
Follow these steps to start FrameMaker at Landmark:
1. Login to charon
2. cd /usr/local/frame/bin
4. maker
Editing a Helpfile
Follow these steps to edit an existing helpfile:
When you get this message check the date. If the date is:
• recent (one day or so), then someone is now editing the file
• old, then someone was editing the file, probably left it open
in FrameMaker, went to lunch, and Framemaker closed
abnormally, such as if the host rebooted or the X-terminal
crashed. Since the file was never exited properly, the lock
status file is still present, even though no one is currently
editing the file. To be safe, check with the person listed in
the warning message dialog box. If they are not using the
file, then click the Reset file lock checkbox and click
Continue to proceed. If you simply want to look at the
file, just click Continue on the message dialog. If you
then do try to save the file, the warning message will
appear again.
Autosave Files
Autosave files are automatically generated by FrameMaker
while you have a file open. The save interval can be specified in
the Preferences option under the File menu. The default has
autosave turned on and set to 5 minutes. Autosave versions of
files are reliable as long as autosave is turned on.
Helpfile Organization
Example Helpfile
Theory
The theory section is an explanation of how a process
accomplishes its purpose. Write this with your audience in
mind. Your audience has a good knowledge of geophysics and
seismic processing; therefore, you do not need to define P-wave
or S-wave, nor do you need to include a discussion of
Zoeppritz’s equations. Consider the 90% rule: mention what
90% of our clients will want to know. The following two
examples illustrate two different but concise theory discussions:
Theory Example 1
The spectral shaping algorithm has two modes of application.
The first scales all frequency components of the data to a
specified contour, while maintaining the original phase
relationships. The second multiplies all frequency components
by the specified contour also without changing the phase. The
contour is defined by a series of frequency-amplitude pairs. The
amplitudes may be given as a percentage of the maximum
amplitude, or as a dB value relative to 1.0.
Theory Example 2
Spectral analysis of the results of IRLS L1 decon show
spectral whitening within the bandwidth of the original data.
The IRLS system is
T T
A W A X = A W Y where:
A X = Y and where:
T
A = transpose of A
W is initially set to the identity matrix, then updated for the next
iteration by:
W i = Y i – ∑ A i, j X j – ( L1 norm minimization )
Usage
The Usage section discusses how to use the process and
includes a description of the input/output headers. For instance,
what kind of data does the process operate upon? What must be
done first in order to use the process? What typically comes
after the use of the process? In this section, you fit the process
into the big picture of using ProMAX. The following paragraph
illustrates one way to write the Usage section:
References
If you use the 90% rule discussed in the preceeding theory
section, you can use the References section to supply our clients
Books
Author’s last name, initials, year. Book title (capitalize only
proper nouns). City of publication, publisher, xxx p.
Parameters
Write the parameter exactly as it appears in the process.
or
or
Minimum velocity
Interactive Display
Several ProMAX processes are interactive. The optional
Interactive Display section comes after the Parameters section
and describes how the interactive display operates. For a good
example, see Trace Display.
Hypertext
Not every helpfile will have or should have hypertext in it. It can
be a very valuable aid to the reader, but most simple helpfiles do
not need it. Please notify the Documentation Department if your
helpfile needs hypertext links.
Code Standards
C Coding Standards
and not
float
cvtibm(float ibm_int)
Do not patch bad code, rewrite it! Rewriting code is often less
work than you would expect and usually dramatically improves
it. Even good software eventually wears out as new features are
added.
Do not use real values to index into arrays such as this example
(some compilers will not accept this at all):
X = 1.0
RWORK(X) = Y
DO I=1,10
X(I) = 0.0
ENDDO
DO 100 J=1,10
DO 100 I=1,10
X(I,J) = 0.0
100 CONTINUE
Good example:
DO 110 J=1,10
DO 100 I=1,10
X(I,J) = 0.0
100 CONTINUE
110 CONTINUE
CHARACTER CWORK*8
CHARACTER CWORK(8)
Be sure that character arrays are null terminated before you pass
them to C routines. Null termination means that a CHAR(0)
exists in the array after the last significant character.
C preprocessor
All ProMAX FORTRAN code is run through the C
preprocessor before it reaches the FORTRAN compiler. The
primary benefits are the use of the #ifdef and #include
statements. The syntax of an include statement is:
IMPLICIT NONE
#include "foo.inc"
#include "header.inc"
rather than:
IMPLICIT NONE
INCLUDE 'foo.inc'
INCLUDE '/usr/ProMAX/sys/misc/header.inc'
Note that the use of full path names for include files is
disallowed (use the -I directive in the compiler).
Comments
Comments should be used to adequately explain the structure
and intent of the code. Poorly commented code is difficult for
the author to maintain and impossible for someone else to
maintain. If you spend much time explaining yourself during
code walk-throughs, your comments are inadequate. No one
ever errors on the side of too many comments.
White Space
Do not be afraid to use white space. Blank lines can be used to
further clarify the structure, and spaces between the elements of
a statement make it easier to read. A statement like:
IF(GL.LT.0.0.AND.GE.GE.GMAX) THEN
just like:
“Amassofcharacterswithoutblanksisdifficulttoread”
Code Structure
Do not use multiple IF conditional tests on the same variable in
the same block of code if an ELSE or ELSEIF will do the same
task.
Bad example:
IF ( NSAMPS .EQ. 1 ) X = Y
IF ( NSAMPS .EQ. 1 ) J0 = 0
Even worse:
IF ( NSAMPS .EQ. 1 ) X = Y
IF ( NSAMPS .EQ. 2 ) X = Y2
IF ( NSAMPS .EQ. 1 ) J0 = 0
Good example:
X = Y2
ENDIF
Miscellaneous
The source code for a particular processing tool should be kept
in a unique directory and include the associated include file.
Be alert for null values in the system (this is our most common
source of bugs). For example, this code will crash if the CDP
number in the trace header is null:
ICDP = ITHDR(IH_CDP)
X(ICDP) = 0.0
and this code will crash if CDP is not defined in the header:
ICDP = ITHDR(ICDPz)
X(ICDP) = 0.0
Purify
14. Use Purify on your code as standard procedure before you
check it in to the production libraries.
Portable Code
$PROMAX_HOME/port/bin/aman
If you are not sure which routine you are looking for, you can
type the command
aman -k keyword
You will see a man page with an overview of the system divided
into sections. There will be a short description of each section,
as well as a list of routines which have online man pages.
Decide on which routine you need from this man page. If you
need more information, narrow it down to a section and then
type aman fs# or aman cs#, where # is the number of the
section on which you desire information. After you determine
which routine you want information, type
aman [routine_name] where [routine_name] is the actual
name of the routine.
$PROMAX_HOME
. . bin/
. . . promax
. . . promaxvsp
. . . promax3d
. . . promax4d
. . . emacs
. . . .
. . exe/
. . . exec.exe
. . . superExec
. . . autostat.exe
. . . dbmath.exe
. . . .
. . . showfile
. . . .
. . lib/
. . . libmaxexec.so
. . . libmaxtool1.so
. . . libmaxtool2.so
. . . libmaxtool3.so
. . . libmaxutil.so
. . . libmaxui.so
. . . libagfc.so
. . . libXaw.so
. . . libXhp.so
. . . . libxcgm.a
. . . .
. . obj/
. . . bin/
. . . . promax/
. . . . . .
. . . . .
. . . exe/
. . . . exec/
. . . . . c_exec.o
. . . . . exec.o
. . . . . toolcall.o
. . . . . .
. . . . autostat/
. . . . . .
. . . . .
. . . lib/
. . . . maxtool/
. . . . . cgmplot/
. . . . . cgmplot.o
. . . . . c_cgmplot.o
. . . . . cgmplot_combined.o
. . . . . rf/
. . . . . cfstack.o
. . . . . .
. . . . . .
. . . . .
. . nodist/
. . . lib/
. . . . sdi/
. . . . . libxcgm.a
. . .
. .
. port/
. . bin/
. . . Makeexec
. . . .
. . misc/
. . . header.inc
. . . color_tbl_b
. . . .
. . . fontimage0
. . . fontimage1
. . . .
. . menu/
. . . promax/
. . . . Processes
. . . . agc.menu
. . . . .
. . . promaxvsp/
. . . . Processes
. . . . agc.menu
. . . . .
. . . promax3d/
. . . . Processes
. . . . agc.menu
. . . . .
. . help/
. . . promax/
. . . . agc.pdf
. . . . .
. . . promaxvsp/
. . . . agc.pdf
. . . . .
. . . promax3d/
. . . . agc.pdf
. . . . .
. . man/
. . . man1/
. . . . .
. . . .
. . include/
. . . header.inc
. . . cglobal.h
. . . cpromax.h
. . . cwp.h
. . . .
. . . private/
. . . . .
. . . interface/
. . . . .
. . . make/
. . . . advance.make
. . . . maxexec.make
. . . . maxprog.make
. . . .
. . . X11/
. . . . Xaw/
. . . . . Box.h
. . . . . .
. . . . cgm.h
. . . . portable.h
. . . .
. . src/
. . . bin/
. . . . promax/
. . . . . .
. . . . emacs/
. . . . . ./
. . . . . .
. . . exe/
. . . . exec/
. . . . . Makefile
. . . . . c_exec.c
. . . . . exec.f
. . . . . toolcall.f or toolcall.c
. . . . . .
. . . . autostat/
. . . . . Makefile
. . . . . .
. . . lib/
. . . . maxtool/
. . . . . Makefile
. . . . . agc/
. . . . . agc.f
. . . . . .
. . . . maxexec/
. . . . . Makefile
. . . . . table.f
. . . . . ex.c
. . . . . err.c
. . . . . par.c
. . . . . .
. . . . maxutil/
. . . . . Makefile
. . . . . c_promax/
. . . . . hdr.c
. . . . . .
. . . . . table/
. . . . . .table.f
. . . . . .
. . . . maxui/
. . . . . Makefile
. . . . . .
. . . . cwp/
. . . . . Makefile
. . . . . .
. . . . X11/
. . . . . Xaw/
. . . . . Makefile
. . . . . Box.c
. . . . . .
. . nodist/
. . . include/
. . . . sdi/
. . . . . cgm.h
. . . . . portable.h
. etc/
. . config_file
. . .
The file cglobal.h gives you access to the global variables, such
as numsmp (number of samples per trace), along with a variety
of standard headers. The file cpromax.h contains the #include
statements for standard C “.h” files, such as math.h and stdlib.h.
It also contains function definitions for the ProMAX C
environment.
cglobal.h
#ifndef CGLOBAL_H
#define CGLOBAL_H
#include <sys/types.h>
/* character globals */
typedef struct globalCharStruct {
char cproj[16]; /* current project name */
char cline[16]; /* current line name */
char carea[16]; /* current area name */
char cflow[16]; /* current flow name */
char cpad[64]; /* pad to 128 */
} GlobalChar;
#ifdef DEFINE_CGLOBALS
#else
#endif /* DEFINE_CGLOBALS */
/* miscellaneous globals */
typedef struct globalMiscStruct {
float exdatum; /* final processing datum elevation (if not variable) */
float vxdatum; /* final datum replacement velocity (if not variable) */
int iunits; /* type of units (see choices below) */
logical i3d; /* true if data is 3-D */
#ifdef DEFINE_CGLOBALS
#else
#endif /* DEFINE_CGLOBALS */
/* runtime globals */
typedef struct globalRuntimeStruct {
float samprat; /* time sampling interval in milliseconds */
int numsmp; /* number of samples per trace */
int ipsort; /* physical primary sort flag (see choices below) */
int maxdtr; /* maximum number of data traces per ensemble */
int idtyp; /* primary data type (see choices below) */
int nth; /* number of 4-byte words in trace header */
int mode; /* processing executive mode (see choices below) */
int iounit; /* Fortran I/O unit for output diagnostics */
int ipkey; /* trace header index of primary sort key */
int iskey; /* trace header index of secondary sort key */
int idate; /* current date (seconds since 00:00:00 GMT, 1/1/70 */
int idomain; /* domain type (see choices below) */
logical cleanup; /* true if system is in cleanup mode */
logical ierror; /* true if system in error mode (trying to cleanup) */
#ifdef DEFINE_CGLOBALS
#else
#endif /* DEFINE_CGLOBALS */
/* runtime globals */
typedef struct globalSmartFrameworkStruct {
logical isValid; /* true if the SMART parameters are valid, otherwise
false */
int nDimensions; /* the number of dimensions, ranging from 3 to 5 */
int64_t framesPerVolume; /* the number of frames per volume */
int64_t volumesPerHypercube; /* the number of volumes per hypercube */
int64_t hypercubeCount; /* the number of hypercubes */
int64_t minSample; /* the minimum "logical" sample value */
int64_t minTrace; /* the minimum "logical" trace value */
int64_t minFrame; /* the minimum "logical" frame value */
int64_t minVolume; /* the minimum "logical" volume value */
int64_t minHypercube; /* the minimum "logical" hypercube value */
int64_t sampleInc; /* the "logical" sample value increment */
int64_t traceInc; /* the "logical" trace value increment */
int64_t frameInc; /* the "logical" frame value increment */
int64_t volumeInc; /* the "logical" volume value increment */
int64_t hypercubeInc; /* the "logical" hypercube value increment */
double sampleOrigin; /* the physical sample origin */
double traceOrigin; /* the physical trace origin */
double frameOrigin; /* the physical frame origin */
double volumeOrigin; /* the physical volume origin */
double hypercubeOrigin; /* the physical hypercube origin */
double traceDelta; /* the physical trace delta */
double frameDelta; /* the physical frame delta */
double volumeDelta; /* the physical volume delta */
double hypercubeDelta; /* the physical hypercube delta */
int ipad[18]; /* padding to 64 words */
char dataType[16]; /* the fundamental data type */
char sampleLabel[16]; /* the name of the sample axis, usually a header
name */
#ifdef DEFINE_CGLOBALS
#else
#endif /* DEFINE_CGLOBALS */
/* geometry globals */
typedef struct globalGeomStruct {
int minsloc; /* minimum surface location number */
int maxsloc; /* maximum surface location number */
int incsloc; /* surface location number increment (always 1) */
int nrcvrs; /* total number of live groups */
int maxtpr; /* maximum traces per receiver ensemble */
int mincdp; /* minimum cdp number */
int maxcdp; /* maximum cdp number */
int inccdp; /* cdp number increment (always 1) */
int numcdp; /* total number of cdps */
#ifdef DEFINE_CGLOBALS
#else
#endif /* DEFINE_CGLOBALS */
/* coordinates globals */
typedef struct globalCoordStruct {
float azimx1; /* azimuth towards increasing SURFLOC number */
float sloc1x; /* X coordinate of first surface location */
float sloc1y; /* Y coordinate of first surface location */
int ipad[5]; /* pad to 8 words */
} GlobalCoord;
#ifdef DEFINE_CGLOBALS
#else
#ifdef DEFINE_CGLOBALS
#else
#endif /* DEFINE_CGLOBALS */
/* acquisition globals */
typedef struct globalAcquisStruct {
int isrctyp; /* source type */
int idatrec; /* date recorded */
int igainx; /* gain mode of field instruments */
float prexamp; /* instrument preamp gain constant */
float earlyg; /* instrument early or initial gain */
float aaxfilt; /* instrument anti-alias filter frequency */
float aaxslop; /* instrument anti-alias filter slope */
float freqxn; /* instrument notch filter frequency */
float fxnslop; /* instrument notch filter slope */
float freqxl; /* instrument low-cut filter frequency */
float freqxh; /* instrument high-cut filter frequency */
float fxlslop; /* instrument low-cut filter slope */
float fxhslop; /* instrument high-cut filter slope */
int nsrecd; /* number of samples per trace on field data */
float origdt; /* sample rate on field data */
int ixform; /* recording system format code */
int manfact; /* recording system manufacturing code */
int iserial; /* recording system serial number */
int nxauxs; /* number of aux channels on field records */
float rcconst; /* recording system "dial in" constant */
int ipad[12]; /* pad to 32 words */
} GlobalAcquis;
#ifdef DEFINE_CGLOBALS
#endif
#else
#endif /* DEFINE_CGLOBALS */
/* ****************************************************************************
IF YOU CHANGE THIS struct, DON’T FORGET TO CHANGE header.inc,
OR YOU WILL BE TRANSFERRED TO THE SUPPORT DEPARTMENT
**************************************************************************** */
#ifdef DEFINE_CGLOBALS
#else
#endif /* DEFINE_CGLOBALS */
/* space global */
typedef struct globalSpaceStruct {
#if defined(SGIMIPS4)
int *ispace; /* base pointer stored in common block */
#else
int ispace[2]; /* match dimension of FORTRAN ISPACEz array */
#endif
} GlobalSpace;
#ifdef DEFINE_CGLOBALS
#else
} SAVED_PARMS;
#define ENDPARMS(p) } *(p)=(void*)(&SAVED_PARMS.buffer[0]);
#elif defined (CONVEX)
extern struct block {
float buffer[NSAVEDPARMS];
} _saved_parms_;
#define ENDPARMS(p) } *(p)=(void*)(&_saved_parms_.buffer[0]);
#else
extern struct {
float buffer[NSAVEDPARMS];
} saved_parms_;
#define ENDPARMS(p) } *(p)=(void*)(&saved_parms_.buffer[0]);
#endif
/* last-trace-in-ensemble flag */
#define LASTTR 1
#define NLAST 0
/* trace type */
#define IAUX 0 /* general auxiliary trace */
#define ILIVE 1 /* live data trace */
#define IDEAD 2 /* dead trace */
#define IDUMMY 3 /* dummy trace */
#define ITBREAK 4 /* time-break trace */
#define IUPHOLE 5 /* uphole trace */
#define ISWEEP 6 /* sweep trace */
#define ITIMING 7 /* timing trace */
#define IWBREAK 8 /* water break trace */
#define IOTHER 9 /* any other trace */
#define IWLOG 10 /* well log trace */
#define ICORRUPTED 11 /* corrupted header (internal use only) */
/* tool types */
#define ISIMPLE 1 /* simple (trace in, trace out) tool */
#define IENSEMBLE 2 /* ensemble tool */
#define ICOMPLEX 3 /* complex tool */
#define IFLOW 4 /* flow control tool (not valid for user tools) */
#define INPUT 6 /* input tool (implies complex tool) */
#define IROLLGATE 7 /* rolling gate tool */
#define IPANEL 8 /* panel tool */
#define ISNL_BUFF 9 /* one-buffer tool */
#define IDBL_BUFF 10 /* two-buffer tool */
#include <cnull.h>
/* release numbers */
#define SOFTRL 601000 /* software */
#define GEORLS 601000 /* geometry */
#endif /* CGLOBAL_H */
cpromax.h
#include <agfc/agfc.h>
#include <cglobal.h>
/************/
/* includes */
/************/
#ifndef __MATH__
#define __MATH__
#endif
#ifndef TRUE
#define TRUE (1)
#endif
#ifndef FALSE
#define FALSE (0)
#endif
#undef Yes
#define Yes 1
#undef No
#define No 0
#include <math.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef DEC
#define usleep(x) sleep((x)/1000000)
#endif
#ifdef CONVEX
#define usleep(x) sleep((x)/1000000)
#endif
/****
Typedefs of old structures which are no longer
public. They are now defined in cpromaxP.h
/*********************************************/
/* C defines and functions useful for ProMAX */
/*********************************************/
/* FUNCTION PROTOTYPES */
void qualifyForIda(void);
void exParInfo (char *name, int *format, int *nwrdpval, int *nvals);
int exParFormat (char *name);
int exParExists (char *name);
int exParWordsPerValue (char *name);
void exParGetIntN (char *name, int n,int *i);
void exParGetFloatN (char *name, int n, float *f);
void exParGetInt (char *name, int *i);
void exParGetFloat (char *name, float *f);
void exParGetDouble (char *name, double *f);
int getPar (char *, char *, void *);
void exParGetString (char *name, char **s);
void exParGetStringN (char *name, int n, char **s);
int exParReturnInt (char *name);
float exParReturnFloat (char *name);
char * exParReturnString (char *name);
void exCheckMenuVersion(const char *name, const char *compat_ver);
void* hdrStateAlloc(void);
void* hdrStateAllocN(int initialBufferSize);
void* hdrCurrentStateFork(void);
void hdrStateFree(void* sv);
const char* hdrStateRead(int descriptor, void**sv);
const char* hdrStateWrite(void* sv, int descriptor);
void* hdrCurrentState( void* sv );
void* hdrOriginalState(void);
void* hdrCurrentStateQuery(void);
int sHdrAdd(void* sv, char *cname, char *cdesc, int length, int iformat,
int *index );
void sHdrStdAdd(void* sv, char *cnames, int nnames);
int sHdrDelete(void* sv, char *cname, int *length, int *index, int *nth);
int sHdrNameInfo(void* sv, char *cname, char *cdesc, int *length,
int *iformat, int *index);
int sHdrChangeDesc(void* sv, char *cname, char *cdesc, int *length,
int *iformat, int *index);
int sHdrIndexInfo(void* sv, int index, char *cname, char *cdesc, int *length,
int *iformat);
int sHdrGetNth(void* sv);
/* misc utilities */
/* error functions */
void exErrFatal (const char *format, ...);
void exErrStop (const char *format, ...);
void exErrMessage (const char *format, ...);
void exErrWarn (const char *format, ...);
int exErrHelp (const char *format, ...);
void uErrFatal (const char *format, ...);
void uErrMessage (const char *format, ...);
void uErrWarn (const char *format, ...);
int uErrHelp (const char *format, ...);
void uErrStop (const char *format,...);
int uTapeHelp( char *device, char *format, ... );
void reportPromaxErr(int);
void *tbl64Allocate( int nz, char *xdesc, char *ydesc, char *zdesc, char *desc );
void *tbl64AllocTb64( char *xdesc, char *ydesc, char *zdesc, char *desc, void
*tb64 );
void *tbl64AllocTmp( int nz );
void tbl64Free( void *tbl );
void tbl64AddXY( void *tbl, double x, float y, float *z );
void tbl64AddXYs( void *tbl, double x, float *y, int ny, float *z );
int tbl64GetX( void *tbl, int ix_counter, double *x_loc );
double tbl64GetEnsemble( void *tbl, double x1, double x2);
int tbl64OpfUpdate( void *tbl, int trustCoords );
int tbl64Copy( void *tbl1, void *tbl2 );
int tbl64DIPtoRMS( void *tblRMS, void *tblDIP );
int tbl64RMStoDIP( void *tblDIP, void *tblRMS );
int tbl64GetXYs( void *tbl, int ix_counter, int ny_max, double *x_loc, float
*y_locs, float *z_vals, int *ny );
int tbl64DeleteXY( void *tbl, double x, float y );
int tbl64DeleteX( void *tbl, double x );
void tbl64Clear( void *tbl );
int tbl64InterpXY( void *tbl, double x, float y, float *z );
int tbl64InterpXYu( void *tbl, double x, float fy, float dy, int ny, float *z );
double tbl64XMin( void *tbl );
double tbl64XMax( void *tbl );
void tbl64MinMax( void *tbl , double *x1Min, double *x1Max, double *x2Min, double
*x2Max, float *yMin, float *yMax, float *zMin, float *zMax);
double tbl64X1Min( void *tbl );
double tbl64X1Max( void *tbl );
double tbl64X2Min( void *tbl );
double tbl64X2Max( void *tbl );
float tbl64YMin( void *tbl );
float tbl64YMax( void *tbl );
float tbl64ZMax( void *tbl );
float tbl64ZMin( void *tbl );
int tbl64CountX( void *tbl );
int tb64CountMaxY( void *tbl );
int tbl64CountZ( void *tbl );
int tbl64Equal( void *tbl1, void *tbl2 );
void tbl64AsciiDump( void *tbl );
int tbl64Write( int ihandle, void *tv );
int tbl64Read( int ihandle, void **tv );
void tbl64SetYZ( void *tbl, int ie, double x1, double x2, int ny, float dy, float
fy, float *y, float *z );
int tbl64DeleteYZ( void *tbl, double x1, double x2, int ny, float dy, float fy,
float *y );
int tbl64Delete( void *tbl, double x1, double x2 );
int tbl64InterpZ( void *tbl, double x1, double x2, int ny, float dy, float fy,
float *y, float *z );
int tbl64IndexX(void* t, int ix, double* x1, double* x2);
int tbl64GetYZ(void* tbl, double x1, double x2, int* ny, float* dy, float *fy,
float* y, float* z);
void tblSetYZ( void *tbl, int ie, float x1, float x2, int ny, float dy, float fy,
float *y, float *z );
void tbl2SetYZ( void *tbl, int ie, double x1, double x2, int ny, float dy, float
fy, float *y, float *z );
int tblDeleteYZ( void *tbl, float x1, float x2, int ny, float dy, float fy, float
*y );
int tbl2DeleteYZ( void *tbl, double x1, double x2, int ny, float dy, float fy,
float *y );
int tblDelete( void *tbl, float x1, float x2 );
int tbl2Delete( void *tbl, double x1, double x2 );
int tblInterpZ( void *tbl, float x1, float x2, int ny, float dy, float fy, float
*y, float *z );
int tbl2InterpZ( void *tbl, double x1, double x2, int ny, float dy, float fy,
float *y, float *z );
/* convenience routines */
void *ex_tblBuild( char *primKeyParm, char *scndKeyParm, char *listParm,
char *tblName, char *storeName, int gateFlag, int *iErr );
void *uTblBuild( char *primKeyParm, char *scndKeyParm, char *listParm,
char *tblName, char *storeNameZ, int gateFlag, int *iErr );
void *tblFromParms( char *primKeyName, char *scndKeyName, char *list,
char *tblDesc, char *storeNameZ, int gateFlag, int *iErr );
/* vector routines */
void vClr (float *a, int inc, int n);
void vMov (void *a, int inca, void *b, int incb, int n);
void vsMul (float *a, int inca, float scale, float *b, int incb, int n) ;
void vAdd (float *a, int inca, float *b, int incb, float *c, int incc, int n) ;
void vSub (float *a, int inca, float *b, int incb, float *c, int incc, int n) ;
void vMul (float *a, int inca, float *b, int incb, float *c, int incc, int n) ;
void vsMA (float *a, int inca, float scale, float *b, int incb, float *c, int
incc, int n) ;
void vFill(float c, float *a, int inc, int n );
void vSqrtz(float *a, int inca, float b, float *c, int incc, int n);
/* database routines */
int opfCreate( const char *domain, int locMin, int locMax );
int opfExpand( const char *domain, int nNewLocs );
int opfExists( const char *domain );
int opfListParms( void *opf, char *infoTypes, char *parmNames, char *parmDescs,
int *lengths, int *formats, int *nullVals, int *modDates );
int opfParmInfo( void *opf, const char *info, const char *name, char *desc,
int *length, int *type );
int opfParmFormat( void *opf, const char *info, const char *name );
int opfParmLength( void *opf, const char *info, const char *name );
char *opfParmDesc( void *opf, const char *info, const char *name );
void *opfParmNull( void *opf, const char *info, const char *name );
int opfParmExists( void *opf, const char *info, const char *name );
int dbDataInt( const char *carea, const char *cline, const char *name,
const char *parm_type );
char *dbDataChar( const char *carea, const char *cline, const char *name,
const char *parm_type );
int dbMoveParmFileToSecondary( const char *name, const char *type );
int dbCreateParmFile(const char *, const char *);
int dbOpenParmFile(const char *, const char *, int);
int dbRewindParmFile(int fd, FILE *fp);
void reportDbErr(int);
void tblToMatrix (void *v_tbl, float *vel, float pos1, float pos2, float datum,
int nx,int nz,float dz);
void matrixToTbl (void *v_tbl, float *vel, float pos1, float pos2, float datum,
int nx,int nz,float dz);
float getTblAvg( void *tbl, float ymin, float ymax) ;
float getResampTblAvg( void *tbl, float xmin, float xmax, float dx, float ymin,
float ymax, float dy) ;
int tblMixInterpXYu(void *tbl, float x, float ymin, float dy, int numy, float *z,
float mixWidth, float dxMix);
int tbl2MixInterpXYu( void *tbl, double x, float ymin, float dy, int numy, float
*z, float mixWidth, float dxMix);
void avgTbl(void *t_in, void *t_out, float step, int slow);
void tblAvg(void *t_in, void *t_out, float step, int slow);
float apertureVIT (void *VITtable, float maxTime, int ntv, int nt, int np);
float apertureVID (void *VIDtable, float maxZ, int nzv, float maxTime, int nt,
int np);
void checkMigVelTbl(void *tbl);
#ifndef __CFORTRAN_LOADED
void int_mix_vec_( int *id_num, int *ix_xtrap, int *iy_xtrap, float *x,
float *yStart, float *yInc, int *npts, float *zVec, int *noInterp,
float *mixWidth, float *dxMix);
#endif
#ifndef __CFORTRAN_LOADED
void convert_v_table_( int *t_in_id, char *in_type, int *t_out_id,
char *out_type, float *in_step, float *out_step);
#endif
/* Miscellaneous routines */
double roundUpInc(double inc);
double roundDownInc(double inc);
void AttachDebugger(const char * envSymbol);
/* 3D geometry routines */
void d3CDPToXY( int icdp, float *x, float *y);
/* signal processing */
float quickMedian( int n, float *a, int destroy, int* iErr );
void* resampleTraceInit( float dtIn, float dtOut, int ntIn,
int alias, int phase, int fidelity, int delay, int* ntOut );
void resampleTrace( void* resamp, int ntIn, float trcIn[],
int ntOut, float trcOut[] );
void resampleTraceFree( void* resamp );
void shift_8sinc_(float *y, int *lenya, float *z, int *lenza, float *shifta);
float windowStat( float *vect, int startSmp, int endSmp, int retType, int *iErr);
#include "misc.h"
#include "db_err.h"
#include "hdr_err.h"
#endif /* CPROMAX_H */
simple.menu
'(
name: SIMPLE
label: "A Simple C Module"
value_tab: 48
parameter: ZMULT
text: "Input a positive multiplier"
type: typein:
type_desc: ( real: 6 0.0 nil )
value: 1.0
mouse_text: "Input a positive valued multiplier."
exec_data: ("SIMPLE"
("GENERAL"
("ZMULT " implicit: (value 'ZMULT ))
)
)
)
simple.c
/*-------------------------------------------------------------------*/
/* init_simple_()
/*
/* initialization routine for ProMAX module simple
/*
/*
/*-------------------------------------------------------------------*/
/* get the number of samples per trace, set the external parm too */
parms->sampsPerTrace = gr->numsmp;
/* set the tool type to simple, (one trace in one trace out). */
/* ISIMPLE is defined in cglobal.h */
*itooltype = ISIMPLE;
/*-------------------------------------------------------------------*/
/* exec_simple_()
/*
/* execution routine for ProMAX module simple
/*
/*
/*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*/
/*
/* multTrc()
/* multiplies trace samples by a scalar
/*
/* input arguments:
/* zmult - float the multiplier
/* sampsPerTrace int number of samples per trace
/* output argument:
/* float *trace the data trace to be scaled
/*
/*-------------------------------------------------------------------*/
{
int i;
ampRatio.c
void
amp_ratio_work (float *trace, float *scratch, int nsams, int ngate,
int imin_samp, int imax_samp, float samprate, float
*ratio_max, float *ratio_time);
/***
C-------------------------------------------------------------------
C
C Description:
C Standard initialization routine
C
C output arguments:
C LEN_SAVE - number of 4-byte words to save for re-entrancy
C ITOOLTYPE - processing tool type
C
C---------------------------------------------------------------------
***/
void
init_amp_ratio_(int *len_sav, int *itooltype)
{
float gatelen;
char *cgatename ;
/* See if the user wants to confine the maximum to fall within a gate*/
parms->use_gate = FALSE;
exParGetString ("GATENAME", &cgatename);
if (strcmp (cgatename, "") != 0 && strcmp (cgatename, "NO__GATE") != 0) {
parms->use_gate = TRUE;
/* Get the gate from the database */
if (parms->gate_tbl == NULL)
exErrFatal ("Cannot open time gate %s !!", cgatename);
if (tblCountZ(parms->gate_tbl) != 2)
exErrFatal ("invalid gate (Gate must have an upper and
lower gate!)");
parms->iformat_pkey = hdrIndexFormat(parms->ih_pkey);
parms->iformat_skey = hdrIndexFormat(parms->ih_skey);
}
/* See if the user wants to load the results into the trace header */
parms->load_hdr = 0;
exParGetInt ("LOAD_HDR", &parms->load_hdr);
if (parms->load_hdr ) {
/* Add new trace header entries */
if (hdrExists ("RATIOMAX") ) {
if (hdrFormat ("RATIOMAX") == HDRFLOAT)
exErrWarn ("RATIOMAX header already exists!");
else
exErrFatal ("RATIOMAX header already exists but
is of wrong type!");
} else {
parms->ih_ratio_max = hdrAdd ("RATIOMAX", "Time of amp
ratio maximum", 1, HDRFLOAT);
if (parms->ih_ratio_max < 0) {
/* This should virtually never happen. */
exErrFatal("Error adding header RATIOMAX");
}
}
if (hdrExists ("RATIOTIM") ) {
if (hdrFormat ("RATIOTIM") == HDRFLOAT)
exErrWarn ("RATIOTIM header already exists!");
else
exErrFatal ("RATIOTIM header already exists but
is of wrong type!");
} else {
parms->ih_ratio_time = hdrAdd ("RATIOTIM", "Time of amp
ratio maximum", 1, HDRFLOAT);
if (parms->ih_ratio_time < 0) {
/* This should virtually never happen. */
exErrFatal("Error adding header RATIOTIM");
}
}
}
/* See if the user wants to load the results into the database*/
parms->load_db = 0;
exParGetInt ("LOAD_DB", &parms->load_db);
if (parms->load_db){
int ierr;
/* Open the database to store the amp ratio information against
trace*/
if (globalRuntime->itrno_valid != 1)
exErrFatal ("Cannot load data into the TRC order without
valid trace numbers (geom assigned?)");
if (!hdrExists ("TRACENO"))
exErrFatal ("TRACENO not found in header");
/* Set the tool type to simple (one trace in, one trace out) */
*itooltype = ISIMPLE;
}
/*********************************************************************
*
* Description:
* Standard execution routine
*
* Input/output arguments:
* trace - array of trace samples
* ithdr - trace header (as integer)
* rthdr - trace header (as floating [point)
*
**********************************************************************/
if (globalRuntime->cleanup) {
if (parms->load_db) {
/* Free memory */
/* memFree functions check for memory overruns and
* abort if an overrun is found */
memFree1(parms->scratch);
/* Pass the buffers off to a routine where the real work is done */
amp_ratio_work(trace, parms->scratch, globalRuntime->numsmp,
parms->ngate, imin_samp, imax_samp, globalRuntime->samprat,
&ratio_max,&ratio_time);
if (parms->load_hdr == 1) {
/* Load the values into the header */
rthdr [parms->ih_ratio_max] = ratio_max;
rthdr [parms->ih_ratio_time] = ratio_time;
}
if (parms->load_db) {
/* Load the values into the database */
void
amp_ratio_work (float *trace, float *scratch, int nsamps, int ngate,
int imin_samp, int imax_samp, float samprate, float
*ratio_max, float *ratio_time)
{
int i, ind_max;
float sum_above, sum_below, rabove, rbelow;
sum_below = 0.0;
rbelow = 0.0;
for (i = 1; i<= ngate; i ++)
if (i < nsamps) {
sum_below = sum_below + fabs (trace[i]);
rbelow = rbelow + 1.0;
}
/* Drop a sample from each gate and add the next one */
if (i - ngate >= 0) {
sum_above = sum_above - fabs (trace [i - ngate]) + fabs
(trace [i]);
}
else {
sum_above = sum_above + fabs (trace[i]);
rabove = rabove + 1.0;
}
amp_ratio.menu
'(
name: AMP_RATIO
label: "Amplitude Ratio"
value_tab: 35
parameter: GATELEN
text: "Amplitude gate length"
type: typein:
type_desc: ( real: 7 1.0e-5 nil )
value: 100.0
mouse_text: "Enter the sliding gate length used to compute amplitude ratios."
parameter: time_gate_opt
text: "Confine the maximum?"
type: boolean:
value: nil
mouse_text: "Select 'Yes' if you wish to use a gate to constrain the search for
the maximum in the amp ratio."
parameter: GATENAME
text: " Select gate parameter file"
type: function:
type_desc: ((parm_list "GAT") parms)
value: "INVALID"
selected_item: "** No Parameter File Selected **"
mouse_text: "Use Mouse Button 1 to select a gate parameter file from the
parameter file menu."
parameter: LOAD_HDR
text: "Load the results into the header?
type: boolean:
value: t
mouse_text: "Select 'Yes' if you wish to load the maximum of the amp ratio and
its time into the trace header."
parameter: LOAD_DB
text: "Load the results into the database?
type: boolean:
value: t
mouse_text: "Select 'Yes' if you wish to load the maximum of the amp ratio and
its time into the database."
exec_data: ("AMP_RATIO"
("GENERAL"
("GATELEN" implicit: (value 'GATELEN))
("GATENAME" implicit: ( if (value 'time_gate_opt)
(value 'GATENAME) "NO__GATE" ))
("LOAD_HDR" implicit: ( if (value 'LOAD_HDR) 1 0 ) )
("LOAD_DB" implicit: ( if (value 'LOAD_DB) 1 0 ) )
)
)
rules: (
(rule1 ( value 'time_gate_opt ) (do_show 'GATENAME) (do_not_show 'GATENAME))
)
amp_ratio.inc
C------------------------------------------------------------------------------
C Include file for AMP_RATIO
C------------------------------------------------------------------------------
IMPLICIT NONE
#include <global.inc>
#include <mem.inc>
PTRDIFF_T IX_SCRATCH
INTEGER NGATE, IH_RATIO_MAX,
& IH_RATIO_TIME, LOAD_HDR, LOAD_DB, ID_MAX, ID_TIME,
& IKEY_TRC, ITBL_HANDLE, IH_PKEY, IH_SKEY,
& IFORMAT_PKEY, IFORMAT_SKEY
LOGICAL USE_GATE
amp_ratio.f
C------------------------------------------------------------------------------
C
C Description:
C Standard initialization routine
C
C Output arguments:
C LEN_SAVE - number of 4-byte words to save for re-entrancy
C ITOOLTYPE - processing tool type
CC------------------------------------------------------------------------------
#ifndef RCS_F77_H_
#define RCS_F77_H_
CHARACTER RCS_KEY*65
DATA RCS_KEY/
&’ ProMAX $Id: amp_ratio.f,v 20031.7.2.2 2007/02/12 21:34:25 djohnston Exp $
$Revision: 20031.7.2.2 $ $Date: 2007/02/12 21:34:25 $
&’/
#endif/*RCS_F77_H_*/
C ..... Set a default that is illegal (in case there is a menu problem)
GATELEN = -1.0
C ..... Call for the input parameter by name. Note the padding in the
C ..... name to 8 characters. It is the programmer’s responsibility to
C ..... provide the correct type of return argument.
CALL EX_GETPARM( ’GATELEN ’, 1, GATELEN )
C ..... See if the user wants to confine the maximum to fall within a gate
USE_GATE = .FALSE.
CGATENAME = ’ ’
CALL EX_CGETPARM( ’GATENAME’, 1, CGATENAME, NCHARS )
IF ( CGATENAME .NE. ’ ’
C ......... There had better be two time values (upper and lower gate)
IF ( NTIMES .NE. 2 ) CALL EX_ERR_FATAL(
& ’Invalid gate (must have an upper and lower gate)’ )
C ......... We will need the index of the primary and secondary key
CALL HDR_NAMINFO( CPRIM_KEY, CDESC_DB, LENGTH, IFORMAT_PKEY,
& IH_PKEY, IERR )
IF ( IERR .NE. 0 ) CALL EX_ERR_FATAL(
& ’The primary key of the time gate (’ //CPRIM_KEY
& //’) is not in the header’ )
ENDIF
C ..... See if the user wants to load the results into the trace header
LOAD_HDR = 0
CALL EX_GETPARM( ’LOAD_HDR’, 1, LOAD_HDR )
ENDIF
C ..... See if the user wants to load the results into the database
LOAD_DB = 0
CALL EX_GETPARM( ’LOAD_DB ’, 1, LOAD_DB )
ENDIF
C ..... Set the number of words that need to be saved for re-entrancy.
C ..... Note that CALC_LENSAV is a macro that uses END1z and SAVE1z
C ..... to calculate the common block length
LEN_SAV = CALC_LENSAV
C ..... Set the tool type to simple (one trace in, one trace out)
ITOOLTYPE = ISIMPLEpz
RETURN
END
C------------------------------------------------------------------------------
C
C Description:
C Standard execution routine
C
C Input/output arguments:
C TRACE - array of trace samples
C ITHDR - trace header (as integer)
C RTHDR - trace header (as floating point)
C
C------------------------------------------------------------------------------
#include "amp_ratio.inc"
#include <header.inc>
INTEGER ITHDR(NTHz), LOC_TRC, IERR, ISAVE, IMIN_SAMP, IMAX_SAMP
REAL TRACE(NUMSMPz), RTHDR(NTHz), RATIO_MAX, RATIO_TIME,
& SKEYVAL, TGATE(2)
REAL*8 PKEYVAL
IF ( CLEANUPz ) THEN
IF ( LOAD_DB .EQ. 1 ) THEN
C ............. Flush the buffers for buffered database I/O
C ............. Note that errors only give rise to warnings in cleanup phase.
C ............. Also note that the "location" is now 0.
CALL DB_BUFFRDPUT( ID_MAX, IKEY_TRC, ’F_B_PICK’,
& ’RATIOMAX’, 0, 0.0, .TRUE., IERR )
IF ( IERR .NE. 0 ) THEN
CALL REPORT_PROMAX_ERR( IERR )
CALL EX_ERR_WARN(
& ’Error loading data into database’ )
ENDIF
CALL DB_BUFFRDPUT( ID_TIME, IKEY_TRC, ’F_B_PICK’,
& ’RATIOTIM’, 0, 0.0, .TRUE., IERR )
IF ( IERR .NE. 0 ) THEN
CALL REPORT_PROMAX_ERR( IERR )
CALL EX_ERR_WARN(
& ’Error loading data into database’ )
ENDIF
ENDIF
IF ( USE_GATE ) THEN
C ......... Interpolate the gate times from the table
CALL EX_GET_DBLEKEY( RTHDR(IH_PKEY), IFORMAT_PKEY, PKEYVAL )
CALL EX_GET_REALKEY( RTHDR(IH_SKEY), IFORMAT_SKEY, SKEYVAL )
CALL INT2_GET( ITBL_HANDLE, 0, 0, PKEYVAL, SKEYVAL,
& TGATE, IERR )
IF ( IERR .NE. 0 ) CALL EX_ERR_FATAL(
& ’Error interpolating time gate’ )
ELSE
C ......... Use the entire trace
TGATE(1) = 0.0
TGATE(2) = FLOAT(NUMSMPz-1) * SAMPRATz
ENDIF
C ..... Pass the buffers off to a routine where the real work is done
CALL AMP_RATIO_WORK( TRACE, RSPACEz(IX_SCRATCH), NUMSMPz,
& NGATE, IMIN_SAMP, IMAX_SAMP, SAMPRATz, RATIO_MAX,
& RATIO_TIME )
ENDIF
ENDIF
RETURN
END
C------------------------------------------------------------------------------
C
C Actual work routine
C
C------------------------------------------------------------------------------
IMPLICIT NONE
INTEGER NSAMPS, NGATE, I, IND_MAX, IMIN_SAMP, IMAX_SAMP
REAL TRACE(NSAMPS), SCRATCH(NSAMPS), SUM_ABOVE, SUM_BELOW,
& RATIO_MAX, RATIO_TIME, SAMPRATE, RABOVE, RBELOW
SUM_BELOW = 0.0
RBELOW = 0.0
DO 110 I=2,1+NGATE
IF ( I .LE. NSAMPS ) THEN
SUM_BELOW = SUM_BELOW + ABS( TRACE(I) )
RBELOW = RBELOW + 1.0
ENDIF
110 CONTINUE
C ......... Drop a sample from each gate and add the next one
IF ( I-NGATE .GE. 1 ) THEN
SUM_ABOVE = SUM_ABOVE - ABS( TRACE(I-NGATE) )
& + ABS( TRACE(I) )
ELSE
120 CONTINUE
RETURN
END
ampRatio.c
void
amp_ratio_work (float *trace, float *scratch, int nsams, int ngate,
int imin_samp, int imax_samp, float samprate, float
*ratio_max, float *ratio_time);
/***
C-------------------------------------------------------------------
C
C Description:
C Standard initialization routine
C
C output arguments:
C LEN_SAVE - number of 4-byte words to save for re-entrancy
C ITOOLTYPE - processing tool type
C
C---------------------------------------------------------------------
***/
void
init_amp_ratio_(int *len_sav, int *itooltype)
{
float gatelen;
char *cgatename ;
/* See if the user wants to confine the maximum to fall within a gate*/
parms->use_gate = FALSE;
exParGetString ("GATENAME", &cgatename);
if (strcmp (cgatename, "") != 0 && strcmp (cgatename, "NO__GATE") != 0) {
parms->use_gate = TRUE;
if (tblCountZ(parms->gate_tbl) != 2)
exErrFatal ("invalid gate (Gate must have an upper and
lower gate!)");
parms->iformat_pkey = hdrIndexFormat(parms->ih_pkey);
parms->iformat_skey = hdrIndexFormat(parms->ih_skey);
}
/* See if the user wants to load the results into the trace header */
parms->load_hdr = 0;
exParGetInt ("LOAD_HDR", &parms->load_hdr);
if (parms->load_hdr ) {
/* Add new trace header entries */
if (hdrExists ("RATIOMAX") ) {
if (hdrFormat ("RATIOMAX") == HDRFLOAT)
exErrWarn ("RATIOMAX header already exists!");
else
exErrFatal ("RATIOMAX header already exists but
is of wrong type!");
} else {
parms->ih_ratio_max = hdrAdd ("RATIOMAX", "Time of amp
ratio maximum", 1, HDRFLOAT);
if (parms->ih_ratio_max < 0) {
/* This should virtually never happen. */
exErrFatal("Error adding header RATIOMAX");
}
}
if (hdrExists ("RATIOTIM") ) {
if (hdrFormat ("RATIOTIM") == HDRFLOAT)
exErrWarn ("RATIOTIM header already exists!");
else
exErrFatal ("RATIOTIM header already exists but
is of wrong type!");
} else {
parms->ih_ratio_time = hdrAdd ("RATIOTIM", "Time of amp
ratio maximum", 1, HDRFLOAT);
if (parms->ih_ratio_time < 0) {
/* This should virtually never happen. */
exErrFatal("Error adding header RATIOTIM");
}
}
}
/* See if the user wants to load the results into the database*/
parms->load_db = 0;
exParGetInt ("LOAD_DB", &parms->load_db);
if (parms->load_db){
int ierr;
/* Open the database to store the amp ratio information against
trace*/
if (globalRuntime->itrno_valid != 1)
exErrFatal ("Cannot load data into the TRC order without
valid trace numbers (geom assigned?)");
if (!hdrExists ("TRACENO"))
exErrFatal ("TRACENO not found in header");
/* Set the tool type to simple (one trace in, one trace out) */
*itooltype = ISIMPLE;
}
/*********************************************************************
*
* Description:
* Standard execution routine
*
* Input/output arguments:
* trace - array of trace samples
* ithdr - trace header (as integer)
* rthdr - trace header (as floating [point)
*
**********************************************************************/
if (globalRuntime->cleanup) {
if (parms->load_db) {
/* Free memory */
/* memFree functions check for memory overruns and
* abort if an overrun is found */
memFree1(parms->scratch);
/* Pass the buffers off to a routine where the real work is done */
amp_ratio_work(trace, parms->scratch, globalRuntime->numsmp,
parms->ngate, imin_samp, imax_samp, globalRuntime->samprat,
&ratio_max,&ratio_time);
if (parms->load_hdr == 1) {
/* Load the values into the header */
rthdr [parms->ih_ratio_max] = ratio_max;
rthdr [parms->ih_ratio_time] = ratio_time;
}
if (parms->load_db) {
/* Load the values into the database */
/**
C---------------------------------------------------------------------
C
C Actual work routine
C
C---------------------------------------------------------------------
**/
void
amp_ratio_work (float *trace, float *scratch, int nsamps, int ngate,
int imin_samp, int imax_samp, float samprate, float
sum_below = 0.0;
rbelow = 0.0;
for (i = 1; i<= ngate; i ++)
if (i < nsamps) {
sum_below = sum_below + fabs (trace[i]);
rbelow = rbelow + 1.0;
}
/* Drop a sample from each gate and add the next one */
if (i - ngate >= 0) {
sum_above = sum_above - fabs (trace [i - ngate]) + fabs
(trace [i]);
}
else {
sum_above = sum_above + fabs (trace[i]);
rabove = rabove + 1.0;
}
ind_max = i;
*ratio_max = trace [i];
}
}
This routine outputs a single trace for each trace ensemble that
is input. The trace sample values are the slope or intercept of a
least squares fit line through the trace amplitudes, as a function
of offset at a given time. The menu file is presented, then the
FORTRAN version and C versions of the code are presented.
The menu file works with either the FORTRAN or C versions.
Fortran Note:
This example shows things that are often done in ensemble
tools. The important points to remember from the INIT_
subroutine are that MAXDTRz (the maximum number of traces
in an ensemble that will be leaving the EXEC_ subroutine) is
set to 1, the type of data is set to ISTACKEDpz, and the trace
number is no longer valid after this process, so
ITRNO_VALIDz is set to 0. The important points in the
EXEC_ subroutine are that the trace header values (particularly
the end-of-ensemble flag) are set, and the trace executive is
notified that the number of traces to be returned from
EXEC_ AVO_DEMO is 1. This is accomplished through setting
the calling argument NSTORED to 1.
C Note:
This example shows things that are often done in ensemble
tools. The important points to remember from the init_
subroutine are that globalRuntime->maxdtr (the maximum
number of traces in an ensemble that will be leaving the exec_
subroutine) is set to 1, the type of data is set to ISTACKED, and
the trace number is no longer valid after this process, so
ITRNO_VALID is set to 0. The important points in the exec_
subroutine are that the trace header values (particularly the
end-of-ensemble flag) are set, and the trace executive is notified
that the number of traces to be returned from exec_avo_demo_
is 1. This is accomplished through setting the calling argument
*nStored to 1.
avo.menu
'(
name: AVO_DEMO
label: "AVO Demo"
value_tab: 35
parameter: AVO_OPT
text: "Type of AVO output"
type: circular:
type_desc: (
("Slope" 1 "Output AVO slope." )
("Intercept" 2 "Output AVO intercept." )
)
value: 1
mouse_text: "Use MB1 to rotate between choices for type of AVO output."
exec_data: ("AVO_DEMO"
("GENERAL"
("AVO_OPT" implicit: (value 'AVO_OPT))
)
)
avo.inc
C------------------------------------------------------------------------------
C Include file for AVO_DEMO
C------------------------------------------------------------------------------
IMPLICIT NONE
#include <global.inc>
#include <mem.inc>
avo.f
C------------------------------------------------------------------------------
C
C Description:
C Standard initialization routine
C
C Output arguments:
C LEN_SAVE - number of 4-byte words to save for re-entrancy
C ITOOLTYPE - processing tool type
CC------------------------------------------------------------------------------
C ..... The include file "avo.inc" contains an include for the global
C ..... parameters ("global.inc")
#include "avo.inc"
#include <header.inc>
INTEGER LEN_SAV, ITOOLTYPE, IERR, IOK_HDR
INTEGER ISLOPEPZ, INTERCEPTPZ
PARAMETER ( ISLOPEPZ=1, INTERCEPTPZ=2 )
#ifndef RCS_F77_H_
#define RCS_F77_H_
CHARACTER RCS_KEY*65
DATA RCS_KEY/
&’ ProMAX $Id: avo.f,v 20031.5.12.1 2007/02/06 22:48:57 djohnston Exp $
$Revision: 20031.5.12.1 $ $Date: 2007/02/06 22:48:57 $
&’/
#endif/*RCS_F77_H_*/
C ..... Call for the input parameters by name. Allow user to output
C ..... slope or intercept.
IOPT = 0
CALL EX_GETPARM( ’AVO_OPT ’, 1, IOPT )
IF ( IOPT .NE. ISLOPEPZ .AND. IOPT .NE. INTERCEPTPZ ) THEN
CALL EX_ERR_FATAL( ’AVO_OPT not recognized’ )
ENDIF
C ..... The trace number is no longer valid, since we are now stacked
ITRNO_VALIDz = 0
C ..... Set the general data type to stacked (not really stacked, but
C ..... more similar to stacked than other types)
IDTYPz = ISTACKEDpz
C ..... Reset the maximum number of data traces per ensemble, for
C ..... subsequent tools.
MAXDTRz = 1
C ..... Set the number of words that need to be saved for re-entrancy
C ..... Note that CALC_LENSAV is a macro that uses END1z and SAVE1z
C ..... to calculate the length of the common block
LEN_SAV = CALC_LENSAV
RETURN
END
C------------------------------------------------------------------------------
C
C Description:
C Standard execution routine
C
C Input/output arguments:
C TRACES - 2-d array of trace samples
C ITHDRS - 2-d array of trace header (as integer)
C RTHDRS - 2-d array of trace header (as floating point)
C NSTORED - number of stored traces
C
C------------------------------------------------------------------------------
C ..... The include file "avo.inc" contains an include for the global
C ..... parameters ("global.inc")
#include "avo.inc"
#include <header.inc>
INTEGER NSTORED, ITHDRS(NTHz,NSTORED)
REAL TRACES(NUMSMPz,NSTORED), RTHDRS(NTHz,NSTORED)
RETURN
END
C------------------------------------------------------------------------------
C
C Actual work routine
C
C------------------------------------------------------------------------------
IMPLICIT NONE
INTEGER NUMSMP, NTH, NSTORED, IH_OFFSET, I, J, ISLOPEPZ,
& INTERCEPTPZ, IOPT
REAL TRACES(NUMSMP,NSTORED), RTHDRS(NTH,NSTORED), TRACE(NUMSMP),
& SLOPE, RINTER, X(NSTORED), Y(NSTORED), WT(NSTORED)
PARAMETER ( ISLOPEPZ=1, INTERCEPTPZ=2 )
C ..... The X values (offset) will not change, so let’s get them once
DO 100 J=1,NSTORED
X(J) = RTHDRS(IH_OFFSET,J)
C ......... While we’re at it, let’s set the weights
WT(J) = 1.0
100 CONTINUE
TRACE(I) = RINTER
ENDIF
120 CONTINUE
RETURN
END
C------------------------------------------------------------------------------
C SUBROUTINE WT_LIN_REG( X_IN, Y_IN, WT, NPTS, A, B )
C------------------------------------------------------------------------------
C
C Description:
C
C Weighted linear regression routine. Least squares analysis
C is performed to solve y = Ax + B. Does not handle infinite
C slope.
C
C Input arguments:
C X_IN - array of X values
C Y_IN - array of Y values
C WT - array of weights
C
C Output arguments:
C A - slope
C B - intercept
C
C------------------------------------------------------------------------------
IMPLICIT NONE
INTEGER I, NPTS
REAL X_IN(NPTS), Y_IN(NPTS), WT(NPTS)
REAL X, SWX, SWY, SW, SWXY, SWX2, B, A
C ..... Initialize:
SWX = 0.0
SWY = 0.0
SW = 0.0
SWXY = 0.0
SWX2 = 0.0
RETURN
END
avoC.c
/*-------------------------------------------------------------------*/
/* init_avo_exer
/*
/* initialization routine for ProMAX module avo_exer
/*
/*-------------------------------------------------------------------*/
/* local variables */
int iErr;
/* set the general data type to stacked. Its not really stacked */
/* but it is closer to stacked than any of the other types. */
gr->idtyp = ISTACKED;
/*-------------------------------------------------------------------*/
/* exec_avo_exer
/*
/* execution routine for ProMAX module avo_exe
/*
/* input and output args:
/* traces - the data traces in continuous memory
/* rthdrs - floating point trace headers
/* local variables */
int iErr;
/*-------------------------------------------------------------------*/
/* acutual work routine
/* input/output
/* traces - the input traces in continuous memory
/* input:
/* rthdrs - floating point header array, in continuous memory
/* nStored - number of traces in the ensemble
/*-------------------------------------------------------------------*/
/* local variables */
int i, j, iErr;
float **rhdrs, **tracs;
float slope, intercept;
/* the offset values will not change, get them just once */
for( i = 0; i < nStored; i++ ){
parms->xVals[i] = rhdrs[i][hdrIndex("OFFSET")];
/* .. fill the weighting array while were at it */
parms->weights[i] = 1.0;
}
/*-------------------------------------------------------------------*/
/* weighted linear regression routine. A least squares analysis is
/* performed to solve y=ax+ b. Does not handle infinite slope.
/*
/* input:
/* x_in - array of input x values
/* y_in - arrry of input y values
/* wt - array of input weights
/* npts - number of points in regression
/*
/* output:
/* a - slope
/* b - intercept
/*
/*-------------------------------------------------------------------*/
void avoDemoWtLinReg( float *x_in, float *y_in, float *wt, int npts,
float *a, float *b )
/* variables */
int i;
float x, swx, swy, sw, swxy, swx2;
/* initialize */
swx = 0.0;
swy = 0.0;
sw = 0.0;
swxy = 0.0;
swx2 = 0.0;
prestk_interp.menu
'(
name: PRESTK_INTERP
label: "Prestack Interpolation"
value_tab: 35
exec_data: ("PRESTK_INTERP"
("GENERAL"
("dummy" implicit: 1)
)
)
)
prestk_interp.inc
C------------------------------------------------------------------------------
C Include file for PRESTK_INTERP
C------------------------------------------------------------------------------
IMPLICIT NONE
#include "global.inc"
prestk_interp.f
#include "prestk_interp.inc"
INTEGER LEN_SAV, ITOOLTYPE
C ..... The trace number is no longer valid, since we are adding new traces
C ..... that have no corresponding slots in the database.
ITRNO_VALIDz = 0
C ..... Set the number of words for re-entrancy and the tool type
LEN_SAV = CALC_LENSAV
ITOOLTYPE = IENSEMBLEpz
RETURN
END
#include "prestk_interp.inc"
INTEGER NSTORED, ITHDRS(NTHz,NSTORED), I, J
REAL TRACES(NUMSMPz,NSTORED), RTHDRS(NTHz,NSTORED)
C ..... Take care of the headers too (interpolated traces will have a copy
C ..... of the header just before them)
DO 130 I=1,NTHz
DO 120 J=NSTORED,2,-1
ITHDRS(I,J*2-1) = ITHDRS(I,J)
ITHDRS(I,J*2-2) = ITHDRS(I,J-1)
120 CONTINUE
130 CONTINUE
RETURN
END
prestk_interp.c
ENDPARMS(parms)
/*-------------------------------------------------------------------
Description:
Initialization routine for prestack interp
output arguments:
len_save - number of 4-byte words to save for re-entrancy
itooltype - processing tool type
---------------------------------------------------------------------*/
/* The trace number is no longer valid, since we are adding new traces */
/* that have no corresponding slots in the database.*/
gr->itrno_valid = FALSE;
/*********************************************************************
*
* Description:
* Execution routine for prestack interp
*
* Input/output arguments:
* traces - array of trace samples
* ithdrs - trace header (as integer)
* rthdrs - trace header (as floating [point)
/* nStored - number of traces input and output
*
**********************************************************************/
int i, j;
/* A place to store the 2-d input array, these are just pointers */
/* to locations in the input traces and rthdrs arrays. */
float **trcs, **rhdrs;
/* Take care of the headers too, interpolated traces will have a copy */
/* of the header just before them */
for( i = 0; i < gr->nth; i++ ){
for( j = *nStored-1; j > 0; j-- ){
rhdrs[2*j][i] = rhdrs[j][i];
rhdrs[2*j-1][i] = rhdrs[j-1][i];
}
}
free( trcs );
free( rhdrs );
panel_test.menu
'(
name: PANEL_TEST
label: "Panel Test"
value_tab: 42
parameter: PANLSIZE
text: "Panel size"
type: typein:
type_desc: ( int: 7 nil nil )
value: 21
mouse_text "Enter the number of traces per panel."
parameter: PANLEDGE
text: "Panel edge"
type: typein:
type_desc: ( int: 7 nil nil )
value: 5
mouse_text "Enter the size of the panel edge."
parameter: PANL_MIX
text: "Panel mix"
type: typein:
type_desc: ( int: 7 nil nil )
value: 0
mouse_text "Enter the size of the panel mix."
parameter: PANL_TPD
text: "Panel trace pad"
type: typein:
type_desc: ( int: 7 nil nil )
value: 0
mouse_text "Enter the size of the panel trace pad."
parameter: PANL_SPD
text: "Panel sample pad"
type: typein:
type_desc: ( int: 7 nil nil )
value: 0
mouse_text "Enter the size of the panel sample pad."
exec_data: ("PANEL_TEST"
("GENERAL"
("version" implicit: "%Z%%M% %I% %G%" )
("PANLSIZE" implicit: (value 'PANLSIZE))
("PANLEDGE" implicit: (value 'PANLEDGE))
("PANL_MIX" implicit: (value 'PANL_MIX))
("PANL_TPD" implicit: (value 'PANL_TPD))
("PANL_SPD" implicit: (value 'PANL_SPD))
)
)
)
panel_test.inc
C------------------------------------------------------------------------------
C Include file for PANEL_TEST
C------------------------------------------------------------------------------
IMPLICIT NONE
#include "global.inc"
#include "mem.inc"
panel_test.f
#include "panel_test.inc"
INTEGER LEN_SAV, ITOOLTYPE, NPANEL_SIZE, NPANEL_EDGE,
& NPANEL_MIX
CHARACTER CSCCS_KEY*50
C ..... Set the panel parameters (and allow them to be returned with a
C ..... different value).
CALL EX_PANEL_PARMS( NPANEL_SIZE, NPANEL_EDGE, NPANEL_MIX,
& NPAD_TRACES, NPAD_SAMPS )
RVAL = 1.0
LEN_SAV = CALC_LENSAV
ITOOLTYPE = IPANELpz
RETURN
END
#include "panel_test.inc"
INTEGER NSTORED, ITHDRS(NTHz,NSTORED), I, J
REAL TRACES(NUMSMPz+NPAD_SAMPS,NSTORED), RTHDRS(NTHz,NSTORED)
IF ( CLEANUPz ) RETURN
DO 110 J=1,NSTORED
DO 100 I=1,NUMSMPz+NPAD_SAMPS
TRACES(I,J) = RVAL
100 CONTINUE
110 CONTINUE
C ..... Write values to padded traces, you will not see the result,
C ..... this is just to demonstrate where the padded traces are.
DO 130 J = NSTORED+1, NSTORED+NPAD_TRACES
DO 120 I = 1, NUMSMPz+NPAD_SAMPS
TRACES(I,J) = RVAL
120 CONTINUE
130 CONTINUE
RETURN
END
panelTest.c
ENDPARMS (parms)
/*-------------------------------------------------------------------*/
/* init_panel_test
/*
/* initialization routine for ProMAX module sine_wave
/*
/*-------------------------------------------------------------------*/
/* local variables */
int panelSize;
int panelEdge;
int panelMix;
/* set the panel parameters. Note that the argument values can be */
/* changed by this routine*/
exPanelParms( &panelSize, &panelEdge, &panelMix,
&nPadTraces, &nPadSamples );
/*-------------------------------------------------------------------*/
/* exec_panelTest
/*
/* execution routine for ProMAX module panel_test
/* input and output args:
/* traces - the data traces in continuous memory
/* rthdrs - floating point trace headers
/* ithdrs - integer trace headers
/* nStored - number of traces in the input array panel
/*-------------------------------------------------------------------*/
/* local variables */
float **tracs;
int i,j;
int nTraces, nSamples;
/* set the trace sample values for the live traces in the panel */
for( i = 0; i < *nStored; i++ ){
for( j = 0; j < nSamples; j++ ){
tracs[i][j] = parms->sampValue;
}
}
/* set the trace sample values for the padding traces. You won't */
/* see the result of this, it is just for demonstration of where */
/* the padding traces are located in the trace array */
for( i = *nStored; i < nTraces; i++ ){
ens_define.menu
'(
name: ENS_DEFINE
label: "Ensemble Re-define"
value_tab: 51
parameter: PRIM_KEY
text: "Select PRIMARY key to re-define output ensembles"
type: function:
type_desc: (header_list headers)
value: "NONE "
selected_item: "**INVALID**"
mouse_text: "Use MB1 to select a header word from the headers menu as the PRIMARY
key for re-defining input ensembles."
parameter: MAXTR
text: "Maximum traces per output ensemble"
type: typein:
type_desc: ( int: 5 1 nil )
value: 0
mouse_text: "What is the maximum number of traces per output ensemble AFTER re-
defining the ensembes?"
exec_data: ("ENS_DEFINE"
("GENERAL"
("version" implicit: "@(#)ens_define.menu 40.1 11/24/92" )
("PRIM_KEY" implicit: (value 'PRIM_KEY))
("MAXTR" implicit: (value 'MAXTR))
)
)
ens_define.inc
C------------------------------------------------------------------------------
C Include file for ENS_DEFINE.
C
C Original code by S. Rutt Bridges, April 30, 1991.
C------------------------------------------------------------------------------
IMPLICIT NONE
#include "global.inc"
ens_define.f
C------------------------------------------------------------------------------
C
C Initialization routine for ENS_DEFINE
C
C ENS_DEFINE is an ensemble definition tool. It resets ensemble flags
C based on a change in a header word. Output ensembles may be larger
C or smaller, depending on the changes in the header word. Examples of
C the use of this tool:
C
C 1. In the Ensemble Decon Parameter Test macro, we input data that
C has a primary sort key of 'REPEAT' and a secondary sort key of
C 'CDP'. For the subsequent CDP stack, we need to have ensembles
C defined by CDP. ENS_DEFINE provides this function.
C
C 2. Typically for Radon Filtering, we need to use Ensemble Split to
C seperate the positive and negative offsets. However, for a
C subsequent CDP stack these traces need to form a single ensemble.
C ENS_DEFINE provides this function.
C
C 3. To create a single ensemble from a CDP stack, you should use the
C special option of setting the primary header key word to NONE
C which will force the entire dataset to be combined into a single
C ensemble.
C
C Output parameters:
C LEN_SAV - the number of parameters that must be saved
C ITOOLTYPE - the tool type
C
C Original code by S. Rutt Bridges, April 30, 1991.
C------------------------------------------------------------------------------
#include "ens_define.inc"
#include "runtime.inc"
cdd - this in now allowed, as a way of indicating that we don't care what the
cdd primary key is
c IF (CPRIM_KEY(1:4) .EQ. 'NONE')
c & CALL EX_ERR_FATAL( 'Primary key must be specified.' )
C ..... Set the maximum number of traces to buffer, and the trace and
C ..... sample padding.
CALL EX_BUFF_PARMS( MAXDTRz+1, 0, 0 )
C ..... set the number of words that need to be saved and the tool type
LEN_SAV = CALC_LENSAV
ITOOLTYPE = ISNL_BUFFpz
RETURN
END
C------------------------------------------------------------------------------
C Flow routine for ENS_DEFINE.
C------------------------------------------------------------------------------
#include "ens_define.inc"
INTEGER NSTORED, ITHDRS(NTHz,NSTORED), IFOUND_EOJ, NOUTPUT,
& NOVERLAP, J
REAL TRACES(NUMSMPz,NSTORED), RTHDRS(NTHz,NSTORED)
RETURN
END
C------------------------------------------------------------------------------
C
C Execution routine for ENS_DEFINE
C
C Input parameters:
C NTR_BUFF - size of the trace buffer (MAX(NSTORED, NOUTPUT)
C from FLOW_ENS_DEFINE
C
C Input/output parameters:
C ITHDRS - 2-d array of INTEGER*4 trace header entries
C RTHDRS - 2-d array of REAL*4 trace header entries
C
C Unused parameters:
C TRACES - 2-D array of trace samples
C
C Original code by S. Rutt Bridges, April 30, 1991.
#include "ens_define.inc"
#include "header.inc"
INTEGER NTR_BUFF, J, ITHDRS(NTHz,NTR_BUFF)
REAL TRACES(NUMSMPz,NTR_BUFF), RTHDRS(NTHz,NTR_BUFF)
RETURN
END
interp_sb.menu
'(
name: INTERP_SB
label: "Single Buffer Trace Interpolation"
value_tab: 35
exec_data: ("INTERP_SB"
("GENERAL"
("dummy" implicit: 1)
)
)
)
interp_sb.c
/*--------------------------------------------------------------------------*/
/* interp_sb
/* An example of a single buffer tool in C. The program collects an ensemble
/* of data traces then passes the ensemble on to the exec_ subroutine.
/* The program uses a change in Primary sort key value to detect that
/* there has been a change in the ensemble rather than by using the END_ENS
/* flag. This is done for demonstration of the nOverlap variable in
/* the flow routine. The output data traces are the original traces
/* plus a trace that is linearly interpolated between each input trace.
/* The output ensemble therefore has 2*N - 1 traces where
/* N is the number of input traces.
/*
/* The example called interp_db.c is identical to this example except that
/* this is a single buffer tool and therefore the input trace buffer also
/* serves as the ouptut trace buffer.
/*-------------------------------------------------------------------------*/
ENDPARMS(parms)
/*-------------------------------------------------------------------*/
/*
/* description:
/* initialization routine for interp_sb:
/*
/* output arguments:
/* len_sav - length of the saved common block
/* itooltype - type of tool
/*
/*-------------------------------------------------------------------*/
/* Get the header array index for the primary sort key of the input data. */
/* Note that 1 is subracted from the value of globalRuntime->ipkey */
/* to obtain the index of the primary sort key that is appropriate for */
/* the C language. The global variable trace indicies are indexed for */
/* FORTRAN. This rule is true for globalRuntime->iskey as well as */
/* the standard headers. */
parms->pKeyHdrIndx = gr->ipkey - 1;
/* Notify trace exec of maximum number of traces it will have to hold for */
/* this module. The ex_buff_parms_() routine must be called in the init */
/* subroutine of any buffered tool. NOTE that the routine is a FORTRAN */
/* routine that is being directly called by this C routine so the address of */
/* the variables are passed. */
max_to_buffer = 2*gr->maxdtr;
nPadTraces = 0;
nPadSamples = 0;
ex_buff_parms_( &max_to_buffer, &nPadTraces, &nPadSamples );
/* we are going to output more traces per ensemble than are input */
gr->maxdtr = (2*gr->maxdtr) - 1;
/*--------------------------------------------------------------------*/
/*
/* flow tool for interp_sb
/*
/* input args
/* traces - 2d array of data traces
/* ithdrs - 2-d array of input integer trace headers
/* rthdrs - 2-d array of input float trace headers
/*
/*
/*--------------------------------------------------------------------*/
if( *nStored == 1 ){
/* .. There is only one trace so we can't compare it to anything. This */
/* .. situtation should only occur on the first call to the routine unless */
/* .. the last trace input is a single-trace ensemble in which case more */
/* .. code would be needed to handle that special case. We leave out that */
/* .. extra code here as it would clutter the example. */
*nOutput = 0;
return;
}
/* see if the primary key header value of most recent input trace has changed */
if( rhdrs[*nStored-2][parms->pKeyHdrIndx] != rhdrs[*nStored-1][parms-
>pKeyHdrIndx] ||
*ifound_eoj != 0 ){
/* .. we have found enough traces to process */
/* .. Set the number of traces to output from exec, a non-zero value tells */
/* .. the trace executive that it is time to pass the traces to */
/* .. exec_interp_sb_ */
*nOutput = 2*(*nStored-1) - 1;
/* .. set the number of traces that are being passed to the exec_ subroutine */
parms->nInEnsemble = *nStored - 1;
/* .. Let the last trace input on this call be the first trace input */
/* .. on the next call since it is part of the next ensemble that we */
/* .. will be collecting. */
*nOverlap = 1;
}
else{
/* .. signal the trace executive that we aren't ready to pass traces exec_ */
*nOutput = 0;
}
free( rhdrs );
/*-------------------------------------------------------------------*/
/*
/* description:
/* exectution routine for interp_sb
/*
/* input arguments:
/* nStored - the amount of memory available (in traces) in the
/* traces array. NOTE that the actual number of traces
/* input was determined in the flow_interp_sb routine and
/* passed to exec_interp_sb via the parms->nInEnsemble
/* variable.
/*
/* input/output arguments:
/* traces - 2-d array of traces
/* ithdrs - 2-d array of integer trace headers
/* rthdrs - 2-d array of float trace headers
/*
/*-------------------------------------------------------------------*/
int i,j;
/* Arrange the trace and header arrays into 2d arrays that are easy to handle. */
tracs = fVecTo2d( traces, *nStored, gr->numsmp );
rhdrs = fVecTo2d( rthdrs, *nStored, gr->nth );
/* Take care of the headers too, interpolated traces will have a copy */
/* of the header just before them */
for( i = 0; i < gr->nth; i++ ){
for( j = parms->nInEnsemble-1; j > 0; j-- ){
rhdrs[2*j][i] = rhdrs[j][i];
rhdrs[2*j-1][i] = rhdrs[j-1][i];
}
}
free( tracs );
free( rhdrs );
semblance.menu
'(
name: SEMBLANCE
label: "Semblance Vel Analysis"
parameter: VSTART
text: "Minimum analysis velocity"
type: typein:
type_desc: ( real: 7 1.0e-5 nil )
value: -1.0
mouse_text: "Minimum expected stacking velocity."
parameter: VEND
text: "Maximum analysis velocity"
type: typein:
type_desc: ( real: 7 1.0e-4 nil )
value: -1.0
mouse_text: "Maximum expected stacking velocity."
parameter: NVELS
text: "Number of test velocities"
type: typein:
type_desc: ( int: 3 1 999 )
value: 25
mouse_text: "Number of constant velocities to use to compute semblance values."
parameter: NORM
text: "Semblance normalization mode"
type: pop_choose:
type_desc: (
("Scale Time Slice" 1 "Divide time slice of semblance values by the maximum in
time slice.")
("Scale Panel" 2 "Divide all semblance values by the maximum semblance in
panel.")
("No Scaling" 3 "Do no scaling of semblance values.")
)
mouse_text: "Choose method of normalizing semblances."
parameter: RNOISE
text: "Noise factor for normalization"
type: typein:
type_desc: ( real: 3 0.0 nil )
value: 0.1
mouse_text: "Add this value to maximum semblance (in time slice, or panel) before
scaling. Recommend 0.0 to 0.4"
parameter: STRETCH
text: "Stretch factor"
type: typein:
type_desc: ( real: 3 0.0 999.0 )
value: 50.0
mouse_text: "Maximum percentage stretch allowed in NMO calculation?"
parameter: MIN_FOLD
text: "Minimum fold"
type: typein:
type_desc: ( int: 2 1 99 )
value: 4
mouse_text: "Minimum fold required for semblance calculation?"
exec_data: ("SEMBLANCE"
("GENERAL"
("version " implicit: "@(#)semblance.menu 40.1 11/24/92" )
("VSTART " implicit: (value 'VSTART))
("VEND " implicit: (value 'VEND))
("NVELS " implicit: (value 'NVELS))
("NORM " implicit: (value 'NORM))
("RNOISE " implicit: (value 'RNOISE))
("STRETCH " implicit: (value 'STRETCH))
("MIN_FOLD" implicit: (value 'MIN_FOLD))
)
)
rules: (
semblance.inc
IMPLICIT NONE
C------------------------------------------------------------------------------
C Include file for SEMBLANCE
C------------------------------------------------------------------------------
#include "global.inc"
semblance.f
C------------------------------------------------------------------------------C
Initialization routine for SEMBLANCE
C------------------------------------------------------------------------------
#include "semblance.inc"
#include "hdr_err.inc"
#include "header.inc"
#include "mem.inc"
CHARACTER CDESC*32
INTEGER IERR, LEN_SAV, ITOOLTYPE, IOK_HDR,
& MAXDTRZ_SAVE, I
#ifndef RCS_F77_H_
#define RCS_F77_H_
CHARACTER RCS_KEY*65
DATA RCS_KEY/
&’ ProMAX $Id: semblance.f,v 20031.6 2006/03/31 21:27:35 djohnston Exp $
$Revision: 20031.6 $ $Date: 2006/03/31 21:27:35 $
&’/
#endif/*RCS_F77_H_*/
C ..... The trace number is no longer valid, and the geometry no longer matches
ITRNO_VALIDz = 0
IGEOM_MATCHz = 0
C ..... Made sure that OFFSET, END_ENS, and TRACENO are present
IF ( IOK_HDR(IAOFFSETz) .NE. 1 ) CALL EX_ERR_FATAL(
& ’AOFFSET not found in trace header’ )
IF ( IOK_HDR(IOFFSETz) .NE. 1 ) CALL EX_ERR_FATAL(
& ’OFFSET not found in trace header’ )
IF ( IOK_HDR(IEND_ENSz) .NE. 1 ) CALL EX_ERR_FATAL(
C ..... Set the maximum number of traces to buffer, and the trace and
C ..... sample padding.
CALL EX_BUFF_PARMS( MAXDTRZ_SAVE, 0, 0 )
C ..... Set the number of words that need to be saved and set the tool type
LEN_SAV = LENSAVED
ITOOLTYPE = IDBL_BUFFpz
RETURN
END
C------------------------------------------------------------------------------
C Flow routine for SEMBLANCE.
C------------------------------------------------------------------------------
#include "semblance.inc"
#include "header.inc"
#include "mem.inc"
INTEGER NSTORED, ITHDRS(NTHz,NSTORED), IFOUND_EOJ, NOUTPUT,
& NOVERLAP
REAL TRACES(NUMSMPz,NSTORED), RTHDRS(NTHz,NSTORED)
RETURN
END
C------------------------------------------------------------------------------
C Execution routine for SEMBLANCE.
C------------------------------------------------------------------------------
#include "semblance.inc"
#include "mem.inc"
#include "header.inc"
INTEGER NTR_BUFF_IN, NTR_BUFF_OUT, J, IERR,
& ITHDRS_IN(NTHz,NTR_BUFF_IN), ITHDRS_OUT(NTHz,NTR_BUFF_OUT)
PTRDIFF_T IX_WORK1
REAL TRACES_IN(NUMSMPz,NTR_BUFF_IN),
& TRACES_OUT(NUMSMPz,NTR_BUFF_OUT),
& RTHDRS_IN(NTHz,NTR_BUFF_IN), RTHDRS_OUT(NTHz,NTR_BUFF_OUT)
IF (CLEANUPz) RETURN
C ..... Calculate the semblance (also need one addition scratch buffer)
CALL MEMORY_RESBUFF( NTR_BUFF_IN*NUMSMPz, IX_WORK1, IERR )
CALL SEMBLANCE_WORK( TRACES_IN, NUMSMPz, RTHDRS_IN, NTHz,
& NTR_BUFF_IN, RSPACEz(IX_WORK1), RSPACEz(IX_WORK2),
& RSPACEz(IX_WORK3), TRACES_OUT, NVELS, NOUT,
& RSPACEz(IX_WORK), IAOFFSETz, SAMPRATz, VSTART, VEND,
& IH_VEL, RSPACEz(IX_VELSAVE), INA_STATz, NFFT, NORM,
& RNOISE, MIN_FOLD, STRETCH, RSPACEz(IX_SAVE) )
CALL MEMORY_FREEBUFF( NTR_BUFF_IN*NUMSMPz, IX_WORK1, IERR )
RETURN
END
IMPLICIT NONE
INTEGER NSAMPS, NTH, NSTORED, IH_OFFSET, I, J, K, NVELS, NSUMS,
& IH_VEL, LENHALF, NFFT, NORM, MIN_FOLD, IH_NA_STAT, NOUT,
& IOUT, N1, N2
REAL TRACES(NSAMPS,NSTORED), TRWORK(NSAMPS,NSTORED), STATIC,
& WORK(NSAMPS), VELARR(NSAMPS,NOUT), SAMPRATE, VSTART,
& VEND, VINC, VEL, OFFSET, VELT, VELV, VELSAVE(NVELS),
& STRETCH, RTHDRS(NTH,NSTORED), WORK2(NSAMPS), SUM, SUM2,
& WORK3(NSAMPS), SAVE(NSAMPS), RMAX, RNOISE, RMAX_PANL, XBYV2
C ..... Initialize:
VINC = (VEND - VSTART) / FLOAT(NVELS-1)
C ..... AGC all of the data first (1000.0 ms or the trace length)
LENHALF = NINT( ( 1000.0 / SAMPRATE ) / 2.0 )
IF ( LENHALF .GT. NSAMPS/2 ) LENHALF = NSAMPS/2
DO 90 J=1,NSTORED
CALL STAT_AGC_RUNAVG( TRACES(1,J), WORK2, NSAMPS,
& LENHALF, 0 )
90 CONTINUE
C ............. Calculate end sample such that we don’t pull samples from
C beyond trace bottom
IF( XBYV2 .GT. (NSAMPS - 1)**2 ) THEN
N2 = 1
ELSE
N2 = 1 + NINT( - STATIC +
& SQRT( (NSAMPS - 1)**2 - XBYV2 ) )
IF( N2 .LT. 1 ) N2 = 1
ENDIF
110 CONTINUE
200 CONTINUE
VELARR(I,NVELS+2) = RMAX/RMAX_PANL
VELARR(I,NVELS+3) = RMAX/RMAX_PANL
ENDIF
210 CONTINUE
RMAX = RMAX_PANL
C ......... scale all semblance values
IF (RMAX .GT. 0.0) THEN
RMAX = (1.0 + RNOISE) / (RMAX + RNOISE)
CALL VSMUL(VELARR(1,1), 1, RMAX, VELARR(1,1),
& 1, NVELS*NSAMPS)
ENDIF
ENDIF
RETURN
END
#else
SUBROUTINE INIT_SEMBLANCE( LEN_SAV, ITOOLTYPE )
IMPLICIT NONE
INTEGER LEN_SAV, ITOOLTYPE
END
IMPLICIT NONE
#include <global.inc>
INTEGER NSTORED, ITHDRS(NTHz,NSTORED), IFOUND_EOJ, NOUTPUT,
& NOVERLAP
REAL TRACES(NUMSMPz,NSTORED), RTHDRS(NTHz,NSTORED)
RETURN
END
IMPLICIT NONE
#include <global.inc>
INTEGER NTR_BUFF_IN, NTR_BUFF_OUT,
& ITHDRS_IN(NTHz,NTR_BUFF_IN), ITHDRS_OUT(NTHz,NTR_BUFF_OUT)
REAL TRACES_IN(NUMSMPz,NTR_BUFF_IN),
& TRACES_OUT(NUMSMPz,NTR_BUFF_OUT),
& RTHDRS_IN(NTHz,NTR_BUFF_IN), RTHDRS_OUT(NTHz,NTR_BUFF_OUT)
RETURN
END
interp_db.menu
'(
name: INTERP_DB
label: "Double Buffer Trace Interpolation"
value_tab: 35
exec_data: ("INTERP_DB"
("GENERAL"
("dummy" implicit: 1)
)
)
)
interp_db.c
/*--------------------------------------------------------------------------*/
/* interp_db
/* An example of a double buffer tool in C. The program collects an ensemble
/* of data traces then passes the ensemble on to the exec_ subroutine.
/* The program uses a change in Primary sort key value to detect that
/* there has been a change in the ensemble rather than by using the END_ENS
/* flag. This is done for demonstration of the nOverlap variable in
/* the flow routine. The output data traces are the original traces
/* plus a trace that is linearly interpolated between each input trace.
/* The output ensemble therefore has 2*N - 1 traces where
/* N is the number of input traces.
/*
/* The single buffer tool example called interp_sb.c is identical to
/* this example except that this is a double buffer tool and therefore
/* the data traces from the input buffer are mapped to the separate
/* output trace buffer.
/*-------------------------------------------------------------------------*/
ENDPARMS(parms)
/*-------------------------------------------------------------------*/
/*
/* description:
/* initialization routine for interp_sb:
/*
/* output arguments:
/* len_sav - length of the saved common block
/* itooltype - type of tool
/*
/*-------------------------------------------------------------------*/
/* Get the header array index for the primary sort key of the input data. */
/* Note that 1 is subracted from the value of globalRuntime->ipkey */
/* to obtain the index of the primary sort key that is appropriate for */
/* the C language. The global variable trace indicies are indexed for */
/* FORTRAN. This rule is true for globalRuntime->iskey as well as */
/* the standard headers. */
parms->pKeyHdrIndx = gr->ipkey - 1;
/* Notify trace exec of maximum number of traces it will have to hold for */
/* this module. The ex_buff_parms_() routine must be called in the init */
/* subroutine of any buffered tool. NOTE that the routine is a FORTRAN */
/* routine that is being directly called by this C routine so the address of */
/* the variables are passed. */
max_to_buffer = 2*gr->maxdtr;
nPadTraces = 0;
nPadSamples = 0;
ex_buff_parms_( &max_to_buffer, &nPadTraces, &nPadSamples );
/* we are going to output more traces per ensemble than are input */
gr->maxdtr = (2*gr->maxdtr) - 1;
/*--------------------------------------------------------------------*/
/*
/* flow tool for interp_db
/*
/*
/*
/*--------------------------------------------------------------------*/
if( *nStored == 1 ){
/* .. There is only one trace so we can't compare it to anything. This */
/* .. situtation should only occur on the first call to the routine unless */
/* .. the last trace input is a single-trace ensemble in which case more */
/* .. code would be needed to handle that special case. We leave out that */
/* .. extra code here as it would clutter the example. */
*nOutput = 0;
return;
}
/* see if the primary key header value of most recent input trace has changed */
/* .. Set the number of traces to output from exec, a non-zero value tells */
/* .. the trace executive that it is time to pass the traces to */
/* .. exec_interp_sb_ */
*nOutput = 2*(*nStored-1) - 1;
/* .. set the number of traces that are being passed to the exec_ subroutine */
parms->nInEnsemble = *nStored - 1;
/* .. Let the last trace input on this call be the first trace input */
/* .. on the next call since it is part of the next ensemble that we */
/* .. will be collecting. */
*nOverlap = 1;
free( rhdrs );
}
else{
/* .. signal the trace executive that we aren't ready to pass traces exec_ */
*nOutput = 0;
}
/*-------------------------------------------------------------------*/
/*
/* description:
/* exectution routine for interp_db
/*
/* input arguments:
/* nStored - the amount of memory available (in traces) in the
/* traces array. NOTE that the actual number of traces
/* input was determined in the flow_interp_db routine and
/* passed to exec_interp_db via the parms->nInEnsemble
/* variable.
/*
/* input/output arguments:
/* traces_in - 2-d array of input traces
/* ithdrs_in - 2-d array of input integer trace headers
/* rthdrs_in - 2-d array of input float trace headers
/*
/*-------------------------------------------------------------------*/
void
exec_interp_db_( float *traces_in, int *ithdrs_in,
float *rthdrs_in, int *nTrBuffIn,
float *traces_out, int *ithdrs_out,
float *rthdrs_out, int *nTrBuffOut )
/* Arrange the trace and header arrays into 2d arrays that are easy to handle. */
tracs_in = fVecTo2d( traces_in, *nTrBuffIn, gr->numsmp );
rhdrs_in = fVecTo2d( rthdrs_in, *nTrBuffIn, gr->nth );
/* Take care of the headers too, interpolated traces will have a copy */
/* of the header just before them */
for( i = 0; i < gr->nth; i++ ){
for( j = parms->nInEnsemble-1; j > 0; j-- ){
rhdrs_out[2*j][i] = rhdrs_in[j][i];
rhdrs_out[2*j-1][i] = rhdrs_in[j-1][i];
}
}
free(tracs_in);
free(rhdrs_in);
free(tracs_out);
free(rhdrs_out);
transform.menu
'(
name: TRANSFORM
label: "Transform"
value_tab: 35
exec_data: ("TRANSFORM"
("GENERAL"
("dummy" implicit: nil)
)
)
)
transform.inc
C------------------------------------------------------------------------------C
Include file for TRANSFORM
C------------------------------------------------------------------------------
IMPLICIT NONE
#include <global.inc>
#include <mem.inc>
transform.f
#include "transform.inc"
#include <header.inc>
INTEGER LEN_SAV, ITOOLTYPE, IOK_HDR
#ifndef RCS_F77_H_
#define RCS_F77_H_
CHARACTER RCS_KEY*65
DATA RCS_KEY/
&’ ProMAX $Id: transform.f,v 20031.5.12.1 2007/02/06 22:51:43 djohnston Exp
$ $Revision: 20031.5.12.1 $ $Date: 2007/02/06 22:51:43 $
&’/
#endif/*RCS_F77_H_*/
C ..... The trace number is no longer valid, and the geometry no longer matches
ITRNO_VALIDz = 0
IGEOM_MATCHz = 0
C ..... Reset the domain. We will have to make up something new, since
C ..... nothing appropriate exists
IDOMAINz = 100
C ..... Save the previous values of the trace length and maximum number
C ..... of traces per ensemble (we will need them in exec phase)
MAXDTRZ_OLD = MAXDTRz
NUMSMPZ_OLD = NUMSMPz
C ..... Reset the trace length and maximum number of traces per ensemble
MAXDTRz = NUMSMPZ_OLD
NUMSMPz = MAXDTRZ_OLD
C ..... Set the number of words that need to be saved and the tool type
C ..... Note that CALC_LENSAV is a macro that uses END1z and SAVE1z
C ..... to calculate the length of the common block
LEN_SAV = CALC_LENSAV
ITOOLTYPE = ICOMPLEXpz
RETURN
END
#include "transform.inc"
#include <header.inc>
INTEGER ITHDR(NTHz)
REAL TRACE(*), RTHDR(NTHz)
ELSE
C ............. Otherwise, we are still in fill mode
CALL EX_FILLMODE
RETURN
ENDIF
ENDIF
C ..... Copy a header from storage (same one every time!!). This is a
C ..... nasty problem
CALL VMOV( ISPACEz(IX_THDRS), 1, ITHDR, 1, NTHz )
ELSE
ENDIF
RETURN
END
IMPLICIT NONE
INTEGER NUMSMPZ_OLD, MAXDTRZ_OLD, I, J
REAL TRACES_OLD(NUMSMPZ_OLD,MAXDTRZ_OLD),
& TRACES_NEW(MAXDTRZ_OLD,NUMSMPZ_OLD)
DO 110 J=1,MAXDTRZ_OLD
DO 100 I=1,NUMSMPZ_OLD
TRACES_NEW(J,I) = TRACES_OLD(I,J)
100 CONTINUE
110 CONTINUE
RETURN
END
transform.c
ENDPARMS(parms)
/*-------------------------------------------------------------------
Description:
Initialization routine for transform
output arguments:
len_save - number of 4-byte words to save for re-entrancy
itooltype - processing tool type
---------------------------------------------------------------------*/
/* local variabes */
GlobalRuntime *gr = globalRuntime;
/* The trace number is no longer valid, and the geometry no longer matches */
gr->itrno_valid = 0;
gr->igeom_match = 0;
/* Save the previous values of the trace length and maximum number */
/* of traces per ensemble (we will need them in exec phase) */
parms->maxdtr_old = gr->maxdtr;
parms->numsmp_old = gr->numsmp;
/* Reset the trace length and maximum number of traces per ensemble */
gr->maxdtr = parms->numsmp_old;
gr->numsmp = parms->maxdtr_old;
/*********************************************************************
*
* Description:
* Execution routine for transform
*
* Input/output arguments:
* trace - array of trace samples
* ithdr - trace header (as integer)
* rthdr - trace header (as floating [point)
*
**********************************************************************/
if ( parms->nstored == 1 ){
/* ..... Get buffers to store input traces and trace headers. */
/* ..... Note that error checking for null returned pointers is */
/* ..... done within ealloc2. */
/* ...... free the memory that stored the original input traces */
_memFree2Float( parms->storedTrcs, "transform.c", 150 );
/* Copy a header from storage (same one every time for this exercise) */
vMov( parms->storedHdrs[0], 1, rthdr, 1, gr->nth );
}
else{
/* .. We still have more traces to dump */
ithdr[hdrIndex("END_ENS")] = NLAST;
/* .. We are still in flush mode, give the current trace to the trace */
/* .. executive and exec_transform doesn't want a new trace on the next */
/* .. since it still has traces to output. */
exFlushMode();
}
/****************************************************************
/*
/* input:
/* storedTrcs - the input traces
/* nstored - number of stored traces == number out samples
/* outTrcLen - the length in samples of the output trace
/* nstored <= outTrcLen
/* numOutTrcs - number of output traces
/*
/****************************************************************/
int i, j;
float **t;
return(t);
sine_wave.menu
'(
name: SINE_WAVE
label: "Sine Wave Generation"
value_tab: 45
parameter: PKEYNAM
text: "Primay key name"
type: circular:
type_desc: (
("Source" "SOURCE" "Generate synthetic shot gathers." )
("CDP " "CDP" "Generate synthetic CDP gathers."))
value: "SOURCE"
mouse_text: "Use B1 to toggle between SHOT or CDP gathers."
parameter: NENS
text: "Number of trace ensembles to generate"
type: typein:
type_desc: ( int: 5 1 nil )
value: 1
mouse_text: "How many ensembles do you wish to generate?"
parameter: NTRACES
text: "Number of traces per ensemble"
type: typein:
type_desc: ( int: 5 1 nil )
value: 60
mouse_text: "How many traces per ensemble do you wish to generate?"
parameter: SAMPRATE
text: "Sample interval for the synthetic traces"
type: typein:
type_desc: ( real: 7 1.0e-5 nil )
value: 2.0
mouse_text: "What is the desired sample interval (in milliseconds) for the
synthetic traces?"
parameter: TRACELEN
text: "Trace length for the synthetic traces"
type: typein:
type_desc: ( real: 7 1.0e-5 nil )
value: 2000.0
mouse_text: "What is the desired trace length (in milliseconds) for the synthetic
traces?"
parameter: FREQS
text: "List of frequencies"
type: edit:
type_desc: (31 80 5 " FORMAT: freq1 , freq2 , freq3 , ...
EXAMPLE: 60.0,125.0
HELP: EMACS Editor Widget (scroll with down/up arrow keys)
CURSOR MOVEMENT: Use the arrow keys:->,<-,etc.;Point the mouse cursor,click B1
CM: Ctrl-A Move the cursor to the BEGINNING of the current line
CM: Ctrl-E Move the cursor to the END of the current line
EDITING: All keyboard entry is in 'insert' mode
E: Backspace, Delete keysDelete one character to the LEFT of the cursor
exec_data: ("SINE_WAVE"
("SPECIAL"
("TOOLTYPE" implicit: "INPUT")
)
("GENERAL"
("PKEYNAM" implicit: (value 'PKEYNAM))
("NENS" implicit: (value 'NENS))
("NTRACES" implicit: (value 'NTRACES))
("SAMPRATE" implicit: (value 'SAMPRATE))
("TRACELEN" implicit: (value 'TRACELEN))
("FREQS" implicit: (value 'FREQS))
)
)
sine_wave.inc
C------------------------------------------------------------------------------C
Include file for SINE_WAVE
C------------------------------------------------------------------------------
IMPLICIT NONE
#include <global.inc>
#include <mem.inc>
PTRDIFF_T IX_FREQS
INTEGER NFREQS, NENS, IENS, ITRACE_IN_ENS
LOGICAL FIRST_VISIT
sine_wave.f
#include "sine_wave.inc"
#include <header.inc>
CHARACTER*8 CNAMES(4)
CHARACTER CPKEYNAM*8
INTEGER NCHARS, NTR_PER_ENS, NS, IERR, LEN_SAV,
& ITOOLTYPE, IOK_HDR
REAL SAMPRATE, TRACELEN
#ifndef RCS_F77_H_
#define RCS_F77_H_
CHARACTER RCS_KEY*65
DATA RCS_KEY/
&’ ProMAX $Id: sine_wave.f,v 20031.5.12.1 2007/02/06 22:50:26 djohnston Exp
$ $Revision: 20031.5.12.1 $ $Date: 2007/02/06 22:50:26 $
&’/
#endif/*RCS_F77_H_*/
C ..... Get the number of traces per ensemble, the sample rate, the length of
C ..... the traces, and the number of ensembles
NTR_PER_ENS = 0
SAMPRATE = 0.0
TRACELEN = 0.0
NENS = 0
CALL EX_GETPARM( ’NTRACES ’, 1, NTR_PER_ENS )
CALL EX_GETPARM( ’SAMPRATE’, 1, SAMPRATE )
CALL EX_GETPARM( ’TRACELEN’, 1, TRACELEN )
CALL EX_GETPARM( ’NENS ’, 1, NENS )
C ..... Set the primary sort flag depending on the primary key name
IF ( CPKEYNAM(1:3) .EQ. ’CDP’ ) THEN
IPSORTz = ISINpz
ENDIF
C ..... HERE ARE RUNTIME GLOBAL VARIABLES THAT YOU DON’T SET:
C ..... NTHz - the current number of 4-byte words in the trace header.
C ..... (incremented by HDR_ADD)
C ..... MODEz - the run mode ( INTERpz, IBACKGpz, IBATCHpz )
C ..... IOUNITz - the I/O unit for output diagnostics
C ..... IDATEz - the current date (seconds since 00:00:00 GMT, Jan. 1, 1970)
C ..... NPRIORFz - Number of prior processing flows
C ..... CLEANUPz - Flag indicating that the system is in cleanup mode (logical)
C ..... IERRORz - Flag indicating that the system is running under an error
C ..... condition (trying to cleanup) (logical)
C ..... INIT_ONLYz - Flag indicating that only initialization phase is
C ..... being executed (logical)
RETURN
END
#include "sine_wave.inc"
REAL TRACE(NUMSMPz), RTHDR(NTHz)
INTEGER ITHDR(NTHz)
LOGICAL NO_DATA_FOUND
IF ( FIRST_VISIT ) THEN
C ......... We only want to do this once
FIRST_VISIT = .FALSE.
IF ( NO_DATA_FOUND ) THEN
CALL EX_ERR_FATAL( ’Unable to create any traces’ )
ENDIF
ENDIF
IF ( NO_DATA_FOUND ) THEN
C ......... We have no data to output
CALL EX_QUITMODE
ELSE
C ......... We have a trace for next time
CALL EX_FLUSHMODE
ENDIF
RETURN
END
#include "sine_wave.inc"
#include <header.inc>
INTEGER ITHDR(NTHz), I
REAL TRACE(NUMSMPz), FREQS(NFREQS), RTHDR(NTHz)
LOGICAL NO_DATA_FOUND
ELSE
NO_DATA_FOUND = .FALSE.
ENDIF
DO 100 I=1,NFREQS
CALL SINE_WAVE_ADD( FREQS(I), SAMPRATz, NUMSMPz, TRACE )
100 CONTINUE
C ......... The source index number should be null until geometry is assigned
ITHDR( ISINz ) = INULLpz
ENDIF
C ..... Set the sequential trace number (null until geometry assignment)
ITHDR( ITRACENOz ) = INULLpz
C ......... Since this is the last trace, set the last-trace-in-ensemble flag
ITHDR( IEND_ENSz ) = LASTTRpz
ELSE
C ......... This is not the last trace in the ensemble, so set the flag as such
ITHDR( IEND_ENSz ) = NLASTpz
ENDIF
RETURN
END
IMPLICIT NONE
INTEGER NUMSMP, I
REAL TRACE(NUMSMP), FREQ, SAMPRAT, TIME, ANGLE, TWO_PI
DO 100 I=1,NUMSMP
TIME = FLOAT(I-1) * SAMPRAT / 1000.0
ANGLE = FREQ * TIME * TWO_PI
TRACE(I) = TRACE(I) + SIN( ANGLE )
100 CONTINUE
RETURN
END
sineWave.c
ENDPARMS (parms)
/*-------------------------------------------------------------------*/
/* init_sine_wave
/*
/* initialization routine for ProMAX module sine_wave
/*
/*-------------------------------------------------------------------*/
gatesFlag = FALSE;
nfreqs = floatDecode( newList, nChars, freqs, gatesFlag );
/* get the number of traces per ensemble, the sample rate the */
/* length of the traces, and the number of ensembles */
ntrPerEns = 0;
nens = 0;
traceLen = 0.0;
sampRate = 0.0;
/* set the tool type to simple, (one trace in one trace out). */
*itooltype = INPUT;
/*-------------------------------------------------------------------*/
/* exec_sine_wave
/*
/* execution routine for ProMAX module sine_wave
/*
/*
/*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*/
/* sineWaveNextTr
/*
/* subroutine to overlay sine waves on a trace
/* input:
/* freqs - array of frequencies to add to the sine wave
/*
/* output:
/* trace - the trace on which sine waves are written
/* ithdr - integer trace header array
/* rthdr - float trace header array
/* returns a logical (int) flag TRUE if trace could not be written to
/* FALSE if normal completion
/*
/*-------------------------------------------------------------------*/
/* local variables */
int i;
int iErr;
float offset;
/* global variables */
GlobalRuntime *gr = globalRuntime;
}
else{
/* .. inputting CDPs */
/* .. set the offset and aoffset, these values don't make much sense */
offset = (float)(parms->currTrcInEns);
rthdr[ hdrIndex("OFFSET") ] = offset;
rthdr[ hdrIndex("OFFSET") ] = (float)fabs( (double)offset );
}
return( FALSE );
/*-------------------------------------------------------------------*/
/* sineWaveAdd
/*
/* subroutine to add a sine wave to a trace
/* input:
/* freq - frequency of sine wave to add
/* sampInt - float sample interval of trace in ms
/* numsmp - number of samples in trace
/* output:
/* trace - the trace
/*
/*-------------------------------------------------------------------*/
/* local variables */
int i;
double angle, twoPi, time;
twoPi = asin(1.0)*4.0;
sc_amp.menu
'(
name: SC_AMP
label: "Sc Amp"
value_tab: 35
exec_data: ("SC_AMP"
("GENERAL"
("dummy" implicit: nil)
)
)
)
sc_amp.inc
C------------------------------------------------------------------------------
C Include file for SC_AMP
C------------------------------------------------------------------------------
IMPLICIT NONE
#include "global.inc"
LOGICAL PROCESSING
INTEGER NSHOTS, NRECS
PTRDIFF_T IX_SHOT_SUM, IX_SHOT_NORM, IX_REC_SUM, IX_REC_NORM,
& IX_TR
sc_amp.f
#include "sc_amp_exer.inc"
#include <header.inc>
INTEGER LEN_SAV, ITOOLTYPE, IERR, IOK_HDR
#ifndef RCS_F77_H_
#define RCS_F77_H_
CHARACTER RCS_KEY*65
DATA RCS_KEY/
&’ ProMAX $Id: sc_amp_exer.f,v 20031.5.12.1 2007/02/06 22:50:26 djohnston
Exp $ $Revision: 20031.5.12.1 $ $Date: 2007/02/06 22:50:26 $
&’/
#endif/*RCS_F77_H_*/
C ..... Ask for two iterations through the data, one the analyze the data
C ..... and one to process the data
CALL EX_SET_DISKITER( 2 )
C ..... Make sure that the needed geometry parameters are valid
IF ( MAXSINz .EQ. INULLpz .OR. MINSINz .EQ. INULLpz
& .OR. INCSINz .EQ. INULLpz .OR. MAXSLOCz .EQ. INULLpz
& .OR. MINSLOCz .EQ. INULLpz .OR. INCSLOCz .EQ. INULLpz )
& CALL EX_ERR_FATAL( ’Geometry parameters are null’ )
C ..... Reserve a buffer to store the sum and normalization factor for every
C ..... shot and receiver
NSHOTS = (MAXSINz-MINSINz) / INCSINz + 1
NRECS = (MAXSLOCz-MINSLOCz) / INCSLOCz + 1
CALL MEMORY_RESBUFF( NSHOTS, IX_SHOT_SUM, IERR )
CALL MEMORY_RESBUFF( NSHOTS, IX_SHOT_NORM, IERR )
CALL MEMORY_RESBUFF( NRECS, IX_REC_SUM, IERR )
CALL MEMORY_RESBUFF( NRECS, IX_REC_NORM, IERR )
C ..... Set the number of words for re-entrancy and the tool type
C ..... Note that CALC_LENSAV is a macro that uses END1z and SAVE1z
C ..... to calculate the length of the common block
LEN_SAV = CALC_LENSAV
ITOOLTYPE = ICOMPLEXpz
RETURN
END
#include "sc_amp_exer.inc"
#include <header.inc>
INTEGER ITHDR(NTHz), ISHOT, IREC
REAL TRACE(NUMSMPz), RTHDR(NTHz), SCALAR
ENDIF
ENDIF
ENDIF
RETURN
END
IMPLICIT NONE
INTEGER ISHOT, IREC, NUMSMP
REAL TRACE(NUMSMP), TR_WORK(NUMSMP), SHOT_SUM(*), SHOT_NORM(*),
& REC_SUM(*), REC_NORM(*), SUM, AVEAMP
RETURN
END
IMPLICIT NONE
INTEGER NSHOTS, NRECS, I
REAL SHOT_SUM(NSHOTS), SHOT_NORM(NSHOTS), REC_SUM(NRECS),
& REC_NORM(NRECS)
DO 100 I=1,NSHOTS
IF ( SHOT_NORM(I) .GT. 0.0 ) THEN
SHOT_SUM(I) = SHOT_SUM(I) / SHOT_NORM(I)
ELSE
SHOT_SUM(I) = 1.0
ENDIF
100 CONTINUE
DO 110 I=1,NRECS
IF ( REC_NORM(I) .GT. 0.0 ) THEN
REC_SUM(I) = REC_SUM(I) / REC_NORM(I)
ELSE
REC_SUM(I) = 1.0
ENDIF
110 CONTINUE
RETURN
END
disk_iter.menu
'(
name: DISK_ITER
label: "Disk Iteration Demo"
value_tab: 50
exec_data: ("DISK_ITER"
("GENERAL"
("DUMMY" implicit: 0)
)
)
disk_iter.c
/*--------------------------------------------------------------------*/
/* disk_iter
/* A demo program for iterating over a dataset and scaling the
/* shot records by the power of the shot record.
/*
/*--------------------------------------------------------------------*/
ENDPARMS(parms)
/*-------------------------------------------------------------------*/
/*
/* description:
/* initialization routine for disk_iter
/*
/* output arguments:
/* len_sav - length of the saved common block
/* itooltype - type of tool
/*
/*
/*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*/
/*
/* description:
/* exectution routine for disk_iter
/*
/* input/output arguments:
/* trace - data trace
/* ithdr - int header array
/* rthdr - float header array
/*
/*-------------------------------------------------------------------*/
{
int i;
float val;
parms->scalVals[parms->hdrIndexSIN] += trace[i]*trace[i];
}
}
/* .. we are in just getting info from traces, not passing them on yet */
exFillMode();
}
else{
/* .. this is the second pass of the data */
/* .. put this trace back into the flow and receive one on the next call */
exPipeMode();
}
prestack.menu
'(
name: DOMAIN_READ
label: "Domain Read*"
value_tab: 47
parameter: LABEL
text: "Select trace data file"
type: function:
type_desc: (dataset_list datasets)
value: "no entry"
selected_item: "* No Datasets Found *"
mouse_text: "Use Mouse Button 1 to select a trace data file description from the
datasets menu."
parameter: DOMAIN
text: "Domain of the data"
type: pop_choose:
type_desc: (
("CDP" 1 "CDP domain." )
("SIN" 2 "Source domain.")
("SRF" 3 "Surface location domain." )
)
mouse_text: "Use B1 to pop up a menu to select the domain."
exec_data: ("DOMAIN_READ"
("SPECIAL"
("TOOLTYPE" implicit: "STAND_ALONE")
("PATHNAME" implicit: "prestack.exe")
)
("GENERAL"
("LABEL" implicit: (value 'LABEL))
("DOMAIN" implicit: (value 'DOMAIN))
)
)
)
prestack.f
C This is the C "wrapper" that passes command line args to the FORTRAN
C stand alone program. This produces the main executable file that is
C referenced in the menu under the "special" parameter section.
C
C #include <stdlib.h>
C
C int main( int argc, char **argv )
C {
C prestack_( &argc, argv[1] );
C return EXIT_SUCCESS;
C }
C ..... This is a sample program that shows how a stand-alone program can
C ..... use the database to grab traces without searching. Traces are
C ..... selected from disk in any order by accessing the trace file using
C ..... the orginal trace number.
IMPLICIT NONE
#include "global.inc"
#include "mem.inc"
INTEGER NARGS, ID_PACKET, IERR, NCHARS, ID_DATASET, IREAD_ONLY,
& NDFILES, ISWAPENDS, ITRTOTAL, NUMSMP, NTH, MAXDTR, MAXATR,
& IPSORT, IPKEY, ISKEY, IDTYP, IDOMAIN, NTRACES, IGEOM_MATCH,
& ITRNO_VALID, NPRIORF, IFORMAT, LENGTH, IH_PKEY,
& MAXFOLD, NENS, INPUT_DOMAIN
PTRDIFF_T IX_TRACE, IX_THDR
REAL SAMPRAT, SOFTRLP, GEORLSP
CHARACTER CINPUT(*), CAREA(16), CLINE(16)
CHARACTER CPACKET_FILE*128, CLABEL*8, CDESC*32, CHDRNAM*8,
& CENS_FLAG*3
C ..... Load the character ARRAY into a character STRING. Be sure that you
C ..... understand the difference.
CALL U_CARR2STR( CINPUT, CPACKET_FILE, 128 )
C ..... Open the parameter packet file, get back the ID, area, and line
CALL PKT_OPEN_LOAD( CPACKET_FILE, ’DOMAIN_READ ’, ID_PACKET,
& CAREA, CLINE )
IF ( ID_PACKET .EQ. 0 ) CALL U_ERR_FATAL(
& ’Unable to open packet file’ )
C ..... Initialize the database for this area and line. Note that CAREA
C ..... and CLINE are character arrays, not character strings. This call
C ..... set globals geom. from LIN OPF and directory path for database
C ..... routines.
CALL DB_INIT_LINE( CAREA, CLINE, IERR )
IF ( IERR .NE. 0 ) THEN
CALL REPORT_PROMAX_ERR( IERR )
C ..... Get the label for the dataset from the packet file. Parameters
C are input using standalone version of EX_GET_PARM
CALL U_CGETPARM( ID_PACKET, ’LABEL ’, 1, CLABEL, NCHARS )
C ..... Get misc. info on the dataset. This is where runtime globals
C ..... are set.
CALL DISKIO_INFO( ID_DATASET, NDFILES, ISWAPENDS,
& ITRTOTAL, SAMPRAT, NUMSMP, NTH, MAXDTR,
& MAXATR, IPSORT, IPKEY, ISKEY, IDTYP, IDOMAIN,
& NTRACES, IGEOM_MATCH, ITRNO_VALID, NPRIORF, SOFTRLP,
& GEORLSP )
IF ( IGEOM_MATCH .NE. 1 )
& CALL U_ERR_FATAL( ’Geometry does not match database’)
IF ( ITRNO_VALID .NE. 1 )
& CALL U_ERR_FATAL( ’Trace numbers do not match database’)
C ..... Set up the trace headers (this will cause a bunch of calls to
C ..... HDR_ADD, creating all of the header entries that were found in
C ..... the dataset). Complete header description info (list of names,
C ..... format, length, etc) is now available using the same in-line
C ..... executive header subroutines.
CALL DISKIO_THDR_SETUP( ID_DATASET, IERR )
C ..... Now we can get header information. We are after the index of
C ..... the primary key in question.
IF ( CENS_FLAG .EQ. ’CDP’ ) THEN
CHDRNAM = ’CDP ’
ELSEIF ( CENS_FLAG .EQ. ’SIN’ ) THEN
CHDRNAM = ’SIN ’
ELSEIF ( CENS_FLAG .EQ. ’SRF’ ) THEN
CHDRNAM = ’REC_SLOC’
ENDIF
CALL HDR_NAMINFO( CHDRNAM, CDESC, LENGTH, IFORMAT,
& IH_PKEY, IERR )
IF ( IERR .NE. 0 ) CALL U_ERR_FATAL(
& ’Domain key ’ // CHDRNAM // ’ not found in header’ )
C ..... Allocate buffers for a trace and a trace header. Same use
C ..... of memory routines as in executive.
CALL MEMORY_RESBUFF( NUMSMP, IX_TRACE, IERR )
CALL MEMORY_RESBUFF( NTH, IX_THDR, IERR )
C ..... Determine the actual number of ensembles and the maximum fold.
C ..... Note that all of these variables were set by DB_INIT_LINE. You
C ..... should check to see if they are null (geometry not loaded).
IF ( CENS_FLAG .EQ. ’CDP’ ) THEN
NENS = ( MAXCDPz - MINCDPz ) / INCCDPz + 1
MAXFOLD = NTRCDPz
ELSEIF ( CENS_FLAG .EQ. ’SIN’ ) THEN
NENS = ( MAXSINz - MINSINz ) / INCSINz + 1
MAXFOLD = MAXCPSz
ELSEIF ( CENS_FLAG .EQ. ’SRF’ ) THEN
NENS = ( MAXSLOCz - MINSLOCz ) / INCSLOCz + 1
MAXFOLD = MAXTPRz
ENDIF
END
IMPLICIT NONE
#include "global.inc"
C ..... Assign the secondary key domain (not called ’FOLD’ in SIN domain)
C ..... Also assign the primary key name
IF ( CENS_FLAG .EQ. ’CDP’ ) THEN
CS_DOMAIN = ’FOLD ’
CPKEYNAM = ’CDP ’
ELSEIF ( CENS_FLAG .EQ. ’SRF’ ) THEN
CS_DOMAIN = ’FOLD ’
CPKEYNAM = ’SRF ’
ELSEIF ( CENS_FLAG .EQ. ’SIN’ ) THEN
CS_DOMAIN = ’NCHANS ’
CPKEYNAM = ’SIN ’
ENDIF
C ......... Get the fold for this ensemble. Use the ensemble number to examine
C ......... the appropriate ordered parameter file and retrieve the fold.
CALL DB_ENSEMBLE_MAP( ITOKEN1, CPKEYNAM, CPKEYNAM,
& CS_DOMAIN, IENS, IFOLD, IFOUND_VAL, IERR )
C ......... Note that in some situations this might not be a fatal error.
IF ( IFOUND_VAL .NE. 1 .OR. IERR .NE. 0 ) THEN
WRITE (*,*) CPKEYNAM, J, IFOUND_VAL, IERR
CALL U_ERR_FATAL( ’Error getting FOLD’ )
ENDIF
WRITE (*,*)
C ......... Read every trace in the ensemble. Note that we are looping over
C ......... the fold for this ensemble.
DO 100 I=1,IFOLD
C ............. Given the primary key and sequence number within ensemble,
C ............. get the trace number. Again the order parameter files are
C ............. the vehicle for extracting the all important original trace #
CALL DB_TRACE_MAP( ITOKEN2, CPKEYNAM, ’sequence’,
& ’traceno ’, IENS, I, ITRACENO, IFOUND_VAL, IERR )
C ............. Note that in some situations this might not be a fatal error
IF ( IFOUND_VAL .NE. 1 .OR. IERR .NE. 0 ) THEN
WRITE (*,*) CPKEYNAM, I, IFOUND_VAL, IERR
CALL U_ERR_FATAL( ’Error getting TRACENO’ )
ENDIF
C ............. This reads in a trace and headers given the original trace
C ............. number. ITRACENO can be replaced with a negative integer to
C ............. simply access the traces by sequential order (ie -143 ->
C ............. gets the 143rd trace).
CALL DISKIO_GET_TR( ID_DATASET, ITRACENO,
& ITHDR, TRACE, IERR )
100 CONTINUE
110 CONTINUE
RETURN
END
Makefile_prestack
##############################################################################
# RCS ProMAX 7.0 @(#) Makefile_example_for_exe 70.2 06/26/97
##############################################################################
# Standard definitions
include advance.make
# Set depend_include to hold the name of the file which will contain
# our amakedepend dependencies. We include this later on, if it exists.
depend_include := $(parentdir).depend
# path is returned which points to either the master object directory or the
# advance object directory. aobjs stands for actual objects. User objects
# take precedence over master objects which in turn take precedence over
# advance objects.
aobjs := $(define_aobjs)
# Misc definitions.
# Use this section to do special things, like define extra things:
scriptdir := $(portdir)/exe
# OR to redine things defined in advance.make or machtype.make:
SYSXXLIBS += -lpthread
# etc...
# Other rules.
# Put other rules here, like for copying things or other special things, like:
$(bitmapdir)/%: %
$(COPYFILE)
$(manpage): pixmap.man
$(COPYFILE)
cleanobjs:
@echo "Removing: $(objexedir)/$(parentdir)"; \
/bin/rm -rf $(objexedir)/$(parentdir) 2> /dev/null
# be quiet
.SILENT:
.PHONY: all depend cleanexe cleanobjs clean
poststack.f
C This is the C "wrapper" that passes command line args to the FORTRAN
C stand alone program. This produces the main executable file that is
C referenced in the menu under the "special" parameter section.
C
C #include <stdlib.h>
C
C int main( int argc, char **argv )
C {
C poststack_( &argc, argv[1] );
C return EXIT_SUCCESS;
C }
C ..... This is a sample program that shows how a stand-alone program can
C ..... read post-stack traces (or otherwise access data without using
C ..... TRACENO as a key)
IMPLICIT NONE
#include "global.inc"
#include "mem.inc"
INTEGER NARGS, ID_PACKET, IERR, NCHARS, ID_DATASET, IREAD_ONLY,
& NDFILES, ISWAPENDS, ITRTOTAL, NUMSMP, NTH, MAXDTR, MAXATR,
& IPSORT, IPKEY, ISKEY, IDTYP, IDOMAIN, NTRACES, IGEOM_MATCH,
& ITRNO_VALID, NPRIORF, IFORMAT, LENGTH, IH_CDP
PTRDIFF_T IX_TRACE, IX_THDR
REAL SAMPRAT, SOFTRLP, GEORLSP
CHARACTER CINPUT(*), CAREA(16), CLINE(16)
CHARACTER CPACKET_FILE*128, CLABEL*8, CDESC*32
C ..... Load the character ARRAY into a character STRING. Be sure that you
C ..... understand the difference.
CALL U_CARR2STR( CINPUT, CPACKET_FILE, 128 )
C ..... Open the parameter packet file, get back the ID, area, and line
C ..... STAND_ALONE was the name specified in the menu file.
CALL PKT_OPEN_LOAD( CPACKET_FILE, ’STAND_ALONE ’, ID_PACKET,
& CAREA, CLINE )
IF ( ID_PACKET .EQ. 0 ) CALL U_ERR_FATAL(
& ’Unable to open packet file’ )
C ..... Initialize the database for this area and line. Note that CAREA
C ..... and CLINE are character arrays, not character strings.
CALL DB_INIT_LINE( CAREA, CLINE, IERR )
IF ( IERR .NE. 0 ) THEN
CALL REPORT_PROMAX_ERR( IERR )
CALL U_ERR_FATAL( ’Unable to initialize the database’ )
ENDIF
C ..... Get the label for the dataset from the packet file. Note that the
C ..... the packet ID is an input arg.
CALL U_CGETPARM( ID_PACKET, ’LABEL ’, 1, CLABEL, NCHARS )
C ..... Set up the trace headers (this will cause a bunch of calls to
C ..... HDR_ADD, creating all of the header entries that were found in
C ..... the dataset). Complete header description info (list of names,
C ..... format, length, etc) is now available using the same in-line
C ..... executive header subroutines.
CALL DISKIO_THDR_SETUP( ID_DATASET, IERR )
END
& ITRTOTAL )
IMPLICIT NONE
#include "global.inc"
INTEGER ITHDR(*)
INTEGER IERR, J, IH_CDP, ID_DATASET, ITRTOTAL
REAL TRACE(*)
DO 100 J=1,ITRTOTAL
C ......... This reads in a trace, given the relative position within the
C ......... file.
CALL DISKIO_GET_TR( ID_DATASET, -J, ITHDR, TRACE, IERR )
100 CONTINUE
RETURN
END
Makefile_poststack
##############################################################################
# RCS ProMAX 7.0 @(#) Makefile_example_for_exe 70.2 06/26/97
##############################################################################
# Standard definitions
include advance.make
# Set depend_include to hold the name of the file which will contain
# our amakedepend dependencies. We include this later on, if it exists.
depend_include := $(parentdir).depend
# path is returned which points to either the master object directory or the
# advance object directory. aobjs stands for actual objects. User objects
# take precedence over master objects which in turn take precedence over
# advance objects.
aobjs := $(define_aobjs)
# Misc definitions.
# Use this section to do special things, like define extra things:
scriptdir := $(portdir)/exe
# OR to redine things defined in advance.make or machtype.make:
SYSXXLIBS += -lpthread
# etc...
# Other rules.
# Put other rules here, like for copying things or other special things, like:
$(bitmapdir)/%: %
$(COPYFILE)
$(manpage): pixmap.man
$(COPYFILE)
cleanobjs:
@echo "Removing: $(objexedir)/$(parentdir)"; \
/bin/rm -rf $(objexedir)/$(parentdir) 2> /dev/null
# be quiet
.SILENT:
.PHONY: all depend cleanexe cleanobjs clean
poststack.c
/* ----------------------------------------------------------------*/
/*
/* poststack()
/* This is a stand-alone ProMAX module for demonstration of a
/* stand alone program that reads in data traces and headers.
/* ----------------------------------------------------------------*/
#include "cglobal.h"
#include "cpromax.h"
#include <stdio.h>
void *tblPntr;
/* The character string "STAND_ALONE " matches the tool name in the menu. */
initStandAlone(argc, argv, "STAND_ALONE ");
/* Get the 8-character label for the dataset from the packet file. */
uParGetString( "LABEL", &dsetLabel );
if( errCode != 0 ){
uErrFatal("Unable to open the trace dataset %s", id_dataset );
}
/* local variables */
int errCode, j, trNum;
/* loop over the dataset trace numbers, they range from 1 to itrtotal. */
for( j = 1; j <= itrtotal; j++ ){
/* .. Read each trace using its relative position within the file by inputting */
/* .. a negative value for the trace number. See docs on diskio_get_tr. */
trNum = -j;
diskio_get_tr_( &id_dataset, &trNum, ithdr, trace, &errCode );
if ( errCode != 0 ){
printf("*** ERROR *** %d %d", j, errCode );
}
else{
printf("CDP= %d\n", ithdr[ih_cdp] );
}
}
vel_io.f
C ..... This is a stand alone program that shows examples on inputting and
C ..... outputting velocities to the ProMAX database
PROGRAM VEL_IO
IMPLICIT NONE
CHARACTER CX_DESC*8, CY_DESC*8, CZ_DESC*8, CTABLE_DESC*128,
& CLABEL*8, CREPLY*1, CDESC*128
INTEGER MODE, IHANDLE, NFUNCTIONS, J, IERR, IRETURN, I,
& LX_NAM, LX_DSC, NTABLES, ISELECT, NUMSMP, IDUMB
REAL SAMPRAT, TIMEIN
REAL*8 RCDP, X
LOGICAL WRITE_TABLE
CHARACTER CAREA(16), CLINE(16), CTBLTYPE(3)
C ..... Call a crude function to let the user select an area and line.
C ..... Normally you would get this info from the packet file.
CALL DB_CHOOSE_AL( CAREA, CLINE, IRETURN )
ENDIF
IF ( WRITE_TABLE ) THEN
NFUNCTIONS = 3
ICDP(1) = 511
ICDP(2) = 204
ICDP(3) = 562
NPAIRS(1) = 3
NPAIRS(2) = 5
NPAIRS(3) = 2
TIME(1,1) = 50.0
VEL(1,1) = 50.0
TIME(2,1) = 1000.0
VEL(2,1) = 1000.0
TIME(3,1) = 1950.0
VEL(3,1) = 1950.0
TIME(1,2) = 75.0
VEL(1,2) = 75.0
TIME(2,2) = 480.0
VEL(2,2) = 480.0
TIME(3,2) = 950.0
VEL(3,2) = 950.0
TIME(4,2) = 1510.0
VEL(4,2) = 1510.0
TIME(5,2) = 1975.0
VEL(5,2) = 1975.0
TIME(1,3) = 100.0
VEL(1,3) = 100.0
TIME(2,3) = 2000.0
VEL(2,3) = 2000.0
C ......... Loop over the functions, inputting them. You could also input
C ......... each time-velocity pair independently (NUMY=1 in TBL_ADD)
DO 100 J=1,NFUNCTIONS
100 CONTINUE
C ......... Get the chosen table from the database. Note that it goes
C ......... straight into a table structure.
CALL DB_TBL_GET( 'VEL', CLABEL, IHANDLE, IERR )
IF ( IERR .NE. 0 ) CALL U_ERR_FATAL(
& 'Error getting velocity table from database' )
C ......... Get some info on the table. We are after the number of functions
CALL TBL_U_INFO( IHANDLE, CX_DESC, CY_DESC, CZ_DESC,
& CTABLE_DESC, NFUNCTIONS )
C ............. Pull the time-velocity pairs out of the table. You could
C ............. also pull each time-velocity pair independently.
CALL TBL2_IX_GET( IHANDLE, J, 100, 1, X, TIME(1,J),
120 CONTINUE
WRITE (*,*)
WRITE (*,*) 'Enter the CDP'
READ (*,'(F10.0)') RCDP
WRITE (*,*) 'Enter the sample rate (ms)'
READ (*,'(F10.0)') SAMPRAT
WRITE (*,*) 'Enter the number of samples'
READ (*,'(I10)') NUMSMP
CALL INT2_VEC( IHANDLE, 0, 0, RCDP, 0.0, SAMPRAT, NUMSMP,
& VELARR, IDUMB )
ENDIF
WRITE (*,*)
WRITE (*,*) 'Enter the CDP'
READ (*,'(F10.0)') RCDP
WRITE (*,*) 'Enter the time (ms)'
READ (*,'(F10.0)') TIMEIN
ENDIF
ENDIF
END
; This is a comment
'(
name: stand_alone
label: "Test IPC tool"
value_tab: 55
parameter: program
text: "Program executable name"
type: edit:
type_desc: (30 100 2 " Example: /usr/stof/promax/sa/my_prog )
value: "/usr/stof/exe/test_sa.exe"
mouse_text: "Type path name of program executible. If the path
doesn't start with a /, the main ProMAX executable directory is used."
parameter: max_freq
text: "Maximum frequency"
type: typein:
type_desc: ( real: 7 1.0e-5 nil )
value: 100.0
mouse_text: "Enter maximum frequency in the data."
parameter: DEBUG
text: "Debug mode?"
type: boolean:
value: nil
mouse_text: "To debug program, enter YES. You will have to
debug the program yourself"
exec_data: ("SOCKET_TOOL"
("GENERAL"
; The program parameter is the executible name of your IPC tool.
; You can hard code by specifying:
; ("program" implicit: "/home/stof/exe/mySocketTool.exe" )
("program" implicit: (value 'program))
("DEBUG" implicit: ( if (value 'debug) 3 0) )
; Put your other program parameters below here
("max_freq" implicit: (value 'max_freq ))
)
)
rules: (
; put your normal rules in
)
IPC C Code
#include <stdio.h>
#include <math.h>
#include "cglobal.h"
#include "cpromax.h"
#include "cSocketTool.h"
/* Open the packet file, get area & line, open database */
initStandAlone(ac,av, "SOCKET_TOOL");
/****
Establish connection with server module in the processing flow
All the global parameters are transferred in from the Executive.
They are accessible through the normal C global structures
(i.e. globalRuntime) or the normal FORTRAN common blocks (i.e.
GLOBAL_RUNTIME)
***/
stConnectToServer();
/* Manipulate headers */
if (!stHdrExists("MY_header") ) { /* Does this header exist */
/* Add Header with arbitrary char string */
iMyHeader=stHdrAdd("MY_header","Description of what
MY_header is",1,HDRINT);
/**
Up until now, we have been communicating with a master
init_stand_alone_module() in the ProMAX Executive. By calling
stEndInitialization(), this sends the possibly altered globalRuntime
parameters back to the Executive, allows the init_stand_alone module
to return, and begins the exec_stand_alone_module() which passes and
receives the traces from this stand alone program. We can no longer
make calls to stHdrIndex(), sHdrAdd(), etc., nor can we change the
globalRuntime structure.
**/
stEndInitialization();
do_work_on_trace(trace,ihead);
stCloseSocketLink();
}
do_work_on_trace()
{
}
IMPLICIT NONE
INTEGER NARGS
CHARACTER CINPUT*128, CPACKET_FILE*128, CAREA*16, CLINE*16
INTEGER ID_PACKET
C ..... Include the file that allows use of the "space array" and memory
C ..... management routines.
#include "mem.inc"
C .... These first few lines are typical of a stand alone program
C ..... Open the parameter packet file, get back the ID, area, and line
CALL PKT_OPEN_LOAD( CPACKET_FILE, 'SOCKET_TOOL ', ID_PACKET,
& CAREA, CLINE )
IF ( ID_PACKET .EQ. 0 ) CALL U_ERR_FATAL(
& 'Unable to open packet file' )
C ..... Initialize the database for this area and line. Note that CAREA
C ..... and CLINE are character arrays, not character strings. This
C ..... must be called in order for access to parameter files in the
C ..... database.
CALL DB_INIT_LINE( CAREA, CLINE, IERR )
IF ( IERR .NE. 0 ) THEN
CALL REPORT_DB_ERR( IERR )
CALL ST_ERR_FATAL( 'Unable to initialize the database' )
ENDIF
C ..... Pass the buffers off to a routine where the real work is done
CALL DO_WORK_ON_TRACE( RSPACEz(IX_TRACE), RSPACEz(IX_HEADER) ,
& RSPACEz(IX_HEADER) )
END
IMPLICIT NONE
#include "header.inc"
END
This is a more involved example that accesses tables and the database.
'(
name: AMP_RATIO
label: "Test FORTRAN amplitude Ratio"
value_tab: 35
parameter: GATELEN
text: "Amplitude gate length"
type: typein:
type_desc: ( real: 7 1.0e-5 nil )
value: 100.0
mouse_text: "Enter the sliding gate length used to compute amplitude
ratios."
parameter: time_gate_opt
text: "Confine the maximum?"
type: boolean:
value: nil
mouse_text: "Select 'Yes' if you wish to use a gate to constrain the
search for the maximum in the amp ratio."
parameter: GATENAME
text: " Select gate parameter file"
type: function:
type_desc: ((parm_list "GAT") parms)
value: "INVALID"
selected_item: "** No Parameter File Selected **"
mouse_text: "Use Mouse Button 1 to select a gate parameter file from
the parameter file menu."
parameter: LOAD_HDR
text: "Load the results into the header?"
type: boolean:
value: t
mouse_text: "Select 'Yes' if you wish to load the maximum of the amp
ratio and its time into the trace header."
parameter: LOAD_DB
text: "Load the results into the database?"
type: boolean:
value: t
mouse_text: "Select 'Yes' if you wish to load the maximum of the amp
ratio and its time into the database."
parameter: DEBUG
text: "Do you want to execute the program from dbx?"
type: boolean:
value: t
mouse_text: "If 'Yes', you must execute this program yourself from
dbx."
exec_data:
("SOCKET_TOOL"
("GENERAL"
; The following four variables are needed by init_stand_alone() to
; run the stand alone program. They are described below.
("program" implicit: "/home/mark/amp_ratio.exe" )
("machine" implicit: "" )
("DEBUG" implicit: ( if (value 'DEBUG) 3 1) )
; variables after here are user parameters
("GATELEN" implicit: (value 'GATELEN))
("GATENAME" implicit: ( if (value 'time_gate_opt)
(value 'GATENAME) "NO__GATE" ))
("LOAD_HDR" implicit: ( if (value 'LOAD_HDR) 1 0 ) )
("LOAD_DB" implicit: ( if (value 'LOAD_DB) 1 0 ) )
)
)
rules: (
(rule1 ( value 'time_gate_opt )
(do_show 'GATENAME) (do_not_show 'GATENAME))
)
ampRatio C Code
#include <cpromax.h>
#include <cglobal.h>
#include <cSocketTool.h>
void
amp_ratio_work (float *trace, float *scratch, int nsams, int ngate,
int imin_samp, int imax_samp, float samprate,
float *ratio_max, float *ratio_time);
int
main (int ac, char **av)
{
float gatelen;
char *cgatename;
float *trace;
int *ithdr;
float *rthdr;
stConnectToServer ();
/* See if the user wants to confine the maximum to fall within a gate */
use_gate = FALSE;
uParGetString ("GATENAME", &cgatename);
if (strcmp (cgatename, "") != 0 && strcmp (cgatename, "NO_GATE") != 0
&& strcmp (cgatename, "NO__GATE") != 0) {
use_gate = TRUE;
/* Get the gate from the database */
gate_tbl = tblFromDatabase ("GAT", cgatename);
if (gate_tbl == NULL)
if (tblCountZ(gate_tbl) != 2)
stErrFatal ("invalid gate (Gate must have an upper and lower gate!)");
iformat_pkey = stHdrFormat(tblDescX(gate_tbl));
iformat_skey = stHdrFormat(tblDescY(gate_tbl));
}
/* See if the user wants to load the results into the trace header */
load_hdr = 0;
uParGetInt ("LOAD_HDR", &load_hdr);
if (load_hdr) {
/* Add new trace header entries */
if (stHdrExists ("RATIOMAX")) {
if (stHdrFormat ("RATIOMAX") == HDRFLOAT)
stErrWarn ("RATIOMAX header already exists!");
else
stErrFatal ("RATIOMAX header already exists but is of wrong
type!");
}
else {
ih_ratio_max = stHdrAdd ("RATIOMAX", "Amp of ampRatio maximum", 1,
HDRFLOAT);
if (ih_ratio_max < 0) {
/* This should virtually never happen. */
stErrFatal ("Error adding header RATIOMAX");
}
}
if (stHdrExists ("RATIOTIM")) {
if (stHdrFormat ("RATIOTIM") == HDRFLOAT)
stErrWarn ("RATIOTIM header already exists!");
else
stErrFatal ("RATIOTIM header already exists but is of wrong
type!");
}
else {
ih_ratio_time = stHdrAdd ("RATIOTIM", "Time of amp ratio maximum", 1,
HDRFLOAT);
if (ih_ratio_time < 0) {
/* This should virtually never happen. */
stErrFatal ("Error adding header RATIOTIM");
}
}
}
/* See if the user wants to load the results into the database */
load_opf = 0;
uParGetInt ("LOAD_DB", &load_opf);
if (load_opf) {
int ierr;
/* Open the database to store the amp ratio information against trace */
if (globalRuntime->itrno_valid != 1)
stErrFatal ("Cannot load data into the TRC order without valid trace
numbers (geom assigned?)");
if (!stHdrExists ("TRACENO"))
stErrFatal ("TRACENO not found in header");
stEndInitialization ();
if (use_gate) {
/* Pass the buffers off to a routine where the real work is done */
amp_ratio_work (trace, scratch, globalRuntime->numsmp,
ngate, imin_samp, imax_samp, globalRuntime->samprat,
&ratio_max, &ratio_time);
if (load_hdr == 1) {
/* Load the values into the header */
rthdr[ih_ratio_max] = ratio_max;
rthdr[ih_ratio_time] = ratio_time;
}
if (load_opf) {
/* Load the values into the database */
loc_trc = ithdr[STDHDR (itraceno)];
if (loc_trc != INULL) {
opfBufPutFloat (opfPtr1, loc_trc, ratio_max);
opfBufPutFloat (opfPtr2, loc_trc, ratio_time);
}
}
/* Flush the buffers for buffered database I/O Note that errors ony give
rise to warnings in cleanup phase. Also note that the "location" is now
0. */
if (opfCloseBufPut (opfPtr1) != 0) {
stErrWarn ("Error loading data into database.");
}
if (opfCloseBufPut (opfPtr2) != 0) {
stErrWarn ("Error loading data into database.");
}
opfClose (opf_trc);
}
/* Free memory */
/* memFree functions check for memory overruns and
* abort if an overrun is found */
memFree1(trace);
memFree1(ithdr);
memFree1(scratch);
stCloseSocketLink ();
return EXIT_SUCCESS;
}
/**
C---------------------------------------------------------------------
C
C Actual work routine
C
C---------------------------------------------------------------------
**/
void
amp_ratio_work (float *trace, float *scratch, int nsamps, int ngate,
int imin_samp, int imax_samp, float samprate, float
*ratio_max, float *ratio_time)
{
int i, ind_max;
float sum_above, sum_below, rabove, rbelow;
sum_below = 0.0;
rbelow = 0.0;
for (i = 1; i <= ngate; i++)
if (i < nsamps) {
sum_below = sum_below + fabs (trace[i]);
rbelow = rbelow + 1.0;
}
else {
scratch[i] = 0.0;
}
/* Drop a sample from each gate and add the next one */
if (i - ngate >= 0) {
sum_above = sum_above - fabs (trace[i - ngate]) + fabs (trace[i]);
}
else {
sum_above = sum_above + fabs (trace[i]);
rabove = rabove + 1.0;
}
IMPLICIT NONE
INTEGER NARGS
CHARACTER CINPUT*128, CPACKET_FILE*128, CAREA*16, CLINE*16
INTEGER ID_PACKET
#include "global.inc"
C ..... Include file with error definitions
#include "hdr_err.inc"
#include "db_err.inc"
C ..... Include the file that allows use of the "space array" and memory
C ..... management routines.
#include "mem.inc"
PTRDIFF IX_SCRATCH
LOGICAL USE_GATE
C ..... Open the parameter packet file, get back the ID, area, and line
CALL PKT_OPEN_LOAD( CPACKET_FILE,'SOCKET_TOOL ',ID_PACKET,
& CAREA, CLINE )
IF ( ID_PACKET .EQ. 0 ) CALL ST_ERR_FATAL(
& 'Unable to open packet file' )
C ..... Initialize the database for this area and line. Note that CAREA
C ..... and CLINE are character arrays, not character strings. This
C ..... must be called in order for access to parameter files in the
C ..... database.
CALL DB_INIT_LINE( CAREA, CLINE, IERR )
IF ( IERR .NE. 0 ) THEN
CALL REPORT_DB_ERR( IERR )
CALL ST_ERR_FATAL( 'Unable to initialize the database' )
ENDIF
C ..... Set a default that is illegal (in case there is a menu problem)
GATELEN = -1.0
C ..... Call for the input parameter by name. Note the padding
C ..... in the character constant. It is the programmers
C ..... responsibility to provide the correct type of
C ..... return argument. Same as Executive!!
CALL EX_GETPARM( 'GATELEN ', 1, GATELEN )
C ..... See if the user wants to confine the maximum to fall within a gate
USE_GATE = .FALSE.
CGATENAME = ' '
CALL EX_CGETPARM( 'GATENAME', 1, CGATENAME, NCHARS )
IF ( CGATENAME .NE. ' '
& .AND. CGATENAME .NE. 'NO__GATE' ) THEN
C ......... Something was specified
USE_GATE = .TRUE.
C ......... There had better be two time values (upper and lower gate)
IF ( NTIMES .NE. 2 ) CALL ST_ERR_FATAL(
& 'Invalid gate (must have an upper and lower gate)' )
C ......... We will need the index of the primary and secondary key
C ......... Note: ST_ appended to header calls
CALL ST_HDR_NAMINFO( CPRIM_KEY, CDESC_DB, LENGTH,
& IFORMAT_PKEY,
& IH_PKEY, IERR )
IF ( IERR .NE. 0 ) CALL ST_ERR_FATAL(
& 'The primary key of the time gate (' //CPRIM_KEY
& //') is not in the header' )
ENDIF
C ..... See if the user wants to load the results into the trace header
LOAD_HDR = 0
CALL EX_GETPARM( 'LOAD_HDR', 1, LOAD_HDR )
ENDIF
ENDIF
ENDIF
C ..... See if the user wants to load the results into the database
LOAD_DB = 0
CALL EX_GETPARM( 'LOAD_DB ', 1, LOAD_DB )
ENDIF
CALL ST_END_INIT()
IF ( USE_GATE ) THEN
C ..... Interpolate the gate times from the table
IF (IFORMAT_PKEY .EQ. IREAL4pz ) PKEYVAL= RTHDR(IH_PKEY)
IF (IFORMAT_PKEY .EQ. INT4pz ) PKEYVAL= ITHDR(IH_PKEY)
IF (IFORMAT_SKEY .EQ. IREAL4pz ) SKEYVAL= RTHDR(IH_SKEY)
IF (IFORMAT_SKEY .EQ. INT4pz ) SKEYVAL= ITHDR(IH_SKEY)
CALL INT_GET( ITBL_HANDLE, 0, 0, PKEYVAL, SKEYVAL,
& TGATE, IERR )
IF ( IERR .NE. 0 ) CALL ST_ERR_FATAL(
& 'Error interpolating time gate' )
ELSE
C ......... Use the entire trace
TGATE(1) = 0.0
TGATE(2) = FLOAT(NUMSMPz-1) * SAMPRATz
ENDIF
C ..... Pass the buffers off to a routine where the real work is done
CALL AMP_RATIO_WORK( TRACE, RSPACEz(IX_SCRATCH), NUMSMPz,
& NGATE, IMIN_SAMP, IMAX_SAMP, SAMPRATz, RATIO_MAX,
& RATIO_TIME )
ENDIF
ENDIF
END
C------------------------------------------------------------------------------
C
C Actual work routine
C
C------------------------------------------------------------------------------
IMPLICIT NONE
INTEGER NSAMPS, NGATE, I, ISTART, IEND, IND_MAX, IMIN_SAMP,
& IMAX_SAMP
REAL TRACE(NSAMPS), SCRATCH(NSAMPS), SUM_ABOVE, SUM_BELOW,
& RATIO_MAX, RATIO_TIME, SAMPRATE, RABOVE, RBELOW
SUM_BELOW = 0.0
RBELOW = 0.0
DO 110 I=ISTART+NGATE+1,ISTART+NGATE*2
IF ( I .GE. 1 .AND. I .LE. NSAMPS ) THEN
SUM_BELOW = SUM_BELOW + ABS( TRACE(I) )
RBELOW = RBELOW + 1.0
ENDIF
110 CONTINUE
C ......... Drop a sample from each gate and add the next one
IF ( I-NGATE .GE. 1 ) THEN
SUM_ABOVE = SUM_ABOVE - ABS( TRACE(I-NGATE) )
& + ABS( TRACE(I) )
ELSE
SUM_ABOVE = SUM_ABOVE + ABS( TRACE(I) )
RABOVE = RABOVE + 1.0
ENDIF
120 CONTINUE
RETURN
END
global.inc
C------------------------------------------------------------------------------
C
C This is the global common block for inter-tool communication of
C processing modules that are linked into the executive. Note that
C all global variables end in lower case ’z’, and all global parameters
C end in lower case ’pz’.
C
C------------------------------------------------------------------------------
C------------------------------------------------------------------------------
C------------------------------------------------------------------------------
C------------------------------------------------------------------------------
C ..... These are the global run-time parameters. The common is padded to
C------------------------------------------------------------------------------
C ..... These are the choices for IPSORTz, the physical primary sort flag
#define ICDPpz 1 /* CDP bin */
#define ISINpz 2 /* source index number */
#define IRECSLOCpz 3 /* receiver surface location */
#define IOFFSETpz 4 /* offset */
#define ICHANpz 5 /* channel number */
#define IUNKNOWNpz 6 /* none of the above */
#define IILINEpz 7 /* 3D inline number */
#define IXLINEpz 8 /* 3D cross line number */
C------------------------------------------------------------------------------
C ..... These are the choices for IDTYPz, the primary data type:
C------------------------------------------------------------------------------
C------------------------------------------------------------------------------
C ..... These are the choices for IDOMAINz, the domain type:
#define ITXpz 0 /* normal time-space domain */
#define IFXpz 1 /* frequency-space domain */
#define IFTpz 2 /* frequency-time domain */
#define IFKpz 3 /* frequency-wavenumber domain */
#define ITAUPpz 4 /* tau-p domain */
#define ISEMBpz 5 /* semblance domain */
#define IMBTpz 6 /* model-based transform */
#define IDEPTHpz 7 /* depth-space domain */
#define TSLICEpz 8 /* time-slice domain */
#define FLEXEDpz 9 /* flex bin data after trace duplication */
C------------------------------------------------------------------------------
C ..... These are the parameters that are necessary for compatibility with
C ..... SMART (Seismic Matrix and Regularized Tranposed) frameworks. To
C ..... understand these parameters you probably need to be versed in JavaSeis
C ..... parlance, and know that "frame" is the same as "ensemble", and that a
C ..... "hypercube" if a 5-dimensional object. See www.javaseis.org for more
C ..... information.
C ..... NOTE: The exec does not copy these parameters in/out of the COMMON
C ..... blocks to keep them consistent for each tool. It is the responsibility
C ..... of the tool to note the values in the COMMON blocks in init phase, change
C ..... the values in the COMMON blocks if appropriate for subsequent tools,
C ..... and then IGNORE THE COMMON BLOCK VALUE, which will presumably have
whatever
C ..... values the last tool left behind during init phase.
COMMON /SMART_FRAMEWORKcz/
& S_IS_VALIDz, S_NDIMENSIONSz,
& S_FRAMES_PER_VOLUMEz, S_VOLUMES_PER_HYPERCUBEz,
& S_HYPERCUBE_COUNTz, S_MIN_SAMPLEz, S_MIN_TRACEz,
& S_MIN_FRAMEz, S_MIN_VOLUMEz, S_MIN_HYPERCUBEz,
& S_SAMPLE_INCz, S_TRACE_INCz, S_FRAME_INCz,
& S_VOLUME_INCz, S_HYPERCUBE_INCz, S_SAMPLE_ORIGINz,
& S_TRACE_ORIGINz, S_FRAME_ORIGINz, S_VOLUME_ORIGINz,
& S_HYPERCUBE_ORIGINz,
& S_TRACE_DELTAz, S_FRAME_DELTAz, S_VOLUME_DELTAz,
& S_HYPERCUBE_DELTAz, IPAD_S_FRAMEWORK,
& S_DATA_TYPEz, S_SAMPLE_LABELz, S_TRACE_LABELz,
& S_FRAME_LABELz, S_VOLUME_LABELz, S_HYPERCUBE_LABELz,
& S_SAMPLE_DOMAINz, S_TRACE_DOMAINz, S_FRAME_DOMAINz,
& S_VOLUME_DOMAINz, S_HYPERCUBE_DOMAINz,
& S_SAMPLE_UNITSz, S_TRACE_UNITSz, S_FRAME_UNITSz,
& S_VOLUME_UNITSz, S_HYPERCUBE_UNITSz,
& CPAD_S_FRAMEWORK_CHAR
SAVE /SMART_FRAMEWORKcz/
LOGICAL S_IS_VALIDz
INTEGER S_NDIMENSIONSz, IPAD_S_FRAMEWORK(18)
C ..... These are 64-bit integers to be more closely compatible with JavaSeis,
C ..... where they are Java long values. Maybe some day we will make NUMSMPz
C ..... and MAXDTRz 64-bit values also.
INTEGER*8 S_FRAMES_PER_VOLUMEz, S_VOLUMES_PER_HYPERCUBEz,
& S_HYPERCUBE_COUNTz, S_MIN_SAMPLEz, S_MIN_TRACEz,
& S_MIN_FRAMEz, S_MIN_VOLUMEz, S_MIN_HYPERCUBEz,
& S_SAMPLE_INCz, S_TRACE_INCz, S_FRAME_INCz,
& S_VOLUME_INCz, S_HYPERCUBE_INCz
C ..... These are 64-bit floats to be more closely compatible with JavaSeis,
C ..... where they are Java double values. Maybe some day we will make SAMPRATz
C ..... a 64-bit value also.
REAL*8 S_SAMPLE_ORIGINz,
& S_TRACE_ORIGINz, S_FRAME_ORIGINz, S_VOLUME_ORIGINz,
& S_HYPERCUBE_ORIGINz, S_TRACE_DELTAz, S_FRAME_DELTAz,
& S_VOLUME_DELTAz, S_HYPERCUBE_DELTAz
C ..... Note the 16-character limits.
CHARACTER S_DATA_TYPEz*16, S_SAMPLE_LABELz*16,
& S_TRACE_LABELz*16, S_FRAME_LABELz*16,
& S_VOLUME_LABELz*16, S_HYPERCUBE_LABELz*16,
& S_SAMPLE_DOMAINz*16, S_TRACE_DOMAINz*16,
& S_FRAME_DOMAINz*16, S_VOLUME_DOMAINz*16,
& S_HYPERCUBE_DOMAINz*16, S_SAMPLE_UNITSz*16,
& S_TRACE_UNITSz*16, S_FRAME_UNITSz*16,
& S_VOLUME_UNITSz*16, S_HYPERCUBE_UNITSz*16,
& CPAD_S_FRAMEWORK_CHAR*128
C ..... S_IS_VALIDz - true if the SMART parameters are valid, otherwise false.
C ..... S_NDIMENSIONSz - the number of dimensions, ranging from 3 to 5.
C ..... S_FRAMES_PER_VOLUMEz - the number of frames per volume.
C ..... S_VOLUMES_PER_HYPERCUBEz - the number of volumes per hypercube.
C ..... S_HYPERCUBE_COUNTz - the number of hypercubes.
C ..... The "logical" values are integer values attached to the different axes.
C ..... As of June 2006, the choices for the SMART data type include "UNKNOWN"
C ..... "CUSTOM", "CMP", "SOURCE", "RECEIVER", "OFFSET_BIN", "STACK".
C ..... As of June 2006, the choices for the SMART domain include "space",
C ..... "time", "depth", "frequency", "wavenumber", "semblance", "velocity",
C ..... "dip", "vsvp", "eta", "sloth", "epsilon", "delta", "alacrity",
C ..... "amplitude", "coherence", "envelope", "impedance", "density", "vs",
C ..... "fold", "incidence angle", "rotation angle", "null", and "unknown"
C ..... As of June 2006, the choices for the SMART units include "feet",
C ..... "meters", "milliseconds", "seconds", "hertz", "degrees", "null",
C ..... and "unknown".
C------------------------------------------------------------------------------
C ..... MINXLINz -
Minimum crossline number
C ..... MAXXLINz -
Maximum crossline number
C ..... XXLNENDz -
X coordinate of far end of first crossline
C ..... YXLNENDz -
Y coordinate of far end of first crossline
C ..... DCDPXLNz -
Distance between CDPs in the crossline direction (same as
C ..... the distance between inlines)
C ..... INCCDP_Ez CDP increment in the inline direction (external)
C ..... MINCDP_Ez minimum CDP number in survey (external)
C ..... NXLINES_Ez number of xlines (CDPs per inline) in survey
C ..... NILINES_Ez number of ilines (inlines per xline) in survey
C------------------------------------------------------------------------------
C ..... These are the global parameters related to coordinates. The common
C ..... is padded to 8 words to facilitate addition of new parameters.
COMMON /GLOBAL_COORDcz/ AZIMX1z, SLOC1Xz, SLOC1Yz,
& IPAD_GLOBAL_COORD
SAVE /GLOBAL_COORDcz/
C ..... These are the global double precision reference coordinates. The
C ..... common is padded to 8 words to facilitate addition of new parameters.
COMMON /GLOBAL_XYcz / XREFz, YREFz, IPAD_GLOBAL_XY
SAVE /GLOBAL_XYcz /
REAL AZIMX1z, SLOC1Xz, SLOC1Yz
REAL*8 XREFz, YREFz
INTEGER IPAD_GLOBAL_COORD(5), IPAD_GLOBAL_XY(4)
C------------------------------------------------------------------------------
C ..... These are the global parameters related to acquisition. The common
C ..... is padded to 32 words to facilitate addition of new parameters.
COMMON /GLOBAL_AQUIScz/ ISRCTYPz, IDATRECz, IGAINXz, PREXAMPz,
& EARLYGz, AAXFILTz, AAXSLOPz, FREQXNz, FXNSLOPz, FREQXLz,
& FREQXHz, FXLSLOPz, FXHSLOPz, NSRECDz, ORIGDTz, IXFORMz,
& MANFACTz, ISERIALz, NXAUXSz, RCCONSTz, IPAD_GLOBAL_AQUIS
SAVE /GLOBAL_AQUIScz/
INTEGER ISRCTYPz, IDATRECz, IGAINXz, NSRECDz, IXFORMz, MANFACTz,
& ISERIALz, NXAUXSz, IPAD_GLOBAL_AQUIS(12)
REAL PREXAMPz, EARLYGz, AAXFILTz, AAXSLOPz, FREQXNz, FXNSLOPz,
& FREQXLz, FREQXHz, FXLSLOPz, FXHSLOPz, ORIGDTz, RCCONSTz
C ..... ISRCTYPz - Source type
C ..... IDATRECz - Date recorded
C ..... IGAINXz - Gain mode of field intruments
C ..... PREXAMPz - Instrument preamp gain constant
C ..... EARLYGz - Instrument early or initial gain
C ..... AAXFILTz - Instrument antialias filter frequency
C ..... AAXSLOPz - Instrument antialias filter slope
C ..... FREQXNz - Instrument notch filter frequency
C ..... FXNSLOPz - Instrument notch filter slope
C ..... FREQXLz - Instrument low cut filter frequency
C ..... FREQXHz - Instrument high cut filter frequency
C ..... FXLSLOPz - Instrument low cut filter slope
C ..... FXHSLOPz - Instrument high cut filter slope
C ..... NSRECDz - Number of samples per trace on field data
C------------------------------------------------------------------------------
C------------------------------------------------------------------------------
C------------------------------------------------------------------------------
C ..... These are the possible values for the last-trace-in-ensemble flag:
#define LASTTRpz 1 /* last trace in the ensemble */
#define NLASTpz 0 /* NOT last trace in the ensemble */
C------------------------------------------------------------------------------
C ..... These are the choices for trace type (as defined in the trace header
C ..... entry TRC_TYPE):
#define IAUXpz 0 /* general auxiliary trace */
#define ILIVEpz 1 /* live data trace */
#define IDEADpz 2 /* dead trace */
#define IDUMMYpz 3 /* dummy trace */
#define ITBREAKpz 4 /* time-break trace */
#define IUPHOLEpz 5 /* uphole trace */
#define ISWEEPpz 6 /* sweep trace */
#define ITIMINGpz 7 /* timing trace */
#define IWBREAKpz 8 /* water break trace */
#define IOTHERpz 9 /* any other trace */
C------------------------------------------------------------------------------
C------------------------------------------------------------------------------
C------------------------------------------------------------------------------
C------------------------------------------------------------------------------
C ..... This is the software release number and geometry release number.
#define SOFTRLpz 601000 /* software */
#define GEORLSpz 601000 /* geometry */
C------------------------------------------------------------------------------
C Source file:
C /advance/port/include/global.inc
cglobal.h
#ifndef CGLOBAL_H
#define CGLOBAL_H
#include <sys/types.h>
/* character globals */
typedef struct globalCharStruct {
char cproj[16]; /* current project name */
char cline[16]; /* current line name */
char carea[16]; /* current area name */
char cflow[16]; /* current flow name */
char cpad[64]; /* pad to 128 */
} GlobalChar;
#ifdef DEFINE_CGLOBALS
#else
#endif /* DEFINE_CGLOBALS */
/* miscellaneous globals */
typedef struct globalMiscStruct {
float exdatum; /* final processing datum elevation (if not variable) */
float vxdatum; /* final datum replacement velocity (if not variable) */
int iunits; /* type of units (see choices below) */
logical i3d; /* true if data is 3-D */
logical imultc; /* true if data is multi-component */
int ntrace; /* number of traces used to initialize database */
#ifdef DEFINE_CGLOBALS
#else
#endif /* DEFINE_CGLOBALS */
/* runtime globals */
typedef struct globalRuntimeStruct {
float samprat; /* time sampling interval in milliseconds */
int numsmp; /* number of samples per trace */
int ipsort; /* physical primary sort flag (see choices below) */
int maxdtr; /* maximum number of data traces per ensemble */
int idtyp; /* primary data type (see choices below) */
int nth; /* number of 4-byte words in trace header */
int mode; /* processing executive mode (see choices below) */
int iounit; /* Fortran I/O unit for output diagnostics */
int ipkey; /* trace header index of primary sort key */
int iskey; /* trace header index of secondary sort key */
int idate; /* current date (seconds since 00:00:00 GMT, 1/1/70 */
int idomain; /* domain type (see choices below) */
logical cleanup; /* true if system is in cleanup mode */
logical ierror; /* true if system in error mode (trying to cleanup) */
logical igeom_match; /* true if header geometry matches database */
logical itrno_valid; /* true if trace number can index database */
#ifdef DEFINE_CGLOBALS
#else
#endif /* DEFINE_CGLOBALS */
#define IARCHIVE 10
#define IOTHER_TAPE 11
/* runtime globals */
typedef struct globalSmartFrameworkStruct {
logical isValid; /* true if the SMART parameters are valid, otherwise
false */
int nDimensions; /* the number of dimensions, ranging from 3 to 5 */
int64_t framesPerVolume; /* the number of frames per volume */
int64_t volumesPerHypercube; /* the number of volumes per hypercube */
int64_t hypercubeCount; /* the number of hypercubes */
int64_t minSample; /* the minimum "logical" sample value */
int64_t minTrace; /* the minimum "logical" trace value */
int64_t minFrame; /* the minimum "logical" frame value */
int64_t minVolume; /* the minimum "logical" volume value */
int64_t minHypercube; /* the minimum "logical" hypercube value */
int64_t sampleInc; /* the "logical" sample value increment */
int64_t traceInc; /* the "logical" trace value increment */
int64_t frameInc; /* the "logical" frame value increment */
int64_t volumeInc; /* the "logical" volume value increment */
int64_t hypercubeInc; /* the "logical" hypercube value increment */
double sampleOrigin; /* the physical sample origin */
double traceOrigin; /* the physical trace origin */
double frameOrigin; /* the physical frame origin */
double volumeOrigin; /* the physical volume origin */
double hypercubeOrigin; /* the physical hypercube origin */
double traceDelta; /* the physical trace delta */
double frameDelta; /* the physical frame delta */
double volumeDelta; /* the physical volume delta */
double hypercubeDelta; /* the physical hypercube delta */
int ipad[18]; /* padding to 64 words */
char dataType[16]; /* the fundamental data type */
char sampleLabel[16]; /* the name of the sample axis, usually a header
name */
char traceLabel[16]; /* the name of the trace axis, usually a header
name */
#ifdef DEFINE_CGLOBALS
#else
#endif /* DEFINE_CGLOBALS */
/* geometry globals */
typedef struct globalGeomStruct {
int minsloc; /* minimum surface location number */
int maxsloc; /* maximum surface location number */
int incsloc; /* surface location number increment (always 1) */
int nrcvrs; /* total number of live groups */
int maxtpr; /* maximum traces per receiver ensemble */
int mincdp; /* minimum cdp number */
int maxcdp; /* maximum cdp number */
int inccdp; /* cdp number increment (always 1) */
int numcdp; /* total number of cdps */
int ntrcdp; /* maximum cdp fold */
#ifdef DEFINE_CGLOBALS
#else
#endif /* DEFINE_CGLOBALS */
/* coordinates globals */
typedef struct globalCoordStruct {
float azimx1; /* azimuth towards increasing SURFLOC number */
float sloc1x; /* X coordinate of first surface location */
float sloc1y; /* Y coordinate of first surface location */
int ipad[5]; /* pad to 8 words */
} GlobalCoord;
#ifdef DEFINE_CGLOBALS
#else
#ifdef DEFINE_CGLOBALS
#else
#endif /* DEFINE_CGLOBALS */
/* acquisition globals */
typedef struct globalAcquisStruct {
int isrctyp; /* source type */
int idatrec; /* date recorded */
int igainx; /* gain mode of field instruments */
float prexamp; /* instrument preamp gain constant */
float earlyg; /* instrument early or initial gain */
float aaxfilt; /* instrument anti-alias filter frequency */
float aaxslop; /* instrument anti-alias filter slope */
float freqxn; /* instrument notch filter frequency */
float fxnslop; /* instrument notch filter slope */
float freqxl; /* instrument low-cut filter frequency */
float freqxh; /* instrument high-cut filter frequency */
float fxlslop; /* instrument low-cut filter slope */
float fxhslop; /* instrument high-cut filter slope */
int nsrecd; /* number of samples per trace on field data */
float origdt; /* sample rate on field data */
int ixform; /* recording system format code */
int manfact; /* recording system manufacturing code */
int iserial; /* recording system serial number */
int nxauxs; /* number of aux channels on field records */
float rcconst; /* recording system "dial in" constant */
int ipad[12]; /* pad to 32 words */
} GlobalAcquis;
#ifdef DEFINE_CGLOBALS
#endif
#else
#endif /* DEFINE_CGLOBALS */
/* ****************************************************************************
IF YOU CHANGE THIS struct, DON’T FORGET TO CHANGE header.inc,
OR YOU WILL BE TRANSFERRED TO THE SUPPORT DEPARTMENT
**************************************************************************** */
/* Standard header entries */
typedef struct stdHdrStruct {
int
isource, icdp, irec_sloc, ioffset,
ichan, ifb_pick, iaoffset, iseqno,
iffid, isin, isou_sloc, isou_x,
isou_y, isou_elev, inchans, irec_x,
irec_y, irec_elev, irec_nfld, icdp_sloc,
icdp_x, icdp_y, icdp_elev, icdp_nfld,
itot_stat, ina_stat, iskewstat, irec_stat,
isou_stat, iend_ens, ieoj, itraceno,
itrc_type, itlive_s, itfull_s, itfull_e,
itlive_e, ilen_surg, iamp_norm, itr_fold,
idepth, iuphole, isr_azim, ipad_trc,
igeo_comp, ircdp, irec_h2od, isou_h2od,
inmo_stat, ifnl_stat, iseq_disk, irepeat,
ifk_waven, ifk_wavel, ift_freq, ics_stat,
icr_stat, ips_stat, ipr_stat, itrimstat,
ilseg_end, ilseg_seq, idmooff, ir_line,
irec_dep, isou_comp, ids_seqno, n_datum,
iofb_cntr, iofb_no, iline_no, ifrn_trno,
iiline_no, ixline_no, idiskiter, isrf_sloc,
is_line, iriline_n, irxline_n, iwb_time,
iavo_attr, isg_cdp, islc_time, iang_valu,
itzero, icdp_xd, icdp_yd, irec_xd,
irec_yd, isou_xd, isou_yd;
} StdHdr;
#ifdef DEFINE_CGLOBALS
#else
#endif /* DEFINE_CGLOBALS */
/* space global */
typedef struct globalSpaceStruct {
#if defined(SGIMIPS4)
int *ispace; /* base pointer stored in common block */
#else
int ispace[2]; /* match dimension of FORTRAN ISPACEz array */
#endif
} GlobalSpace;
#ifdef DEFINE_CGLOBALS
#else
/* last-trace-in-ensemble flag */
#define LASTTR 1
#define NLAST 0
/* trace type */
#define IAUX 0 /* general auxiliary trace */
#define ILIVE 1 /* live data trace */
#define IDEAD 2 /* dead trace */
#define IDUMMY 3 /* dummy trace */
#define ITBREAK 4 /* time-break trace */
#define IUPHOLE 5 /* uphole trace */
#define ISWEEP 6 /* sweep trace */
#define ITIMING 7 /* timing trace */
#define IWBREAK 8 /* water break trace */
#define IOTHER 9 /* any other trace */
#define IWLOG 10 /* well log trace */
#define ICORRUPTED 11 /* corrupted header (internal use only) */
/* tool types */
#define ISIMPLE 1 /* simple (trace in, trace out) tool */
#define IENSEMBLE 2 /* ensemble tool */
#define ICOMPLEX 3 /* complex tool */
#define IFLOW 4 /* flow control tool (not valid for user tools) */
#define INPUT 6 /* input tool (implies complex tool) */
#define IROLLGATE 7 /* rolling gate tool */
#define IPANEL 8 /* panel tool */
#define ISNL_BUFF 9 /* one-buffer tool */
#define IDBL_BUFF 10 /* two-buffer tool */
/* release numbers */
#define SOFTRL 601000 /* software */
#define GEORLS 601000 /* geometry */
#endif /* CGLOBAL_H */
db_disp.f
PROGRAM DB_DISP
IMPLICIT NONE
#include "global.inc"
CHARACTER CORDNAM*3, CINFO*8, CNAME*8, CREPLY*1, CWORK*144,
& CFORMAT*9, CNULL*1
CHARACTER*8 CINFOBUF(100), CNAMEBUF(100)
CHARACTER*80 CDESCBUF(100)
CHARACTER CAREA(16), CLINE(16)
INTEGER IWORDBUF(100), IFORMBUF(100), INULLBUF(100),
& IBUFF(100000), IERR, INUL, IKEY, LMIN, LMAX, LINC,
& NSTORED, IGDATE, IGTIME, NGTRACE, NFOUND, I, IREPLY,
& IRFIRST, IRLAST, IRFLAG, NVALS, IND, IRETURN, IDATEBUF(100)
REAL RBUFF(100000), RNUL, SOFTRLSE
REAL*8 RCBUFF(500)
EQUIVALENCE (INUL,RNUL)
EQUIVALENCE (IBUFF,RBUFF)
EQUIVALENCE (IBUFF,RCBUFF)
C ..... Initialize:
IKEY = 0
IERR = 0
CNULL = CHAR(0)
CINFO = ' '
CNAME = ' '
C ..... Call a crude function to let the user select an area and line
50 CALL DB_CHOOSE_AL( CAREA, CLINE, IRETURN )
90 WRITE (*,*)
WRITE (*,*) 'Choose an ordered database:'
WRITE (*,*)
WRITE (*,*) '1) LIN (line)'
WRITE (*,*) '2) TRC (trace)'
WRITE (*,*) '3) SRF (surface location)'
WRITE (*,*) '4) SIN (source)'
WRITE (*,*) '5) CDP'
WRITE (*,*) '6) CHN (channel)'
WRITE (*,*) '7) start over'
WRITE (*,*)
C ..... Lock the ordered database file that was selected (call DB_ORDLOCK)
CALL DB_ORDLOCK( CORDNAM, IKEY, IERR )
IF ( IERR .NE. 0 ) THEN
CALL REPORT_DB_ERR( IERR )
WRITE (*,*) 'ERROR opening database file, try again'
GO TO 90
ENDIF
C ..... Write out the first and last location, increment, and number of
C ..... stored parameters
WRITE (*,*)
WRITE (*,*) 'First location = ', LMIN
WRITE (*,*) 'Last location = ', LMAX
WRITE (*,*) 'Location increment = ', LINC
WRITE (*,*) 'Number of stored parameters = ', NSTORED
WRITE (*,*)
WRITE (*,*) 'Enter 1-8 >'
READ (*,'(A1)') CREPLY
ELSE
WRITE (*,*)
WRITE (*,*) 'Infotype Name Length Format'
& //' Null value Date created'
WRITE (*,*)
DO 130 I=1,NSTORED
C ............. Give the character name of the format
IF ( IFORMBUF(I) .EQ. INT4pz ) THEN
CFORMAT = 'INTEGER'
ELSEIF ( IFORMBUF(I) .EQ. IREAL4pz ) THEN
CFORMAT = 'REAL'
WRITE (*,*)
WRITE (*,*) 'Existing information types:'
DO 160 I=1,NFOUND
WRITE (*,'(1X,I4,1X,A8)') I, CINFOBUF(I)
160 CONTINUE
WRITE (*,*)
WRITE (*,*) 'Select an information type (enter number) >'
READ (*,'(I4)') IREPLY
IF ( IREPLY .LT. 1 .OR. IREPLY .GT. NFOUND ) THEN
WRITE (*,*) 'ERROR - invalid response'
CINFO = ' '
GO TO 110
ENDIF
CINFO = CINFOBUF(IREPLY)
C ......... Show the list of all name for this info type (call DB_INFOLIST)
CALL DB_INFOLIST( IKEY, ' ', CINFO, NSTORED, NFOUND,
& CNAMEBUF, CDESCBUF, IDATEBUF, IERR )
IF ( IERR .NE. 0 ) THEN
WRITE (*,*) 'Error retrieving list of names'
GO TO 110
ENDIF
WRITE (*,*)
WRITE (*,*) 'Stored parameters for this info type:'
WRITE (*,*)
DO 170 I=1,NSTORED
WRITE (*,*) 'Name= ', CNAMEBUF(I),
& ' Date created= ', IDATEBUF(I)
WRITE (*,'(1X,A13,A65)') 'Description: ', CDESCBUF(I)
170 CONTINUE
C ......... Exit
C ......... Unlock the database (call DB_ORDUNLK)
CALL DB_ORDUNLK( IKEY, IERR )
STOP
ELSE
WRITE (*,*) 'ERROR - invalid response'
ENDIF
GO TO 110
END
comp_opf.menu
'(
name: COMP_OPF
label: "OPF Compare for QC*"
value_tab: 50
parameter: AREA2
text: "Comparison Area name"
type: edit:
type_desc: (28 80 5 " FORMAT: string
EXAMPLE: test_area1
HELP: EMACS Editor Widget (scroll with down/up arrow keys)
CURSOR MOVEMENT: Use the arrow keys:->,<-,etc.;Point the mouse cursor,click B1
CM: Ctrl-AMove the cursor to the BEGINNING of the current line
CM: Ctrl-EMove the cursor to the END of the current line
EDITING: All keyboard entry is in 'insert' mode
E: Backspace, Delete keysDelete one character to the LEFT of the cursor
E: Ctrl-D Delete one character to the RIGHT of the cursor
E: Ctrl-KKILL to the end of the line (from the cursor)
E: Ctrl-YYANK back the contents of the kill buffer; 'Cut and
paste'; (Can move the cursor first) " 3 )
value: "test_area"
mouse_text: "Enter name of the area containing the OPF to compare. "
parameter: LINE2
text: "Comparison Line name"
type: edit:
type_desc: (28 80 5 " FORMAT: string
EXAMPLE: test_line
HELP: EMACS Editor Widget (scroll with down/up arrow keys)
CURSOR MOVEMENT: Use the arrow keys:->,<-,etc.;Point the mouse cursor,click B1
CM: Ctrl-AMove the cursor to the BEGINNING of the current line
CM: Ctrl-EMove the cursor to the END of the current line
EDITING: All keyboard entry is in 'insert' mode
E: Backspace, Delete keysDelete one character to the LEFT of the cursor
E: Ctrl-D Delete one character to the RIGHT of the cursor
E: Ctrl-KKILL to the end of the line (from the cursor)
E: Ctrl-YYANK back the contents of the kill buffer; 'Cut and
paste'; (Can move the cursor first) " 3 )
value: "test_line"
mouse_text: "Enter name of the line containing the OPF to compare. "
parameter: OPF_NAME
text: "OPF type"
type: edit:
type_desc: (28 80 5 " FORMAT: string
EXAMPLE: SIN or TRC
HELP: EMACS Editor Widget (scroll with down/up arrow keys)
CURSOR MOVEMENT: Use the arrow keys:->,<-,etc.;Point the mouse cursor,click B1
CM: Ctrl-AMove the cursor to the BEGINNING of the current line
CM: Ctrl-EMove the cursor to the END of the current line
EDITING: All keyboard entry is in 'insert' mode
E: Backspace, Delete keysDelete one character to the LEFT of the cursor
E: Ctrl-D Delete one character to the RIGHT of the cursor
E: Ctrl-KKILL to the end of the line (from the cursor)
parameter: PARMNAME
text: "Paramter Name"
type: edit:
type_desc: (28 80 5 " FORMAT: string
EXAMPLE: FB_PICK
HELP: EMACS Editor Widget (scroll with down/up arrow keys)
CURSOR MOVEMENT: Use the arrow keys:->,<-,etc.;Point the mouse cursor,click B1
CM: Ctrl-AMove the cursor to the BEGINNING of the current line
CM: Ctrl-EMove the cursor to the END of the current line
EDITING: All keyboard entry is in 'insert' mode
E: Backspace, Delete keysDelete one character to the LEFT of the cursor
E: Ctrl-D Delete one character to the RIGHT of the cursor
E: Ctrl-KKILL to the end of the line (from the cursor)
E: Ctrl-YYANK back the contents of the kill buffer; 'Cut and
paste'; (Can move the cursor first) " 3 )
value: "FB_PICK"
mouse_text: "Enter the parameter name within the OPF to compare. Example would be
FB_PICK"
parameter: INFOTYPE
text: "Information type of the paramter"
type: edit:
type_desc: (28 80 5 " FORMAT: string
EXAMPLE: STATICS or GEOMETRY
HELP: EMACS Editor Widget (scroll with down/up arrow keys)
CURSOR MOVEMENT: Use the arrow keys:->,<-,etc.;Point the mouse cursor,click B1
CM: Ctrl-AMove the cursor to the BEGINNING of the current line
CM: Ctrl-EMove the cursor to the END of the current line
EDITING: All keyboard entry is in 'insert' mode
E: Backspace, Delete keysDelete one character to the LEFT of the cursor
E: Ctrl-D Delete one character to the RIGHT of the cursor
E: Ctrl-KKILL to the end of the line (from the cursor)
E: Ctrl-YYANK back the contents of the kill buffer; 'Cut and
paste'; (Can move the cursor first) " 3 )
value: "STATICS"
mouse_text: "Enter the information type of the OPF to compare. Example would be
STATICS"
parameter: TOLERANC
text: "Percent error tolerated"
type: typein:
type_desc: ( real: 6 0.0 nil )
value: 0.001
mouse_text: "Percent error tolerated in floating point database values, see help
file for error calculation method."
exec_data: ("COMP_OPF"
("SPECIAL"
("TOOLTYPE" implicit: "STAND_ALONE")
("PATHNAME" implicit: "/promax/1998.6/rs6000/exe/comp_opf.exe")
)
("GENERAL"
("version" implicit: "%Q% %M% %I% %G%")
comp_opf.c
/* ----------------------------------------------------------------*/
/*
/* comp_opf
/* this is a stand-alone ProMAX module for comparing opf files
/* in separate areas and lines and primarily for use in QC of
/* promax processing modules.
/*
/* original code by B. Fuller, 31-oct-94 (BOO!)
/* ----------------------------------------------------------------*/
#include "cglobal.h"
#include "cpromax.h"
#include <stdio.h>
#include <math.h>
int numErrorsFound = 0;
int errCode, id_packet, format;
int ival1, ival2, loc;
int i_128=128;
float *fval1, *fval2;
float diff, mean;
float tolerance, totalError = 0.0;
uParGetString("OPF_NAME", &opfName );
uParGetString("PARMNAME", &parmName );
uParGetString("INFOTYPE", &infoType );
uParGetFloat ("TOLERANC", &tolerance );
/* initialize the global variables and open the OPF for line2 */
db_init_line_( area2, line2, &errCode );
if( errCode != 0 ){
uErrFatal("Error initializing the database for %s, %s.", area2, line2);
}
EXAMPLE.menu
‘(
name: PROG_NAME
label: “Sample ProMAX Menu”
value_tab: 48
parameter: CHOOSE1
text: “This is an item you can choose”
type: choose:
type_desc: (
(“Item 1 “ 1 “Mouse pointing help for Item 1.” )
(“Item 2 “ 2 “Mouse pointing help for Item 2.” )
(“Item 3 “ 3 “Mouse pointing help for Item 3.” ) )
value: 3
mouse_text: “This is the mouse pointing help you see when you point to the ‘This
is an item you can choose’ text.”
parameter: CHOOSE2
text: “This menu entry will generate a ‘pop choose’”
type: pop_choose:
type_desc: (
(“Item 1” 1 “Mouse pointing help for Item 1.” )
(“Item 2” 2 “Mouse pointing help for Item 2.” )
(“Item 3” 3 “Mouse pointing help for Item 3.” ) )
value: 3
mouse_text: “This is the mouse pointing help you see when you point to the menu
line.”
parameter: CIRCULAR1
text: “This item rotates in a circular fashion”
type: circular:
type_desc: (
(“Item 1” 1 “Mouse pointing help for Item 1.” )
(“Item 2” 2 “Mouse pointing help for Item 2.” ) )
value: 3
mouse_text: “This is the mouse pointing help you see when you point to the menu
line.”
parameter: SIMPLE_REAL
text: “This is a simple ‘REAL’ number item”
type: real:
value: 1.0
mouse_text: “Mouse pointing help goes here (simple reals are 10 characters wide
and have no input test limits).”
parameter: FANCY_REAL
text: “This is a sophisticated ‘REAL’ number item”
type: typein:
type_desc: ( real: 6 1.0e-4 nil )
value: 2.0
mouse_text: “Mouse pointing help goes here (this real is 6 characters wide, test
limits are 1.0E-4 (lower) with no upper limit).”
parameter: SIMPLE_INTEGER
text: “This is a simple ‘INTEGER’ number item”
type: int:
value: 3
mouse_text: “Mouse pointing help goes here (simple integers are 8 characters wide
and have no input test limits).”
parameter: FANCY_INTEGER
text: “This is a sophisticated ‘INTEGER’ number item”
type: typein:
type_desc: ( int: 3 nil 999999 )
value: 4
mouse_text: “Mouse pointing help goes here (this integer is 8 characters wide,
test limits are 999999 (upper) with no lower limit).”
parameter: BOOLEAN1
text: “This is a BOOLEAN (true/false) type”
type: boolean:
value: nil
mouse_text: “This mouse pointing help explains the item (note: default ‘value:’
can be ‘t’ (true) or ‘nil’ (false).”
parameter: STRING1
text: “This is a ‘STRING’ type”
type: typein:
type_desc: (string: 30)
value: “Initial default goes here”
mouse_text: “This mouse pointing help should normally include the input format
and an example.”
parameter: EDIT_STRING
text: “This is an ‘EDITOR’ field type”
type: edit:
type_desc: (30 80 5 “ Format: Enter format example here, followed by a carriage
return
Example: Enter Example here
HELP: EMACS Editor Widget (scroll with down/up arrow keys)
CURSOR MOVEMENT: Use the arrow keys:->,<-,etc.;Point the mouse cursor,click B1
CM: Ctrl-AMove the cursor to the BEGINNING of the current line
CM: Ctrl-EMove the cursor to the END of the current line
EDITING: All keyboard entry is in ‘insert’ mode
E: Backspace, Delete keysDelete one character to the LEFT of the cursor
E: Ctrl-D Delete one character to the RIGHT of the cursor
E: Ctrl-KKILL to the end of the line (from the cursor)
E: Ctrl-YYANK back the contents of the kill buffer; ‘Cut and
paste’; (Can move the cursor first) “ 3 )
value: “Initial default goes here”
mouse_text: “This item calls the EDIT function. The ‘type_desc:’ dictates an
editor 80 characters by 5 lines (30 chars to show on the menu.”
parameter: DATA_FILE
text: “Used to select a trace data file”
type: function:
type_desc: (dataset_list datasets)
value: “no entry”
selected_item: “INVALID”
mouse_text: “Use Mouse Button 1 to select a dataset file description from the
DATASETS menu.”
parameter: HEADER_SELECT
text: “Used to select a trace header word”
type: function:
type_desc: (header_list headers)
value: “SOURCE “
selected_item: “Live source number”
mouse_text: “This option calls a ‘C’ language function that presents the user
with a list of trace header words to choose from.”
parameter: TIME_GATES
text: “Used to select a TIME GATE parameter file”
type: function:
type_desc: ((parm_list “GAT”) parms)
value: “no entry”
selected_item: “* No Parameter File has been Selected *”
mouse_text: “Use Mouse Button 1 to select a gate parameter file from the
parameter file menu.”
parameter: MUTE_FILE
text: “Used to select a MUTE TIMES parameter file”
type: function:
type_desc: ((parm_list “MUT”) parms)
value: “no entry”
selected_item: “* No Parameter File has been Selected *”
mouse_text: “Use Mouse Button 1 to select a MUTE parameter file from the
parameter file menu.”
parameter: VEL_FILE
text: “Used to select a VELOCITY parameter file”
type: function:
type_desc: ((parm_list “VEL”) parms)
value: “no entry”
selected_item: “* No Parameter File has been Selected *”
mouse_text: “Use Mouse Button 1 to select a VELOCITY parameter file from the
parameter file menu.”
parameter: HORIZON_FILE
text: “Used to select an AUTOSTATICS HORIZON file”
type: function:
type_desc: ((parm_list “AHZ”) parms)
value: “no entry”
selected_item: “* No Parameter File has been Selected *”
mouse_text: “Use Mouse Button 1 to select an AUTOSTATICS HORIZON file from the
parameter file menu.”
parameter: KILL_FILE
text: “Used to select a TRACE KILL parameter file”
type: function:
type_desc: ((parm_list “KIL”) parms)
value: “no entry”
selected_item: “* No Parameter File has been Selected *”
mouse_text: “Use Mouse Button 1 to select a TRACE KILL parameter file from the
parameter file menu.”
parameter: REVERSE_FILE
text: “Used to select a TRACE REVERSAL parameter file”
type: function:
type_desc: ((parm_list “RVS”) parms)
value: “no entry”
selected_item: “* No Parameter File has been Selected *”
mouse_text: “Use Mouse Button 1 to select a TRACE REVERSAL parameter file from
the parameter file menu.”
exec_data: (“PROG_NAME”
(“GENERAL”
(“version” implicit: “@(#)EXAMPLE.menu 40.1 11/24/92” )
(“PARM1” implicit: (value ‘CHOOSE1))
(“PARM2” implicit: (value ‘CHOOSE2))
(“PARM3” implicit: (value ‘CIRCULAR1))
(“PARM4” implicit: (value ‘SIMPLE_REAL))
(“PARM5” implicit: (value ‘FANCY_REAL))
(“PARM6” implicit: (value ‘SIMPLE_INTEGER))
(“PARM7” implicit: (value ‘FANCY_INTEGER))
(“PARM8” implicit: (if (value ‘BOOLEAN1) 1 0 ))
(“PARM9” implicit: (value ‘STRING1))
(“PARM10” implicit: (value ‘EDIT_STRING))
(“PARM11” implicit: (value ‘DATA_FILE))
(“PARM12” implicit: (value ‘HEADER_SELECT))
(“PARM13” implicit: (value ‘TIME_GATES))
(“PARM14” implicit: (value ‘MUTE_FILE))
(“PARM15” implicit: (value ‘VEL_FILE))
(“PARM16” implicit: (value ‘HORIZON_FILE))
(“PARM17” implicit: (value ‘KILL_FILE))
(“PARM18” implicit: (value ‘REVERSE_FILE))
)
)
rules: (
(rule1 ( = ( value ‘SIMPLE_INTEGER ) 3 ) (do_show ‘FANCY_REAL) (do_not_show
‘FANCY_REAL))
(rule2 ( > ( value ‘FANCY_INTEGER ) 0 ) (do_show ‘SIMPLE_REAL) (do_not_show
‘SIMPLE_REAL))
(rule3 (value ‘BOOLEAN1) (progn (do_not_show ‘STRING1)
(do_not_show ‘EDIT_STRING)
(do_not_show ‘HEADER_SELECT))
(progn (do_show ‘STRING1)
(do_show ‘EDIT_STRING)
(do_show ‘HEADER_SELECT)))
)
➲ Plotting575
➲ Data Structures576
➲ Sorting and Searching580
Error Routines
Error Routines
Subroutine Description
exErrStop Stops flow immediately, prints message, & calls tools in cleanup mode.
exErrHelp Prompts user to select an option. An X window automatically pops up
with the possible options. Options are in the string text and are separated
by a vertical bar (|). For example: exErrHelp(“choice 1|choice 2|choice
3”).
uErrWarn Prints warning message without killing process. This is different from
uErrMessage() in the preamble printed before the message.
uErrStop Kills process and print a message. This is different from uErrFatal() in the
preamble.
Control Functions
Control Functions
Subroutine Description
exFillMode Sets mode of the current tool to fill mode; no trace is returned by this call,
and one trace will be accepted in the next call of this tool.
exFlushMode Sets mode of the current tool to flush mode; one trace is returned by this
call, and no trace will be accepted in the next call of this tool
exPipeMode Sets mode of the current tool to pipe mode; one trace is returned by this
call, and one trace will be accepted in the next call of this tool. If there are
no other traces to input, the module will not be called again.
exPushMode Sets mode of the current tool to push mode; one trace is returned by this
call, and one trace will be accepted in the next call of this tool. This
routine will be called even if there are no more traces to input.
exQuitMode Sets mode of the current tool to quit mode; no more traces are output by
this complex tool and no more are input.
exTraceHeadersOnlyOK Called by a processing tool in initialization phase if the tool can process
trace headers only. (By default, tools require traces.)
memCheckResBuf Checks the memory buffers allocated by the ProMAX fortran memory
allocator, MEMORY_RESBUFF(). Does not check memory allocated by
malloc(). This is useful if an array passed by a fortran routine to a C
routine is being corrupted by the C routine.
Parameter Input
Parameter Input
Subroutine Description
getPar General subroutine for getting a parameter that is compatible with the old
Stanford getpar() routines. The obselete occurence parameter has been
removed.
Configuration
Configuration
Subroutine Description
configDevList Returns a list of all of the devices of a particular type that are listed in the
configuration file.
Database
Database
Subroutine Description
dbInitDomainProject Initializes domain project capability which projects a position from one
domain (such as CDP) into another one (such as Surface Location); that
is, what surface location corresponds to CDP 127.
dbInitTraceMap Initializes trace mapping capability which, given two locations of in one
domain, gives the corresponding location in another domain; that is, what
is the traceno of SIN 2 and CHN 88 (domain1 is SIN, domain2 is CHN,
and domain3 is traceno).
dbDomainProject Projects a position from one domain (such as CDP) into another one
(such as Surface Location); dbInitDomainProject() must first be called.
dbEnsembleMap Maps a parameter (such as elevation) from one domain (such as CDP) to
another (such as surface location); that is, what is the elevation at the
surface location nearest to CDP 127.
dbTraceMap Maps a parameter (such as elevation) from one domain (such as CDP) to
another (such as surface location); that is, what is the elevation at the
surface location nearest to CDP 127.
Database (Continued)
Subroutine Description
opfGet Gets a value from the database.
opfInitGetXY Initializes getting the (X,Y) values for the location corresponding to a
database.
opfCloseGetXY Closes getting the (X,Y) values for the location corresponding to a
database.
opfGetXY Gets the (X,Y) values for the location corresponding to a database; this is
actually a macro for two opfGet()’s.
Database (Continued)
Subroutine Description
getFullName Converts a file name, as read in from a packet file, to a full path name of
the parameter table. The pathname has the proper directory of the area
and line.
opfPutFloats Puts several float values to a data base location that has length greater
than one.
opfPutDouble Puts a double value to the data base.
opfPutDoubles Puts several double values to a data base location that has length greater
than one.
opfPutInts Puts an array of integer values to one location in the database that has a
length greater than one.
opfInitPseudoLine
opfDeinitPseudoLine
opfParmList Returns a character string containing the names of the parameters for a
particular info type. Includes parameters with no format (deleted).
Freeing the returned space is left to the user.
dbDataInt Gets information on a data set, integer version; for stand-alone programs
only.
dbDataChar Gets information on a data set, string version; for stand-alone programs
only.
dbCreateParmFile Creates and initializes a parameter file that can be used for binary output
in a non-standard table format.
dbOpenParmFile Opens a parameter file that can be used for binary input in a non-standard
table format.
Database (Continued)
Subroutine Description
dbRewindParmFile Positions file opened with dbOpenParmFile() at the end of the header
portion and at the beginning of the user data position.
opfSoftRlse Returns the software release in use when the OPF was created.
opf Returns number of traces on the line when the geometry was created.
datasetReadHeaderFile Reads the header file associated with a table into the Parameter Group.
datasetWriteHeaderFile Writes a parameter group into a header file associated with a table.
d3CDPToXY Given a CDP, returns the corresponding X,Y coordinates (3D only).
d3XYToCDP Given an X,Y coordinate, returns the corresponding CDP number (3D
only).
d3LinesToCDP Given an inline and crossline number, returns the corresponding CDP
number (3D only).
d3CDPToLines Given a CDP number, returns the corresponding inline and crossline
number (3D only).
d3LinesToXY Given inline and crossline numbers, gets the corresponding (X,Y)
coordinates.
Memory Allocation/Management
Memory Allocation/Management
Subroutine Description
promaxMalloc Similar to malloc() but leaves marks for subsequent checking the ends of
the arrays.
promaxCalloc Similar to calloc() but leaves marks for subsequent checking the ends of
the arrays.
promaxFree Similar to free() but checks whether array ends have been overwritten
before freeing.
memAllAllocated Returns total memory allocated minus that freed, as specified by the
uordblks member of the structure returned from the system mallinfo()
call.
memArenaSize Returns size of the heap, as specified by the arena member of the structure
returned from the system mallinfo() call.
Trace Headers
Trace Headers
Subroutine Description
hdrExists Determines whether or not a header entry with specified name exists.
hdrIndexExists Determines whether or not a header entry with specified index exists.
hdrDesc Returns description of trace header entry specified by name.
hdrLength Returns length (in words) of trace header entry specified by name.
hdrIndexLength Returns length (in words) of trace header entry specified by index.
initHdrs Clears all header values. Sets the standard header entries that must be in a
trace to their defaults. Sets others that exist to reasonable defaults.
Trace Muting
Trace Muting
Subroutine Description
muteGetTimes Gets tapered mute start and end times from trace header.
muteSetTimes Sets tapered mute start and end times in trace header.
muteSlide Slides and applies tapered mutes according to first and last non-zero
samples.
muteRezero Re-zeros samples that were previously zero and tapers surgical mutes.
convertVTable Converts velocity from one type to another; that is, RMS velocities in
time to Interval velocities in depth.
vIntStepConv Converts RMS velocity to interval using constant velocity steps.
tblAvg Creates a one averaged velocity function V(z) from a variable velocity
field, V(x,z). Averaging is spatially weighted, such that functions are
weighted by the distance of their neighboring functions.
apertureVIT Computes the maximum aperture for a velocity function (in time) via ray
tracing.
apertureVID Computes the maximum aperture for a velocity function (in depth) via ray
tracing.
checkMigVelTbl Checks velocities for migration. Bombs if velocites are non-positive.
Prints warnings if minimum velocity is less than 100, maximum velocity
is greater than 30000, and the ratio of the maximum to the minimum
velocity is greater than 20.
Vector Routines
Vector Routines
Subroutine Description
Parameter Lists
Parameter Lists
Subroutine Description
listAlloc Allocates and initializes a new parameter list (for use with float values).
listAllocInts Allocates and initializes a new parameter list (for use with integer values).
listAdd Adds parameter starting value, ending value, and value increment to the
parameter list.
listAddInts Adds parameter starting value, ending value, and value increment to the
parameter list.
Packet Files
Packet Files
Subroutine Description
pktOutParmN Puts multiple values for one parameter into the packet file.
Parameter Interpolation
Parameter Interpolation
Subroutine Description
Unix Interface
Unix Interface
Subroutine Description
promaxPathName Returns the path to specific directories and files in the ProMAX directory
structure. Local host-pecific version of promaxHostPath().
promaxPath Returns the path to specific directories and files in the ProMAX directory
structure. Backward-compatible version of promaxPathName().
promax_path_ Returns the path to specific directories and files in the ProMAX directory
structure. Fortran wrapper for promaxPath().
promaxHostExtPath Returns array of paths to specific directories and files in the ProMAX
extended directory structure.
promaxExtPath Returns array of paths to specific directories and files in the ProMAX
extended directory structure for the calling host.
diskAvail A nicer interface for determining the amount of disk space available in a
directory.
cpusec Returns cpu time (UNIX user time) in seconds.
cputime Returns cpu time (UNIX user time) in seconds using ANSI C built-ins.
walltime Returns elapsed time (wall clock time) in seconds using ANSI C built-ins.
Return value will be an integral number of seconds since t1 and t2, as
returned by the time() intrinsic, are the number of seconds since the
epoch.
IPC Tools
IPC Tools
Subroutine Description
stGetEnsemble Reads in an Ensemble from the ProMAX flow into a socket tool program.
pstGetEnsemble Reads in an Ensemble from the ProMAX flow into a socket tool program.
stPassSocketLink Closes the socket link to the ProMAX flow, but has the flow continue to
pass traces so the flow continues without this tool.
stEndInitialization Signals the end of program initialization to the ProMAX flow. This
causes the init phase of the flow to return. After this call, only traces can
be sent and received.
stHdrAddStd Adds a ProMAX standard header to the data. The description, length, &
format are read from system files.
stSetOutPanels Sets Panel dimensions for later panel output. If stSetPanels() is called, but
this is not, it is assumed that the output panel dimensions will be identical
to the input panel dimensions.
stSetPanels Sets Panel dimensions for later panel input and output. This is identical to
the normal executive panel tool, except that the executive cannot override
the choices of panel parameters. The purpose of this tool is to read in a
group of traces, like a portion of an ensemble or stacked section, that is
managable in a limited amount of memory. Each group of traces can be
treated as a sub-ensemble. The groups can be overlapping to avoid edge
effects. The groups are recombined on output. If data is stacked, a series
of stacked traces is passed; if data is not stacked, only those traces up to
the end of the ensemble is passed. So, a migration does not need to know
if it is working with stacked data or a series of NMO’d, DMO’d common
offset sections. Or, FK filter does not need to know if it is filtering a shot
gather or stacked data.
stStatMemReserve Tells the executive how much memory the IPC tools will use. Repeated
calls increment the memory usage.
st_get_trace_ Reads in a trace from the ProMAX flow into a socket tool program.
st_get_ensemble_ Reads in an Ensemble from the ProMAX flow into a socket tool program.
st_end_init_ Signals the end of program initializtion to the ProMAX flow. This causes
the init phase of the flow to return. After this call, only traces can be sent
and received.
st_set_panels_ Sets Panel dimensions for later panel input and output. This is identical to
the normal executive panel tool, except that the executive cannot override
the choices of panel parameters. The purpose of this tool is to read in a
group of traces, like a portion of an ensemble or stacked section, that is
managable in a limited amount of memory. Each group of traces can be
treated as a sub-ensemble. The groups can be overlapping to avoid edge
effects. The groups are recombined on output. If data is stacked, a series
of stacked traces is passed; if data is not stacked, only those traces up to
the end of the ensemble is passed. So, a migration does not need to know
if it is working with stacked data or a series of NMO’d, DMO’d common
offset sections. Or, FK filter does not need to know if it is filtering a shot
gather or stacked data.
Parameter Tables
Parameter Tables
Subroutine Description
tblAllocTmp Allocates and initializes a temporary parameter table for z(x,y), for the
case in which true spatial coordinates can be ignored.
tblResolveX1X2 Given an X (ensemble number), returns the spatial coordinates that are
used within the table functions.
tblGetX Gets X location from a table. This is identical to calling: tblGetXYs( tbl,
ix_counter, 0, x_loc, NULL, NULL, NULL ). This routine does not
gaurantee the functions are retrieved in order of increasing X.
tblGetEnsemble Gets ensemble number (X location) (CDP,SIN,etc) for a given table node,
in order of increasing X.
tblCopy Copies all groups from tbl2 to tbl1. tbl1 does not have to be empty.
tblGetXYs Gets X-Y-Z group from a table. This routine does not guarantee the
functions are retrieved in order of increasing X.
tblDeleteXY Deletes z value(s) at specified (x,y) point.
tblDescFromDatabase Gets a table description from database using the hash label. This routine
is needed because the menu can return the hash name of a newly created
(using Add option) table for output. To save the table, however, we need
the description. See also tblToDatabaseHashName.
tblSetType Sets three letter code that identifies the table type.
tblToDatabaseHashName Puts a parameter table to database using a hash label. This is designed to
be used when the menu returns the hash name of a table. This routine
copies the description of that table into the description of the table being
written. A Fatal error occurs if the table does not already exist.
tblToDatabase Puts a parameter table to database.
tblWriteHeaderFile Writes a parameter group into a header file associated with a table.
tblXMin Gets minimum X value for table. For 2D tables, this is the same as
tblX1Min(). For 3D tables, this is ensemble number while X1 is a
coordinate.
tblXMax Gets maximum X value for table. For 2D tables, this is the same as
tblX1Max(). For 3D tables, this is ensemble number while X1 is a
coordinate.
tblMinMax Gets several maximum and minimum values for table. If NULL is passed
for an address, that value is not returned.
tblZMax Gets maximum Z value for table. This function assumes only one z value
per node.
tblZMin Gets minimum Z value for table. This function assumes only one z value
per node.
tblGetYZ Gets sample coordinates and values from an existing node in table.
tb3SetData Sets user-specified data in node of table. If node does not exist, makes one
with the specified data. If data exists, replaces it.
tb3SetYZ Sets samples in node of table. If node does not exist, makes one with the
specified samples. If samples exist at specified y, replaces their values.
tb3GetTri Gets pointer to the triangulation structure used for the tables.
tb3DeleteData Deletes user-specified data from an existing node in table. If the node has
no samples, deletes the node.
tb3DeleteYZ Deletes sample coordinates and values from an existing node in table. If
the node has no user-specified data, deletes the node.
tb3MinMax Returns minimum and maximum node and sample coordinates and
sample values.
makeSamples Allocates and initializes samples. If ny==0, samples are not made and
NULL is returned. If y==NULL, uniform sampling is specified by dy and
fy.
findSample Returns index of sample with coordinate yFind; returns -1 if sample not
found.
locateSample Determines largest iy such that y[iy] < yLocate or y[iy] == yLocate,
where “==” is defined by the APPROX macro. If yLocate < y[0], sets iy =
-1. If y[iy] == yLocate (as defined by APPROX), returns 1; otherwise,
returns 0.
makeNode Makes a new node, with samples and data attached.
killNode Deletes a node, if the node exists. User-specified data is not freed.
cleanNodes Cleans up nodes by removing nodes with no data and/or samples. For
what=0, removes nodes with no data. For what=1, removes nodes with no
samples.
updateInterp Updates the table interpolator; if it does not exist, makes it.
PVM
PVM
Subroutine Description
pvm_pvmd Starts pvm daemon, if one is not already running, and enrolls process in
pvm.
pvm_rMinContext Returns minimum valid value for an context label
pvm_rcurrentContext Returns current context number (does not change context number)
pvm_rmcast Multicasts the data in the active message buffer to a set of tasks
pvm_rbcast Immediately broadcasts the data in the active message buffer tasks in a
group
**********************************************************
********************
Input: group name of an existing group context message context label (0
<=
context <= CONTEXT_MAX) msgtag message tag supplied by user (0
<= msgtag
<= MSG_MAX) Returned: >= 0 -> success ; < 0 -> error
pvm_rrecv Blocks until a message with specified context and message tags has
arrived from the specified source, and places message in a new active
receive buffer
pvm_crecv PVM checking re-entrant receive. This receive acts like a blocking
receive if the sending process is still alive. If the sending process dies, this
function returns with the error PvmNoTask.
PVM (Continued)
Subroutine Description
pvm_rcrecv PVM checking re-entrant receive. This receive acts like a blocking
receive if the sending process is still alive. If the sending process dies, this
function returns with the error PvmNoTask.
pvm_rcrecvm PVM checking re-entrant multiple receive. This receive acts like a
blocking receive if the sending process is still alive. If the sending process
dies, this function returns with the error PvmNoTask.
getenvstring Packs the environment into a single null-terminated string. Within the
string, the environmental variable strings are delimited by new-line
characters.
execPvmtool Signals exec that initialization of this tool is complete and that it is ready
to begin execution.
endPvmtool Tells exec that this tool has finished, and leaves PVM
ptAtEOF Informs whether EOF has been reached
PVM (Continued)
Subroutine Description
ptRcvPromaxHeader Receives ProMAX header from another PVM process
upkGlobalAcquis Receives ProMAX global acquisition info from another PVM process
upkGlobalChar Receives ProMAX global character info from another PVM process
pkGlobalCoord Sends ProMAX global coord info to another PVM process
upkGlobalCoord Receives ProMAX global coord info from another PVM process
upkGlobalGeom Receives ProMAX global geometry info from another PVM process
upkGlobalMisc Receives ProMAX global misc info from another PVM process
upkGlobalRuntime Receives ProMAX global runtime info from another PVM process
Matrix Functions
Matrix Functions
Subroutine Description
tridif Solves a tridiagonal linear system of equations Tu=r for u (float version)
sdot Returns sum of x[i]*y[i] (i.e., return the dot product of x and y)
Interpolation Routines
Interpolation Routines
Subroutine Description
intcub Evaluate y(x), y’(x), y’’(x), ... via piecewise cubic interpolation
tinAddWithData Adds an array of z values and user-specified data at the specified x,y
makeNodeData Allocates space for node data and set its members
makeTempNodeData Allocates space for temporary boundary node data and set the data values
deleteNode Deletes specified node and its data, and invalidate gradient data of nabors
naborNodes Returns null-terminated list of nodes that are nabors of the specified node
triNearestNodes Finds the n nodes in triangulation that are nearest to the point (x,y)
triAddTempBoundaryNode If the node opposite any boundary edge is near enough to that edge and
far enough from the its endpoints, creates and returns a temporary node
between the endpoints of the edge; otherwise, returns NULL
triTempBoundaryNode If any temporary boundary nodes exist, returns one; otherwise, returns
NULL
makeNodeInside Makes node inside triangle defined by nodes n1, n2, and n3, ordered
counter-clockwise
makeNodeOutside Makes node outside boundary; connects the new node n to all boundary
nodes between n1 and n2 inclusive, where n1 is the leftmost (as viewed
from n) node on the boundary that is visible from n, and n2 is the
rightmost node on the boundary visible from n
makeNodeOnLine Makes node on line of co-linear nodes; connects the new node n to nodes
n1 and n2. If n2 is NULL, then n1 is assumed to be an end node, and the
new mnode n will become the new end node. If n2 is not NULL, then n1
is assumed to be left of n2.
makeNodeOffLine Makes node off line of co-linear nodes; connects the new node n to all
nodes in line
oppositeNode Returns node opposite n1, on the other side of edge n2-n3, where
n1,n2,n3 are currently triangle vertices in counter-clockwise order.
Returns NULL if edge n2-n3 is a boundary edge.
swapTest Determines whether or not to replace edge n2-n3 with edge n1-n4 in a
quadrilateral, in which n1,n2,n3 are currently triangle vertices in
counter-clockwise order. Returns non-zero iff swap should be performed.
swapEdge Replaces edge n2-n3 with edge n1-n4 in convex quadrilateral, in which
n1,n2,n3 are currently triangle vertices in counter-clockwise order.
Math Functions
Math Functions
Subroutine Description
tokenPairInt Converts token to pair of ints; for example, token=”2--3” yields i1=2,
i2=-3
tokenReplicatedInt Converts token to replicated int; for example, “2(3)” yields n=3, i=2
tokenIteratedInt Converts token to iterated int; for example, token=”2-6(2)” yields n=3,
d=2, i=2
tokenDecodeInts Decodes int tokens specified in a compact style to an array of ints; for
example, string=”-5 - -1(2), 0, 1-3(1),4(2)” yields n=9 and i[]={-5, -3, -1,
0, 1, 2, 3, 4, 4}
tokenPairFloat Converts token to pair of floats; for example, token=”2--3.2” yields f1=2,
f2=-3.2
tokenIteratedFloat Converts token to iterated float; for example, token=”2-3(.5)” yields n=3,
d=0.5, f=2
tokenDecodeFloats Decodes float tokens specified in a compact style to an array of floats; for
example, string=”-2--1.4(0.2),0,1-2.5(0.5),3(2)” yields n=11 and f[]={-2,
-1.8, -1.6, -1.4, 0, 1, 1.5, 2, 2.5, 3, 3}
tioSetSwapflag Establishes the need for byte swapping on a file that was opened by
tioOpen or tioOpenU. This routine or tioReadSwapflag must be called
before any I/O is done on a file.
tioReadSwapflag Establishes the need for byte swapping on a file that was opened by
tioOpen or tioOpenU. This routine or tioSetSwapflag must be called
before any I/O is done on a file.
ddot Returns sum of x[i]*y[i] (i.e., return the dot product of x and y)
dnrm2 Returns square root of sum of squares of x[i] (i.e. length of the vector)
Signal Processing
Signal Processing
Subroutine Description
npfa Returns smallest valid n not less than nmin for prime factor fft
npfao Returns optimal n between nmin and nmax for prime factor fft
npfar Returns smallest valid n not less than nmin for real-to-complex or
complex-to-real prime factor ffts
Plotting
Plotting
Subroutine Description
Data Structures
Data Structures
Subroutine Description
rbtInsert Inserts data into tree. If the same data already exists in tree, another copy
is inserted.
hpsort Sorts an array so that a[0] <= a[1] <= ... <= a[n-1]
qkipart Quicksort partition (FOR INTERNAL USE ONLY): Takes the value x of
a random element from the subarray a[p:q] of a[0:n-1], and rearranges
indices in the subarray i[p:q] in such a way that there exist integers j and k
with the following properties: p <= j < k <= q, provided that p < q a[i[l]]
<= x, for p <= l <= j a[i[l]] == x, for j < l < k a[i[l]] >= x, for k <= l <= q.
This effectively partitions the subarray with bounds [p:q] into lower and
upper subarrays with bounds [p:j] and [k:q].
qkiinss Quicksort insertion sort (FOR INTERNAL USE ONLY): Sort a subarray
of indices bounded by p and q so that a[i[p]] <= a[i[p+1]] <= ... <= a[i[q]]
qkisort Sorts an array of indices i[] so that a[i[0]] <= a[i[1]] <= ... <= a[i[n-1]]
qkifind Partially sorts an array of indices i[] so that the index i[m] has the value it
would have if the entire array of indices were sorted, such that a[i[0]] <=
a[i[1]] <= ... <= a[i[n-1]]
qkpart Quicksort partition (FOR INTERNAL USE ONLY): Take the value x of a
random element from the subarray a[p:q] of a[0:n-1], and rearranges the
elements in this subarray in such a way that there exist integers j and k
with the following properties: p <= j < k <= q, provided that p < q a[l] <=
x, for p <= l <= j a[l] == x, for j < l < k a[l] >= x, for k <= l <= q. This
effectively partitions the subarray with bounds [p:q] into lower and upper
subarrays with bounds [p:j] and [k:q].
qkinss Quicksort insertion sort (FOR INTERNAL USE ONLY): Sorts a subarray
bounded by p and q so that a[p] <= a[p+1] <= ... <= a[q]
qksort Sorts an array such that a[0] <= a[1] <= ... <= a[n-1]
qkfind Partially sorts an array so that the element a[m] has the value it would
have if the entire array were sorted such that a[0] <= a[1] <= ... <= a[n-1]
➲ Parameter Input618
➲ Packet Files619
➲ Character Routines621
➲ Seg-Y Disk622
➲ Geophysical Routines622
➲ Signal Processing627
➲ Disk I/O634
➲ SEG Vector Routines636
➲ Resource Reporting642
➲ UNIX Interface643
Area/Line(Survey)/Flow
Area/Line(Survey)/Flow
Subroutine Description
DB_AREACOUNT Returns the total number of areas in the ProMAX database and the
number of characters in the longest area name
DB_AREALIST Returns a list of the (null-terminated) names of all of the areas in the
ProMAX database
DB_LINECOUNT Returns the total number of lines in an area and the number of characters
in the longest line name
DB_LINELIST Returns a list of the (null-terminated) names of all of the lines in an area
DB_INIT_LINE Initializes the variables in global.inc for a line in the ProMAX database
DB_FLOWCOUNT Returns the total number of flows in a particular line in an area and the
number of characters in the longest flow name
DB_DATACOUNT Returns the total number of datasets in a particular line in an area and the
number of characters in the longest dataset name
DB_PARMCOUNT Returns the total number of parameter sets in a particular line in an area
and the number of characters in the longest parameter set name
DB_TBL_COUNT Returns the total number of tables in a particular line in an area and the
number of characters in the longest table name
Area/Line(Survey)/Flow (Continued)
Subroutine Description
DB_FOREIGN_COUNT Returns the total number of foreign files in a particular line in an area and
the number of characters in the longest name. Hidden directories are
included.
DB_RE_FILE_COUNT Returns the total number of files in a particular line whose names match a
regular expression and the number of characters in the longest name.
Does not include directory names.
DB_LIST_COUNT Returns the total number of lists in a particular line in an area and the
number of characters in the longest list name
DB_FOREIGN_LIST Returns a list of the (null-terminated) names of all of the foreign files in a
particular line in an area
DB_INIT_DATA Initializes a dataset in the ProMAX database (stores the description and
nothing else)
DB_INIT_PARM Initializes a parameter set (table/list) in the ProMAX database (stores the
description and nothing else)
DB_THDRCOUNT Returns the number of basic standard trace header entries and the total
number of standard trace header entries
DB_THDRCOUNT_STK Returns the number of basic standard trace header entries and the total
number of standard trace header entries used in post-stack processing
DB_THDRLIST Returns the list of standard trace header entry names and their
descriptions
Area/Line(Survey)/Flow (Continued)
Subroutine Description
DB_THDRLIST_STK Returns the list of standard trace header entry names and their
descriptions used for post-stack processing
Configuration
Configuration
Subroutine Description
CONFIG_GET_STR Returns a user-defined character string entry from the configuration file
Database Orders
Database Orders
Subroutine Description
LINEDB_PARMPUT Loads a particular parameter into the LIN database ordered parameter
file. The parameter is not created by this routine. It is assumed that the
parameter already exists and only its value is being modified (the
parameters are created when the line is initialized).
DB_ORDLIST Returns a list of the ordered parameter files that exist
DB_ORD_MINMAX Retrieves the min and max location for existing ordered parameter file
DB_ORDINFO Retrieves global info for an existing ordered parameter file
DB_ORDOPEN Opens an ordered parameter file in shared mode. Subsequent calls should
be read-only. Significantly reduces I/O time for subsequent database calls.
No more than 100 files can be opened at one time.
DB_ORDLOCK Locks an ordered parameter file, ensuring that other processes do not
access it until it is unlocked. Locking also significantly reduces I/O time
for subsequent database calls. No more than 100 files can be locked at one
time.
DB_PARMINFO Retrieves information for one parameter from an ordered database file
DB_PARMPUT Writes values for one parameter into an ordered database file
DB_PARMGET Reads values for one parameter from an ordered database file
DB_INFOLIST Returns a list of NAMEs, descriptions, and dates for a unique INFOTYP
DB_ORDADD Rebuilds and appends an ordered parameter file with more locations
DB_BUFFRDPUT Inputs parameter values to the database in a buffered fashion. Values are
passed in one at a time.
DB_FIELD2NAMES Extracts an order name, info type, and parm name from a character field.
Normally the character field is extracted from a packet file after being
output by the user interface by using the menu function
choose_new_db_parm or choose_old_db_parm.
Domain Mapping
Domain Mapping
Subroutine Description
DB_ENSEMBLE_MAP
DB_TRACE_MAP
DOMAIN_PROJECT Projects points from one domain into another domain, based on the X,Y
coordinates of points in both domains; for example, CALL
DOMAIN_PROJECT (ITOKEN, ‘SIN’, ‘CDP’, 44, & RCDP, IERR).
This would return the CDP number that corresponds to the position of
SIN (shot index number) 44. The returned value is a floating point
number that includes a fractional portion of the CDP number. The routine
can be called with more than one set of parameters within a single
process, and crooked lines are supported.
Miscellaneous 1
Miscellaneous 1
Subroutine Description
DB_TBL_GET
DB_LIST_GET
DB_TBL_PUT
DB_LIST_PUT
DB_CHOOSE_AL Prompts the user to select an area and line via I/O to standard input/output
D3_CDP_TO_XY Given a CDP, this routine returns the corresponding X,Y coordinates (3-D
only)
D3_XY_TO_CDP Given an X,Y coordinate, this routine returns the corresponding CDP
number (3-D only)
D3_XY_TO_XLINE Given an X,Y coordinate, this routine returns the corresponding crossline
number (3-D only)
D3_XY_TO_INLINE Given an X,Y coordinate, this routine returns the corresponding inline
number (3-D only)
D3_LINES_TO_CDP Given an inline and crossline number, this routine returns the
corresponding CDP number (3-D only)
D3_CDP_TO_LINES Given a CDP number, this routine returns the corresponding inline and
crossline number (3-D only)
Trace I/O
Trace I/O
Subroutine Description
DATASET_INFO_ALL Returns all parameters that describe the state of the system when a dataset
was written (replaces DISKIO_INFO).
DATASET_INFO Returns parameters that describe the state of the system when a dataset
was written (replaces DISKIO_INFO).
DISKIO_THDR_SETUP Creates all of the trace header words that exist in the dataset and makes a
map of header words from how they existed on disk to how they currently
exist
Trace Executive
Trace Executive
Subroutine Description
EX_PANEL_PARMS Called during initialization phase by any tool that wishes to processes
overlapping panels (2-D arrays of traces). Panel processing can be done
pre-stack or post-stack.
EX_BUFF_PARMS Sets parameters for single or double buffered tools
EX_SET_DISKITER Causes Disk Data Input to iterate over the list of input traces
Trace Headers
Trace Headers
Subroutine Description
HDR_DELETE_UPDATE Corrects a trace header after a header entry is removed from the current
list of header entries (via HDR_DELETE)
HDR_STD_ADD Adds standard header words to the trace header if they do not already
exist
HDR_STD_INIT_VALS Initializes the values in a trace header for all of the minimum standard
header entries. This routine should be called by all input tools.
EX_HDR_DELETE Removes a trace header entry from the current list of header entries;
intended for use by tools running under the executive
KILL_TRACE Kills traces; also sets the relevant trace header entries
Memory Management
Memory Management
Subroutine Description
MEM_FREEBUFF_ALL Frees all buffer of memory in the SPACE array on a 32-bit O/S.
MEMORY_FREEBUFF_ALL Frees all buffer of memory in the SPACE array on a 32-bit or 64-bit O/S.
MEM_TRAP Checks for memory problems, displays a message if problems exist, and
stops the execution of the program. This routine is intended only for
debugging purposes; sprinkle through suspect source code to identify
where memory problems are caused. This is used on a 32-bit O/S.
MEMORY_TRAP Checks for memory problems, displays a message if problems exist, and
stops the execution of the program. This routine is intended only for
debugging purposes; sprinkle through suspect source code to identify
where memory problems are caused. This is used on a 32-bit or 64-bit
O/S.
Mute/Kill
Mute/Kill
Subroutine Description
REMUTE_INIT Initializes for the REMUTE subroutine. Must be called once before every
call to REMUTE.
REMUTE Remutes a buffer of traces (applies the same mute that existed previously,
before some operation such as a filter). Must be the same buffer of traces
that was passed to REMUTE_INIT. REMUTE_INIT mute be called once
before every call to REMUTE.
RESET_MUTES Resets all of the standard mute times in a buffer of trace headers
(typically after static shifts have been applied)
REMUTE_CHANGE Resets the mute times in the trace headers and re-ramps the mute after
some change has occurred in the data (such as NMO). This routine allows
the mute to move (in contrast to REMUTE).
Statics
Statics
Subroutine Description
Summing
Summing
Subroutine Description
AT_WMEAN Finds the alpha trimmed WEIGHTED mean of a group of values. The
input arrays are DESTROYED by this routine.
AT_MEAN Finds the alpha trimmed mean of a group of values. The input arrays are
DESTROYED by this routine.
Error Routines
Error Routines
Subroutine Description
U_ERR_FATAL 1) Selects the appropriate destination for output messages. 2) Displays the
input error message. 3) Stops the process, returning control to the parent
process. This routine is not restricted for use by tools that are linked into
the executive.
U_ERR_WARN 1) Selects the appropriate destination for output messages. 2) Displays the
input warning message. 3) Returns control to the routine that called it.
This routine is not resticted for use by tools that are linked into the
executive.
U_ERR_HELP Prompts the user to provide help or select an option to change the course
of action. This routine is intended for use by tools that are not linked into
the executive (otherwise use EX_ERR_HELP)
RM_SCRATCH_FILE Removes a file if the file exists within the ProMAX scratch directory
EX_ERR_RESTART 1) Selects the appropriate destination for output messages. 2) Informs the
user of the state of the system, including current trace, current ensemble,
and current tool. 3) Displays the input message. 4) Cleans up the job,
including calling tools in cleanup mode. 5) Restarts the process.
EX_ERR_STOP 1) Selects the appropriate destination for output messages. 2) Informs the
user of the state of the system, including current trace, current ensemble,
and current tool. 3) Displays the input message. 4) Cleans up the job,
including calling tools in cleanup mode. 5) Stops the process, returning
control to the parent process.
EX_ERR_FATAL 1) Selects the appropriate destination for output messages. 2) Informs the
user of the state of the system, including current trace, current ensemble,
and current tool. 3) Displays the input error message. 4) Cleans up the
job, including calling tools in cleanup mode. 5) Stops the process,
returning control to the parent process.
EX_ERR_MSG 1) Selects the appropriate destination for output messages. 2) Informs the
user of the state of the system, including the current tool. 3) Displays the
input message. 4) If running in interactive mode, waits for the user to
press return. 5) Returns control to the calling routine.
EX_ERR_HELP Prompts the user to provide help or select an option to change the course
of action.
Parameter Tables
Parameter Tables
Subroutine Description
TBL_VAL_DECODE This routine decodes a location:parameter string and loads the results in a
parameter table. Typical input is CLIST = ‘5:20-30:-47.5/8-9:36:-55.3/’
TBL_GATE_DECODE This routine decodes a location:time gates parameter string and loads the
results in a parameter table. Typical input is
CGATE = ‘0:100-500,800-1800/5280:1200-1900,2100-2800/’
TBL_VEL_DECODE This routine decodes a location:times-vels parameter string and loads the
results in a parameter table. Typical input is
CVEL = ‘1:0-5000,4000-12000/100:0-6000,4000-12800/’
TBL_ALLOC_TMP Allocates and initializes a temporary parameter table for z(x,y), for the
case in which true spatial coordinates can be ignored
TBL_FETCH_TB3 Returns the underlying tb3 so that the tb3 functions can be used directly
TBL_RESOLVE_X1_X2 Given an X (ensemble number), returns the spatial coordinates that are
used within the table functions
TBL_DESC_FROM_DB Gets a table description from database using the hash label. This routine
is needed because the menu can return only the hash name of a newly
created (using Add option) table for output. To save the table, however,
we need the description.
EX_TBL_BUILD Sets the primary and secondary header key values (normally used for
table interpolation)
Tables Obsolete
Tables Obsolete
Subroutine Description
TBL_VAL_DECODE This routine decodes a location:parameter string and loads the results in a
parameter table. Typical input is CLIST = ‘5:20-30:-47.5/8-9:36:-55.3/’
TBL_GATE_DECODE This routine decodes a location:time gates parameter string and loads the
results in a parameter table. Typical input is
CGATE = ‘0:100-500,800-1800/5280:1200-1900,2100-2800/’
TBL_VEL_DECODE This routine decodes a location:times-vels parameter string and loads the
results in a parameter table. Typical input is
CVEL = ‘1:0-5000,4000-12000/100:0-6000,4000-12800/’
Parameter Interpolation
Parameter Interpolation
Subroutine Description
INT_GET Interpolates values or groups of values by using the parameter table. If the
values are outside the ranges of the parameter table, the values may be
extrapolated, linearly extended from the last control or the error flag can
be set to true.
INT_VEC Interpolates vectors NPTS_VEC long, starting at Y_START and at an
increment of Y_INC by using the parameter table. If the input X,Y
location values are outside the ranges of the parameter table, the values
may be extrapolated, linearly extended from the last control or the error
flag can be set to true.
Input arguments:
ID_TABLE - the table ID number
IX_XTRAPOLAT - 1 if the data is to be extrapolated in the X direction -
0 for linear extention (duplicate the last specified values) - -1 to return
NO_INTERP = 1 if the requested location is outside the range for which
values are defined
IY_XTRAPOLAT - 1 if the data is to be extrapolated in the Y direction -
0 for linear extention (duplicate the last specified values) - -1 to return
NO_INTERP = 1 if the requested location is outside the range for which
values are defined. X - the desired output X location (primary key) of the
interpolated data.
Y_START - the starting Y (secondary key) value of the desired output
vector
Y_INC - the Y value increment for the desired output vector
NPTS_VEC - the number of output values for the desired output vector
Output arguments: Z_VEC - the output array of interpolated values
NO_INTERP - 1 if the requested X and Y is outside the user-specified
parameter interpolation values and the user forbade extrapolation or
linear extention, else NO_INTERP = 0 if the interpolation was successful.
Warning: The parameter table must have been properly closed via a call
to TBL_END to be used by this subroutine. A fatal error will result if this
is not the case. A fatal error will also occur if the parameter table has
more than one Z value per Y value.
See also:
TBL_OPEN,TBL_WRITE,TBL_CLOSE,TBL_INIT,TBL_INFO,TBL_
ADD,
TBL_GET,TBL_DELETE,TBL_END,TBL_FREE,INT_GET,INT_VEC
INT_PS_KEYS Sets the primary and secondary header key values (normally used for
table interpolation)
Parameter Lists
Parameter Lists
Subroutine Description
LIST_INIT_INTS Initializes a totally new list for use with integer values
LIST_INIT Initializes a totally new list for use with floating point values
LIST_ADD Adds parameter starting value, ending value, and value increment entries
to the parameter list
LIST_CHECK Tests input parameters against list values to see if they are within the
primary/secondary/tertiary/etc. value specifications
LIST_LEVEL_CHECK Tests input parameters against list values to see if they are within the
value specifications for a particular level
LIST_GET Tests input location parameters against list values to see if they are within
the primary/secondary/tertiary/etc. list value specifications. If they are,
LIST_GET returns the ‘bottom’ level LIST values VAL1_OUT,
VAL2_OUT and VAL_INC_OUT.
LIST_SORT Sorts input arrays of header values for up to ten levels and creates an
output list of trace index addresses
LIST_BV_SORT Sorts input arrays of header values for up to ten levels and creates an
output list of trace index addresses
LIST_SELECT Selects input traces from input arrays of header values (up to ten levels)
and creates an output list of trace index addresses
String Decoding
String Decoding
Subroutine Description
PAIR_DECODE Decodes free form list of pairs of values, such as time gates; for example,
‘400-1200,1500-2000/’ => 400.0, 1500.0 and 1200.0, 2000.0
FLOAT_DECODE Subroutine decodes free form list of floating point values; for example,
‘100,101.0-111.0(2),-118.5(2)’ =>
100.0,101.0,103.0,105.0,107.0,109.0,111.0,-118.5,-118.5
Legal characters are 0-9 plus ‘ ,()./ -*’
DECODE_PREP Prepares character strings for decoding (corrects bad syntax if possible,
removes bad characters, etc.)
FLOAT_MAX_DECODE Subroutine decodes free form list of floating point values; for example,
‘100,101.0-111.0(2),-118.5(2)’ =>
100.0,101.0,103.0,105.0,107.0,109.0,111.0,-118.5,-118.5
Legal characters are 0-9 plus ‘ ,()./ -*’
Miscellaneous 2
Miscellaneous 2
Subroutine Description
PROMAX_PATH Returns the path to specific directories and files in the ProMAX directory
structure. These paths can be controlled via environmental variables. The
default root directory is “/advance”.
REGEXP_MATCH Checks for a match between a regular expression and a string
VAX_TO_IEEE Converts an array of VAX 32 bit floating point numbers to IEEE 32 bit
floating point numbers
IEEE_TO_VAX Converts an array of IEEE 32 bit floating point numbers to VAX 32 bit
floating point numbers
HEAPSORT Sorts a real array RA of length N into ascending numerical order using
the Heapsort algorithm (see pg. 231 of Numerical Recipes, Cambridge
University Press, 1986)
HEAPSORT2 Sorts a real array RA of length N into ascending numerical order using
the Heapsort algorithm (see pg. 231 of Numerical Recipes, Cambridge
University Press, 1986). Differs from HEAPSORT in that it makes the
corresponding rearrangement of RB
HEAPSORT_INT Sorts an integer array IA of length N into ascending numerical order
using the Heapsort algorithm (see pg. 231 of Numerical Recipes,
Cambridge University Press, 1986)
U_DOUBLE2INT Loads a DOUBLE that is stored in an array (such as a trace header) into a
single INTEGER
U_DOUBLELOAD
U_DOUBLE2REAL
Miscellaneous 2 (Continued)
Subroutine Description
U_SWAPENDS4 Swaps the ends of 4-byte values to switch between big-endian and
little-endian machines (in place)
U_SWAPMOVE4 Swaps the ends of 4-byte values to switch between big-endian and
little-endian machines (NOT in place)
U_SWAPENDS2 Swaps the ends of 2-byte values to switch between big-endian and
little-endian machines (in place)
U_SWAPMOVE2 Swaps the ends of 2-byte values to switch between big-endian and
little-endian machines (NOT in place)
U_SWAPENDS8 Swaps the ends of 8-byte values to switch between big-endian and
little-endian machines (in place)
U_SWAPMOVE8 Swaps the ends of 8-byte values to switch between big-endian and
little-endian machines (NOT in place)
FIND_NEAR_IVAL Finds the index of a integer value in an array, assuming that the value that
was found last time is a good place to start searching
FIND_NEAR_RVAL Finds the index of a real value in an array, assuming that the value that
was found last time is a good place to start searching
Parameter Input
Parameter Input
Subroutine Description
EX_PARMINFO Returns information for an input parameter in the current tool’s parameter
packet
U_PARMINFO Returns information for an input parameter. Equivalent in functionality to
EX_PARMINFO, except that it is intended for use by stand-alone
programs.
EX_CGETPARM Returns values for a character input parameter in the current tool’s
parameter packet
EX_GETPARM_GRP Returns values for an input parameter in Jth occurence of a group in the
current tool’s parameter packet
Packet Files
Packet Files
Subroutine Description
PKT_TOOLNAM Gets the name of a particular tool without loading the entire packet
PKT_LOAD Loads a packet for a particular tool so that the contents of the packet can
be retrieved.
PKT_GET_NGROUPS Returns the number of groups in the current tool’s packet. Called by tools
during init phase.
PKT_GROUPINFO Returns the name and number of parms in a particular group, identified by
sequence number. This assumes that the group is within the current
packet.
PKT_PINFO Returns information for an input parameter within the current group
PKT_OPEN_LOAD Opens an existing packet file and loads the packet for a specified tool
Character Routines
Character Routines
Subroutine Description
PROMAX_SEGY_RINIT Reads the initialization portion of the header file for a ProMAX
SEGY-like dataset
PROMAX_SEGY_WRITE Writes a trace to the files of a ProMAX SEGY-like dataset
PROMAX_SEGY_READ Reads the next trace from the files of a ProMAX SEGY-like dataset
Seg-Y Disk
Seg-Y Disk
Subroutine Description
PROMAX_SEGY_RINIT Reads the initialization portion of the header file for a ProMAX
SEGY-like dataset
PROMAX_SEGY_WRITE Writes a trace to the files of a ProMAX SEGY-like dataset
PROMAX_SEGY_READ Reads the next trace from the files of a ProMAX SEGY-like dataset
Geophysical Routines
Geophysical Routines
Subroutine Description
STAT_AGC_RUNAVG Does an agc or running average using an asymmetrical gate at the ends
STAT_AGC_RUNAVG1 Does an agc or running average using an asymmetrical gate at the ends
CONVERT_V_TABLE Converts velocity from one type to another; that is, RMS velocities in
time to Interval velocities in depth. These conversions honor reciprocity.
SPLIN1 Inputs X,Y pairs unequally sampled in X and the first derivatives at the
first and last sample values (Y21,Y2N), computes the second derivatives
of the interpolation function, and stores them in Y2ARR for future spline
evaluation
LOWPASS Generates an Ormsby low pass filter where F1 is the left corner frequency
and F2 is the right stop frequency.
Signal Processing
Signal Processing
Subroutine Description
GET_NFFT Computes the nearest even prime factor product greater than or equal to
the number of samples NSAMP
MEMSPECT Computes the maximum entropy power spectrum of the time samples in
DATA where SAMPRAT is the time sample increment in milliseconds.
MEMSPECT computes NFREQ spectral values starting at frequency F1
and incrementing DELTAF hz. The routine uses NCOF polynomial
coefficients to compute each spectral contribution.
MIN_PHZ_GEN Computes the complex spectrum of a minimum phase filter whose real
Amplitude values are in the first NFFT/2+1 samples of AMP
EUREKA Routine to generate a WIENER filter from the autocorrelation and right
hand vector
RMEDIAN Finds the median sample amplitude and returns its address
COVARY Calculates the normalized covariance between two signals ARRSTL and
ARRMOV displaced against each other, -NLAGS through +NLAGS.
ARRSTL is the waveform that is held stationary, and ARRMOV is the
waveform displaced through 2*NLAGS+1 delays noted above. NPTS is
the number of points to use in computing each correlation coefficient.
ISSTART and MSTART are the indexes of the first points on the two
arrays ARRSTL and ARRMOV, respectively, that will be lined up at zero
lag.
Caution: This means MSTART had better be larger than NLAGS and
ARRMOV had better be NPTS+2*NLAGS or longer.
FILT_SPIKE
FILT_2D_SLOW Simple but slow 2-D spatial filter, using either a median or an
alpha-trimmed mean algorithm
FILT_2D_W Relatively fast 2-D WEIGHTED filter, using either a weighted median or
a weighted alpha-trimmed mean algorithm
FILT_2D_W_SLOW Relatively slow (but with very simple code) 2-D WEIGHTED filter, using
either a weighted median or a weighted alpha-trimmed mean algorithm.
FILT_2D_C 2-D filter (across traces and samples), employing a simple time domain 2-
D CONVOLUTIONAL filter algorithm.
MIN_PHZ_EQV Computes the minimum phase complex spectrum of the input complex
array of NFFT/2+1 complex values using the Hilbert Trasform. The
output is independent of the input phase.
BOXCAR_SMOOTH Smooths input values with a BOXCAR smoother. True zero sample
values are optionally excluded from smoothing and the smoother
normalization. The smoother length grows from ISMOOTH/2 + 1 at the
first sample to ISMOOTH, then similarly shrinks down to ISMOOTH/2 +
1 for the last sample.
TRIANG_SMOOTH Smooths input values with a TRIANGULAR smoother. True zero sample
values are optionally excluded from smoothing and the smoother
normalization. The smoother length grows from ISMOOTH/2 + 1 at the
first sample to ISMOOTH, then similarly shrinks down to ISMOOTH/2 +
1 for the last sample.
BOXCAR_FILTER Filters input values with a BOXCAR filter. True zero sample values may
be optionally excluded from filtering and the filter normalization. The
smoother length grows from ISMOOTH/2 + 1 at the first sample to
ISMOOTH, then similarly shrinks down to ISMOOTH/2 + 1 for the last
sample.
TRIANG_FILTER Filters input values with a TRIANGULAR filter. True zero sample values
may be optionally excluded from filtering and the filter normalization.
The smoother length grows from ISMOOTH/2 + 1 at the first sample to
ISMOOTH, then similarly shrinks down to ISMOOTH/2 + 1 for the last
sample.
NORM_TO_ONE Normalizes an array of real values by the maximum positive value. This
value becomes 1.0 on output, with all other values divided by this
maximum positive value. If no positive values exist in the input array, the
X_VALS array is returned unaltered.
Disk I/O
Disk I/O
Subroutine Description
TIO_SET_SWAPFLAG Routine to establish the need for byte swapping on a file that was opened
by TIO_OPEN or TIO_OPENU. This routine or
TIO_READ_SWAPFLAG must be called before any I/O is done on a file.
TIO_READ_SWAPFLAG Routine to establish the need for byte swapping on a file that was opened
by TIO_OPEN or TIO_OPENU. This routine or TIO_SET_SWAPFLAG
must be called before any I/O is done on a file.
ACOR
ACORF
ACORT
ASPEC
BLKMAN
CCOR
CCORF
CCORT
CDOTPR
CFFT
CFFTB
CFFTSC
COHER
CONV
CRVADD
CRVDIV
CRVMUL
CRVSUB
CSPEC
CVABS
CVADD
CVCMA
CVCMPX
CVCMUL
CVCONJ
CVDIV
CVEXP
CVEXPM
CVMA
CVMAGS
CVMGSA
CVMOV
CVMUL
CVNEG
CVPHAS
CVRCIP
CVSQRT
CVSUB
DEQ22
DESAMP
DOTPR
FLNZ
HAMM
HANN
HIST
LVEQ
LVGE
LVGT
LVLE
LVLT
LVNE
LVNOT
MAXMGV
MAXV
MINMGV
MINV
MVE
MVESQ
MVESSQ
NZCROS
POLAR
RECT
RFFT
RFFTB
RFFTSC
RMVESQ
SVDIV
SVE
SVEMG
SVESQ
SVESSQ
TCONVL
TRANS
VAAM
VABMRG
VABS
VADD
VAIMAG
VAINT
VAM
VAMERG
VASBM
VASM
VATAN
VATAN2
VAVEXP
VCLIP
VCLR
VCMERG
VCMPRS
VCOS
VDBCON
VDIV
VDIVZ
VERROR
VEXP
VEXP10
VFILL
VFLOAT
VFLOT2
VFRAC
VGATHR
VGEN
VGENP
VICLIP
VINDEX
VINT
VINT2
VINTB
VLINT
VLMERG
VLOG
VLOG10
VLOGZ
VMAX
VMAXMG
VMIN
VMINMG
VMMA
VMMSB
VMOV
VMSA
VMSB
VMUL
VNABS
VNEG
VNINT
VNINT2
VPMERG
VPOLY
VPYTHG
VQINT
VRAMP
VREAL
VRECIP
VRSUM
VRVRS
VSADD
VSBM
VSBSBM
VSBSM
VSCATR
VSDIV
VSIN
VSMA
VSMSA
VSMSB
VSMUL
VSQ
VSQRT
VSQRTZ
VSSQ
VSUB
VSWAP
VTAN
VTHR
VTHRSC
VTMERG
VTRAPZ
VXCS
WIENER
VCHARMOV
CVMAG Vector magnitude routine
C(IC) = SQRT(A(IA) * A(IA) + A(IA+1) * A(IA+1))
Resource Reporting
Resource Reporting
Subroutine Description
U_RESERVE Reserves resources (such as memory and tape drives) for later utilization
UNIX Interface
UNIX Interface
Subroutine Description
C_FILECHECK Determines if a file exists and if the user has read/write privilege
C_DIRCHECK Determines if a file is a directory
DISK_SPACE_SCRATCH Returns the number of Kbytes of space available in the ProMAX scratch
partition
ALT_SHELL
C_CHARTIME Gets the current system time and date as a character array; for example,
Sun Sep 16 01:03:52 1985\n\0
C_TIME_CARR Returns a time as a character array; for example, Sun Sep 16 01:03:52
1985\n\0
C_TIMES
C_TIME
C_UTIME
SHELL_COMM_STAT Issues a command to the shell. The status and error flag are returned.
UNIX_COM Issues a UNIX command and returns the message that would normally be
displayed on the screen
Index
U
UNIX interface (C)
UNIX interface (FORTRAN)
User Interface
User setup
utopdir
V
variables, Makefile
vector routines (C)
vel_io.f
velocity (C)