Sei sulla pagina 1di 700

ProMAX® Developer’s

Programming Guide Contents


➲ Introduction 2

➲ 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

Other Docs Search Page Known Problems


Contents2 Devloper’s Programming Guide

➲ 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

➲ Directory Structure 123


➲ Directory Hierarchy 124
➲ Machine-dependent Directories 127
➲ Directory Naming Conventions 128
➲ Product-dependent Subdirectories 129
➲ Third-party Software 130
➲ Recompilation - GNU Make 131
➲ Makefile Rules 132
➲ Makefile Options 133
➲ User and Master Versions 134
➲ Master Versions for Landmark Clients 136

➲ C Environment 137

Other Docs Search Page Known Problems


Contents3 Devloper’s Programming Guide

➲ C Process Components 138


➲ C and FORTRAN Links 139
➲ Calling a FORTRAN Routine from a C Routine 139
➲ Calling a C Routine from a FORTRAN Routine 139
➲ Global Parameters 141
➲ Trace Header Index Values 141
➲ Re-Entrancy 142

➲ Tool Types 143


➲ Executive Tools 144
➲ Simple Tools 147
➲ Ensemble Tools 149
➲ Panel Tools 150
➲ Single Buffer Tools 155
➲ Double Buffer Tools 158
➲ Complex Tools 159
➲ Stand-alone Tools 163
➲ IPC Tools 165
➲ IPC Tool Details 166
➲ IPC Tool Debugging 167

➲ Global Parameters 169


➲ Overview of Global Parameters 170
➲ Common Blocks and C Structure Descriptions 171

➲ Ordered Parameter Files 173


➲ Overview of the ProMAX Database 174
➲ Standard Orders 178

➲ Trace Headers 181


➲ Overview of Trace Headers 182
➲ Definition and Usage of Standard Header Entries 186
➲ Alphabetical Reference of Trace Header Entries 186
➲ Sequential Reference of Trace Header Entries 188

➲ Parameter Tables 201


➲ Overview of Parameter Tables 202
➲ Structure of ProMAX Tables 202
➲ Table Rules 204
➲ Table Interpolation 204
➲ X Values in Tables 208
➲ Precision of Key Values 209
➲ Table Extrapolation 209
➲ Table Subroutine Categories 210
➲ Examples of Table Routines 212
➲ FORTRAN Code Examples 212

Other Docs Search Page Known Problems


Contents4 Devloper’s Programming Guide

➲ C Code Examples 217

➲ Memory Management 223


➲ Overview of Memory Management 224
➲ C Memory Management 225
➲ Multi-dimensional Arrays 225
➲ Multi-dimensional Routine Names 227
➲ References 229
➲ FORTRAN Memory Management 230
➲ mem.inc 230
➲ RSPACEz and ISPACEz 231
➲ Fortran Indexing For RSPACEz and ISPACEz 231
➲ Big Vector Routines 233

➲ Debugging with gdb 235


➲ Overview of gdb 236
➲ System Review 237
➲ Debugging Exec and IPC Tools 239
➲ Debugging a ProMAX Exec Tool 239
➲ Debugging A ProMAX IPC Tool 246

➲ 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

Other Docs Search Page Known Problems


Contents5 Devloper’s Programming Guide

➲ Starting FrameMaker 299


➲ Creating a New Helpfile 299
➲ Editing a Helpfile 299
➲ Working with FrameMaker Files 300
➲ Helpfile Organization 303
➲ Example Helpfile 304
➲ Theory 304
➲ Usage 305
➲ References 305
➲ Parameters 306
➲ Interactive Display 307
➲ Common Error Messages 307
➲ Customizing the User Interface 308
➲ Hypertext 309

➲ Code Standards 311


➲ C Coding Standards 312
➲ ProMAX C Routine Documentation 313
➲ FORTRAN Coding Standards 315
➲ General Text File Format 316
➲ Variable Naming and Declarations 317
➲ C preprocessor 318
➲ Comments 319
➲ White Space 320
➲ Code Structure 320
➲ Miscellaneous 321
➲ Purify 321
➲ ProMAX Fortran Routine Documentation 321
➲ Portable Code 323

➲ Man Page Reference 325


➲ Using the Man Pages 326
➲ Finding what you want 327

➲ Appendix: Expanded Directory Structure 329


➲ Expanded Directory Structure 330

➲ Appendix: C Programming Examples 339


➲ Example Include Files 340
➲ cglobal.h 341
➲ cpromax.h 353
➲ Example Simple Processes 367
➲ simple.menu 368
➲ simple.c 369
➲ ampRatio.c 371

Other Docs Search Page Known Problems


Contents6 Devloper’s Programming Guide

➲ Appendix: Simple Tool Examples 379


➲ amp_ratio.menu 380
➲ amp_ratio.inc 381
➲ amp_ratio.f 382
➲ ampRatio.c 389

➲ Appendix: Ensemble Tool Examples 397


➲ AVO Ensemble Tools 398
➲ avo.menu 399
➲ avo.inc 400
➲ avo.f 401
➲ avoC.c 405
➲ Trace Interpolation Tools 410
➲ prestk_interp.menu 411
➲ prestk_interp.inc 412
➲ prestk_interp.f 413
➲ prestk_interp.c 415

➲ Appendix: Panel Tool Examples 419


➲ panel_test.menu 420
➲ panel_test.inc 421
➲ panel_test.f 422
➲ panelTest.c 424

➲ Appendix: Single Buffer Tool Examples 427


➲ ens_define.menu 428
➲ ens_define.inc 429
➲ ens_define.f 430
➲ interp_sb.menu 434
➲ interp_sb.c 435

➲ Appendix: Double Buffer Tool Examples 439


➲ semblance.menu 440
➲ semblance.inc 442
➲ semblance.f 443
➲ interp_db.menu 451
➲ interp_db.c 452

➲ Appendix: Complex Tool Examples 457


➲ transform.menu 458
➲ transform.inc 459
➲ transform.f 460
➲ transform.c 464

➲ Appendix: Input Tool Examples 469


➲ sine_wave.menu 470

Other Docs Search Page Known Problems


Contents7 Devloper’s Programming Guide

➲ sine_wave.inc 472
➲ sine_wave.f 473
➲ sineWave.c 479

➲ Appendix: Disk Iteration Examples 487


➲ sc_amp.menu 488
➲ sc_amp.inc 489
➲ sc_amp.f 490
➲ disk_iter.menu 494
➲ disk_iter.c 495

➲ Appendix: Stand-alone Tool Examples 499


➲ prestack.menu 500
➲ prestack.f 501
➲ Makefile_prestack 506
➲ poststack.f 509
➲ Makefile_poststack 512
➲ poststack.c 515
➲ vel_io.f 518

➲ Appendix: IPC Tool Examples 525


➲ IPC Menu Code 526
➲ IPC C Code 527
➲ IPC FORTRAN Code 529
➲ amp_ratio Menu Code 533
➲ ampRatio C Code 535
➲ amp_ratio FORTRAN Code 541

➲ Appendix: Global Include File Examples 549


➲ global.inc 550
➲ cglobal.h 559

➲ Appendix: Ordered Parameter File Examples 571


➲ db_disp.f 572
➲ comp_opf.menu 579
➲ comp_opf.c 582

➲ Appendix: Lisp Menu Example 585


➲ EXAMPLE.menu 586

➲ Appendix: C Library Summary 591


➲ Error Routines 593
➲ Control Functions 594
➲ Parameter Input 595
➲ Configuration 596
➲ Database 597

Other Docs Search Page Known Problems


Contents8 Devloper’s Programming Guide

➲ Memory Allocation/Management 601


➲ Trace Headers 603
➲ Trace Muting 604
➲ Velocity (Geophysical Routines) 605
➲ Vector Routines 606
➲ Parameter Lists 607
➲ Packet Files 608
➲ Parameter Interpolation 609
➲ Unix Interface 610
➲ IPC Tools 611
➲ Parameter Tables 614
➲ PVM 619
➲ Matrix Functions 622
➲ Interpolation Routines 624
➲ Math Functions 628
➲ Signal Processing 630
➲ Plotting 632
➲ Data Structures 633
➲ Sorting and Searching 636

➲ Appendix: FORTRAN Library Summary 637


➲ Area/Line(Survey)/Flow 639
➲ Configuration 642
➲ Database Orders 643
➲ Domain Mapping 645
➲ Miscellaneous 1 646
➲ Trace I/O 647
➲ Trace Executive 648
➲ Trace Headers 649
➲ Memory Management 650
➲ Mute/Kill 651
➲ Statics 652
➲ Summing 653
➲ Error Routines 654
➲ Parameter Tables 656
➲ Tables Obsolete 658
➲ Parameter Interpolation 659
➲ Parameter Lists 660
➲ String Decoding 662
➲ Miscellaneous 2 663
➲ Parameter Input 665
➲ Packet Files 666
➲ Character Routines 667
➲ Seg-Y Disk 668
➲ Geophysical Routines 669
➲ Signal Processing 671

Other Docs Search Page Known Problems


Contents9 Devloper’s Programming Guide

➲ Disk I/O 674


➲ SEG Vector Routines 675
➲ Resource Reporting 681
➲ UNIX Interface 682

➲ Index 685

Other Docs Search Page Known Problems


Contents10 Devloper’s Programming Guide

Other Docs Search Page Known Problems


1 Developer’s Programming Guide

ProMAX Developer’s
Programming Guide

Other Docs Search Page Known Problems


2 Developer’s Programming Guide

Introduction

This Programmer’s Guide is written and designed to help you


create ProMAX software modules. It assumes that you are
familiar with large software system architecture, such as setting
up a make system and accessing parameter tables. It provides
instructional text for newer ProMAX programmers and serves
as a reference book for experienced ProMAX developers.

This manual is updated as of the ProMAX/SeisSpace 2003.19.1


Linux-only release.

Organization
We divided this manual into chapters and sections that discuss
the key processes of the ProMAX system. In general, this
consists of:

• environment setup and testing

• tools and tool building

We added extensive Appendices to include:

• an expanded directory structure

• source code examples

• C and FORTRAN library summaries

Documentation Conventions
We use the following documentation conventions in this
manual:

• Boldface represents menu commands, push-button


options, and keystrokes.

• Courier refers to text that you should type into a


command line and represents program code listings. When
a line of text or code is longer than we can print on one line

Other Docs Search Page Known Problems


3 Developer’s Programming Guide

in this manual, we use the UNIX standard of a backslash (\)


at the end of the line to indicate that it continues on the
next line.

• Hypertext represents hyperlink-active text; click on this red


text to go to related information.

• Italics emphasizes key terms and concepts and refers you


to other documents, chapters, or sections.

• [Italics inside brackets] represent dummy parameters;


replace the brackets and their contents with your
user-specific information.

• Text enclosed in a box signifies a warning, caution, or note.


A warning or caution warns you when you could lose data
or crash your system. A note emphasizes an important
issue.

Example

This is an example of the box we use for warnings, cautions, and


notes.

We suggest that you read:

• the Quick Start chapter first for a brief overview of


ProMAX IPC processes if you want to implement new
code without investing time in learning the other parts of
the ProMAX processing system

• the Self-Guided Tutorial chapter first if you are interested


in a step-by-step course in writing ProMAX software
processes

• the System Overview chapter first if you want an overall


understanding of the ProMAX system. You should then be
able to determine how this manual can further help you.

Other Docs Search Page Known Problems


4 Developer’s Programming Guide

Other Docs Search Page Known Problems


5 Developer’s Programming Guide

Quick Start

This chapter is designed to give a programmer a quick overview


of a particular type of ProMAX processing process, the IPC
(Inter-Process Communication) tool. It should allow you to
implement some new code without investing much time in
learning other parts of the ProMAX programming system. If
you have previous experience with ProMAX programming, this
chapter may be all that you need to get a program running on
the ProMAX system. If this is not enough to get you going, the
Self-Guided Tutorial chapter takes you step-by-step through a
ProMAX programming course.

Topics Covered in this Chapter:


➲ Overview of a ProMAX Process
➲ Creating your own Directory Hierarchy
➲ Writing a Menu
➲ Installing the Menu
➲ Overriding the Default ProMAX Files
➲ Writing a ProMAX Program
➲ Viewing Online Documentation
➲ Writing Helpfiles

Other Docs Search Page Known Problems


Overview of a ProMAX Process6 Developer’s Programming Guide

Overview of a ProMAX Process

There are three parts to writing a ProMAX process:

• 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 classes of ProMAX programs: inline flow tools


and stand-alones. Inline flow tools process data as it streams by
in a flow; examples are AGC, FK filter, and migrations. Inline
flow tools do not contain an asterisk in the Processes list. Stand-
alone tools either read their own data, as occurs with random
data access, or do not need data, as occurs with velocity
manipulation. Stand-alone tools include such processes as the
interactive velocity editor, and some of the statics programs.
These tools do contain an asterisk in the Processes list.

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.

Other Docs Search Page Known Problems


Creating your own Directory Hierarchy7 Developer’s Programming Guide

Creating your own Directory Hierarchy

To help give you some order to your ProMAX programming,


we have a recommended directory hierarchy for you to create in
your home directory. Use the Makeadvance program, which is
actually a shell script that is in $PROMAX_HOME/port/bin to
create this directory hierarchy in your home directory. The
environmental variable $PROMAX_HOME is the path to
where your ProMAX software is installed. The Makeadvance
command produces a mirror of the $PROMAX_HOME
directory hierarchy, but without any of the files. This will let
you work on ProMAX modules under your home directory.

Other Docs Search Page Known Problems


Writing a Menu8 Developer’s Programming Guide

Writing a Menu

The menu file is an ASCII file that is interpreted on the fly by


the User Interface. Writing a menu is simple enough that you
should be able to do this using the ProMAX menu files
delivered with your system as examples. The menus are in
$PROMAX_HOME/port/menu/promax. A good example to
start with is vdatum.menu; see also EXAMPLE.menu.

vdatum.menu is an example of a menu for a an IPC tool. Most


menus in the system, such as agc.menu, are for inline flow tools
that are non-IPC tools. The only difference between these two
menus occurs at the beginning of the exec_data section of the
menu. You should be able to tell the minor differences between
a IPC tool and a non-IPC tool, so you can still use all the menus
as examples.

An example of a menu of for a stand alone module is


autostat.menu. Again, the only difference between this type of
menu and others occurs at the beginning of the exec_data
portion of the menu.

We recommend that you write your menu in your mirror of


$PROMAX_HOME/port/menu/promax under your home
directory; that is, under
~/$PROMAX_HOME/port/menu/promax, or wherever you
decide to make it.

Menus are actually written in Lisp. If you write menus often,


you will notice that you are starting to learn Lisp. For more
information on writing menus, refer to the Menus chapter. To
test the menus you write, use the pwin program which is in
$PROMAX_HOME/sys/bin. If you are an emacs user, type
pwin my.menu and you should be in familiar surroundings. If
you are not an emacs user, type pwin my.menu t and bring up
your favorite editor in another window; you can create, debug,
and edit the menu using your editor. After you write your edits
to disk, click with the mouse in the pwin window and you will
see the sample menu updated to reflect your changes. If you
have syntax errors in your menu, pwin will generally print the
line number containing the syntax error.

Other Docs Search Page Known Problems


Installing the Menu9 Developer’s Programming Guide

Installing the 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.

Other Docs Search Page Known Problems


Overriding the Default ProMAX Files10 Developer’s Programming Guide

Overriding the Default ProMAX Files

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)
))
)

Remember that a backslash (\) at the end of a line indicates that


the line of code is longer than we can print on one line of this
manual and, therefore, continues on the next line; you should
type it all as one line without the backslash. Also, you can use a
“~” rather than typing out your home directory.

Note that specifying /mnt/stof/promax/1998.6/menu:promax


creates a search path, separated by a “:”, for menus. Also note
that just specifying promax or “.” refers to the default master
directory tree such as /advance/port/menu/promax. You can use
a “.” only for the executables master directory; for the others,

Other Docs Search Page Known Problems


Overriding the Default ProMAX Files11 Developer’s Programming Guide

you must use promax. Thus, this search path above looks first in
your home directory, and then in the master location.

When you now start the user interface by typing promax or


$PROMAX_HOME/sys/bin/promax, the User Interface should
read your personal Processes file, and you should see your new
tool in the list of Processes. You should be able to bring your
menu into a flow and parameterize it.

You can supply any number of product stanzas in your personal


.promax file, just so long as the initial single character strings,
e.g. “P” and “3”, are unique. The User Interface will then
display your list under the “Products” menu item in the Flow
window and you can select any of them with the mouse prior to
building or editing a flow. This avoids having to exit the User
Interface in order to switch between development and/or
production environments.

Finally, it is important to remember that the User Interface


looks at the setting of the environment variable new_menu to
determine the menu init behavior. If new_menu=t, then the User
Interface will re-initialize the menu every time it is displayed. If
new_menu=f, then the flow builder will only read files once.
This means if you modify the processes file or a menu file after
starting the flow builder, it will not see your changes.
Furthermore, if you add a tool to a flow, the corresponding
menu file will be saved with the flow, and the menu file will not
be read again when the flow is accessed again. Setting
new_menu=t is a big help in testing menus and should be part
of the ProMAX programmer’s environment. This setting slows
down the User Interface because the menu files are reread;
therefore, it is not recommended for the typical production
processing environment.

Other Docs Search Page Known Problems


Writing a ProMAX Program12 Developer’s Programming Guide

Writing a ProMAX Program

To examine a sample IPC tool, written in C, look in


$PROMAX_HOME/port/src/exe/c_socket and
$PROMAX_HOME/port/src/exe/ampRatio. A sample
FORTRAN IPC tool is in
$PROMAX_HOME/port/src/exe/f_socket and
$PROMAX_HOME/port/src/exe/amp_ratio. Each of these
directories contain sample menus, although you should copy the
menus to a more proper location, such as your own menu
directory. Sample FORTRAN standalone programs are in
$PROMAX_HOME/port/src/exe/stand_alone.

A good portion of this manual deals with creating inline tools


that are executive tools, not IPC tools. To compile and link these
programs, go to ~/$PROMAX_HOME/port/src/c_socket. Then
type

/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.

If you copy this directory and start making modifications to the


code, you will need to change the name in the Makefile to
match the name of your directory.

You can change your product file to include your home


directory in the search path for ProMAX executables. See the
description in the product file.

If you install your working source code under the


$PROMAX_HOME tree, you can do a gmake there and your
executable will be placed under the standard ProMAX
executable path, $PROMAX_HOME/sys/exe. You could do
your development under the $PROMAX_HOME directory tree
rather than in your home directory, but we discourage this. It
will become a maintenance hassle when many developers work
in that area.

Other Docs Search Page Known Problems


Viewing Online Documentation13 Developer’s Programming Guide

Viewing Online Documentation

All ProMAX subroutines are accessible from either FORTRAN


or C. We have online manual pages for these subroutines, which
you can access by typing

$PROMAX_HOME/port/bin/aman tblToMatrix

The aman command supports the -k option; to find all C


subroutines for dealing with tables, type

aman -k table | fgrep “C routine”

For a quick summary of the ProMAX subroutines, type

aman c_promax

or

aman fortran_promax

Other Docs Search Page Known Problems


Writing Helpfiles14 Developer’s Programming Guide

Writing Helpfiles

Documentation is an important part of the ProMAX system.


You should write a helpfile for your new process if it is going to
be used in a production processing environment. At Landmark,
we produce our online documentation in Adobe PDF format.
For more information, see the Helpfiles chapter.

Other Docs Search Page Known Problems


15 Developer’s Programming Guide

Self-guided Tutorial

This chapter is designed to be used as a guide for programmers


who want to learn to write ProMAX software modules. The
tutorial directs you through a sequence of chapters to read and
specific exercises to work on in order to learn the parts of the
system.

Topics Covered in this Chapter:


➲ Support Documentation
➲ System Overview
➲ Your Development Directory
➲ Tool Anatomy
➲ Programming Exercises: Simple Tools (amp_ratio)
➲ Debugging
➲ C Programming Environment
➲ Tool Types
➲ Programming Exercise: Ensemble Tools (AVO_exer)
➲ Programming Exercise: Panel Tools
➲ Programming Exercise: Input Tools
➲ Programming Exercise: IPC Tools

Materials Needed for this Tutorial:


• This Programmer’s Reference Manual

• The ProMAX 2D Reference Manual

• The FORTRAN Programmer’s Reference Manual or the C


Programmer’s Reference Manual, depending on your
programming language preference. These manuals are
summarized in the C Library Summary and FORTRAN
Library Summary appendices.

Other Docs Search Page Known Problems


16 Developer’s Programming Guide

• Access to a computer on which ProMAX and the ProMAX


Development Environment have been installed. In addition,
the computer must have an editor program, such as vi or
emacs, to allow you to create new files, as well as a C or
FORTRAN compiler.

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.

Other Docs Search Page Known Problems


Support Documentation17 Developer’s Programming Guide

Support Documentation

The online C or FORTRAN Programmer’s Reference Manual


contains documentation on hundreds of subroutines that are
available in the ProMAX system. We have summarized these
subroutines in the C Library Summary and FORTRAN Library
Summary appendices.

➱ Take a few minutes now to skim through the C or FORTRAN library


summaries to become familiar with the subroutine categories, such
as Trace Headers and Parameter Input. To get a even better over-
view of the manual, read through the individual subroutine names
and descriptions.
We discuss only a small percentage of the available subroutines
in this tutorial, so it is up to you to study the library to get the
maximum use from it.

You will also want to refer to the ProMAX Reference Manual.


This manual provides basic information about the ProMAX
system from the user’s point of view, along with additional
information about Parameter tables and other parts of the
database. We will give you specific reading assignments in
these chapters at the appropriate times.

Finally, the ProMAX routines are also documented in the online


manual pages. You can access these manual pages by using the
aman command. For example, to view the documentation for
the ProMAX routine tblCopy, type:

aman tblCopy

from the command line of the computer. Your path must include
$PROMAX_HOME/port/bin.

To see a name and short description of all table routines, type

aman -k tbl

➱ Try typing aman tblCopy to see if your environment is set up properly


for using the aman online documentation.
If a message is returned saying that there is no manual entry for
tblCopy, contact your system administrator for help in setting
environment variables.

Other Docs Search Page Known Problems


Support Documentation18 Developer’s Programming Guide

Another aman command allows you to see all ProMAX


subroutine names by category. Type

aman c_promax

to see all ProMAX C routines by category, or

aman fortran_promax

to see all ProMAX FORTRAN routines by category.

Other Docs Search Page Known Problems


System Overview19 Developer’s Programming Guide

System Overview

The primary function of ProMAX is to create, modify, and


execute processing flows. A flow is a sequence of processes
which are used to manipulate seismic data. Flows are built by
selecting processes from a Processes List. A typical flow
contains an input process, one or more data manipulation
processes, and a display and/or output process.

Some of the chapters in this manual provide basic information


on how the system components work together and introduce
ideas that are present throughout the rest of this tutorial. Others
describe the specific processes of the ProMAX system. Because
you will be writing new menus which appear as part of the User
Interface, you should have a basic familiarity with the selection
of menu parameters at the User Interface level.

➱ Turn to the chapter entitled Working with ProMAX in the ProMAX 2D


Reference Manual. Read the sections entitled Getting Started and
Building a Flow. These sections provide a brief overview of Areas,
Lines, and Flows.
➱ Read the System Overview, Executive, and Directory Structure in
this manual.
If you are already familiar with the User Interface, the ProMAX
data directory structure, tables, and datasets, you may skip these
chapters.

Other Docs Search Page Known Problems


Your Development Directory20 Developer’s Programming Guide

Your Development Directory

In order to develop ProMAX software, a particular directory


structure must exist under the programmer’s home directory.
The following exercises will help you create this directory
structure.

➱ Read the Make System chapter. Complete the Makeadvance exer-


cise in the User Setup section; be sure you can complete the Make-
exec exercise. Contact your system administrator if the computer
refuses to allow you to complete everything discussed in the chap-
ter.
➱ Be sure to read the Adding A New Tool section of the Tool Types
chapter. This section provides a recap of the critical components of
a new processing tool and shows how they work together.

Other Docs Search Page Known Problems


Tool Anatomy21 Developer’s Programming Guide

Tool Anatomy

Before you actually get started on the programming exercises,


you first need to understand the structure of the ProMAX tools.

➱ 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.

Other Docs Search Page Known Problems


Programming Exercises: Simple Tools (amp_ratio)22 Developer’s Programming Guide

Programming Exercises: Simple Tools (amp_ratio)

The exercises in this tutorial consist primarily of example


programs to which you add code as a way of learning the
important parts of ProMAX programming. The first such
program is called amp_ratio.f for FORTRAN programmers, and
ampRatio.c for C programmers. The functionality of the C and
FORTRAN versions is the same, so the program will in general
be referred to as amp_ratio.

amp_ratio is an example of a simple tool. A simple tool


operates on a single trace at a time. amp_ratio operates on a
single trace by sliding two windows down the trace, taking the
ratio of powers in the windows, and outputting the ratio as a
sample at the beginning of the upper window. This is a crude
first break picker, since the peak value of the output trace is
normally at approximately the first break time. While this
routine is not high tech by any means, the programming
exercises involving amp_ratio demonstrate four important
features of ProMAX Programming:

• the general mechanics of adding a tool

• adding and manipulating trace headers

• the use of the ordered parameter files

• the use of tables to store time gates

The FORTRAN programming exercises that demonstrate these


last three features are amp_ratio1.f, amp_ratio2.f, and
amp_ratio3.f, respectively. Working code which contains
solutions to all three of these programming exercises can be
found in amp_ratio.f. The corresponding C programming
exercises and code is ampRatio1.c, ampRatio2.c, ampRatio3.c
and ampRatio.c.

➱ To begin, move to your own maxtool/amp_ratio directory by typing


the following command on the command line:
cd ~/$PROMAX_HOME/port/src/lib/maxtool/amp_ratio

➱ If you are programming in C, copy the .c files from the system


amp_ratio directory to your own directory by typing:
cp $PROMAX_HOME/port/src/lib/maxtool/amp_ratio/*.c .

Other Docs Search Page Known Problems


Programming Exercises: Simple Tools (amp_ratio)23 Developer’s Programming Guide

If you are programming in FORTRAN, copy the .f and .inc files


from the system amp_ratio directory to your own directory by
typing a command similar to the one above.

➱ Set the access permissions to the files by typing:


chmod 644 *.*

➱ 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

then type the following command:

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

amp_ratio Exercise 1: Adding Trace Headers


The first amp_ratio exercise involves getting a first break pick
time from the amp_ratio program, getting a quality estimate of
the first break pick time, and placing those values into a trace
header.

➱ Read the Trace Headers chapter.


➱ Next, edit amp_ratio1.f (or ampRatio1.c) so that the first break time
and first break quality information can be read into the trace header
for each trace. You can find solutions in the file amp_ratio.f or
ampRatio.c.
➱ If you do not know how to compile and link the code into a new
exec.exe, review the Make System chapter.
Try your new program!

Remember to add the path to amp_ratio1.menu to your


Processes list. Review the Make System chapter if necessary.
Also remember that you need to have a .promax file set up in
your directory in order to tell ProMAX where to look for your
Processes file and where to find the executable code that you
have created. The .promax file is also discussed in the Make
System chapter.

Other Docs Search Page Known Problems


Programming Exercises: Simple Tools (amp_ratio)24 Developer’s Programming Guide

Menus
A ProMAX menu is a file which controls how menu parameters
appear to the user.

➱ Read the Menus chapter.


➱ Copy the EXAMPLE.menu file to your own menu directory by typing
the following on the command line:
cd ~/$PROMAX_HOME/port/menu/promax

cp $PROMAX_HOME/port/menu/EXAMPLE.menu .

➱ Use the pwin program described in the Menus chapter to experi-


ment with menu parameters in 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 Global Parameters chapter. C programmers can then look


at:
$PROMAX_HOME/port/include/cglobal.h

and/or read the C Environment chapter for more information.

amp_ratio Exercise 2: ordered parameter files


The next amp_ratio exercise involves putting the first break
information from the previous exercise into the ordered
parameter files in the database.

➱ Read the Ordered Parameter Files chapter.


➱ Edit amp_ratio2.f or ampRatio2.c to add parameters to the TRC
(trace) ordered parameter file; fill those database locations with the
appropriate information. Add the necessary code to the menu file to
allow the option of writing to the database.
You might notice that there is already code in amp_ratio2.f and
ampRatio2.c to take care of the trace headers.

Other Docs Search Page Known Problems


Programming Exercises: Simple Tools (amp_ratio)25 Developer’s Programming Guide

Remember to change the Processes list to point to the right


menu since there is a different menu for amp_ratio1 and
amp_ratio2.

➱ Run Makeexec on your new program and try it out.


➱ Run the database display program and see the first break pick
times.

amp_ratio Exercise 3: time gates and tables


The final amp_ratio exercise is to limit the time window for
which the first break is searched. In the previous example, the
entire trace was searched for the first break. The start and end
times of the analysis window can be controlled through use of
ProMAX parameter tables which are stored in the database.

➱ 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.

Other Docs Search Page Known Problems


Debugging26 Developer’s Programming Guide

Debugging

Most full-time programmers find that use of a debugger speeds


up their code development. Use of the program dbx or gdb with
ProMAX requires a few special considerations, primarily
related to the packet.job file.

➱ Read the Debugging with dbx/gdb chapter. Practice using the


debugger on one of the amp_ratio or ampRatio routines.

Other Docs Search Page Known Problems


C Programming Environment27 Developer’s Programming Guide

C Programming Environment

The system level code of ProMAX is largely written in


FORTRAN, although most new ProMAX module development
is now in C and C++. The C programming environment actually
lies on top of the FORTRAN environment; therefore, there are a
few things that the C programmer should know about, including
some conveniences that have been developed for programming
in C.

➱ Read the C Environment chapter.

Other Docs Search Page Known Problems


Tool Types28 Developer’s Programming Guide

Tool Types

Before you continue on with other programming examples, you


need to know about other kinds of processing tools. As you
learned earlier in this chapter, the program amp_ratio is an
example of a simple tool, which is a processing tool that only
processes one data trace at a time. There are several other types
of tools that make handling multiple traces very convenient.

➱ 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.

Other Docs Search Page Known Problems


Programming Exercise: Ensemble Tools (AVO)29 Developer’s Programming Guide

Programming Exercise: Ensemble Tools (AVO)

This section involves programming with ensemble tools.


Ensemble tools operate on bundles of traces.

➱ Go to your personal maxtool directory:


cd ~/$PROMAX_HOME/port/src/lib/maxtool

➱ Copy the avo_exer directory from the $PROMAX_HOME directory


tree by typing the following on the command line:
cp -r $PROMAX_HOME/port/src/lib/maxtool/avo_exer .

This routine is an AVO (Amplitude Variation with Offset)


module. The intent of this routine is that a CDP ensemble,
sorted by the absolute value of offset, is input into the exec
subroutine as a 2D array. The routine fits a least squares straight
line to the amplitude versus offset graph for each time sample in
the input array (see the following figure).

Least Squares Fit Line

Intercept of
LSF Line

Amplitude

Sample amplitude
at an offset

Offset

Least Squares fit line through Amplitude versus Offset Data

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.

Other Docs Search Page Known Problems


Programming Exercise: Ensemble Tools (AVO)30 Developer’s Programming Guide

➱ Edit amp_ratio1.f or ampRatio1.c; input code where the comment


lines direct you to do so. A working solution to the exercise is in
amp_ratio.f and ampRatio.c.
Remember to change your tools_to_add file and Makefile
before running Makeexec. The entry in tools_to_add will look
like this:

AVO_EXER same panel internal

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.

A further example of an ensemble tool is in


$PROMAX_HOME/port/src/lib/maxtool/prestk_interp, which
outputs more traces in an ensemble than are input.

Other Docs Search Page Known Problems


Programming Exercise: Panel Tools31 Developer’s Programming Guide

Programming Exercise: Panel Tools

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 .

➱ Edit the file panel_test.f or panelTest.c where the comments direct


you to do so. A working solution to this exercise is in panel_test.f or
panelTest.c.
➱ Remember to change your tools_to_add file and Makefile before
running Makeexec. The entry in tools_to_add will look like this:
PANEL_TEST same ensemble internal

➱ Also remember to change your Processes file before starting Pro-


MAX so that the new menu will be read.

Other Docs Search Page Known Problems


Programming Exercise: Input Tools32 Developer’s Programming Guide

Programming Exercise: Input Tools

An input tool is, by default, the first processing tool in a flow. It


is the tool that feeds trace data to the rest of the flow. The
exercise for an input tool can be found in

$PROMAX_HOME/port/src/lib/maxtool/sine_wave

The sine_wave.f and sineWave.c programs generate traces and


give them to the trace executive to be passed along to other
modules. The traces output from sine_wave consist of a set of
summed sine waves of user-specified frequency.

➱ 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:

SINE_WAVE same complex internal

A working solution to this problem is in sine_wave.f and


sineWave.c. If you have problems with this module, review the
Tool Types chapter in this manual, paying special attention to
the responsibilities of an input tool, such as global variables and
headers. Then review the section on complex tools in that same
chapter, paying attention to the modes, in particular
EX_FLUSHMODE and EX_QUITMODE.

Other Docs Search Page Known Problems


Programming Exercise: IPC Tools33 Developer’s Programming Guide

Programming Exercise: IPC Tools

An IPC Inter-Process Communication) Tool is a special type of


tool that allows the trace executive to pass data to and from a
separate unix process or separate piece of executable code. IPC
tools used to be called socket tools.

➱ Read the IPC Tools section of the Tool Types chapter.


➱ Copy the directory $PROMAX_HOME/port/src/exe/f_socket or
$PROMAX_HOME/port/src/exe/c_socket to your own directory tree;
that is, $~/$PROMAX_HOME/port/src/exe/f_socket or c_socket.
Notice that you are not in the maxtool directory where all work
has been done until now. The src/exe directory is for programs
that are not linked to the Trace Executive, or said another way,
tools that are not called from toolcall.f.

This exercise is just a demonstration of how to Make an IPC


tool executable. There is a file in the c_socket and f_socket
directories called Makefile. The Makefile contains, among other
things, the name of the output executable. The name is specified
where the Makefile states:

name = c_socket

The name of the executable must match the name of the


directory in which the Makefile resides. The Makefile also
contains a list of the object files that need to be used.

➱ 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.

Other Docs Search Page Known Problems


Programming Exercise: IPC Tools34 Developer’s Programming Guide

Other Docs Search Page Known Problems


35 Developer’s Programming Guide

System Overview

This chapter provides an overview of ProMAX. It describes the


directory structure of the system and the User Interface.

Topics covered in this chapter:


➲ ProMAX Organization: Areas, Lines, and Flows
➲ The User Interface: The Flow Builder
➲ Menu Files
➲ Flow Execution
➲ Super Executive
➲ Executive

Other Docs Search Page Known Problems


ProMAX Organization: Areas, Lines, and Flows36 Developer’s Programming Guide

ProMAX Organization: Areas, Lines, and Flows

The primary function of ProMAX is to create, modify, and


execute processing flows. The program is built upon three levels
of organization: areas, lines, and flows. An area can represent
any grouping of seismic lines, but it is usually used as a
prospect level collection of seismic lines. A line (in 2D) or
survey (in 3D) usually represents a single seismic line or survey
in the traditional sense. A flow is a sequence of processes which
are used to manipulate seismic data. Flows are built by selecting
processes from a Processes list. A typical flow contains an input
process, one or more data manipulation processes, and a display
and/or output process.

Before we describe the system software any further, it is useful


if we first describe the directory structure of the system,
particularly the data files (see the ProMAX Directory Structure
illustration at the end of this chapter). The ProMAX home
directory is set by the environmental variable
$PROMAX_HOME. Beneath the ProMAX home directory is a
subdirectory named data/, which you can also be re-specify
with the environmental variable $PROMAX_DATA_HOME
(see the ProMAX Data Directory Structure illustration at the
end of this chapter).

Any directory or symbolic link within the data/ subdirectory is,


by definition, an area. Any subdirectory or symbolic link
beneath an area subdirectory is, by definition, a line or a survey.
ProMAX expects a line to be a collection of data that can be
described by a single geometry. Most of the actual data files
reside at the line or survey directory level (see the Dataset
Components, Ordered Database Files, and Parameter Tables
illustrations at the end of this chapter). Traces, trace headers,
Ordered Parameter Files, and Parameter Tables, such as
velocities, first break picks, mutes, gates, trace kills, also reside
at this level.

Any subdirectory beneath a line or survey subdirectory


represents a further subgrouping, namely a flow. The flow
subdirectory contains all of the files related to a particular
processing flow, such as the saved binary job flow and the
runtime job output (see the Flow Components illustration at the
end of this chapter).

Other Docs Search Page Known Problems


ProMAX Organization: Areas, Lines, and Flows37 Developer’s Programming Guide

There is an exception to the rules that govern the existence of


areas, lines, and flows in the database: any subdirectory with a
period in the name is ignored to facilitate the customization of
the database to contain non-ProMAX files.

Other Docs Search Page Known Problems


The User Interface: The Flow Builder38 Developer’s Programming Guide

The User Interface: The Flow Builder

What people have come to know as ProMAX is sometimes


called the User Interface, but is more correctly called the flow
builder. This is the very top level of the system (see the System
Overview illustration at the end of this chapter). If you are
familiar with the previous generations of the processing system,
the flow builder is analogous to the editor that was used to build
jobs in those previous generations. In fact, the flow builder is
just a very specialized editor; it actually has no notion of
geophysics built into it. Its primary purpose is to present menus
and accumulate a collection of parameters, write those
parameters to disk, and then launch programs that will use the
parameters. The ProMAX Flow Builder Window Map
illustration (at the end of this chapter) sketches the various flow
builder menus, and the Flow Builder illustration (at the end of
this chapter) shows an screen image of the Flow Menu where
jobs are actually built and executed.

Other Docs Search Page Known Problems


Menu Files39 Developer’s Programming Guide

Menu Files

In order for the flow builder to know how to present parameters


to the user, it must read menu specification files, which are also
called menu files. Menu files are closely integrated with the
underlying processing tools; both are usually written by the
same author. Within the menu files, programmers specify what
parameters should exist, what their properties are—such as
parameter type, default value, and description—and how they
interrelate. Experience has shown that good menu parameter
specification evolves to the point of approaching a language; at
Landmark, we use Lisp, a language with suitable features. The
resulting menu specification is extremely well-suited to
handling traditional problems, such as context-sensitive hiding
of unused parameters, and is clearly one of the cornerstones of
ProMAX’s success. Please refer to the Menus chapter for
further discussion of ProMAX menu specifications.

Other Docs Search Page Known Problems


Flow Execution40 Developer’s Programming Guide

Flow Execution

When a user clicks on the Execute button on the Flow Menu,


the first step that the flow builder performs is to write all of the
parameters to disk in the form of a packet file. A packet file is
analogous to the ASCII job deck that existed in older systems,
except that it is binary in form and cannot be modified by any
editor except the flow builder. This protects the integrity of the
contents. The flow builder writes the packet file into the flow
directory that was created when the user constructed a new flow
or copied an existing flow. After the flow builder writes the
packet file, it executes the following shell command:

superExec packet_file host_name

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.

The Super Executive first checks for the presence of multiple


tasks within the packet file. For example, if there are multiple
serial input steps in a flow, the Super Executive subdivides the
packet file and executes the separate jobs sequentially. In
addition, the Super Executive checks to see if a job should be
run on another host. It also performs other tasks, such as
expanding certain macros—for example, the Parameter Test—
in what we could loosely describe as filtering the packet file.
The Super Executive knows how to do most of these things
because it receives instructions from programmers via special
parameters that are included in the menu files, and are therefore
included in the packet file.

Some of the functionality within the Super Executive could be


included in the flow builder without changing the behavior of

Other Docs Search Page Known Problems


Flow Execution41 Developer’s Programming Guide

the system. The exception is that the Super Executive waits on


the completion of the tasks that it spawns, rather than spawning
them in the background. This enables it to spawn processes
sequentially if required, and makes the spawning of one
subprocess contingent on completion of the previous one. It
also allows the Super Executive to report the completion status
of any process back to the flow builder—even processes that are
not strictly part of the ProMAX product.

After the Super Executive modifies the packet file, it writes a


new packet file in a scratch directory and launches the process
that does the actual work. In a normal processing flow, the form
of this command is:

exec.exe packet_file host_name PID

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.

The Executive includes the actual processing tools, such as


gain, decon, filter, etc. Ordinary processing tools are not
separate programs, but are rather a set of routines that are linked
together in the Executive. Tools can be single trace input and
output types or one of a number of multi-trace types (see the
Processing Pipeline illustration at the end of this chapter). The
primary function of this manual is to provide you with
information on how to add functionality to the Executive.

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.

Other Docs Search Page Known Problems


Flow Execution42 Developer’s Programming Guide

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.

Other Docs Search Page Known Problems


Flow Execution43 Developer’s Programming Guide

$PROMAX_HOME /sys /bin


promax
promax3d
promaxvsp

/exe
exec.exe /sdi
superExec /(3rd party )
*.exe

/lib
libxxxxx.so

/port /help /promax


promax2d.pdf *.pdf (Adobe)
promax3d.pdf *.help (ASCII)
(Manuals) /promax3d
/promaxvsp

/menu
promax
promax3d
promaxvsp

/misc
*.rgb (colormaps)
ProMAX defaults
/etc
config_file
product
pvmhosts
qconfig

ProMAX Directory Structure

Other Docs Search Page Known Problems


Flow Execution44 Developer’s Programming Guide

PROMAX_DATA_HOME

Area Line Trace Headers

/data /area1 /line1 /12345678


DescName DescName HDR1
Project 12345678CIND HDR2
12345678CMAP TRC1
TRC2

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)

ProMAX Data Directory Structure

Other Docs Search Page Known Problems


Flow Execution45 Developer’s Programming Guide

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.

Other Docs Search Page Known Problems


Flow Execution46 Developer’s Programming Guide

Mutes Gates Surg Mutes

Kills Reversals Horizons

Velocities Etc....

Ordered Database Files

Parameter Tables

Flow
Directory

Packet File Job Output DescName TypeName


(packet.job) (job.output)

Flow Components

Other Docs Search Page Known Problems


Flow Execution47 Developer’s Programming Guide

Job Builder
(promax.exe)

Batch
Queue

Super Executive
(superExec)

Stand-alone Executive
Programs (exec.exe)

IPC Tool Tool Caller

Diskread AGC Mute

NMO Filter

Line Database
Information
(datasets, parameter tables, Packet File
ordered database files, etc.)

System Overview

Other Docs Search Page Known Problems


Flow Execution48 Developer’s Programming Guide

ProMAX Flow Builder Window Map

Other Docs Search Page Known Problems


Flow Execution49 Developer’s Programming Guide

Area: XXXXXX Windows


Overlap

Line: YYYYYY

Flow: ZZZZZZ

Edit Flow Processes

Window
Overlay
Seismic Datasets Parameter Tables

Other Docs Search Page Known Problems


Flow Execution50 Developer’s Programming Guide

Global OptionsProcessing Flow

Flow Builder

Other Docs Search Page Known Problems


Flow Execution51 Developer’s Programming Guide

Input
Data

FK Filter

Gain
Running Mix

Mute
Stack

NMO

Output
Data

Single Trace Processes Multi-Trace Processes

Processing Pipeline

Other Docs Search Page Known Problems


Flow Execution52 Developer’s Programming Guide

Other Docs Search Page Known Problems


53 Developer’s Programming Guide

Executive

This chapter describes the architecture and functions of the


Executive system.

Topics covered in this chapter:


➲ System Architecture
➲ Headers and Global Variables
➲ Input Tools
➲ Re-entrancy
➲ Common Blocks and Parms Structures
➲ Executive Functions
➲ Communication between Tools
➲ OPF Database

Other Docs Search Page Known Problems


System Architecture54 Developer’s Programming Guide

System Architecture

The ProMAX Executive is a pipeline system. In this system,


traces are dropped into the flow one at a time by the input tool
(see the Processing Pipeline illustration at the end of the System
Overview chapter). Individual traces continue to drop through
the flow until they encounter a multi-trace processing tool. The
trace executive collects all of the necessary traces for the
multi-trace processing tool and returns the traces back to the
flow when the tool is finished.

There are a variety of tool types; each type is designed to


minimize the coding required to implement the necessary trace
handling. These tool types range from simple, single-trace
input/output tools, to multi-trace input/output tools of a variety
of natural trace groupings, and finally to complex tools that
facilitate the ultimate user control of trace buffering. Please see
the Tool Types chapter for a description of each tool.

The Executive creates an essentially isolated environment for


each tool. It manages most of the tedious duties of trace and
trace header I/O, data buffering, initialization of global
variables, and other miscellaneous tasks. The following sections
describe these duties.

Other Docs Search Page Known Problems


Headers and Global Variables55 Developer’s Programming Guide

Headers and Global Variables

At run time, each tool is presented with a list of active headers


and a set of initialized global variables. The header list contains
the description, format, and size of all headers that are valid at
that step in the flow. The global parameters can be categorized
as static or volatile. The static type of global parameters are
typically geometry-related: the number of CDP’s, minimum and
maximum station number, maximum offset in data, etc. The
volatile type of globals, named global run time or run time
variables, refer to variables that can change from step to step
within the flow: sample rate, trace length, sort order, maximum
ensemble size, etc.

Headers can be added or deleted and run time variables changed


at any step in the flow; for example, resampling changes the
sample rate and trace length. Because of this, the Executive
actually keeps a separate copy of headers and run time globals
for every step in the flow. In a sense, then, the environment
changes dynamically as traces pass from tool to tool. Please see
the Global Parameters and Trace Headers chapters for details
on these subjects.

It is important to note, however, that the global run time


attributes cannot change within a process or tool. In other
words, while the sample rate, sort, trace length, and maximum
ensemble size can all change from tool to tool, they can not
change from trace to trace, such as by shot position within a
tool. Please review the list of run times in the Global
Parameters chapter.

Other Docs Search Page Known Problems


Input Tools56 Developer’s Programming Guide

Input Tools

The primary responsibility for setting the globals and


establishing the current header list is assigned to the first tool in
the flow, which by definition is an input tool. All input tools
must retrieve the current state of headers and run time variables
from the input ProMAX dataset and must make these available
to subsequent tools. The input tool must also retrieve the
remaining static global variables from the Ordered Parameter
Files (geometry). If your input tool is reading a non-ProMAX
(foreign) dataset or creating data, you are responsible for
retrieving the necessary data from whatever source and creating
all possible header and global values. See the Input Tool
Examples in the Appendix for code examples.

Other Docs Search Page Known Problems


Re-entrancy57 Developer’s Programming Guide

Re-entrancy

Another related issue that the Executive manages is the issue of


re-entrancy. As mentioned above, the Executive attempts to
isolate each tool in such a way that the programmer codes his
tool as if it is the only one in the flow. There is no need to worry
about a ProMAX user putting your tool in the flow multiple
times, which could create confusion over which set of
parameters goes with which instance of the tool. Nor is there
need to worry about two tools coincidentally sharing identical
menu parameters or internal local variables. The Executive
assures that each tool can only access menu parameters from its
corresponding menu in the flow; it offers protection for
duplicate variables.

Other Docs Search Page Known Problems


Common Blocks and Parms Structures58 Developer’s Programming Guide

Common Blocks and Parms Structures

The Executive manages a SAVED_PARMS COMMON block


for each tool for FORTRAN code, or a parms structure for C
code. The n FORTRAN COMMON block or C parms structure
stores variables that need to be passed from the initialization
routine to the execution routine, or local variables that must
retain their values between each call of the Executive routine.
Clearly this must be accomplished by swapping a separate
COMMON block in and out of memory for each step in the
flow. Again, the application programmer can develop a routine
as if it is the only tool and with a single COMMON block. The
FORTRAN SAVED_PARMS COMMON block must be fixed
in size to accommodate memory swapping. Currently the size is
limited to 1000 4-byte words. If your application requires more
than a small fraction of this, you are probably misusing the
space by passing arrays instead of pointers or indexes to the
FORTRAN RSPACE memory array.

Because the size of the SAVED_PARMS common block in


Fortran, and parms structure in C needs to be 1000 4-byte
words, and your tool parameters may one be a few tens of bytes
long, there are macros which pad out your allocation to the full
4000 byte size. In Fortran, this padding is accomplished using
SAVE1z and END1z parameters in the /SAVED_PARMS/
common block. Here is an example from the amp_ratio.inc file:

COMMON /SAVED_PARMS/ SAVE1z, NGATE, IX_SCRATCH, IH_RATIO_MAX,


& IH_RATIO_TIME, LOAD_HDR, LOAD_DB, ID_MAX, ID_TIME,
& IKEY_TRC, USE_GATE, ITBL_HANDLE, IH_PKEY,
& IH_SKEY, IFORMAT_PKEY, IFORMAT_SKEY, END1z

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

Here is a C programming example from ampRatio.c file:

/* define saved parameters */

Other Docs Search Page Known Problems


Common Blocks and Parms Structures59 Developer’s Programming Guide

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. */

*len_sav = NPARMS (parms);

As described in the Executive section of the System Overview


chapter, each tool consists of two FORTRAN or C routines: the
initialization (or init) routine, and the execution (or exec)
routine. The Executive runs each of the init routines in the flow
once. The exec routines are cycled through many times until all
of the traces are processed through the pipe. The init routine is
responsible for reading menu parameters, making any one-time
calculations, resetting run time parameters (for example,
changing the maximum ensemble size to one if stacking), and
creating/deleting headers entries. Remember, changing the
status of the headers or global run time parameters must be
done in the init routine in order for other init routines to be
aware of the change. This is one of the few situations where you
must consider what happens before or after your application.

Other Docs Search Page Known Problems


Executive Functions60 Developer’s Programming Guide

Executive Functions

The exec routine does the actual trace processing. The


Executive passes traces and headers to the exec routine in
buffers and expects the processed traces to be in the same
buffers when exiting the routine. If the tool is a multi-trace type,
the Executive will allocate the memory necessary to accumulate
the proper trace grouping, then free the memory after that group
of traces is processed and passed to the next tool. This memory
management is done automatically without any coding at the
tool level. Often you will need to dynamically allocate
additional memory within the tool to hold temporary results.
This is supported both in FORTRAN and C, but it is assumed
that such memory will be de-allocated upon exiting the exec
routine. Remember that many tools could comprise a flow: your
tool could be repeated many times. After exiting your
multi-trace exec routine, it might be some time before the
remaining flow is executed and traces are again accumulated
and passed to your exec routine. This is another situation where
you must consider the entire flow instead of simply your
application. It is assumed system-wide that two ensembles will
fit comfortably in memory. However, tools that require many
ensembles, multiple copies of ensembles, or large collections of
stacked traces should buffer traces on disk or process panels of
traces.

Other Docs Search Page Known Problems


Communication between Tools61 Developer’s Programming Guide

Communication between Tools

As previously discussed, tool-to-tool isolation makes the


programming environment simple, and the Executive does this
task well. However, inter-tool or inter-process communication
is necessary. Tools that change the sample rate, trace length, kill
a trace, statically shift a trace, etc., need to communicate this
change to processes later in the flow or in a subsequent flow.
Trace headers move with the data, and are an excellent way to
tag traces with information that may be required for a future
process. Headers move through the flow and are stored on disk
or tape upon output. Run time global parameters are also an
excellent vehicle for communicating global changes in the data.
As with headers, they move through the flow and are stored
with the traces upon output. However, these global parameters
cannot change from one trace to the next within a tool.

Other Docs Search Page Known Problems


OPF Database62 Developer’s Programming Guide

OPF Database

The Ordered Parameter Files database is another form of


inter-tool communication. Refer to the Ordered Parameter Files
chapter for a definition of this database. It is typically used to
communicate information that is global to all datasets within
the line; field geometry data is a good example. Convenience is
a governing factor in choosing the form of communication that
is used. For example, geometry information that is placed in the
Ordered Parameter Files database can be conveniently accessed
by stand-alone programs that do not wish to read trace data.

Other Docs Search Page Known Problems


63 Developer’s Programming Guide

Make System

This chapter provides an overview of the ProMAX make


system.

Topics covered in this chapter:


➲ Working with ProMAX Systems
➲ Getting Started
➲ System Administrator Setup
➲ User Setup: Aliases, Makeadvance, Makeexec
➲ Converting to the New System
➲ Understanding the Directory Structure
➲ Customizing the System
➲ Toggling Products: .promax
➲ Adding a New Tool
➲ Making Your New Executable
➲ Incorporating New Functionality
➲ Creating Menus
➲ Adding a ProMAX menu
➲ Changing Files
➲ Understanding the Makefile System

Other Docs Search Page Known Problems


Working with ProMAX Systems64 Developer’s Programming Guide

Working with ProMAX Systems

The ProMAX file and recompilation systems allow large groups


of programmers to develop and maintain software for multiple
machine types from a single master copy of source code. Some
important features of these systems are:

• All Landmark software lies beneath a single directory, e.g.


/promax/2003.12.1/, in subdirectories with standard UNIX
names like bin/, include/, lib/, and src/. We will henceforth
refer to this directory as the environment variable
$PROMAX_HOME.

• To support concurrent development, each programmer has


a subset of $PROMAX_HOME (containing the files they are
working on) in their home directory.

• Machine-dependent subdirectories of $PROMAX_HOME


enable a single file server or programmer’s home directory
to contain executable programs and libraries for all
machine types supported by Landmark.

• Software is organized to facilitate the evolution of


Landmark products, such as ProMAX, ProMAX VSP,
ProMAX 3D, and ProMAX 4D.

• Third-party software is organized to facilitate distribution


(if permitted) to Landmark clients and to avoid conflicts in
file names among different third-party vendors.

• GNU make program is used to build executable programs


and libraries

• Programmers write Makefiles, one for each program or


library, with compilation, link and installation commands
that may be customized without affecting other programs.

• Makefiles used at Landmark are designed to be used by


Landmark clients.

• Source code can be compiled and linked from one location


for all machine types supported by Landmark.

Other Docs Search Page Known Problems


Getting Started65 Developer’s Programming Guide

Getting Started

The following sections describe the System Administrator and


User setup.

System Administrator Setup


The following steps must be performed after installing the
ProMAX release to configure the Development Environment.
These steps help ensure that you will have little trouble when
attempting that first compile and link.

Modify the $PROMAX_HOME/port/include/make/master.make file


1. Confirm the line atopdir := /... is the absolute path to your
$PROMAX_HOME directory. This is set when you first
install ProMAX. An example might be:

atopdir := /Landmark/ProMAX/2003.12.1

2. Use the line utopdir := $(HOME)$(atopdir) to be the


path where each developer will build and use his own copy
of the ProMAX development tree. An example might be:

utopdir := $(HOME)/Landmark/ProMAX/2003.12.1

Generally, Landmark recommends the default setting of


utopdir making each user’s development path parallel the
master installation path.

3. Verify the line ctopdir := is blank.

Additional Setup Step


For each platform on which your company develops, review the
corresponding [machine type].make file located in
$PROMAX_HOME/port/include/make/. Such files are supplied
for the following machine types:

• linux
• linux64

Other Docs Search Page Known Problems


Getting Started66 Developer’s Programming Guide

The [machine type].make file should point to the default


locations of such things as compilers, include files, and
libraries; however, if your system has these located in
nonstandard places, you will have to edit the appropriate
[machine type].make file to reflect this.

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

atopdir := $(shell cd $(atopdir); /bin/pwd)

If you suspect that you have a discrepancy here, cd to


atopdir—in this case /promax/2003.12.1—and type /bin/pwd. If
it is an automounted directory, it should return the actual path,
something like /tmp_mnt/promax/2003.12.1. If it returns
/promax/2003.12.1, you may have a problem which might be
solved a number of ways:

• Hard mount the ProMAX master directory.

• Change /bin/pwd to a pwd program which returns the


proper path.

• Override the definition of atopdir to reflect the


automounted version.

User Setup
The following sections describe the User setup.

Creating Aliases, Makeadvance, Makeexec


To use the make system, complete the following four steps if
you have not already done so (this assumes that you have
already installed the release distribution). Substitute
/promax/2003.12.1 with whatever directory your system
administrator used to install the release. Because most ProMAX
development and testing is done using the UNIX/Linux ksh
command interpreter, including all Makefile and shell script
commands, Landmark recommends you employ ksh for

Other Docs Search Page Known Problems


Getting Started67 Developer’s Programming Guide

developing your own ProMAX modules as well. It is normally


straightforward to develop under other command interpreters
and the following instructions include settings for several
popular alternatives to the ksh.

1. Place the release toplevel directory into environment


variable PROMAX_HOME.

For csh/tcsh users this line might look like:

setenv PROMAX_HOME /promax/2003.12.1

For ksh/zsh/sh users this line might look like:

PROMAX_HOME=/promax/2003.12.1; export PROMAX_HOME

2. Add $PROMAX_HOME/sys/bin and


$PROMAX_HOME/port/bin to your path (or PATH) in your
~/.cshrc (or ~.profile, depending on your shell and what
files it looks for upon login). csh looks for a .cshrc; tcsh
looks for a .tcshrc (if it cannot find one of these, it uses a
.cshrc); zsh looks for a .zshrc; sh and ksh uses .profile. If
you are unsure of which shell you are using, the command
echo $SHELL should tell you.

For csh/tcsh users this line might look like:

set path = ($path /promax/2003.12.1/sys/bin \


/promax/2003.12.1/port/bin)

For ksh/zsh/sh users this line might look like:

export PATH=”$PATH:/promax/2003.12.1/sys/bin:\
/promax/2003.12.1/port/bin)”

3. Add the following lines to your ~/.cshrc, ~/.tcshrc,


~/.zshrc, or ~/.profile file.

csh/tcsh 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'

Other Docs Search Page Known Problems


Getting Started68 Developer’s Programming Guide

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'

This tells gmake and Makeexec where to look for included


files.

4. Csh users should type source .cshrc (or .profile) to reset


your aliases and paths. Ksh users should type the command
. .kshrc to reset their aliases and paths.

5. Type Makeadvance. This will make a User development


tree under your home directory. In addition to making lots
of directories, Makeadvance will also put a Makefile into
your utopdir/port/src/exe/exec/ as well as your
utopdir/port/src/lib/maxtool/ directory. You should study
the two Makefiles—they are short because they include
other files that do most of the work. (The other files are in
$PROMAX_HOME/port/include/make/)

6. From somewhere in your ~/utopdir/port/src/ directory,


type Makeexec. This invokes a script that makes or
updates as needed two libraries libmaxtoolc.so and
libtoolcall.so and then creates a new ProMAX exec.exe
script file. It simply cd’s to utopdir/port/src/exe/exec,
where the Makefile for exec.exe resides, and does a gmake
with the arguments that you provide to Makeexec.

FORTRAN or C toolcall: By default, Makeexec builds


and compiles a FORTRAN version of toolcall, toolcall.f.
By setting the option language=C for the Makeexec
command, that is Makeexec language=C ..., Makeexec
builds and compiles a C version of toolcall, toolcall.c. This
allows the building of exec.exe without a FORTRAN
compiler.

Understanding What Happens


Because exec.exe depends on libraries, such as libmaxtoolc.so,
in addition to files like toolcall.f or toolcall.c, the first thing
Makefile does is check the libraries to see if it should try to
update them. To help Makefile make this decision:

Other Docs Search Page Known Problems


Getting Started69 Developer’s Programming Guide

• If a Makefile exists in the src directory for the library, then


it ensures that the library is up-to-date by changing to that
directory and running gmake; or,

• It uses the master version of the library and assumes that it


is up-to-date.

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.

Once the libraries are built, then an exec.exe is created that


packages up these libraries along with a command script that
unpacks them into a temporary directory at runtime, arranging
that the libmaxtoolc.so and libtoolcall.so libraries you have just
built are the ones used at runtime when you invoke this
Alternate Executive.

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.

Based on the arguments to Makeexec or gmake, the buildtoolcall


script will then build a utopdir/port/src/exe/exec/toolcall.f
FORTRAN file (default), or a
utopdir/port/src/exe/exec/toolcall.c C file if buildtoolcall is

Other Docs Search Page Known Problems


Getting Started70 Developer’s Programming Guide

invoked from gmake or Makeexec with language=C. The new


toolcall source file will then be compiled and linked into a
libtoolcall.so library which is then, combined with
libmaxtoolc.so, used to build a new alternate executive
utopdir/[machtype]/exe/exec.exe executable script. Here
[machtype] is the current machine architecture, i.e. linux or
linux64

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.

Other Docs Search Page Known Problems


Converting to the New System71 Developer’s Programming Guide

Converting to the New System

Normally, it is sufficient to copy source files and Makefile


newsrcs := ... entries from your previous user development
tree into your new user tree to build them under the new system.
You will probably want to reexamine your Makefile(s), if any,
for local dependencies. Landmark has created several Makefile
examples in $PROMAX_HOME/port/include/make to assist in
creating Makefiles for new tools or reworking older Makefiles
for improved compatibility.

Other Docs Search Page Known Problems


Understanding the Directory Structure72 Developer’s Programming Guide

Understanding the Directory Structure

Before dealing with the details of the development system, it is


essential to have a basic understanding of the directory structure
in which it functions. A few of the files and directories of
interest in the development system include:

• $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.

compile.test A simple makefile used in conjunction with


$PROMAX_HOME/port/bin/ctest which allows you to compile source files
into executables.

libmaxtool.example An example user makefile for the maxtoolc library. This file is used by
Makeadvance to create a user environment.

Other Docs Search Page Known Problems


Understanding the Directory Structure73 Developer’s Programming Guide

$PROMAX_HOME/port/include/make/ Files (Continued)


File Description
exec.example An example makefile for the executive. This file is used by Makeadvance to
create a user environment.

stand_alone1.example An example makefile for a stand-alone module. This file is used by


Makeadvance to create a user environment.

stand_alone2.example An example makefile for a stand-alone module utilizing the maxprog.make


template.

Makefile_example_* Sample makefiles for creating new modules under the bin, exe, and lib user
port/src development subdirectories.

The following examples uses files from this directory.

Example: simple.make
This makefile example uses simple.make to compile into the
current directory.

1. cd $HOME

2. mkdir simpletest

3. cd simpletest

4. Edit Makefile to look like:


srcs1 := a.c b.c
srcs2 := c.c d.f
exec1 := abtest
exec2 := cdtest
include simple.make

5. Edit a.c to look like:


#include <stdio.h>
a() {printf(“a()\n”);}

6. Edit b.c to look like:


#include <stdio.h>
b() {a(); printf(“b()\n”);}
main() {b();}

7. Edit c.c to look like:


#include <stdio.h>

Other Docs Search Page Known Problems


Understanding the Directory Structure74 Developer’s Programming Guide

c_() {printf(“c()\n”);}

8. Edit d.f to look like:


SUBROUTINE D
CALL C
WRITE(*,*)’D()’
RETURN
END

PROGRAM D
CALL D
END

9. Type gmake. The executables abtest and cdtest should be


compiled in the current directory.

Example: compile.test
This makefile example uses compile.test.

1. cd $HOME

2. mkdir compiletest

3. cd compiletest

4. Edit a.c to contain:


#include <stdio.h>
main() {printf(“Hello World From a.\n”);}

5. Edit b.f to contain:


PROGRAM MAIN
WRITE(*,*) ’HELLO WORLD FROM MAIN()’
END

6. ctest a b should compile executables a and b corresponding


to your source code a.c and b.f.

Other Docs Search Page Known Problems


Understanding the Directory Structure75 Developer’s Programming Guide

$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.

Makeadvance A script which sets up a user development environment.

Makeexec A script which creates a user version of the executive.


Setqueues A script which allows users to toggle between LPD, NQS, and PBS queues.

aman A script which allows users to get online man pages.

Promax A script which is used to bring up the user interface.

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.

checkout2 A script which is used to check out an Landmark sccs file.

testFlows Another script which is used for automated testing.

buildtoolcall A script which is used to build toolcall source in FORTRAN or C. It is normally


called from the Makefile but may also be invoked from the command line.
buildtoolcall accepts as an optional first command line argument -C; this switch
instructs buildtoolcall to build C code instead of the default FORTRAN.

app A small script which preprocesses, adding $PROMAX_HOME/port/include and


$PROMAX_HOME/port/include/private to your include paths.

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.

Nmgrep A utility used for extracting information from object files.

Fid A simple utility used to print out include dependencies in a file.

Other Docs Search Page Known Problems


Understanding the Directory Structure76 Developer’s Programming Guide

$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.

aviewer Landmark’s command-line interface to FrameViewer. This is no longer used


with new ProMAX releases, having been superceded by Acrobat Reader and the
PDF format.
copycat A program which runs every 1/2 hour and takes the tape catalog files and copies
them to another directory. It ensures that there is always an uncorrupted version
of the tape catalog database handy.

ctags A program used to generate tag files for vi.

ctar A program similar to UNIX tar except that it understands the notion of
secondary storage. It uses the advance tape catalog optionally.

emacs An editor provided by the Free Software Foundation.

etags A program used to generate tag files for emacs files.

gmake Gnu Make. Gnu’s version of the make utility.

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.

pkt_dump A program used to display a packet file to standard out.

promax Landmark’s 2D GUI.

promax3d Landmark’s 3D GUI.

promax4d Landmark’s 4D GUI.

promaxvsp Landmark’s VSP GUI.

pwin A menu interpreter/editor allowing menus to be created interactively.

qdel NQS routine (see man pages).

qdev NQS routine (see man pages).

qjob NQS routine (see man pages).

Other Docs Search Page Known Problems


Understanding the Directory Structure77 Developer’s Programming Guide

$PROMAX_HOME/sys/bin/ Files (Continued)


Script Description
qlimit NQS routine (see man pages).

qmgr NQS routine (see man pages).

qpr NQS routine (see man pages).

qstat NQS routine (see man pages).


qsup NQS routine (see man pages).

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.

tcatd A daemon which performs transactions on a tape catalog.

winlic GUI-based license utility

xxxxxx Many other undocumented script files for ProMAX products

$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.

Other Docs Search Page Known Problems


Customizing the System78 Developer’s Programming Guide

Customizing the System

Much of the system can be customized via the environmental


variable; that is, the path to most files and directories can be
re-specified. The name of the environmental variable is always
the path name, with the slashes replaced by underscores, every
character promoted to upper case, and _HOME appended.

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
• ...

Other Docs Search Page Known Problems


Toggling Products: .promax79 Developer’s Programming Guide

Toggling Products: .promax

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) )

Entry3 is the absolute or relative pathname to the directory


containing the executable files for the product. If specified as a
relative pathname, it will be appended to
$PROMAX_SYS_EXE_HOME. The executable directory is
common to all Landmark products. There are no
product-specific subdirectories. The default entry would be
blank, directing the flow builder to the standard ProMAX /exe
subdirectory typically defined by the environmental variable
$PROMAX_SYS_EXE_HOME. For your development
environment, the following entry may be preferred:

"~/[$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/:."

The “.” following or preceding the colon denotes the system


default as specified by environmental variables.

Other Docs Search Page Known Problems


Toggling Products: .promax80 Developer’s Programming Guide

The preceeding entry assumes that you are working on a Linux


machine. If you are developing code across multiple hardware
platforms, a more general entry is

"~/[$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.

Entry4 is the absolute or relative pathname to the directory


containing the menu files. If specified as a relative pathname, it
will be appended to $PROMAX_PORT_MENU_HOME. The
menus for each product are divided into subdirectories under
the main directory defined by $PROMAX_PORT_MENU_HOME.
For example, a default entry for the ProMAX 2D product would
be "promax", directing the flow builder to
$PROMAX_PORT_MENU_HOME/promax for menus. For your
development environment, the following entry may be
preferred:

"~/[$PROMAX_HOME]/port/menu/promax/:\
[$PROMAX_HOME]/port/menu/promax"

or

"~/[$PROMAX_HOME]/port/menu/promax/:promax"

This entry will cause a search of your menu directory for


custom menus and the system menu directory next.

Entry5 is the absolute or relative pathname to the Processes


file. The Processes list is different for each product; by default
the Processes file resides with the product menus. This entry
generally will be the same as the menus with /Processes
appended. A similar search mechanism outline for menus
(Entry4) can be employed except that the path must include the
Processes file name as this is a single file instead of a group of
menus or helps. For example:

"~/[$PROMAX_HOME]/port/menu/promax/Processes:\
promax/Processes"

Entry6 is the absolute or relative pathname to the directory


containing the help files. If specified as a relative pathname, it

Other Docs Search Page Known Problems


Toggling Products: .promax81 Developer’s Programming Guide

will be appended to $PROMAX_PORT_HELP_HOME. The helps


for each product are divided into subdirectories under the main
directory defined by $PROMAX_PORT_HELP_HOME. For
example, a default entry for the ProMAX 2D product would be
"promax", directing the flow builder to
$PROMAX_PORT_HELP_HOME/promax for help files. For
your development environment, the following entry may be
preferred:

"~/[$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.

Entry7 is the absolute or relative pathname to the directory


containing the misc files. If specified as a relative pathname, it
will be appended to $PROMAX_PORT_MISC_HOME. As with the
executable directory, there is no product level subdivision of
misc files. The misc/ level files control configuration aspects
such as color tables and are rarely redirected. However, if
desired, search path control is done in the same manner as that
for the executables, Entry3, above.

Entry8 is the absolute or relative pathname to the directory


containing the primary data storage files. If specified as a
relative pathname, it will be appended to
$PROMAX_DATA_HOME. The data directory is also not divided
by products, nor is a search path supported in the .promax file.

Entry9 is a library search path listing the directories that


ProMAX is to use when searching for dynamic libraries to
resolve the various ProMAX supplied processes, tools and
interfaces. These directories augment, and take precedence
over, the standard ProMAX library paths. This facilitates local
development and ProMAX support patches without the need to
modify the current ProMAX installation.

The following examples demonstrate product stanzas in the


.promax file:

Standard:
(:product ("P" "ProMAX" "" "promax" "promax/Processes"\
"promax" "" "" "" t)
("v" "ProMAXVSP" "" "promaxvsp" "promaxvsp/Processes"\
"promaxvsp" "" "" "" t) )

Custom:

Other Docs Search Page Known Problems


Toggling Products: .promax82 Developer’s Programming Guide

(:product ("P" "ProMAX" "/disk2/exe" "promax"\


"promax/Process" "promax" "" "" "/disk2/lib:.:syslibs" t)
("3" "ProMAX 3D" "" "promax3d" "/home/joe/processes"\
"promax3d" "" "/advance/mydata" "" t) )

Please refer to the ProMAX Reference Manual for further


discussion of the .promax file.

Other Docs Search Page Known Problems


Adding a New Tool83 Developer’s Programming Guide

Adding a New Tool

In ProMAX, the menu file controls what parameters are


presented to the user. The help file provides textual/graphical
help during parameterization. The initialization routine checks
the input parameters for validity and generally tries to
accomplish any tasks that are performed on a one-time basis.
The execution routine performs the actual trace processing. The
include file provides communication between the initialization
routine and the execution routines, and facilitates re-entrancy.

Nine generic steps are required to add a new processing tool to


the system and see the results. In typical chronological order
they are:

• Creating or copying a source file that contains an


initialization phase and an execution phase.

• Creating or copying an include file (if using Fortran).

• Creating a modified version of tools_to_add for new tools.

• Compiling and linking the source code via Makeexec.

• Creating or copying a new menu.

• Adding an entry to the Processes file.

• Restarting the flow builder.

• Parameterizing a flow, including the new tool and the


Alternate Executive or the Alternate Libraries directive.

• Executing the flow.

The following steps outline the first-time process for adding a


new tool, using the amp_ratio tool as an example. The default
setting of utopdir to ~/$PROMAX_HOME is assumed in this
example.

1. Build a parallel directory tree within your home directory.

% cd (go to your $HOME directory)


% Makeadvance (builds entire Landmark directory tree
beneath $HOME)

Other Docs Search Page Known Problems


Adding a New Tool84 Developer’s Programming Guide

% chmod -R a+rw ~/$PROMAX_HOME (give read/write


permissions to all files)
% cd ~/$PROMAX_HOME; ln -s [platform] sys
link the platform type to sys

2. Copy needed source code into directories.

% 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 .

3. Add new tool to Makefile.

% 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]

4. Update toolcall source (toolcall.f or toolcall.c).

% 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]

5. Create new libraries (libmaxtoolc.so & libtoolcall.so) and


executable (exec.exe).

% cd ~/$PROMAX_HOME/port/src
% Makeexec (Builds toolcall.f. Compiles it)

or

% Makeexec language=C (Builds toolcall.c.\


Compiles it)
% cd ~/$PROMAX_HOME/linux/exe
% ls -l (File called ‘exec.exe’ should now exist)

6. Add the new tool to your Processes list. (Be sure to


configure your .promax file as shown earlier.)

% cd ~/$PROMAX_HOME/port/menu/promax
% cp $PROMAX_HOME/port/menu/promax/Processes .
% [edit] Processes

Other Docs Search Page Known Problems


Adding a New Tool85 Developer’s Programming Guide

under "Amplitude" section add the entry:


("Amp ratio" "amp_ratio1")
[save file]

7. Run the new tool within ProMAX.

% $PROMAX_HOME/port/bin/Promax (start ProMAX UI)


Add "Amp Ratio" to a flow
Add "Alternate Executive" to a flow pointing it at
the new ~/$PROMAX_HOME/[machtype]/exe/exec.exe
Execute the flow
Minimize the ProMAX User Interface window.

8. Iteratively make changes to the source code.

% [edit] ~/$PROMAX_HOME/port/src/lib/maxtool\
/amp_ratio/amp_ratio1.f
% Makeexec
[Try it out in ProMAX]

Other Docs Search Page Known Problems


Making Your New Executable86 Developer’s Programming Guide

Making Your New Executable

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:

1. Move to the tools subdirectory in your advance/ directory


tree:

% 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 *

2. Add an entry to your


~/$PROMAX_HOME/port/src/exe/exec/tools_to_add file
(this file is used to make
~/$PROMAX_HOME/port/src/exe/exec/toolcall.f or
toolcall.c, which contains the glue between the Executive
and the individual tools):

% [edit] ~/$PROMAX_HOME/port/src/exe/exec/\
tools_to_add

AMP_RATIO is a simple tool (see the Tool Types chapter).


Search for AGC and add a similar entry for AMP_RATIO
so that the file looks like this:

AMP_RATIO same simple internal

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.

3. Add an entry to the tools Makefile:

% [edit] ~/$PROMAX_HOME/port/src/lib/maxtool/\
Makefile

Other Docs Search Page Known Problems


Making Your New Executable87 Developer’s Programming Guide

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

4. Remake the exec:

% Makeexec (build and compile a toolcall.f)

or:

% Makeexec language=C (build and compile a toolcall.c)

or, directly using gmake:

% cd ~/$PROMAX_HOME/port/src/exe/exec
% gmake [language=C](build and compile toolcall.f or .c)

Step 4 should produce the script file exec.exe in the directory


~/$PROMAX_HOME/[machtype]/exe/ where [machtype]
reflects the type of machine that you are working on ( linux or
linux64).

The Details
The following things happened when you typed Makeexec:

1. The Makeexec script cd’d to your


~/$PROMAX_HOME/port/src/exe/exec directory and
spawned the Makefile there with the same arguments that
you gave 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

Other Docs Search Page Known Problems


Making Your New Executable88 Developer’s Programming Guide

for existence and whether or not a Makefile is present in


each of:

• ~/$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

If a Makefile is present, the makefile ensures that the


library is up to date by cd’ing to the directory and
spawning the Makefile with the same arguments that were
given to Makeexec.

If no Makefile is found, it is assumed that you will link


with the client or master version of the library.

4. After ensuring/assuming that the libraries are up to date,


$PROMAX_HOME/port/src/exe/exec/Makefile respawns
itself so it can see if the exec.exe really needs to be remade.
Depending on the answer it will either report that the
exec.exe is up to date or re-link a new exec.exe in the
~/$PROMAX_HOME/[machtype]/exe/ directory.

Other Docs Search Page Known Problems


Incorporating New Functionality89 Developer’s Programming Guide

Incorporating New Functionality

By following the preceeding steps, you successfully made a


new version of the exec and added new functionality. However,
you might be disappointed to find that the ProMAX Flow
Builder is still unaware of your achievement. We will return to
this example after a discussion about customizing ProMAX
menus.

In the Executive section of the System Overview chapter, we


discussed how each tool must have an initialization and
execution routine. A menu file must also exist if you hope to do
more than admire the new executable. Menu files are used to
specify what parameters should exist, what their properties are
(such as their type, default value, and description), and how
they interrelate. Without a menu file, the flow builder has no
idea how to capture and output the parameters that will make
your new processing tool operate.

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.

Other Docs Search Page Known Problems


Creating Menus90 Developer’s Programming Guide

Creating Menus

The User Interface looks at the setting of the environment


variable new_menu to determine the menu init behavior. If
new_menu=t, then the User Interface will re-initialize the menu
every time it is displayed. If new_menu=f, then the flow builder
will only read files once. This means if you modify the
processes file or a menu file after starting the flow builder, it
will not see your changes. Furthermore, if you add a tool to a
flow, the corresponding menu file will be saved with the flow,
and the menu file will not be read again when the flow is
accessed again. Setting new_menu=t is a big help in testing
menus and should be part of the ProMAX programmer’s
environment. This setting slows down the User Interface
because the menu files are reread; therefore, it is not the default
setting for the typical production processing environment.

The menu file contains the description of parameters and rules


that control what the User Interface presents. Menu files are
written in Lisp and are interpreted at run time (no compilation is
necessary). No Lisp programming experience is necessary,
however. The syntax is simple and there are abundant examples
in the directory $PROMAX_HOME/port/menu (see files
ending with the extension .menu). In most cases, it is easiest to
find existing parameters in the system that are similar to those
that you wish to use, and then cut and paste them into a new file.
While you are creating the new menu file, it is a good idea to
use an editor that has parentheses checking, since mismatched
parentheses are the most common source of errors.

A utility program called promenu exists for debugging menu


files. After the menu file is near completion, use promenu to
adjust cosmetic features and to test the menu rules (if they exist
in your menu file). The program promenu takes the menu file as
a command line argument; therefore, if your menu file is named
testtool.menu, the command would be:

% $PROMAX_HOME/sys/bin/promenu testtool.menu

Each time you change the menu file, use File->Reread to


reflect any changes made to the menu file in the editor.

Other Docs Search Page Known Problems


Adding a ProMAX Menu91 Developer’s Programming Guide

Adding a ProMAX Menu

To use a tool, such as the simple tool AMP_RATIO (see the


chapter entitled Tool Types), you must do two things: 1) make
the flow builder aware of the menu file, and 2) direct execution
to the new exec.exe that you made. You can accomplished this
with the following steps:

1. Exit the flow builder if it is already running.

2. Copy the production Processes file into your development


tree and make it writable. The commands will look similar
to this:

% cd
% cp $PROMAX_HOME/port/menu/promax/Processes\
~/$PROMAX_HOME/port/menu/promax/Processes
% chmod +w ~/$PROMAX_HOME/port/menu/promax/Processes

3. Add an entry to your Processes file:

% [edit] ~/advance/port/menu/promax/Processes

Search for “agc” and add another line for AMP_RATIO :

(“Automatic Gain Control” “agc”)\


(“Amplitude Ratio” \
“/home/joe/prog_course/src/amp_ratio/
amp_ratio” ) \
(“Time-Variant Scaling” “tvs”)

Note that your entry is different; it includes the full path to


the menu file within your home directory. In the absence of
a full path, the flow builder assumes that the file resides in
the production menu directory. Also note that the .menu
extension of the file name is implied.

Alternatively, you can add your new menu without an


explicit path and use the search path facility in the .promax
file. For instance, you can direct the menu search to check
your personal menu directory first and the standard menu
directory next. In this case, the amp_ratio.menu file must
be copied to your menu directory.

4. Redirect the flow builder to your custom version of the


Processes file. For future benefit, it is probably best to edit

Other Docs Search Page Known Problems


Adding a ProMAX Menu92 Developer’s Programming Guide

the file ~/.promax and add a product stanza as discussed in


the Toggling Products section of this chapter.

5. Restart the flow builder (that is, restart ProMAX).

6. Create a new flow and add Disk Data Input, followed by


Amplitude Ratio and Screen Display. If Amplitude Ratio
does not show up at all in the list of tools, step 4 failed.
(Take a close look at your .promax file, and look at the file
$PROMAX_HOME/port/misc/misc_files/sys_ad/promax_dev.)

7. Set the parameters for the individual steps in the flow. If


you are using the tutorial datasets, “Raw shots with
geometry” is a good input dataset. If you get an error
message when you attempt to parameterize Amplitude
Ratio, you have a typo in your Processes file. (Take a close
look at the path that you specified. Note that you cannot
use ~/prog_course/src/amp_ratio/amp_ratio as the path.)
The defaults for “Amplitude Ratio” and “Screen Display”
are fine.

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

Again, the best approach may be to direct the flow builder


to search your exe/ subdirectory first via the .promax file.

8. Run the flow. You should see fairly dead-looking traces,


with a large peak where the first breaks once were.
AMP_RATIO transforms a trace by taking the ratio of the
amplitudes in two sliding gates (lower gate / upper gate).
When the lower gate is in the first break energy and the
upper gate is in the noise, the result is a large peak (this is
the beginning of a crude first break picker).

Please be sure to complete this exercise before moving on to be


certain that any and all idiosyncrasies in your release,
installation, and make environment are resolved.

Other Docs Search Page Known Problems


Changing Files93 Developer’s Programming Guide

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

and the .c and/or .f files found in this directory are changed


frequently during development. The .promax file found in the
home directory is changed infrequently.

The first illustration shows files that need to be changed or


added when an inline tool (linked to the trace executive) is
added. The second illiustration shows files that must be changed
or added when a stand-alone or IPC (socket) tool is added to the
system. These charts have proven to be very useful when used
as a reminder of the file changes that are needed for a new tool.

Other Docs Search Page Known Problems


Changing Files94 Developer’s Programming Guide

your advance directory


Makefile

. promax lib maxtool your_tool .c, .f


src
port exe exec tools_to_add
~/ $PROMAX_ menu
HOME
promax

Processes

your_menu.menu

exe *.exe
linux
lib system libraries (libmaxtool*.so)

infrequently changed file

frequently changed file

Files to be changed for an inline tool

Other Docs Search Page Known Problems


Changing Files95 Developer’s Programming Guide

.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)

infrequently changed file

frequently changed file

Files to be changed for a stand-alone or IPC tool

Other Docs Search Page Known Problems


Understanding the Makefile System96 Developer’s Programming Guide

Understanding the Makefile System

This section describes the Makefile system.

C++ Template Instantiation


One of the more difficult aspects of the Makefile system is C++
template instantiation due to the differences in the way it is
handled between the various platforms. Basically, there are two
different types of template instantiation among the platforms
Landmark currently supports.

• Manual Template Instantiation - With the Linux g++


compiler ProMAX employs manually-instantiated
templates. That is, if you want the use of a template, you
must instantiate it yourself. This is pretty simple from the
Makefile perspective because the complexity is transferred
to the code, whose responsibility is to instantiate every
template it expects to use.

Terms and Variable Descriptions


There are a number of variables of which the Makefile writer
should be aware. The following tables describe the general
terms and makefile conventions.

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 $@

Other Docs Search Page Known Problems


Understanding the Makefile System97 Developer’s Programming Guide

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.

Directory Variable A variable which contains a path to a directory.

Makefile Variable A variable which contains a path to a makefile.

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)

Command Line Interaction:


% gmake
FOOBAR: foo bar

Other Docs Search Page Known Problems


Understanding the Makefile System98 Developer’s Programming Guide

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 Interaction:


% gmake
FOOBAR1: foo
FOOBAR2: foo bar

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 Interaction:


% gmake
VAR: Makefile Value
% gmake var=”command line value”
VAR: command line value

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)”

Command Line Interaction:


% gmake
VAR: Makefile Value
% gmake var=”command line value”
VAR: command line value Makefile Value

Other Docs Search Page Known Problems


Understanding the Makefile System99 Developer’s Programming Guide

Conventions
The following list describes Makefile conventions.

1. A regular expression such as [A|B|]foo means Afoo, Bfoo,


or foo. The variable foo is assumed to be the base of Afoo
and Bfoo, or rather, Afoo and Bfoo inherit from foo. This is
explained in further detail below.

2. When you see statements such as FOO->BAR, this means


that BAR inherits FOO. Or rather, BAR contains FOO.
Thus, anything which is set in FOO, will also be set in
BAR.

3. Anytime you see something like (FOO1, FOO2)->BAR,


this will mean that BAR inherits from both FOO1 and
FOO2.

4. Anytime you see something like FOO1->FOO2->BAR,


this will mean that BAR inherits from FOO2 and that
FOO2 inherits from FOO1. This construction is similar to
the statement (FOO1, FOO2) -> BAR with the difference
that we now know a little more about the hierarchy of the
variables in that we also know the relationship between
FOO1 and FOO2 as well. We may say that BAR directly
inherits from FOO2, FOO2 directly inherits from FOO1,
thus BAR indirectly inherits from FOO1.

5. Variables whose names are prefixed with with either a, m


or nothing at all will be denoted with something like [a|m|].
These types of variables are paths to files and directories in
the Makefile system. For example, suppose we have a three
variables, representing three directories, afoodir, mfoodir
and foodir. Each variable is so similar in function that we
wished to document this as one variable. The variable
would appear as [a|m|]foodir. This should look familar to
those familiar with regular expressions. In addition, the
prefixes “a” and “m” have special signifigance. When
discussing variables of this nature, we will sometimes refer
to $path. For variables preceded with “a”, $path will be the
same value as the shell environmental variable
$PROMAX_HOME. For variables preceded with “m”,
$path will have the same value as $mtopdir. For variables

Other Docs Search Page Known Problems


Understanding the Makefile System100 Developer’s Programming Guide

lacking the “m” or “a” prefix, $path will be either $mtopdir


or $utopdir, depending on the context of the make.

• Variables preceded with an “a” signify that they are


Landmark’s version of this variable. Since these types
of variables contain paths to directories or files, their
contents would represent Landmark’s version of this
directory or file. Clients of Landmark should not
concern themselves with these types of variables as
they are internal to Landmark’s use of the Makefile
system.
• Variables preceded with an “m” signify the master
version (or client version), of this variable. Their
contents would represent the master version of this
directory or file.
• Variables not preceded with either an “m” or an “a”
are evaluated at the time the make is run. They are
interpreted by the context of the make. In a master
make context, the variable defaults to the master
version of the variable. In a user make context (that
is, when someone is performing a make in his home
directory), these variables default to the version of the
file or directory in the user’s home directory version
of the advance tree.

6. Variables whose names are prefixed with KRC, C, F, CXX,


or AMD or nothing will be denoted with something like
[KRC|C|F|CXX|AMD|Y|LEX|] prefixed before the
basename of the variable. The version of this variable
which does not have a prefix is said to be the base for all
the rest of the variables. The only exception to this rule are
the [a|m|] variables described previously in step 5. Thus,
given:

[KRC|C|F|CXX|AMD|Y|LEX]foo

we can assume:

foo -> (KRCfoo, Cfoo, Ffoo, CXXfoo, AMDfoo, Yfoo,


LEXfoo) or rather KRCfoo, Cfoo, Ffoo, CXXfoo,
AMDfoo, Yfoo, and LEXfoo all inherit from the base
variable foo.

In addition, the prefixes themselves having meaning.


Anything preceded with KRC will apply to the K&R C
compiler.

Other Docs Search Page Known Problems


Understanding the Makefile System101 Developer’s Programming Guide

The following table describes each of the prefixes with


their meaning.

Variable Prefixes
Prefix Meaning

KRC These variables apply to K&R C preprocessing, compiling and linking


options. (It is best to upgrade code to ANSI C, however.)
C These variables apply to ANSI C preprocessing, compiling and linking
options.
F These variables apply to Fortran 77 preprocessing, compiling and linking
options.
CXX These variables apply to C++ preprocessing, compiling, and linking options.
Y These variables apply to Yacc preprocessing and translation.
LEX These variables apply to Lex preprocessing and translation.
AMD These variables apply to the Amakedepend options. This is Landmark’s
special version of the unix makedepend utility.

7. The inheritance notation can be combined with the regular


expression notation to express several relationships more
efficiently. For example, a statement such as
[KRC|C|]foo -> [KRC|C|]bar can be used to express the
relationships KRCfoo -> KRCbar, Cfoo->Cbar, foo->bar.
Also note that there are a couple of implicit relationships:
bar->KRCbar, bar->Cbar, foo->KRCfoo, foo->Cfoo.

The following example illustrates a more subtle issue:

([KRC|]foo1, [KRC|C|]foo2) -> [KRC|C|]bar

This says:

• (KRCfoo1, KRCfoo2) -> KRCbar


• Cfoo2 -> Cbar (There is no Cfoo1)
• (foo1, foo2) -> bar

We also know implicitly that:

• a) foo1->KRCfoo1 (Cfoo1 does not exist)


• b) foo2->(KRCfoo2, Cfoo2)
• c) bar->(KRCbar, Cbar)

Other Docs Search Page Known Problems


Understanding the Makefile System102 Developer’s Programming Guide

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.

profile Boolean Variable. When set to yes, profiling is


activated.

[KRC|C|CXX|F|AMD|] INCPATH Variables. These variables hold the include


path(s) for [KRC|C|CXX|F|AMD|]
preprocessing. Note we are using
the regular expression format.

[KRC|C|CXX|F|] DEFINES Variables. These variables hold the defines for


[KRC|C|CXX|F|] preprocessing.

[KRC|C|CXX|F|AMD|] PPFLAGS Variables. These variables hold the


preprocessor flags for
[KRC|C|CXX|F|AMD|]
preprocessing.

[KRC|C|CXX|F|] Variables. These variables are used to hold


OPTIONS options given to the
[KRC|C|CXX|F|AMD|] programs.

[KRC|C|CXX|F|] Variables. These variables are used to hold


OPTIMIZATION the optimization options given to
the [KRC|C|CXX|F|] compilers. It
can be argued that this should be
part of the OPTIONS variable but
was split apart for the convenience
of efficiency minded developers.

[KRC|C|CXX|F|AMD|Y|]FLAGS Variables. These variables are used to hold


flags given to the
[KRC|C|CXX|F|AMD|Y|]
programs.
([KRC|C|CXX|F|AMD|]\
OPTIONS,
[KRC|C|CXX|F|AMD|]\
OPTIMIZATION) ->
[KRC|C|CXX|F|AMD|]FLAGS

[KRC|C|CXX|F|] Variables. These variables are used to hold


LDFLAGS any flags passed down to the
[KRC|C|CXX|F|] link phase, such
as directories to search for
libraries.

Other Docs Search Page Known Problems


Understanding the Makefile System103 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
[KRC|C|CXX|F|]LIBS Variables. These variables hold a list of
libraries, specific to the compiler
being used, which are to be linked
when doing a [KRC|C|CXX|F|]
link.

[KRC|C|CXX|F|] Variables. These are prepended to a


PRECOMPILE [KRC|C|CXX|F] compilation.
Purify and quantify take advantage
of these variables.

KRCC Command Variable. The command which invokes the


K&R C compiler.
CC Command Variable. The command which invokes the
ANSI C Compiler.

CXX Command Variable. The command which invokes the


C++ compiler.

FC Command Variable. The command which invokes the


Fortran 77 compiler.

CPP Command Variable. The command which invokes the C


Preprocessor. This is also used by
the other compilers, with the
exception of the fortran compiler.

FPP Command Variable. The comand which invokes the


Fortran Preprocessor.

SYSLIBS Command Line A list of system libraries to be used


Augmentable Variable. to link executables (with the
exception of C++ executables).

SYSXXLIBS Command Line A list of system libraries to be used


Augmentable Variable. to link C++ executables.

XLIBS Variable. A list of X11 libraries with which


to link.

XMLIBS Variable. A list of Motif and X11 libraries


with which to link.

cxxlink Boolean Variable. When this is set to yes, it indicates


that a C++ executable is being
created. As a result, certain things
are set to their C++ defaults instead
of their C defaults.

shared_libs Boolean Variable. A boolean yes/no value. When


shared_libs is set to yes, libraries
and executables created will be
shared.

Other Docs Search Page Known Problems


Understanding the Makefile System104 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
lib_suf Variable. lib_suf contains the library suffix.
It is usually “.a”.

master Boolean Variable. A boolean yes/no value which


indicates whether or not a master
make is occurring.

GET Command Variable. The command which performs an


SCCS get on a file or files.

ctopdir Directory Variable. The client’s top directory.


utopdir Directory Variable. The user’s top directory, usually
$HOME/$PROMAX_HOME.

atopdir Directory Variable. Landmark’s top directory. atopdir


should be the same as the
$PROMAX_HOME
environmental variable.

topdir Directory Variable. The effective top directory. In a


master make context, it will be the
same as mtopdir; in a user make
context, it will be utopdir; in an
advance master make context, it
will be atopdir. For Landmark,
mtopdir is the same as atopdir, a
fact which causes a small amount
of terminology confusion when
dealing with clients.

loadmap Boolean Variable. A boolean yes/no value which


determines whether or not a
loadmap is generated; traces which
function came from which library.
mtopdir Directory Variable. This is the master top directory. It
is the same as ctopdir for clients.
For Landmark, it is the same as
atopdir (Landmark is it’s own
client).

AR Command Variable. The ar or library archiver


command.

ARCHIVE_REPLACE_FLAGS Command Flags A variable containing the flags to


Variable. be given to AR when an archive
replace is to be done.

ARCHIVE_CREATE_FLAGS Command Flags A variable containing the flags to


Variable. be given to AR when a library
archive is to be created.

Other Docs Search Page Known Problems


Understanding the Makefile System105 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
AS Command Variable. The as command, AKA the
assembler.

RANLIB Command Variable. The ranlib command. On machines


without the ranlib command, it
replaces ranlib with touch.

RANLIB_TARGET CCS Rule Variable. A CCS which ranlibs the library


described in the target section of a
make dependency.

Other Docs Search Page Known Problems


Understanding the Makefile System106 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
CXX_LINK Command Variable. A command which will C++ link
an executable. How this variable is
handle depends on whether the
compiler performs automatic
template instantiation.
Manual Template Instantiating
Compilers:
On platforms which require
manual instantiation of templates,
this command is simply a call to
the C++ compiler with
CXXLDFLAGS thrown in.
CXX_LINK -> (CXX,
CXXLDFLAGS)

Automatic Template Instantiating


Compilers
On auto instantiating machines, the
makefile system will use
CXXTEMPLATES to set the
template directory or directories. If
CXXTEMPLATES is not set, it
will attempt to determine what the
template repositories should be.
These repositories are determined
via the algorithm:
1. Get the list of object
dependencies.
2. Create a list, uobjlist, which
contains a list of all objects in the
dependency list whose base path
points to the user’s directory
utopdir.
3. Create a list, mobjlist, which
contains a list of all objects in the
dependency list whose base path
points to the master directory
mtopdir.
4. Create a list, aobjlist, which
contains a list of all objects in the
dependency list whose base path
points to the advance directory
atopdir.
(continued)

Other Docs Search Page Known Problems


Understanding the Makefile System107 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
CXX_LINK (continued) (continued)
5. If uobjlist contains one or more
files, take the first object file and
replace the filename.o portion with
templates and prepend -ptr to the
string. Add this to the tail end of
our CXX_LINK canned command
sequence. Repeat this step with
mobjlist and aobjlist (in that order).
Thus, user directories get first
crack and being the read/write
template repository, then master
directories and advance directories
get last crack. Also note that if you
have object files coming from more
than one location in your user
directory, the object file listed first
in the dependency list will be the
one whose path is inherited by the
repository.
Thus, in cases such as this, list
object files which reside in the
location where you want the
template repository first.
CXX_LINK -> (CXX,
CXXPPFLAGS, CXXTEMPLATES
CXXLDFLAGS)

Other Docs Search Page Known Problems


Understanding the Makefile System108 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
COPY_CXX_TEMPLATES CCS Rule Variable. A CCS which you should not have
to worry about. This is called from
with the make to copy all
instantiated templates into a
temporary repository which
ARCHIVE_CXX_LIB[NS]
recognize and archive into their
respective libraries. This command
works differently depending on the
context of the make.
Master Context:
In a master context, a temporary
directory is created. Then, the
read/write template directory’s
object files are copied into this
temporary directory and renamed
to Template1.o Template2.o and so
forth. When the
ARCHIVE_CXX_LIB[NS] CCS’s
are called, they will ensure that
these template instantiations are
archived into the library currently
being built.
User Context
In a user context, a temporary
directory is created. Then a list of
template instantiation object files
are created based on the user’s
read/write template repository, the
master template repository, and
advance template repository.
Duplicate names are thrown out
and the result is saved to a new list
named files.
COPY_CXX_TEMPLATES then
loops over each entry of this list
and prepends a user, master, or
advance path to this base filename.
The user path will be prepended if
the user templates directory
contains this object file.
(continued)

Other Docs Search Page Known Problems


Understanding the Makefile System109 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
COPY_CXX_TEMPLATES (continued) If it does not, the
(continued) master template directory is
scanned for it. If the master
contains this template object file,
the master template repository path
is prepended to the base object
filename. Otherwise, the advance
template repository path is
prepended to the base template
object file. Thus we ensure that we
have a singular list of template
object files in which the user’s
directory overrides the master,
which in turn overrides the
advance definitions. At this point,
the object files are copied into the
temporary template directory
under the names Template1.o
Template2.o etc... and are archived
into the user’s personal library as
described in the master context.

ARCHIVE_CXX_LIB CCS Rule Variable. A CCS which will archive a shared


version of a C++ library. On
automatic template instantiating
platforms, the template
instantiations created via
INSTANTIATE_CXX_\
TEMPLATES and
COPY_CXX_TEMPLATES will
also be archived into the shared
library.

ARCHIVE_CXX_LIBNS CCS Rule Variable. A CCS which will archive a


nonshared version of a C++ library.
On automatic template
instantiating platforms, the
template instantiations created via
INSTANTIATE_CXX_\
TEMPLATES and
COPY_CXX_TEMPLATES will
also be archived into the nonshared
library.

machtype Variable. A string identifying the current


platform.

[a|m|]sysdir Directory Variable. The top level of where the system


$path/sys. dependent files are kept.

Other Docs Search Page Known Problems


Understanding the Makefile System110 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
[a|m|]bindir Directory Variable. The directory where the system
$path/sys/bin/. dependent command line
executables are kept.

[a|m|]aexedir Directory Variable. The directory where the system


$path/sys/exe/. dependent executables are located.
These executables are generally
invoked via the
ProMAX/VSP/ProMAX3D\
/Prospector user interfaces.

[a|m|]libdir Directory Variable. The directory where the system


$path/sys/lib/. dependent libraries are kept.
[a|m|]objdir Directory Variable. The top level directory where the
$path/sys/obj/. object files are located.

[a|m|]objbindir Directory Variable. The directory where the object files


$path/sys/obj/bin/. for the system dependent
executables are located.
Executables in this directory are
generally invoked via the
command line, interactively by the
user.

[a|m|]objexedir Directory Variable. The directory where the system


$path/sys/obj/exe/. dependent object files (which
correspond to the executables in
[a|m|]exedir) are located.

[a|m|]objuidir Directory Variable. The directory where the object files


$path/sys/obj/ui/. corresponding to the for user
interface are located.

[a|m|]objlibdir Directory Variable. The directory where the object files


$path/sys/obj/lib/. corresponding to the various
libraries are located.

[a|m|]portdir Directory Variable. The top level directory of the port


$path/port/. hierarchy. Files under here are
considered to be portable.

[a|m|]incdir Directory Variable. The top level directory where the


$path/port/include/. include files are stored.

[a|m|]srcdir Directory Variable. The top level directory for all the
$path/port/src/. portable source code.

[a|m|]srcbindir Directory Variable. The directory where the portable


$path/port/src/bin/. source code corresponding to the
executables in [a|m|]bindir are
located.

Other Docs Search Page Known Problems


Understanding the Makefile System111 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
[a|m|]srcexedir Directory Variable. The directory where the portable
$path/port/src/exe/. source code corresponding to the
executables in [a|m|]exedir are
located.

[a|m|]srclibdir Directory Variable. The directory where the portable


$path/port/src/lib/. source code corresponding to the
libraries in [a|m|]libdir are located.

libmaxexec Library Variable. $path\ The library containing executive


/sys/lib/libmaxexec.a. ($path/sys/exe/exec.exe) support
functions.
libmaxtool1 Library Variable. $path\ The library containing some of the
/sys/lib/libmaxtool1.a. modules composing the executive.

libmaxtool2 Library Variable. $path\ The library containing some more


/sys/lib/libmaxtool2.a. of the modules composing the
executive.

libmaxtool3 Library Variable. $path\ The library containing the rest of


/sys/lib/libmaxtool3.a. the modules composing the
executive.

libmaxutil Library Variable. $path\ The library containing general


/sys/lib/libmaxutil.a. support routines.

libuiutils Library Variable. $path\ The library containing general


/sys/lib/lib/libuiutils.a. support routines used by the user
interface.

libmaxui Libary Variable. $path\ The library containing more


/sys/lib/lib/libmaxui.a. general support routines used by
the user interface.

libagfc Library Variable. $path\ The library containing the old cwp
/sys/lib/libagfc.a. routines used by the various
modules in the system.

libpar Library Variable. $path\ A library providing a mechanism


/sys/lib/libpar.a. for decoding command line
arguments.

libagX Library Variable. $path\ A library contains C++ graphics


/sys/lib/libagX.a. objects for OOP graphics design.

libagXi Library Variable. $path\ A library containing classes and


/sys/lib/libagXi.a. functions which are not quite ready
to be in libagX yet. libagXi is
internal to Landmark (denoted via
the suffix ‘i’).

Other Docs Search Page Known Problems


Understanding the Makefile System112 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
libagC Library Variable. $path\ A library containing base template
/sys/lib/libagC.a. as well as other objects used by the
agX graphics library.

libagCi Library Variable. A library containing routines and


$path/sys/lib/libagCi.a. classes which are not quite ready to
be placed in libagC.

libeispack Library Variable. $path\ A library containing Landmark’s


/sys/lib/libeispack.a. version of Lynn Kirlin’s eispack
library for K-L Transforms.

libGeom Library Variable. $path\ A library containing geometry


/sys/lib/libGeom.a. database routines.

libpagefile Library Variable. $path\ A library containing the file


/sys/lib/libpagefile.a. manipulation and access routines
used by the database.

libgeoquest Library Variable. $path\ A library containing Geoquest


/sys/lib/libgeoquest.a. routines used to interface with IES
on SunOS 4.1.x platforms.

libpvm Library Variable. $path\ A library containing Parallel


/sys/lib/libpvm.a. Virtual Machine routines used to
run certain jobs in parallel.

libXpm Library Variable. The color pixmap support library.

libpsplot Library Variable. The postscript plotting library.

libpp Library Variable. The library for creating a promax


path variable.

AGCLIBS Collection of Libraries. A list of advance libraries normally


linked with standalone
executables. AGCLIBS is a
convenience to Makefile writers.

MAXTOOLLIBS Collection of libraries. A list of maxtool libraries.


MAXTOOLLIBS is a convenience
to makefile writers.

libmaxtoolmake Makefile Variable. The location of the maxtool library


makefile.

libmaxutilmake Makefile Variable. The location of the maxutil library


makefile.

libmaxexecmake Makefile Variable. The location of the maxexec


library makefile.

libuiutilsmake Makefile Variable. The location of the uiutils library


makefile.

Other Docs Search Page Known Problems


Understanding the Makefile System113 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
libmaxuimake Makefile Variable. The location of the maxui library
makefile.

libagfcmake Makefile Variable. The location of the agfc library


makefile.

libagXmake Makefile Variable. The location of the agX graphics


library makefile.

libagXimake Makefile Variable. The location of the agXi library


makefile.
libagCmake Makefile Variable. The location of the agC library
makefile.

libeipackmake Makefile Variable. The location of the eispack library


makefile.

libGeommake Makefile Variable. The location of the Geom library


makefile.

libpagefilemake Makefile Variable. The location of the pagefile library


makefile.

libpvmmake Makefile Variable. The location of the pvm library


makefile.

libXpmmake Makefile Variable. The location of the Xpm library


makefile.

libpsplotmake Makefile Variable. The location of the psplot library


makefile.

libppmake Makefile Variable. The location of the pp library


makefile.

report Boolean Variable. A boolean “yes/no” value which


determines whether to report errors
in the make to a log file.

BACKUP CCS Variable. A routine which will backup the


target to a .bak file. This is
intended for use with
BACKUP_ON_ERROR.

BACKUP_ON_ERROR CCS Rule Variable. A routine which handles errors by


moving the backup back into the
original file (depends on BACKUP
and ERROR_HANDLER).

ERROR_HANDLER CCS Rule Variable. A routine which handles errors in


the make. Depending on how
report is set, it will log errors to a
file or simply report errors to the
screen.

Other Docs Search Page Known Problems


Understanding the Makefile System114 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
define_usrcs CCS Function Variable. A routine which will figure out
what the user source code actually
is. For a master make, it will be the
same value as $(srcs). For a user
make, it will look at $(srcs) and
then figure out which of those files
the user has and return that subset.
(Assumes that the user has set a
string srcs to contain a list of all
source code comprising the
executable or library.)

define_asrcs CCS Function Variable. A routine which will figure out


what the actual source code is. It
takes $(srcs) and replaces each file
in the $(srcs) list with the user
version, master version, or advance
version. If the user does not have
one of the files in his home
directory, the master directory is
scanned; if it does not exist there,
the advance version of the filename
is returned. For example, suppose
srcs = a.c b.f c.C and that a.c exists
in the master, advance and user
directory. Also suppose that b.f
exists in the master and advance
directories while c.C exists only in
the advance directory. A call
$(define_asrcs) will yield a string
$(path1)/a.c $(path2)/b.f
$(path3)/c.C where a.c points to
the user’s version, b.f to the master
version and c.C to the Landmark
version. (Assumes that the user has
set a string srcs to contain a list of
all source code comprising the
executable or library.)

define_uobjs CCS Function Variable. A routine, similar to the


define_usrcs routine, except that it
translates the directory to the
corresponding obj directory and
replaces the .c, .f or .C with .o.
(Assumes that the user has set a
string srcs to contain a list of all
source code comprising the
executable or library.)

Other Docs Search Page Known Problems


Understanding the Makefile System115 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
define_aobjs CCS Function Variable. A routine, similar to the
define_asrcs routine, except that it
translates the directory to the
corresponding obj directory and
replaces .c, .f, or .C with .o.
(Assumes that the user has set a
string srcs to contain a list of all
source code comprising the
executable or library.)

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.

AMAKEDEPEND_TO_STDOUT CCS Rule Variable. A rule, similar to the


AMAKEDEPEND rule, except
that the output is sent to standard
output. This is useful when you
have multiple targets but want to
append the depedency output to a
single file.

ANSIC_COMPILE CCS Rule Variable. A CCS which takes an ANSI C


source file in the dependency and
compiles it into an object file using
the ANSI C compiler defined in the
variable CC. It applies CPPFLAGS
as well as CFLAGS in the
compilation. If an error occurs,
ERROR_HANDLER is invoked.

KRC_COMPILE CCS Rule Variable. A CCS which takes a K&R C


source file in the dependency and
compiles it into an object file using
the K&R C compiler defined in the
variable KRCC. It applies
KRCPPFLAGS as well as
KRCFLAGS in the compilation. If
an error occurs,
ERROR_HANDLER is invoked.

Other Docs Search Page Known Problems


Understanding the Makefile System116 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
CXX_LINK Command Variable. This is a variable which invokes
the C++ compiler with
CXXLDFLAGS and
CXXPPFLAGS if your compiler
needs include paths in the link
phase as well. For compilers with
automatic template instantiation, it
will also set a template directory
corresponding to what is being
linked.

CXX_COMPILE CCS Rule Variable. A CCS which takes a C++ source


file in the dependency and
compiles it into an object file using
the C++ compiler defined in the
variable CXX. It applies
CXXPPFLAGS as well as
CXXFLAGS in the compilation. If
an error occurs,
ERROR_HANDLER is invoked.

F_COMPILE CCS Rule Variable. A rule which takes a Fortran 77


source file in the dependency and
compiles it into an object file using
the Fortran 77 compiler defined in
the variable FC. First, it
preprocesses the file into a *PP.f
file and then it compiles the PP.f
file. It applies FPPFLAGS, as well
as FFLAGS in the compilation. If
an error occurs,
ERROR_HANDLER is invoked.

YACC_COMPILE CCS Rule Variable. A CCS which takes a yacc source


file in the dependency and
translates it into C code, perhaps
with a header file yy.tab.h.
YACC_COMPILE applies
YFLAGS when yacc is applied. If
an error occurs,
ERROR_HANDLER is invoked.

LEX_COMPILE CCS Rule Variable. A CCS which takes a lex source


file in the dependency and
translates it into C code. If an error
occurs, ERROR_HANDLER is
invoked.

Other Docs Search Page Known Problems


Understanding the Makefile System117 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
AS_COMPILE CCS Rule Variable. A CCS which takes assembler
code and assembles it into an
object file. If an error occurs,
ERROR_HANDLER is invoked.

COPYFILE CCS Rule Variable. A CCS which takes a destination


file in the target and a source file in
the dependency. It then copies the
source file to the destination.

LINKFILE CCS Rule Variable. A CCS which takes a destination


link in the target and a source file
in the dependency. It then links the
destination link to the source file.

COPYLIB CCS Rule Variable. A CCS which takes a destination


library in the target and a source
library in the dependency. It then
copies the source library to the
destination library and ranlibs it.

ARCHIVE_REPLACE CCS Rule Variable. A CCS which takes a destination


library name in the target and a list
of object files in the dependency
list. It then performs an archive
replace of all the object files within
the target library. It then ranlibs the
library to update the SYMDEF
table. It applies the variable
ARCHIVE_REPLACE_FLAGS
when archive replacing.

ARCHIVE_CREATE CCS Rule Variable. A CCS which takes a destination


library name in the target and a list
of object files in the dependency
list. It first removes the old version
of the library, if it exists. It then
performs an archive create and
creates the target library. It them
ranlibs the library. It applies the
variable
ARCHIVE_CREATE_FLAGS
when archive creating.

MAKETARGETDIR CCS Rule Variable. A CCS which ensures that the


destination directory of the target
is present. If it is not present, then
MAKETARGETDIR will create
the directory.

Other Docs Search Page Known Problems


Understanding the Makefile System118 Developer’s Programming Guide

Makefile Variables (Continued)


Variable Type Explanation
UPDATE_[libname] CCS Rule Variables. These CCSs correspond to the
UPDATELIB[libname] rules. The
difference is that
UPDATE_[libname] rules are used
by other routines
(UPDATE_LIBRARIES) to
automatically generate updated
libraries. The only difference from
their UPDATELIB[libname]
counterparts is the name. The
UPDATELIB[libname] macros are
in the process of being phased out.

UPDATE_LIBRARIES CCS Rule Variable. This is a macro which will update a


series of libraries (assumed to be
defined in libs).

cleanlib Rule. This rule will clean the library in


the corresponding library directory.

cleanexe Rule. This rule will clean the


executable(s) in the corresponding
executable directory.

cleanobjs Rule. This rule will clean the object files


in the corresponding object
directory.

Makefile Techniques
The following tips illustrate how the makefile system can be
used to solve common problems.

Creating the executable in a non-standard place


Sometimes you may wish to install the target executable in a
nonstandard place such as your current directory. This is useful
if you wish to debug an executable in your current directory
instead of supplying the somewhat cumbersome pathnames
common to the ProMAX tree. To do this, simply supply the
variable exe which contains the path to the target executable
name.

gmake exe=./myexe

Other Docs Search Page Known Problems


Understanding the Makefile System119 Developer’s Programming Guide

Compile without updating libraries


For a faster compile/link, you may supply the ul=no option.
This option tells the make to assume that the libraries you are
linking with are up to date, foregoing the time consuming
time/date stamp check for each library. Do not use this option if
you are concerned that the libraries in question are in fact not up
to date. It is also useful if filesystem timestamps or missing
files are interfering with the gmake system.

gmake ul=no

Creating an exec.exe which does not contain the


C++ extensions
Linking via the C++ compiler is slower than using the C
compiler due to the complexity that goes into linking in C++. If
you do not need any of the C++ functionality in your
executives, you may use the clink:=yes option in conjunction
with the “utc” rule to create an executable which does not
contain any of the C++ stuff. The first time you create your C++
executive, you must supply the utc rule. The utc rule tells the
makefile to Update The Toolcall. A new toolcall is created
which does not contain any of the C++ functionality. Having
updated the toolcall, successive makes need only give the
clink:=yes option. When switching back to a C++ based
executive, you must again provide the utc rule to update the
toolcall to once again provide the C++ functionality.

gmake clink:=yes utc

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

This is how you switch back to a C++ based executive.

Adding a library to the link without changing the Makefile


You may wish to add a library to the link without changing the
link line in the Makefile. To do this, you may supply the

Other Docs Search Page Known Problems


Understanding the Makefile System120 Developer’s Programming Guide

SYSLIBS in the case of C linkage or SYSXXLIBS in the case


of C++ linkage. SYSLIBS and SYSXXLIBS enter the library in
question after the advance and X11 libraries and before the
system libraries. If you need the libraries to be inserted in a
different location, you will probably want to go into the
Makefile and edit the link. If not, XLIBS, CLIBS, CXXLIBS
and libs are also available.

gmake SYSLIBS:=”libfoo.so”
gmake SYSXXLIBS:=”libC++foo.so”

Debugging a make failure


Figuring out why your make is failing can be a painful
experience. These suggestions may help you debug your make
problems a bit faster.

gmake [options] -n >& file

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.

Edit the compile/linking options to include the -v option


for verbosity.

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.

You can add print statements to your makefile by doing


something like this:

foo := $(shell echo>&2 “My Variable = $(My_Var)”)

Debugging a failed link


A failure to link is one of the most common make failures. To
assist in figuring just why your link is failing, Landmark has
provided the Nmgrep utility. The Nmgrep tool is a fairly
comprehensive library analysis tool; you should not have to
worry about all its bells and whistles. Perl 5.0 must be installed
for this tool to function properly. A few example usages of this
tool follows. To get a comprehensive help listing on this tool,
type Nmgrep -h

To show DEFs and REFs in $PROMAX_HOME/sys/lib:

Other Docs Search Page Known Problems


Understanding the Makefile System121 Developer’s Programming Guide

Nmgrep

To show where any routines with trace in the name are


defined/referenced in $PROMAX_HOME/sys/lib.

Nmgrep trace

Using another compiler for this make only


You may wish to substitute the compiler temporarily for some
reason or another. CC, KRCC, CXX and FC correspond to the
default Ansi C, K&R C, C++ and Fortran compilers
respectively. Simply supply a definition for these to override the
default.

gmake CC=/usr/bin/cc
gmake CC=”/usr/bin/cc” CXX:=”/usr/bin/CC”

GNU compilers are only supported on Linux, and their output


object files and library dependencies on other platforms are
sometimes not compatible with the compilers and libraries
ProMAX uses.

Other Docs Search Page Known Problems


Understanding the Makefile System122 Developer’s Programming Guide

Other Docs Search Page Known Problems


123 Developer’s Programming Guide

Directory Structure

This chapter describes the organization of the ProMAX


directories and files.

Topics covered in this chapter:


➲ Directory Hierarchy
➲ Machine-dependent Directories
➲ Directory Naming Conventions
➲ Product-dependent Subdirectories
➲ Third-party Software
➲ Recompilation - GNU Make
➲ Makefile Rules
➲ Makefile Options
➲ User and Master Versions
➲ Master Versions for Clients

Other Docs Search Page Known Problems


Directory Hierarchy124 Developer’s Programming Guide

Directory Hierarchy

Everything we need to build our products, except for standard,


vendor-supplied software such as ANSI C include files, goes
under the single directory $PROMAX_HOME. For example, if
we need the latest X11R4 (or X11R5, ...) include files, and these
files are not supplied with all machine types we support, then
we put them in $PROMAX_HOME/port/include/X11/, instead
of /usr/local/include/X11/. Having everything under a single
directory makes it easier to find things during development and
maintenance, to build distribution tapes, and to save/recover
new/old releases of the software.

The next level of the hierarchy contains several directories


named after machine types, such as linux/. These directories
contain machine-dependent object code, libraries, and
executable programs. Software that does not depend on
machine type goes in port/. port/ contains everything necessary
to port our software to a new machine type.

The etc/ directory contains configuration files (such as the


ProMAX config_file) that may vary from machine to machine,
even when the machines are of the same type. A listing of some
of the more important, higher level directories of theProMAX
hierarchy follows. You may also refer to the Expanded
Directory Structure appendix.

$PROMAX_HOME

. linux/ (sys/ -> linux/ on Linux32-bit machines)

. linux64/ (sys/ -> linux64 / on Linux 64-bit machines)

. . bin/

. . exe/

. . lib/

. . obj/

. . . bin/

Other Docs Search Page Known Problems


Directory Hierarchy125 Developer’s Programming Guide

. . . exe/

. . . lib/

. . nodist/

. . . lib/

. port/

. . bin/

. . misc/

. . menu/

. . . promax/

. . . promaxvsp/

. . . promax3d/

. . . promax4d/

. . help/

. . . promax/

. . . promaxvsp/

. . . promax3d/

. . . promax4d/

. . man/

. . include/

. . src/

. . . bin/

. . . exe/

. . . lib/

Other Docs Search Page Known Problems


Directory Hierarchy126 Developer’s Programming Guide

. . nodist/

. . . include/

. etc/

Other Docs Search Page Known Problems


Machine-dependent Directories127 Developer’s Programming Guide

Machine-dependent Directories

Machine-dependent directories, such as linux/ and linux64/(for


Intel and AMD based Linux machines) are used for two
reasons:

1. They make it easy for programmers working in their own


version of the $PROMAX_HOME hierarchy to build and
test code on all platforms. The Makefile will put machine-
dependent files in the appropriate machine-dependent
subdirectories of a programmer’s home directory. The
Makefile rules determine machine type automatically, so
programmers rarely have to specify machine-dependent
directory names.

2. They provide a standard way for groups with a single large


file server to support multiple platforms. To provide a
uniform look across different machines, system
administrators might do the following:

mount igor:/promax/1998.6/linux/ /promax/1998.6/sys/


mount igor:/promax/1998.6/port/ /promax/1998.6/port/

on Linux machines that are NFS clients of a file server igor.


Then, users can add something like
/promax/1998.6/sys/bin/ to their PATH and forget about
machine-dependent directory names.

System administrators would not typically mount


igor:/promax/1998.6/etc/ remotely, because the
configuration files in /promax/1998.6/etc/ are likely to vary
from machine to machine.

Machine-dependent directories are named after the machine


type, not the vendor name.

Other Docs Search Page Known Problems


Directory Naming Conventions128 Developer’s Programming Guide

Directory Naming Conventions

Where possible, directory names are chosen to follow


UNIX/Linux conventions. In particular, the names bin/, etc/,
include/, lib/, and src/ are used for directories that contain files
that an experienced UNIX/Linux user would expect.

bin/ directories contain programs or shell scripts that are


launched by humans, such as the flow builder.
Machine-dependent programs go in machine-dependent
directories, such as $PROMAX_HOME/linux/bin/.
Machine-independent shell scripts go in
$PROMAX_HOME/port/bin/. Programs that are typically
executed by other programs, such as a ProMAX executive, go in
the exe/ directory and have names that mostly end in .exe.

Subdirectories beneath src/ correspond to the destination of the


compiled code. Thus, src/lib/ contains source code for the
libraries in lib/, src/exe/ contains the source for executables in
exe/, and so on. The source code for libmaxutil.so is in
src/lib/maxutil/. Likewise for other libraries. Every subdirectory
of src/lib/ contains a Makefile that is responsible for building
the corresponding library.

All .o files are built in machine-dependent obj/ directories, so


that source code can be compiled for all machine types
simultaneously. The hierarchy beneath obj/ is the same as that
for src/, and the default Makefile rules exploit this similarity.

Some of our subdirectories, such as misc/, menu/, and help/


have no UNIX/Linux counterparts, so their names are simply
chosen to reflect the contents of these directories. Directory
names contain only lower-case characters (except for CVS/
directories), simply to make them easier to type.

Other Docs Search Page Known Problems


Product-dependent Subdirectories129 Developer’s Programming Guide

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.

The lib/ directories contain shared libraries (.so archives) of .o


files that are used to build executables. The following table
describes some of the more important libraries.

Some Example Libraries


File Description

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.

libmaxui.so ProMAX user interface functions.

libagfc.so ProMAX library of sort routines, FFTs, interpolators, etc.

X11/libXaw.so Our customized and bug-free X Athena widget library.


X11/libXhp.so Our customized and bug-free X HP widget library.
Libraries developed at Landmark follow the UNIX naming convention of
beginning with lib and ending with .a for shared versions.

Other Docs Search Page Known Problems


Third-party Software130 Developer’s Programming Guide

Third-party Software

Third-party software requires special handling because third


parties are unlikely to organize their files in the same way that
Landmark does. Two or more vendors may choose the same
name for different files. Some vendors permit Landmark to
distribute their software and some do not. Today, no two sets of
third-party software can be handled in exactly the same way.

When a third party permits Landmark to distribute its software,


we simply install it in the usual place in the
$PROMAX_HOME hierarchy, except that we put it inside a
subdirectory that reflects the vendor’s name. An example is the
golden.so library from Golden Geophysical, which goes in
$PROMAX_HOME/sys/lib/golden/golden.so. We distribute
this library because Golden uses hooks into our licensing
system that force users of Golden’s software to obtain a license
from Golden. Another example of software that Landmark
distributes is SDI’s viewer (in
$PROMAX_HOME/sys/exe/sdi/sdi_view) for CGM metafiles,
which has its own security/licensing scheme.

All third-party software is installed (or symbolically linked) in


the $PROMAX_HOME directory tree with a unique directory
name corresponding to the vendor. For example, inside
$PROMAX_HOME/port/include/ are geoquest/ and sdi/
directories. These vendor-specific directories minimize file
name collisions. (Note that both geoquest/ and sdi/ have a
portable.h file.) Software that includes portable.h should do so
with #include geoquest/portable.h or #include sdi/portable.h,
depending on which portable.h is needed. In some cases both
may be included, so the vendor-specific directory name is
important. As always, full pathnames should not and need not
be specified in these #include statements.

Other Docs Search Page Known Problems


Recompilation - GNU Make131 Developer’s Programming Guide

Recompilation - GNU Make

Every executable or library has its own Makefile, which is


located in the directory containing its source code. For example,
the Makefile for sys/exe/exec.exe is located in
port/src/exe/exec/. Likewise, the Makefile for the library
sys/lib/libmaxutil.so is located in port/src/lib/maxutil/.

Landmark Makefiles must be used with the GNU make


program (which we call gmake)—they are incompatible with
the make program provided with most UNIX/Linux systems.
We use gmake primarily because it provides a powerful and
uniform set of features for all UNIX/Linux systems. The set of
make features provided by all UNIX/Linux systems is
inadequate for the management of software development
projects as complex as ours. The Free Software Foundation
supports and distributes GNU make with source code and
documentation that is lucid and complete. The GNU Make
Manual (Stallman and McGrath, 1991) is highly recommended.
In addition, a UNIX man page is located in
$PROMAX_HOME/port/man/man1/.

Other Docs Search Page Known Problems


Makefile Rules132 Developer’s Programming Guide

Makefile Rules

Each developer of a library or executable program must provide


a Makefile to build it on all machine types supported by
Landmark. Most programmers will never have to write a
Makefile from scratch because there are several examples in the
src/ directories. However, if you write or modify Makefiles, be
sure the Makefile does not reference anything outside of the
$PROMAX_HOME directory tree. This simple rule:

• facilitates system administration

• makes porting to new machines easier

• helps ensure that we distribute everything that clients need


for their own ProMAX development

Makefiles should reference only those libraries and include files


that are absolutely necessary to build whatever it is that they are
supposed to build. Makefiles should provide recipes for
building programs and/or libraries with no extra ingredients. If
programmers follow these rules, then it is easy to determine, for
example, which of our programs may be affected if a 3rd party
company modifies its libraries.

Writing Makefiles is simplified by the standard definitions and


rules contained in advance.make and other files stored in the
$PROMAX_HOME/port/include/make/ directory.
advance.make sets numerous variables for directory paths that
are used in Makefiles, among other things. In particular,
advance.make automatically determines the machine type and
sets variables for machine-dependent libraries, compilers, flags,
etc. Hardwired pathnames to libraries, include files, etc., should
not be specified in Makefiles.

Yet another useful file in


$PROMAX_HOME/port/include/make is machine_type.make,
where machine_type might be linux or linux64. This file sets
variables which are specific to that platform.

Other Docs Search Page Known Problems


Makefile Options133 Developer’s Programming Guide

Makefile Options

To make a program or library, just cd to the directory containing


the source code for the program or library, and type gmake.

All Makefiles that include advance.make provide two important


command line options. The first is for debugging. Typing
gmake debug=yes turns on debugging and turns off optimization.
The default is debug=no. Another useful command line option
for gmake is gmake clean, which deletes libraries and objects in
your personal directories, or gmake clearlibs, which only
deletes libraries.

Other supported options are purify=yes (Sun only), and


quantify=yes. purify=yes will try to run the commercial Purify
package on compiled code in order to find memory leaks.
quantify=yes will try to run the commercial Quantify package
on compiled code in order to profile the code. (This assumes
that Purify and/or Quantify are loaded on your system.) An
executable shell, $PROMAX_HOME/port/bin/Makeexec, is
provided to make it easy to build any variant of exec.exe. This
shell simply cd’s to the exec source directory and runs gmake
with the command line arguments provided to Makeexec. For
example, typing

Makeexec debug=yes

will build the ProMAX exec with debugging enabled.


Makeexec is most convenient after modifying a tool, such as in
lib/maxtool/agc/, although it can be used from within any
subdirectory of $PROMAX_HOME/port/src/.

Other Docs Search Page Known Problems


User and Master Versions134 Developer’s Programming Guide

User and Master Versions

The Makefiles have been designed to support simultaneous


development by a large number of programmers. Each
programmer should have his own version of the Master
$PROMAX_HOME directory tree in his home directory. For
example, /home/dave/$PROMAX_HOME would contain
Dave’s User version of $PROMAX_HOME. The actual
locations of the User and Master versions are set in
master.make.

The Makefiles behave differently depending on which version


(User or Master) is the current working directory when running
gmake. For example, if Barry types gmake in
$PROMAX_HOME/port/src/lib/maxtool/ (the Master
directory), then the Makefile will compile source code as
necessary to ensure that the libraries
$PROMAX_HOME/sys/lib/libmaxtool*.so are up-to-date.
However, if Dean types gmake in
/home/dean/$PROMAX_HOME/port/src/lib/maxtool/, then the
Makefile will update
/home/dean/$PROMAX_HOME/sys/lib/libmaxtoolc.so and
libtoolcall.so.This algorithm ensures that Dean always has the
latest tools that have been installed in the Master versions,
while enabling him to have his own User version for
development.

An important difference between User and Master versions of


$PROMAX_HOME is that a User version need not contain
everything that is in the Master version. Typically,
/home/larry/$PROMAX_HOME might contain subdirectories
for only those tools on which Larry is working, plus the
subdirectories necessary for his own version of exec.exe. When
Larry links his User versions of exec.exe, the exec Makefile will
ensure that any prerequisite libraries found in Larry’s
$PROMAX_HOME directory tree are up-to-date. Any
prerequisite libraries not found in Larry’s $PROMAX_HOME
tree will be obtained from the Master version of
$PROMAX_HOME, and the Master libraries will be assumed
(not ensured) to be up-to-date.

A general rule to remember in using the $PROMAX_HOME


Makefiles is that they will search for include files and libraries
in the User version and the Master version of
$PROMAX_HOME, in that order. If Christof has his own User

Other Docs Search Page Known Problems


User and Master Versions135 Developer’s Programming Guide

version of the include file cglobal.h, then that version will be


included when he makes something in
/home/stof/$PROMAX_HOME/port/src/. Otherwise, the
Master version of cglobal.h will be included. The search order
used by the Makefiles implies that Christof does not need a
copy of every include file or library in order to build his own
User versions of exec.exe, but that he can override the Master
versions as necessary during his development and testing.

Other Docs Search Page Known Problems


Master Versions for Landmark Clients136 Developer’s Programming Guide

Master Versions for Landmark Clients

Makefiles were designed to support development efforts by


Landmark clients, who themselves may have a large number of
programmers. A programmer at a client site must be able to
develop and test new ProMAX tools without changing anything
in the site’s own Master version of the $PROMAX_HOME
directory tree. Likewise, the ProMAX guru at a client site who
is in charge of the Master version should not change the
software distributed by Landmark. Therefore, to facilitate their
use by clients, the Makefiles actually support three different
versions of $PROMAX_HOME—User, Master, and Landmark.

By default, the Master version for clients is assumed to be the


Landmark version. This default will work well for clients with
no more than one or two programmers. However, clients with
more programmers will likely want the Master version to be
different from that provided by Landmark. These clients would
make their own top directory, such as
$PROMAX_HOME/client/, and then define the variable ctopdir
in advance.make. If ctopdir is defined, then it is assumed to be
the root directory of the client’s Master version of the software.

The client’s programmers would have their own User versions,


just like programmers at Landmark. A client programmer who
develops a new ProMAX tool could make it available to all
ProMAX users at the site by installing it in the Master directory
tree and remaking the Master versions of exec.exe.

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.

At Landmark, the variable ctopdir is left undefined, so that the


Master version is the Landmark version. You might say that
Landmark is its own client. Only programmers at Landmark
should modify the Landmark version of $PROMAX_HOME.

Reference:
Stallman, R. M., and McGrath, R., 1991. GNU Make: a
program for directing recompilation. Free Software Foundation.

Other Docs Search Page Known Problems


137 Developer’s Programming Guide

C Environment

This chapter introduces the ProMAX C programming


environment and highlights some of the conveniences within
that environment. (See the C Programmng Examples appendix
for examples of C include files and simple processes.)

Topics covered in this chapter:


➲ C Process Components (non-socket tools)
➲ C and FORTRAN Links
➲ Global Parameters

Other Docs Search Page Known Problems


C Process Components138 Developer’s Programming Guide

C Process Components

The components of a ProMAX process written in the C


programming language are as follows:

• 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 menu is written using Lisp commands.

The initialization routine is executed once. It is used to get user


input parameters, allocate any memory that is needed
throughout the process, and to do anything that you will need to
do just once in the course of the processing. It is also used to
declare the number of parameters that need to be saved for
re-entrancy.

Included files usually have an .h appended to their name, but


these included files do not generally contain parameters for
re-entrancy.

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.

Finally, the entry in the Processes list points to your menu.

Other Docs Search Page Known Problems


C and FORTRAN Links139 Developer’s Programming Guide

C and FORTRAN Links

The UNIX convention for linking C and FORTRAN


subroutines is demonstrated in the following examples.

Calling a FORTRAN Routine from a C Routine


The following syntax is used to call a FORTRAN routine from a
C routine. Suppose we have the following FORTRAN routine:

A_FORTRAN_ROUTINE( ALPHA, CNAME, NINT, ARRAY, CNAME2 )


REAL ALPHA, ARRAY()
INT NINT
CHARACTER CNAME, CNAME2

We call it from a C routine as follows:

float alpha, array[128];


int nint;
char cname[8], cname2[64];

a_fortran_routine_( &alpha, cname, &nint, array, cname2,


8, 64 );

Note that:

• The name is all lower case with an underscore appended to


the name.
• Only addresses are passed to FORTRAN (call by
reference).
• The length of the character strings are appended to the
calling arguments.

Calling a C Routine from a FORTRAN Routine


The following syntax would be used to call a C routine from a
FORTRAN routine. Suppose we have the following C routine:

a_c_routine_( float *alpha, char *cname, int *nint,\


float *array, char *cname2 );

We call it from a FORTRAN routine as follows:

CALL A_C_ROUTINE( ALPHA, CNAME, NINT, ARRAY, CNAME2 )

Other Docs Search Page Known Problems


C and FORTRAN Links140 Developer’s Programming Guide

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

init_name_( int *len_sav, int *itooltype )

and the execution routine must be called

exec_name_( float *trace, float *rthdr, int *ithdr )

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.

Other Docs Search Page Known Problems


Global Parameters141 Developer’s Programming Guide

Global Parameters

The cglobal.h file (listed in the C Programming Examples


appendix) provides the facilities for accessing the ProMAX
external global common blocks using C structures. In
FORTRAN, common blocks are stored in a format similar to
structures in C. For example, using cglobal.h, the C variable

globalRuntime->samprat

corresponds to the FORTRAN variable SAMPRATz of the


GLOBAL_RUNTIMEcz common block. Other global variables
follow the same style of using the common block name as the
structure name and the same variable name in lower case
without the trailing z.

The FORTRAN constants, IENGLISHpz, are identical in C,


keeping the upper case but with the trailing pz dropped
(IENGLISH). For a complete listing of the C external global
variable names and constants, see the Global Parameters
chapter.

Trace Header Index Values


Array index values in C start with 0 while array index values in
FORTRAN typically start with 1. The ProMAX trace header
routines for the C programming language always use the C
standard of 0 being the index of the first element in a trace
header array.

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.

Other Docs Search Page Known Problems


Global Parameters142 Developer’s Programming Guide

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);

This block is placed outside of the init and exec subroutine


blocks.

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;

The *len_sav calling argument for init_name_( ) can be


conveniently set as follows:

*len_sav = NPARMS(parms);

The syntax of BEGINPARMS, ENDPARMS, and NPARMS are


macros defined as follows:

#define BEGINPARMS static struct{


#define ENDPARMS(p) } *(p)=(void *)
(&saved_parms_.buffer[1] );
#define NPARMS(p) (2+sizeof(*p)/sizeof(float));

Other Docs Search Page Known Problems


143 Developer’s Programming Guide

Tool Types

ProMAX supports three main types of tools: executive,


stand-alone, and IPC. This chapter provides an overview of
these types.

Topics covered in this chapter:


➲ Executive Tools
➲ Simple Tools
➲ Ensemble Tools
➲ Panel Tools
➲ Single Buffer Tools
➲ Double Buffer Tools
➲ Complex Tools
➲ Stand-alone Tools
➲ IPC Tools

Other Docs Search Page Known Problems


Executive Tools144 Developer’s Programming Guide

Executive Tools

The Executive supports six varieties of tools: simple, ensemble,


panel, single buffer, double buffer, and complex (with the input
tool being special case of the complex tool). Each of these tool
types is designed to expedite the coding of typical trace
handling situations that arise in seismic processing. The
Executive attempts to do as much as possible to simplify data
management and the development environment (see the
Executive chapter).

Each of the Executive tools require a subroutine known as the


init phase and another subroutine known as the exec phase. The
name of an init or exec subroutine is dictated by ProMAX. The
name of the init routine is the tool name preceded by INIT_.
The name of the exec phase is the tool name preceded by
EXEC_. The Executive uses the tool name found in the
exec_data portion of each menu in the flow (see the Menu
chapter) pre-pended with init or exec to call the appropriate
tool.

The following sections describe the purpose and general


structure of the init and exec subroutines, and the mechanism by
which processing parameters are passed between the routines.

The buffered tools (single and double buffered tools) also


require a subroutine called the flow routine, which is discussed
later in the buffered tools sections.

init Subroutine
The init routines are responsible for:

• getting menu parameters from the packet flow file and


saving them in the common block (FORTRAN) or in
external parameters (C) for use in the exec subroutine

• doing one time calculations, such as calculating and saving


a filter for application in the exec phase. The filter’s
location in memory, not the filter itself, would be saved in
the common block defined in the include file

Other Docs Search Page Known Problems


Executive Tools145 Developer’s Programming Guide

• 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.

• creating or deleting new header or database entries and


resetting any global runtime variables

• checking parameters, memory and disk usage


requirements, etc. and erroring out if necessary

In short, the init subroutine does things that need to be done just
once during the execution of a particular processing tool.

The final and important responsibility of the init subroutine is to


set the values of the init subroutine return arguments called
LEN_SAV and ITOOLTYPE. The LEN_SAV parameter is the
number of memory words allocated to keep re-entrant
parameters and variables. ITOOLTYPE is a integer variable
indicating the tool type. The tool types are defined in the global
parameter include files global.inc for FORTRAN and cglobal.h
for C. Both of these variables must be set prior to exiting the init
routine.

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).

SUBROUTINE INIT_AMP_RATIO( LEN_SAV, ITOOLTYPE )

In the C programming language the function definition is

void init_amp_ratio( int* len_sav, int* itooltype )

parms Structure and .inc File


As discussed above, the init subroutine retrieves processing
parameters from the menu. The processing parameters are
passed from the init to the exec subroutines by way of a
common block called SAVED_PARMS in FORTRAN and
through an external structure called parms in C processes. The
SAVED_PARMS common block and parms structure must be
used so that the trace executive can save the processing

Other Docs Search Page Known Problems


Executive Tools146 Developer’s Programming Guide

parameters for each instance of a tool in a flow. This allows a


tool to be used more than once in a flow while saving the
parameters for each occurrence of the tool. For example, the
band-pass filter module could be used twice in one flow, but
since there is only one subroutine for band-pass filter, the
parameters for each occurrence of the routine in the flow must
be kept separate and loaded into the routine when that
occurrence is called by the trace executive. The ability to use a
routine more than once in a flow is called re-entrancy.

In a FORTRAN module, the SAVED_PARMS common block


is a standard common block. In C, the parms structure is created
through use of the BEGINPARMS and ENDPARMS macros
which are defined in
$PROMAX_HOME/port/include/cglobal.h, where
$PROMAX_HOME is the directory path where the ProMAX
system is installed. An example of the SAVED_PARMS
common block and its use can be seen in the .inc files in the
directory $PROMAX_HOME/port/src/lib/maxtool/amp_ratio.
An example of the parms structure and its use can be seen in the
.c files in $PROMAX_HOME/port/src/lib/maxtool/ampRatio.

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.

A feature common to all exec tools is the cleanup condition.


After the last trace has passed through a tool in the flow (the rest
of the flow may have been executing for some time), the
Executive will call that routine one more time with the global
runtime ICLEANUPz set to true(=1). In C this value is in
globalRuntime->cleanup. This gives the tool an opportunity to
release any allocated memory, flush buffers of data, etc., and
signals the Executive not to call this portion of the flow again.

Other Docs Search Page Known Problems


Executive Tools147 Developer’s Programming Guide

Be careful to return from the routine immediately after these


tasks and not continue on in the routine. For all tool types,
except complex and buffer tools, the Executive automatically
handles the last trace condition.

The complete calling argument list for an exec subroutine is


dependent upon the type of the processing tool (COMPLEX,
SIMPLE, etc). There are some common features to the
argument lists however. In all exec subroutines the calling
arguments include a buffer to hold a data trace array, a trace
header array for integer array values and another trace header
array for floating point trace header values. Note that the real
and floating point header arrays are actually equivalent
locations in memory. The subroutine definition for amp_ratio in
both FORTRAN and C is as follows:

SUBROUTINE EXEC_AMP_RATIO( TRACE, ITHDR, RTHDR )

void exec_amp_ratio( float* trace, int* ithdr, float*


rthdr )

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 amp_ratio example module makes an approximate first


break pick by finding the maximum of the ratio of a pair of
adjacent sliding time windows. After making the pick, the user
optionally stores the results in the trace headers and TRC
Ordered Database. The program also demonstrates the use of
interpolated time gates to limit the pick search range. This
example can be found in the Simple Tool Examples appendix.

Before leaving the init phase of amp_ratio, or any simple tool,


ITOOLTYPE must be set to ISIMPLEpz.

Other Docs Search Page Known Problems


Executive Tools148 Developer’s Programming Guide

The exec phase routine for the Amp Ratio simple tool has the
following calling arguments:

SUBROUTINE EXEC_AMP_RATIO( TRACE, ITHDR, RTHDR )

TRACE is a buffer containing a single input or output trace


array (NUMSMPz long; see the Global Parameters chapter).
The Executive passes in a trace and returns the processed trace
(in TRACE buffer) to the flow for subsequent processing upon
exiting. ITHDR and RTHDR are fixed and floating point
equivalenced trace header arrays (NTHz long; see the Global
Parameters chapter) which are passed in and out with the
corresponding trace.

The ampRatio example in C has the same arguments of course,


but trace, ithdr, and rthdr are all pointers to arrays.

void exec_amp_ratio_(float *trace, int *ithdr, float


*rthdr)

Simple tools require little additional discussion except for


runtime variables. Consider the case of resampling the data
from 2 ms to 4 ms. Both the number of samples per trace and
the sample rate are changing from that point in the flow down.
Remember from the Executive chapter that a separate copy of
the runtime variables will be kept for each tool in the flow. The
last tool’s copy was given to you at the initiation of your init
phase; you must change these as needed before exiting. The
next tool in the flow will inherit your changes. With each call of
your exec phase, the globals will have the new, updated
versions; therefore, if you need some of the old values, you
must store them as new variables in the common block. In this
example, the runtime variables NUMSMPz (number of
samples/trace) and SAMPRATz will change. Specifically
consider that NUMSMPz will be about half the size after
processing by the tool. So what is the dimension of the TRACE
array passed to the exec phase or the tool? The Executive will
take care of you and set it to the larger of the incoming or
outgoing value. In this example, NUMSMPz may be set at
1001, but incoming trace buffer would be filled with 2001
samples in order to handle the incoming trace. This sort of hand
holding can be expected of the Executive even in more complex
situations described later.

Other Docs Search Page Known Problems


Executive Tools149 Developer’s Programming Guide

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.

Refer to the Ensemble Tool Examples appendix for examples of


an ensemble tool. The AVO attribute analysis creates either a
zero offset or gradient stack of incoming ensembles, and
provides an example of fewer traces in the output ensemble than
the input. In the prestack trace interpolation example, more
traces are output than were input.

Before leaving the init phase of an ensemble tool, ITOOLTYPE


must be set to IENSEMBLEpz in FORTRAN or IENSEMBLE
in a module written in C.

The exec phase of a FORTRAN ensemble tool has the


following calling arguments:

SUBROUTINE EXEC_AVO( TRACES, ITHDRS, RTHDRS, NSTORED )

and for C the exec arguments look like this:

void exec_avo_( float *traces, int* ithdrs, float


*rthdrs,\ int *nStored )

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

REAL TRACES( NUMSMPz, MAXDTRz)

and the headers as

REAL RTHDRS( NTHz, MAXDTRz)

INTEGER ITHDRS( NTHz, MAXDTRz )

where MAXDTRz is the maximum number of traces that the


tool is going to see in any trace ensemble in the flow.
MAXDTRz is one of the global variables and its value is

Other Docs Search Page Known Problems


Executive Tools150 Developer’s Programming Guide

maintained by the Trace Executive. NTHz is the number of


trace header entries in the trace header array.

Most C programmers find it convenient to allocate an array of


(float*) of length globalRuntime->maxdtr (same value as in the
MAXDTRz discussed above) and point the beginning of each
data trace to a place in the array. The trace header arrays are
handled in a similar way. The ProMAX routine fVecTo2d() is
written to make this task easy.

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

Other Docs Search Page Known Problems


Executive Tools151 Developer’s Programming Guide

sufficient room in memory to hold the entire 2D dataset at one


time. Post-stack migration and FK filter of large stacked
sections are two examples. With a panel approach, the dataset
can be divided into pieces that can be comfortably processed by
the system and then appropriately blended back together.

Panel tools attempt to collect a set number of traces to process


in each call of the exec routine. The exec subroutine processes
the 2D array that has been passed to it and passes the array back
out. The trace executive blends the processed array back
together with the adjacent panels that have been processed in a
like manner. The following figure depicts a stacked section; the
dashed vertical lines represent data traces, and the solid vertical
lines represent the panel of traces from within the section that is
being processed. The traces at the edge of the panel are summed
with the traces at the edge of the previous panel to provide
continuity from panel to panel in the processed section.

A panel of traces within a stacked section

Panel tools can panel through a large ensemble as well as a


through a stacked section. If an ensemble is found to be smaller
than the panel size, the panel exec will process the ensemble as
an ensemble tool would, without paneling or blending the traces
back together. An exception to this is the special case in which
an ensemble size is equal to one trace, since this typically
represents stack data. Panel tools are generally written in such a
way that the panel size is larger than a typical shot ensemble.

Other Docs Search Page Known Problems


Executive Tools152 Developer’s Programming Guide

They will process shots (and small to moderate stack datasets)


like an ensemble tool, but will still panel for large stack datasets
or anomalously large ensembles (common offset sort).

In a panel tool, the programmer codes simply for a matrix of


traces. The Executive handles the buffering of traces and the
overlap blending automatically. The only special coding
required is for a panel that has fewer than the expected number
of traces. When you reach the end of a dataset or a large
ensemble there will usually be insufficient traces to complete
the panel. You can not anticipate when this will happen and
must be ready to deal with it for any panel.

Before leaving the init phase of a panel tool, ITOOLTYPE must


be set to IPANELpz in a FORTRAN module or to IPANEL in a
C module. Another routine that must be called in the init
subroutine of a panel tool is EX_PANEL_PARMS in
FORTRAN or exPanelParms in C. The arguments
EX_PANEL_PARMS and exPanelParms notify the trace
executive of panel size, overlap, and the number of traces to mix
between sequential panels. It also tells the trace executive how
much padding is required. The panel width, overlap, and mixing
are demonstrated by the example illustrated in the figure below.
The symbol “O” in the figure is used to indicate a trace that is
output after the panel is processed. An “X” indicates a trace that
is discarded after the panel is processed. An “M” indicates a
trace that is mixed with a trace from a previous panel and then
passed on in the trace pipeline for further processing. The
variable PANEL_SIZE is the number of traces in the panel.
PANEL_EDGE is the number of traces on either end of the
panel that will be either discarded or mixed after the panel is
processed. The variable PANEL_MIX is the number of traces at
either end of the panel that will be mixed with adjacent panels.

Other Docs Search Page Known Problems


Executive Tools153 Developer’s Programming Guide

Adjacent panels in the figure are represented by rows of “X”,


“M”, and “O” characters.

A. NPANEL_SIZE=12, NPANEL_EDGE =3, NPANEL_MIX=0

OOOOOOOOOXXX
XXXOOOOOOXXX
XXXOOOOOOOOO

B. NPANEL_SIZE=12, NPANEL_EDGE =3, NPANEL_MIX=1

OOOOOOOOOMXX
XX MOOOOOOMXX
XXMOOOOOOOOO

C. NPANEL_SIZE=12, NPANEL_EDGE =3, NPANEL_MIX=3

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:

SUBROUTINE EXEC_PANEL_TEST( TRACES, ITHDRS, RTHDRS,


NSTORED )

for FORTRAN and

void exec_panel_test( float* traces, int* ithdrs,


float*\ rthdrs, int* nstored )

for C.

The NSTORED argument passes the number of traces found in


the current panel. NSTORED will be equal to the panel size in
traces specified in the init phase, except when the last trace in
the panel is at the end of a datasets or is at the end of an
ensemble that was not large enough to fill out the panel.

Other Docs Search Page Known Problems


Executive Tools154 Developer’s Programming Guide

Panel tools offer padding in both time and space. This is to


facilitate such things as in place FFT’s without the allocation of
additional memory. When using time padding, the traces that
are input to the exec subroutine are of length NUMSMPz + time
pad length. The executive provides the traces in a buffer that is
long enough to hold the padded trace, then shortens the trace on
output to NUMSMPz for subsequent processes. The value of
NUMSMPz remains set to the number of samples that will be
output from the tool after the panel tool is finished processing.
Therefore, NUMSMPz is always less than or equal to the
padded trace length. When padding traces are used, the padded
traces occur at the trailing edge of the 2D array containing the
data traces. In other words, the first trace in the input array is a
valid, live trace. There are NSTORED live traces in the array.
These live traces are followed in the array by the number of
padding traces that were specified in the init subroutine.

The padded regions always contain zero amplitudes; a padded


2D array input to the exec subroutine of a panel tool looks like
the following figure in which the dark shaded region represents
the original data and the light shaded region represents the
padded region of zero values.

Other Docs Search Page Known Problems


Executive Tools155 Developer’s Programming Guide

traces

Original live data traces


Trace
Padding

time

Time padding

A padded 2D array

In FORTRAN programs it is vital to dimension the input trace


array to the exec routine as being NUMSMPz + the number of
padding samples. Therefore, the number of padding samples
must be sent to the exec routine from the init routine through
the SAVED_PARMS common block. Panel modules written in
C must also handle the extra trace length. See the example
programs in both C and FORTRAN in the panel test sections of
the Panel Tool Examples appendix.

Single Buffer Tools


Unlike ensemble tools that stop at ensemble groups or panel
tools that stop at a fixed number of traces, single buffer tools
stop collecting traces at some custom condition set by the
programmer. For example, you may write a tool that needs five
CDP ensembles in memory to implement some enhancement
process to the center CDP. This center CDP will be output, and
the next CDP ensemble will be read with the last four shuffled
down in memory; in other words, you will create a sliding
window of ensembles containing 5 CDP except at the dataset
boundaries. Generally, the condition to stop collecting and start

Other Docs Search Page Known Problems


Executive Tools156 Developer’s Programming Guide

processing in the exec routine will be dependent on some trace


header condition, such as last trace in fifth CDP gather. For
ensemble tools, this check is simply for the END_ENS flag set
to 1, and is done automatically by the Executive.

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).

Refer to the Single Buffer Tool Examples appendix for an


exercise example of a single buffer tool. This example process
resets ensemble flags whenever a selected header changes. The
traces are accumulated in a buffer until this condition is met.

The calling arguments for the flow routine are:

SUBROUTINE FLOW_ENS_DEFINE( TRACES, ITHDRS, RTHDRS,


NSTORED,
& IFOUND_EOJ, NOUTPUT, NOVERLAP )

Input arguments
Input arguments consist of:

TRACES: the 2D array of input accumulated traces


ITHDRS: the 2D array of trace accumulated headers
equivalenced to RTHDRS
NSTORED: number of traces currently stored in TRACES
IFOUND_EOJ: flag to indicate if the EOJ trace has been
encountered (1=true). Since you are accumulating traces,
you may hit the end of the dataset prior to reaching your

Other Docs Search Page Known Problems


Executive Tools157 Developer’s Programming Guide

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:

SUBROUTINE EXEC_ENS_DEFINE( TRACES, ITHDRS, RTHDRS,


NTR_BUFF )

and the following argument in C:

void exec_ens_define( float* traces, int* ithdrs, float*


rthdrs, int* ntr_buff )

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.

Like ensemble tools, the number output can be larger (or


smaller) than the number accumulated. This could get tricky
with trace overlapping. Remember that NSTORED minus
NOVERLAP traces will be dropped from the first portion of the

Other Docs Search Page Known Problems


Executive Tools158 Developer’s Programming Guide

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


Double buffer tools are identical to single buffer tools in all
aspects except one: the exec phase has extra buffers that are
managed by the Trace Executive to store the output traces and
headers. This allows the programmer to fill the output buffer
without changing the buffer of input traces. In other words, the
Executive handles the allocating and de-allocating of one extra
work buffer. This type of automatic buffering is particularly
convenient for transforming data from one form to another; for
example, in generating a semblance plot from an input CDP or
in interpolating traces within an ensemble.

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

SUBROUTINE EXEC_SEMBLANCE( TRACES_IN, ITHDRS_IN,


RTHDRS_IN,
& NTR_BUFF_IN, TRACES_OUT, ITHDRS_OUT,
RTHDRS_OUT,
& NTR_BUFF_OUT )

where TRACES_IN, ITHDRS_IN, and RTHDRS_IN are the


input buffers for the traces and trace headers. NTR_BUFF_IN is
the amount of buffer space, measured in numbers of traces, in
the input buffer. TRACES_OUT, ITHDRS_OUT and
RTHDRS_OUT are the output buffers of traces and headers.
NTR_BUFF_OUT is the number of traces available in the
output buffer measured in numbers of traces.

Please refer to the Double Buffer Tool Examples appendix for


an example of how to use a double buffer tool.

Other Docs Search Page Known Problems


Executive Tools159 Developer’s Programming Guide

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.

Please refer to the Complex Tool Examples appendix for an


exercise example of a complex tool. This example process
transforms a shot ensemble so that the time axis is replaced by
the space axis. In other words, the shot is turned on its side.

Before leaving the init phase of a complex tool, ITOOLTYPE


must be set to ICOMPLEXpz in FORTRAN and ICOMPLEX
in a module written in C. The exec phase calling arguments of
complex tools is identical to simple tools:

SUBROUTINE EXEC_TRANSFORM( TRACE, ITHDR, RTHDR )

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

Other Docs Search Page Known Problems


Executive Tools160 Developer’s Programming Guide

tool). The exec phase of complex tools must declare their state
prior to exiting the routine. The options are described in the
following table:

Complex Tool Options


Option Description

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.

Other Docs Search Page Known Problems


Executive Tools161 Developer’s Programming Guide

Complex Tool Options (Continued)


Option Description
PUSH Set by a call to EX_PUSHMODE. Push mode behaves exactly like pipe mode except for the
important difference that the EOJ trace is input to the tool. Recall that when a tool is in pipe
mode, the Executive does not pass the EOJ flag to the tool. The ability to see the EOJ flag
allows the tool to flush traces that may be stored in a buffer internal to the routine. If a tool has
more traces to flush after the EOJ flag has been found, it goes into flush mode until all of the
traces have been dumped into the processing flow, at which point the tool sets itself to pipe
mode to trip the cleanup flag. The general logic is as in the following pseudo-code for the exec
subroutine.
if( trace header has end of job flag (EOJ) )
set a saved variable that indicates the EOJ trace has
been seen
have_seen_EOJ_flag = TRUE
endif

if( have_seen_EOJ_flag is TRUE )


move trace and header from buffer to output trace
if( the trace being dumped is the last to dump )
set to pipe mode to trigger cleanup mode on next call
else
set to flush mode to continue outputting traces
endif
else
set to push mode, output this trace, accept the next
input trace on next call
endif

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.

An input tool is a type of complex tools; by default, it is the first


tool in a processing flow. An input tool gets data and feeds it
into a processing flow. Examples include those which read data
from a disk or tape or a program that generates synthetic
seismograms. An input tool starts and remains in flush mode
until the last available trace is given to the flow. When the tool is
called again and it finds that it has no more trace to output, the

Other Docs Search Page Known Problems


Executive Tools162 Developer’s Programming Guide

mode is set to quit mode. Refer to the Input Tool Examples


appendix for an example.

Another complex tool type is the iteration tool. Disk iteration


means to have ProMAX read a group of data traces more than
once from the disk. This facility is useful when all calculations
on an entire dataset must be done before results of calculations
can be applied. Examples include derive-and-apply processes
that must see all the data to first derive surface consistent
parameters (amplitude, decon, statics, etc.) and then pass
through the data again for an application phase. Refer to the
Disk Iteration Examples appendix for a crude example of
surface consistent amplitude correction. The data must pass
through the flow above the iteration tool two or more times, but
this is usually a small price to pay. There are even some
advantages: the first pass can optionally be enhanced (mixed,
FK filter strong low frequency noise, etc.) for the derive phase,
but not enhanced in the application phase. These tools have
virtually eliminated the need for stand-alone tools that handle
data traces.

Other Docs Search Page Known Problems


Stand-alone Tools163 Developer’s Programming Guide

Stand-alone Tools

There are certain situations to which the pipeline model of trace


flow is not well suited. Modules that need to randomly access
traces off the disk many times are such examples. In these cases
a stand-alone tool that does its own trace I/O may be the answer.
(Executive multiple iteration tools have largely eliminated the
need for stand-alone tools that handle data traces. Refer to the
preceeding discussion in the Complex Tools section of this
chapter.)

ProMAX supports stand-alone executables for data input only.


These executables are launched by the Super Executive just as
the Executive. However, the menu for a stand-alone tool must
supply the executable name in a special section in the exec_data
portion of the menu. The tool is declared a stand-alone type to
the super exec in the same section. The TOOLTYPE and
PATHNAME parameters pass on this information to the super
exec, for example:

exec_data: (“STAND_ALONE”
(“SPECIAL”
(“TOOLTYPE” implicit: “STAND_ALONE”)
(“PATHNAME” implicit: “poststack.exe”)
)
(“GENERAL”
(“LABEL” implicit: (value ’LABEL))
)
)

Stand-alone flows can contain only one executable and one


menu associated with that executable. Please examine the
stand-alone menus in the Stand-alone Program Examples
appendix.

Stand-alone programs must handle much of what is done


automatically in the Executive, including:

• input of the packet file and special routines for parameter


retrieval
• initialization of global geometry and runtime variables
• trace input and selection

Please refer to the prestack.f code in the Stand-alone Program


Examples appendix for detailed comments on each of these
items.

Other Docs Search Page Known Problems


Stand-alone Tools164 Developer’s Programming Guide

For FORTRAN modules, a C wrapper main must be written to


pass the command line arguments containing the packet file
name to the FORTRAN work routine. The wrapper for the
prestack example looks like:

void main( argc, argv )


int argc;
char **argv;
{
prestack_( &argc, argv[1] );
}

Compiling and linking stand-alone modules are somewhat


different than for the Executive subroutines; the compiling of
the C wrapper for FORTRAN processes is one specific
example.

Other Docs Search Page Known Problems


IPC Tools165 Developer’s Programming Guide

IPC Tools

IPC tools are a relatively new way of programming a ProMAX


process. We recommend this approach to people for starting to
program in ProMAX. If you are an experienced ProMAX
programmer, note that IPC tools used to be called socket 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.

The main advantages of this method of incorporating modules


into ProMAX are:

• The executable size is smaller and links are much faster


and simpler.

• The issue of re-entrancy is avoided—each program has its


own address space.

• The logic of a complex tool is simplified. When an IPC


tool needs traces, it calls the subroutines stGetTrace,
stGetEnsemble, or stGetPanel for C, and
ST_GET_TRACE or ST_GET_ENSEMBLE for
FORTRAN (panel I/O is not supported in FORTRAN).
Whenever it wants to write traces, it calls the subroutines
saPutTrace, saPutEnsemble, or saPutPanel for C, and
ST_PUT_TRACE or ST_PUT_ENSEMBLE for
FORTRAN.

• The toolcall source code does not have to be edited.

• An Alternative Executive does not have to be run for a new


module.

These characteristics mean that it is easy to maintain IPC tools.


You can update individual programs as needed. The compile
and link problems of some other modules does not effect your

Other Docs Search Page Known Problems


IPC Tools166 Developer’s Programming Guide

module. IPC tools are also easy to trade since you do not need
to trade the entire executive.

On the downside, the IPC tool is less efficient that a normal


tool because of the overhead of data transfer; however, this
overhead is generally very small. And, at present, IPC tools can
only run on the same machine as the executive.

The best approach for understanding IPC tools is to examine the


example programs in the IPC Tool Examples appendix. The
comments in the code describe the steps. The user does not have
to alter the Executive or toolcall source code. The proper subset
of the packet file from the menu is transferred to the the IPC
tool. You can have repeated instances of the same IPC tool in a
flow. And, the IPC tool can access the data base and use other
ProMAX features, just as any normal stand alone program can.
Note, however, that all header routines must be preceded with
an “st” for C (stHdrAdd instead of hdrADD) and “ST_” for
FORTRAN (ST_HDR_ADD instead of HDR_ADD). The same
is true for the Executive error routines.

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.

IPC Tool Details


The IPC tool approach is implemented with master
init_stand_alone and exec_stand_alone routines that are
complex tools in the Executive. The packet file passes the path
of the IPC tool executable to init_stand_alone, which executes
it, hooks up sockets with it, passes it the proper subset of packet
files, and handles such items as passing global parameters and
headers. After a signal from the IPC tool, the init_stand_alone
routine returns and the exec_stand_alone starts. The
exec_stand_alone passes the traces via sockets to the IPC tool.
As a complex tool, it can read and write traces as the IPC tool
demands them. On the IPC tool end, we have written routines
that hide the IPC communication from the user.

The performance degradation using this IPC-based method is


not significant. The overhead to initiate and transfer data to an
IPC tool is comparable to running in-line Automatic Gain
Control (AGC). Since AGC is a computationally cheap module
(one or two operations per sample), the communication time

Other Docs Search Page Known Problems


IPC Tools167 Developer’s Programming Guide

may not be significant. The transfer time to a process that is


running on a different machine from the rest of the flow is
greater, but not unmanageable. The cost of the transfer will be
less when the stand-alone process performs more computations,
since traces are sent and buffered on the receiving machine
while the module is computing. When the process needs the
traces, they are immediately available for access.

IPC Tool Debugging


To debug a IPC based tool, pass the DEBUG parameter in the
menu a value of 2 or 3. In a normal, no debug execution, this
value should be set to either 0 or 1 (1 = verbose listing of IPC
information).

When DEBUG is set to 2, the Executive will not start up the


IPC tool. You just start it, probably under dbx or gdb. The
Executive will print out the name of the packet file in /tmp that
you must execute with your program (see the View button in the
user interface). The command in dbx is:

(gdb) run /tmp/pFile_287657

where /tmp/pFile_287657 is the name of the packet file printed


by the Executive. Then, continue debugging your program as
you normally would.

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.

Other Docs Search Page Known Problems


IPC Tools168 Developer’s Programming Guide

Other Docs Search Page Known Problems


169 Developer’s Programming Guide

Global Parameters

This chapter describes ProMAX global parameters.

Topics covered in this chapter:


➲ Overview of Global Parameters
➲ Common Blocks and C Structure Descriptions

Other Docs Search Page Known Problems


Overview of Global Parameters170 Developer’s Programming Guide

Overview of Global Parameters

ProMAX global parameters are dataset-specific values that are


commonly needed within a processing tool. These values are
made conveniently available through the cglobal.h file for C and
the global.inc file for FORTRAN. (See the Global Include File
Examples appendix for examples of global.inc and global.h
files.)

An example of a global parameter is the number of samples per


trace, which can be accessed through the variable name
NUMSMPz in FORTRAN and the structure member
globalRuntime->numsmp.

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.

Other Docs Search Page Known Problems


Common Blocks and C Structure Descriptions171 Developer’s Programming Guide

Common Blocks and C Structure Descriptions

The following table describes the common blocks and C


structure names and how they are initialized. The names of the
common block members are listed in some cases; the name of
the corresponding C member parameter is obtained by dropping
the trailing z on the name and changing all upper case letters to
lower case. For example, the number of samples per trace in the
FORTRAN GLOBAL_RUNTIMEcz common block is
NUMSMPz. The analogous name in the globalRuntime
structure is numsmp.

Common Blocks and C Structure Names


Item Description

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

Other Docs Search Page Known Problems


Common Blocks and C Structure Descriptions172 Developer’s Programming Guide

Common Blocks and C Structure Names (Continued)


Item Description
GLOBAL_GEOMcz (FORTRAN) These are the critical global parameters related to geometry
globalGeom (C) and are stored in the line order 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_MISCcz (FORTRAN) These are the miscellaneous global parameters related to


globalMisc (C) geometry and are 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_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.

Other Docs Search Page Known Problems


173 Developer’s Programming Guide

Ordered Parameter Files

This chapter describes the ProMAX database, which consists of


a set of ordered parameter files that are used to store
information. See the Ordered Parameter File Examples
appendix for code examples.

Topics covered in this chapter:


➲ Overview of the ProMAX Database
➲ Standard Orders

Other Docs Search Page Known Problems


Overview of the ProMAX Database174 Developer’s Programming Guide

Overview of the ProMAX Database

The ProMAX Database consists of a set of ordered parameter


files used to store information for each seismic line in structured
categories representing unique sets of information. There are
nine standard Orders that are created when the geometry is
loaded:

• 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)

Information stored in these Ordered Parameter Files is


considered common to all datasets in the line (or survey)
directory level. Information that is dataset dependent should be
stored in trace headers. See the discussion in the Trace Headers
chapter.

In each Order there are N slots available for storage of


information, where N is the number of elements in the Order
(number of sources, number of surface locations, number of
CDPs, etc.). Each slot contains various parameters (in various
formats) for one particular element of the Order. If values for a
particular parameter are not stored in all of the available slots,
the empty slots contain the proper null value for that parameter.

The following figure shows a sketch of an ordered parameter


file. The order has N elements (columns) and five parameters

Other Docs Search Page Known Problems


Overview of the ProMAX Database175 Developer’s Programming Guide

(rows). Values would be stored in each of the boxes


(intersection of a row and column).

ORDER ELEMENTS

1 2 3 4 5 .... .... N

PARM 1

PARM 2

PARM 3

PARM 4

PARM 5

An ordered parameter file with


N elements and 5 parameters

Collectively, the Ordered Parameter Files are used to store large


classes of data, including the acquisition parameters, the
geometry, statics (and other surface-consistent information),
and pointers between the source, receiver, and CDP domains.
The design of the Orders is tailored for seismic data and
provides a compact format without duplication of information.
Of particular interest to programmers is the cross-referencing
between domains, which reduces the book-keeping in programs
such as residual statics.

The ordered parameter files serve four main purposes:

• They serve as a geometry database to Executive tools,


stand-alone processes, and to the flow builder. Menu
parameters can be defaulted to parameters in the line (LIN)
Order; examples include minimum CDP number or
nominal CDP spacing. Surface consistent processing
modules can access these files to determine buffer sizes
and surface relation of shots and receivers, etc.

Other Docs Search Page Known Problems


Overview of the ProMAX Database176 Developer’s Programming Guide

• They provide general inter-tool communication of


information that is global to all datasets in the line or
survey; first break or residual statics picks are typical
examples. In ProMAX, in-line tools make these time picks
and place the picks in the trace Order. Another in-line or
stand-alone tool reduces these picks to shot and receiver
statics that are stored, respectively, as parameters in the
SIN and SRF Orders. Once in the database, these final shot
and receiver static parameters can be applied to any of the
line’s datasets. As with trace headers, user defined Ordered
parameters can be of any length or format.

• They allow domain mapping between the CDP, SIN, SRF


and TRC Orders. When geometry is installed, these
domains are cross-referenced for fast access. Two
convenience routines exist that utilize this
cross-referencing: DB_ENSEMBLE_MAP and
DB_TRACE_MAP. For example, when using
DB_ENSEMBLE_MAP, from a particular CDP, the
routine can return the receiver static of the nearest station
or the uphole time of the nearest shot. The analogous
routines in C are dbEnsembleMap and dbTraceMap.

• They provide quick sorting of traces off disk. Each trace


dataset has a mapping file which maps the relative position
of each trace on disk to the original geometry trace number.
For each of the common ensemble sorts (CDP, shot,
receiver, offset bin, 3D inline, and 3D crossline), a row in
the TRC Ordered Parameter file serves as a look-up table
containing these original trace numbers sorted by the
associated ensemble. A corresponding starting address
look-up row (SLOOKUP) in each of the ensemble Order
files points to the start of each ensemble group in the
corresponding TRC look-up row. For example, assume you
want to read CDP 437 off a disk dataset of unknown sort
order. Disk Data Input will use the column associated with
CDP 437 in the CDP Order to determine the CDP fold—
we will use 30 for this example—and the starting position
(SLOOKUP) in the TRC look-up row for CDP—we will
use 4201. At position 4201 in the CDP look-up row of the
TRC Order is the original trace number for the first trace in
CDP 437, and the next consecutive 29 positions contain the
remaining trace numbers for CDP 437. From this set of
trace numbers, the dataset map file can be used to directly

Other Docs Search Page Known Problems


Overview of the ProMAX Database177 Developer’s Programming Guide

determine the disk positions of the CDP traces. This


appears complicated, but it suffices to say that Orders
facilitate quick sorts of data from disk.

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.

Other Docs Search Page Known Problems


Standard Orders178 Developer’s Programming Guide

Standard Orders

The following table describes the nine 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.

Other Docs Search Page Known Problems


Standard Orders179 Developer’s Programming Guide

Standard Orders (Continued)


Order Description
SIN Order The SIN Order contains information that is unique to each source, such as:
Geometry:
NCHANS - Number of channels in each source
X_COORD - X coordinate of every source
Y_COORD - Y coordinate of every source
ELEV - Elevation of every source
SRF - Nearest surface location number of every source
SOURCE - Live source number of every source
PATTERN - Pattern number of every source
PATT_REF - Pattern reference surface location of every source
DEPTH - Hole depth of every source
UPHOLE - Uphole time of every source
SLOOKUP - Starting address in SIN look-up table for every source
User parameters:
Source statics
Etc.
Source index numbers are unique sequential numbers that are assigned to all of the
records that exist in the dataset that is used to initialize the database. They include
records that are not live sources. Live sources are therefore a subset of shot index
numbers and not a suitable order.

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.

Other Docs Search Page Known Problems


Standard Orders180 Developer’s Programming Guide

Standard Orders (Continued)


Order Description
CDP Order The CDP Order contains information that is unique to each CDP bin, such as:
Geometry:
FOLD - Fold of every CDP
X_COORD - X coordinate of every CDP
Y_COORD - Y coordinate of every CDP
ELEV - Elevation of every CDP
SRF - Nearest surface location to every CDP
SLOOKUP - Starting address in CDP look-up table for every CDP
Plus user parameters:
CDP statics
Etc.
ILN Order The ILN Order contains information that is unique to each ILN bin, such as:
Geometry:
FOLD - Fold of every ILN
SLOOKUP - Starting address in ILN look-up table for every ILN

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.

Other Docs Search Page Known Problems


181 Developer’s Programming Guide

Trace Headers

This chapter describes trace headers, the primary form of


inter-tool communication within the ProMAX system.

Topics covered in this chapter:


➲ Overview of Trace Headers
➲ Definition and Usage of Standard Header Entries

Other Docs Search Page Known Problems


Overview of Trace Headers182 Developer’s Programming Guide

Overview of Trace Headers

Trace headers are the primary form of inter-tool communication


within the ProMAX system. They are typically used to
communicate information which is unique to individual traces
of the current dataset.. Global variables, another form of inter-
tool communication, are typically used to communicate
information that is shared by all traces of the current dataset.
The Ordered Database, a third form of inter-tool
communication, is typically used to communicate information
that is global to all datasets within the line (unless the datasets
are flagged as not matching the Ordered Database).
Convenience is a governing factor in the form of
communication that is used. For example, geometry
information that is placed in the parameter database can be
conveniently accessed by stand-alone programs that do not wish
to read trace data.

Trace headers within ProMAX are very flexible. Individual


entries may have any length, order, or format. This has proven
to be a tremendous benefit in accommodating new ideas as the
system evolves. (We prefer to use the term trace header entry
rather than trace header word to avoid the notion of fixed
length.)

The concept of an ensemble within the Executive is facilitated


by trace headers. An ensemble is defined as any collection of
traces which (normally) share the same primary sort key value.
Typical examples are shot records, CDP gathers, and common-
receiver gathers. All of the traces within an ensemble have the
header entry END_ENS set to false (NLASTpz in FORTRAN
and NLAST in C), except the last trace, where it is set to true
(LASTTRpz in FORTRAN and LASTTR in C). The global
variable MAXDTRz (maxdtr in C) is the maximum number of
traces per ensemble, which must be greater than the number of
contiguous traces that have END_ENS set to NLASTpz, or else
the trace executive will stop the flow with an error.

You may be surprised to learn that when a flow is initially


executed, nothing exists in the trace header. All trace header
entries are created one-at-a-time during initialization phase by
calls to the routine HDR_ADD (hdrAdd in C) or
HDR_STD_ADD (hdrAddStd in C). This is done primarily by
the input tool, which has special responsibility for creating all
of the header entries that existed when a dataset was written out

Other Docs Search Page Known Problems


Overview of Trace Headers183 Developer’s Programming Guide

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.

For convenience, the trace header is presented in the calling


arguments of the execution routine of every tool in both integer
AND real format to avoid the need for juggling the formats of
common trace header entries (the integer and real array are
equivalent within the toolcall routine and therefore occupy the
same memory).

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.

For programmers to communicate via trace headers, there must


be some agreement on what the names and definitions of
headers are. A standard list can be found in the file
$PROMAX_PORT_MISC/header.list. It is important to note
that this is not the list of headers that WILL exist during any
given flow, it is just a list of what certain headers will look like
if they DO exist. It is also important to remind yourself that the
order of the headers may be different between any two flows
and has nothing to do with the order that they appear in
header.list. The strict definition and use of all of the standard
header entries is presented in at the end of this chapter.

There is a subset of the standard trace header entries known as


the guaranteed headers that are always guaranteed to exist in a

Other Docs Search Page Known Problems


Overview of Trace Headers184 Developer’s Programming Guide

flow (although their positions may vary). The names,


descriptions, and initial values of these headers are as follows:

Guaranteed Headers
Name Description Initial Values

SEQNO Sequence number in ensemble. (variable)

END_ENS End-of-ensemble flag. (variable)


EOJ End-of-job flag. (variable)

TRACENO Trace number in seismic line. (INULLpz)

TRC_TYPE Trace type (data, aux, etc.). (ILIVEpz)


TLIVE_S Start time of live samples. (0.0)

TFULL_S Start time of full samples. (0.0)

TFULL_E End time of full samples. (end of trace)

TLIVE_E End time of live samples. (end of trace)

LEN_SURG Length of surgical mute taper. (0.0)

TOT_STAT Total static for this trace. (0.0)

NA_STAT Portion of static not applied. (0.0)

AMP_NORM Amplitude normalization factor. (1.0)

TR_FOLD Current trace fold. (1.0)

SKEWSTAT Multiplex skew static correction. (0.0)

LINE_NO Line number (hashed line name)*. (hashed line name)

LSEG_END Line segment end*. (NLASTpz)

LSEG_SEQ Line segment sequence number*. (1)

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.

In most cases, tools call HDR_NAMINFO (hdrIndex in C)


simply to find out where a standard header entry can be found

Other Docs Search Page Known Problems


Overview of Trace Headers185 Developer’s Programming Guide

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:

#define STDHDR(x) ( (stdHdr->x)-1)

in which “x” is a member of the StdHdr structure defined in


cglobal.h, such as icdp.

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.

Other Docs Search Page Known Problems


Definition and Usage of Standard Header Entries186 Developer’s Programming Guide

Definition and Usage of Standard Header Entries

Header entries adhere to the following general rules:

• All standard header entries are one word in length.

• Some header entries should not be modified by the user


(except indirectly); they contain an asterisk in the
description. Think of these as read-only.

• All times are in milliseconds.

• All elevations are relative to sea level and should be


negative for headers such as the source elevation in marine
shooting.

• It is the convention within ProMAX that a negative static


shifts data up (towards time 0.0), and a positive static shifts
data down (away from time 0.0).

• Other standard header entries may be added in future


releases. For a more complete list of header values used by
ProMAX see the file
$PROMAX_HOME/port/misc/header.list.

• For a list of valid variable names that can be used within


functions like STDHDR(x), see
$PROMAX_HOME/port/include/(cglobal.h and
header.inc)

Alphabetical Reference of Trace Header Entries


The following table lists all currently defined standard trace
header entries. Each entry is followed by its sequential number
as listed in the Sequential Reference.

Standard Trace Header Entries


AMP_NORM (12) FB_PICK (71) OFFSET (45) SOU_H2OD (41)

AOFFSET (46) FFID (18) PR_STAT (68) SOU_SLOC (28)

AVO_ATTR (79) FK_WAVEL (81) PS_STAT (69) SOU_STAT (65)

RCDP (22) FK_WAVEN (80) REC_DEP (52) SOU_X (35)

CDP( 21) FNL_STAT (62) REC_ELEV (34) SOU_Y (36)

Other Docs Search Page Known Problems


Definition and Usage of Standard Header Entries187 Developer’s Programming Guide

Standard Trace Header Entries (Continued)


CDP_ELEV (44) FRN_TRNO (7) REC_H2OD (40) SG_CDP (23)
CDP_NFLD (24) FT_FREQ (82) REC_NFLD (30) SR_AZIM (53)

CDP_SLOC (31) GEO_COMP (49) REC_SLOC (25) TFULL_E (75)

CDP_X (42) ILINE_NO (54) REC_STAT (64) TFULL_S (74)

CDP_Y (43) PAD_TRC (78) REC_X (32) TLIVE_E (76)


CHAN (19) LEN_SURG (77) REC_Y (33) TLIVE_S (73)

CR_STAT (67) LINE_NO (6) REPEAT (5) TOT_STAT (60)

CS_STAT (66) LSEG_END (8) SEQNO (2) TRACENO (4)


DEPTH (38) LSEG_SEQ (9) SEQ_DISK (16) TRC_TYPE (11)

DISKITER (14) NA_STAT (58) SIN (10) TRIMSTAT (70)

DMOOFF (83) NCHANS (20) SKEWSTAT (63) TR_FOLD (13)

DS_SEQNO (15) NMO_STAT (61) SOURCE (17) UPHOLE (39)

END_ENS (1) OFB_CNTR (48) SOU_COMP (50) XLINE_NO (56)

EOJ (3) OFB_NO (47) SOU_ELEV (37) SLC_TIME (84)

S_LINE (27) RILINE_N (55) RXLINE_N (57) R_LINE (26)

N_DATUM (59) FRN_TRNO (7) SRF_SLOC (29) WB_TIME (72)

ANG_VALU (88) CDP_XD (89) CDP_YD (90) REC_XD (91)

REC_YD (92) SOU_XD (93) SOU_YD (94) TZERO (87)

Other Docs Search Page Known Problems


Definition and Usage of Standard Header Entries188 Developer’s Programming Guide

Sequential Reference of Trace Header Entries


The tables on the following pages provide detailed descriptions
of the trace header entries in sequential order. The first table
describes system-related headers.

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.

2 SEQNO Sequence number in integer The sequence number of an individual trace


ensemble within the current ensemble.

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.

4 TRACENO Trace number in integer An internal reference number that is


seismic line* assigned by the system when the database is
initialized. It represents the unique
sequential trace number within the dataset
that is used to initialize the database.
TRACENO is undefined (and set to
INULLpz) after stack. The value of
TRACENO in the headers can be used to
reference the TRC ordered parameter file in
the parameter database if the global variable
ITRNO_VALIDz is true (=1).

Other Docs Search Page Known Problems


Definition and Usage of Standard Header Entries189 Developer’s Programming Guide

System-Related Headers (Continued)


# Header Name Type Description
5 REPEAT REPEATED data integer Set by the Reproduce Traces processing
copy number directive to reflect the copy number when
ensembles or all data is repeated.
(Subsequent processing frequently keys on
the REPEAT copy number for purposes of
comparison.) The Reproduce Traces
directive creates and sets the header
REPEAT_T when traces are repeated on an
individual basis.

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.

Other Docs Search Page Known Problems


Definition and Usage of Standard Header Entries190 Developer’s Programming Guide

System-Related Headers (Continued)


# Header Name Type Description
10 SIN Source index number integer An internal reference number that is
(internal)* assigned by the system when the database is
initialized. It represents the unique
sequential source number (including test
records, bad shots, etc.) within the dataset
that is used to initialize the database. The
value of SIN in the headers can be used to
reference the SIN ordered parameter file in
the parameter database if the global variable
IGEOM_MATCHz is true (=1).

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).

12 AMP_NORM Amplitude real Defined as the average amplitude


normalization factor normalization that has been applied to a
trace. For example, if a time-variant gain
increased the amplitude of each sample of a
trace by an average factor of 2.0, then it
should also multiply the value of
AMP_NORM by 2.0.

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.

The following table describes input-related headers.

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.

Other Docs Search Page Known Problems


Definition and Usage of Standard Header Entries191 Developer’s Programming Guide

Input-Related Headers (Continued)


# Header Name Type Description
15 DS_SEQNO Input dataset integer If Disk Data Input or Tape Data Input are
sequence number* reading multiple datasets, DS_SEQNO
reflects from which dataset a trace was
originally read.

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.

The following table describes geometry-related headers.

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.

Other Docs Search Page Known Problems


Definition and Usage of Standard Header Entries192 Developer’s Programming Guide

Geometry-Related Headers (Continued)


# Header Name Type Description
21 CDP CDP bin number integer Also known as the CMP, this is assigned by
whatever method the user chooses to do
binning. Note that the increment between
CDP numbers is allowed to be greater than
one. CDP numbers can be used to reference
the CDP ordered parameter file in the
parameter database if the global variable
IGEOM_MATCHz is true (=1).

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.

25 REC_SLOC Receiver index integer An internal reference number that is


number (internal)* assigned when the database is initialized. It
represents the unique sequential receiver
number within the dataset that is used to
initialize the database. The value of
REC_SLOC in the headers can be used to
reference the SRF ordered parameter file in
the parameter database if the global variable
IGEOM_MATCHz is true (=1).

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.

Other Docs Search Page Known Problems


Definition and Usage of Standard Header Entries193 Developer’s Programming Guide

Geometry-Related Headers (Continued)


# Header Name Type Description
32 REC_X Receiver X real Always the actual coordinates, not the
coordinate receiver surfloc coordinates (if they are not
coincident, as in the case of marine 3D). All
coordinates are relative to reference
coordinates in the parameter database
(XREFz and YREFz).

33 REC_Y Receiver Y real See discussion of coordinates under


coordinate REC_X.

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).

36 SOU_Y Source Y coordinate real See discussion of coordinates under


SOU_X.

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).

Other Docs Search Page Known Problems


Definition and Usage of Standard Header Entries194 Developer’s Programming Guide

Geometry-Related Headers (Continued)


# Header Name Type Description
42 CDP_X X coordinate of CDP real The bin center (not the center of mass of the
contributing traces). All coordinates are
relative to reference coordinates in the
parameter database (XREFz and YREFz).

43 CDP_Y Y coordinate of CDP real See discussion of CDP_X.

44 CDP_ELEV Elevation of CDP real Elevations of CDPs are problematic because


they are not specified and may be difficult to
interpolate. Historically, the elevation of
each CDP was taken as the elevation of the
nearest surfloc. The elevations of CDPs are
interpolated from the elevations of surflocs.
45 OFFSET Signed source- real The separation between source and receiver
receiver offset for a given trace. If the source is at a lower
surfloc than the receiver then the offset is
positive, otherwise the offset is negative (the
convention is the same for 3D, although the
sign of OFFSET has little meaning).

46 AOFFSET Absolute value of real Literally abs(OFFSET). AOFFSET is a


offset convenience for users for specifying
parameters in some situations.

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.

Other Docs Search Page Known Problems


Definition and Usage of Standard Header Entries195 Developer’s Programming Guide

The following table describes special geometry-related headers


for VSP/Crosshole, 3D, and multi-component recording.

Special Geometry-Related Headers


# Header Name Type Description

49 GEO_COMP Geophone integer For multi-component recording,


component (x,y,z) GEO_COMP is set to 1 for the vertical
component of motion, 2 for the east-west
(or inline for 3D) component of motion, and
3 for the north-south (or crossline for 3D)
component of motion.

50 SOU_COMP Source component integer For multi-component shooting,


(x,y,z) SOU_COMP is set to 1 for the vertical
component of motion, 2 for the east-west
(or inline for 3D) component of motion, and
3 for the north-south (or crossline for 3D)
component of motion.

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.

53 SR_AZIM Source to receiver real In 3D surveys, SR_AZIM is defined as the


azimuth azimuth FROM the source to the receiver,
clockwise, where 0.0 is north (or the Y axis
of the survey coordinate system). The units
are radians.

54 ILINE_NO 3D inline number integer In 3D surveys, ILINE_NO is defined as the


number of the common inline to which a
trace belongs, where inlines and crosslines
are defined by the CDP binning, but the
inline direction is the direction of source
motion (if applicable). For example, in a
marine 3D survey, a single sail line with a
single streamer would tend to produce a set
of traces with a common INLINE_NO but
varying XLINE_NO.

55 RILINE_N Real/alias 3D inline real The floating point version of ILINE_NO for
number use typically with parameter table routines.

56 XLINE_NO 3D crossline number integer In 3D surveys, XLINE_NO is defined as the


number of the common crossline to which a
trace belongs. See the discussion of
ILINE_NO.

57 RXLINE_N Real/alias 3D real The floating point version of XLINE_NO


crossline number for use typically with parameter table
routines.

Other Docs Search Page Known Problems


Definition and Usage of Standard Header Entries196 Developer’s Programming Guide

The following table describes statics-related headers.

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.

64 REC_STAT Total static for real The portion of TOT_STAT that is


receiver attributed to the receiver (from elevation
statics).

65 SOU_STAT Total static for source real The total portion of TOT_STAT that is
attributed to the source (from elevation
statics).

Other Docs Search Page Known Problems


Definition and Usage of Standard Header Entries197 Developer’s Programming Guide

Statics-Related Headers (Continued)


# Header Name Type Description
66 CS_STAT Corr. autostatics real The source static that was computed by a
source static correlation autostatics program. It exists
for convenience during parameterization
of the process that applies autostatics
solutions to the data. CS_STAT was
dropped for Releases 5.0+ (see
AS_STAT).

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.

Other Docs Search Page Known Problems


Definition and Usage of Standard Header Entries198 Developer’s Programming Guide

The following table describes mute-related headers.

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.

Other Docs Search Page Known Problems


Definition and Usage of Standard Header Entries199 Developer’s Programming Guide

The following table describes special applications-related


headers.

Special Applications-Related Headers


# Header Name Type Description

79 AVO_ATTR AVO Attribute integer The value of this number indicates the
number particular computes AVO attribute, like
slope or gradient.

80 FK_WAVEN Wavenumber of F-K real The common wavenumber of a series of


domain trace amplitudes (a trace) after transformation to
the F-K domain.
81 FK_WAVEL Wavelength of F-K real The common wavelength of a series of
domain trace amplitudes (a trace) after transformation to
the F-K domain.

82 FT_FREQ Frequency of F-T real The common frequency of a series of


domain trace amplitudes (a trace) after conversion to the
F-T domain.

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.

The following table describes non-standard headers.

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.

Other Docs Search Page Known Problems


Definition and Usage of Standard Header Entries200 Developer’s Programming Guide

The following table describes newly added headers.

Newly Added Headers


# Header Name Type Description

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.

88 ANG_VALU AVO Angle of real When generating AVO angle gathers or


incidence stacks, the value of this trace header
represents a particular AVO angle.

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).

90 CDP_YD Y coordinate of CDP real*8 See discussion of CDP_XD.


(double)

91 REC_XD X coordinate of real*8 Always the actual coordinates, not the


receiver (double) receiver surfloc coordinates (if they are not
coincident, as in the case of marine 3D). All
coordinates are relative to reference
coordinates in the parameter database
(XREFz and YREFz).

92 REC_YD Y coordinate of real*8 See discussion of coordinates under


receiver (double) REC_XD.

93 SOU_XD X coordinate of real*8 Always the actual coordinates, not the


source (double) coordinates of the nearest surfloc. All
coordinates are relative to reference
coordinates in the parameter database
(XREFz and YREFz).
94 SOU_YD Y coordinate of real*8 See discussion of coordinates under
receiver (double) SOU_XD.

Other Docs Search Page Known Problems


201 Developer’s Programming Guide

Parameter Tables

This chapter describes ProMAX parameter tables.

Topics covered in this chapter:


➲ Overview of Parameter Tables
➲ Structure of ProMAX Tables
➲ Table Rules
➲ Table Interpolation
➲ X Values in Tables
➲ Table Extrapolation
➲ Table Subroutine Categories
➲ Examples of Table Routines

Other Docs Search Page Known Problems


Overview of Parameter Tables202 Developer’s Programming Guide

Overview of Parameter Tables

ProMAX parameter tables are useful for storing and


interpolating parameters, such as velocity functions, time
windows, mutes, etc. The general philosophy behind ProMAX
tables is that parameters, such as first break mute times, are
stored on disk and retrieved into memory when they are needed.
Interpolation of the parameters can then be done as needed by
the ProMAX parameter interpolation routines. For example,
suppose a ProMAX user picks mute times on a set of shot
records. Those mute times will be stored in a ProMAX table on
disk. When the user wants to apply those mutes, the mute times
are read into memory and traces for which no mute times were
specifically picked will be interpolated by the ProMAX
interpolation routines. The application of the routines is, of
course, under the control of the programmer.

Structure of ProMAX Tables


A ProMAX table is a framework for storing information at a
location within a 3-dimensional volume. The following figure
shows a 3-dimensional volume with axes X1, X2, and Y. A
black dot marked P is a location at which information can be
stored.

X1

X2

A three dimensional volume with point P


where data can be stored

Other Docs Search Page Known Problems


Overview of Parameter Tables203 Developer’s Programming Guide

A consistent terminology is used to describe locations within


ProMAX tables. As in the previous figure, a location within the
table is described in terms of the X1, X2, and Y axes. Data
stored at a point within the table is referred to as a Z value.
Therefore, a ProMAX table is a description of Z(X1, X2, Y).
In fact, any number of Z values can be stored at an X1, X2, Y
location, so this description might be more accurately be written
as Z[ ](X1,X2, Y), where the “[ ]” indicates that a vector of Z
values can be stored.

An example use of a ProMAX table would be in the storage of


NMO functions for a 3D seismic survey. Suppose that NMO
functions had been picked for several CDP bin locations in the
survey, as in the following figure. These functions could be
stored in a ProMAX table using the X1, X2 coordinates to
describe the spatial location of the CDP bins, the Y axis to
describe the times at which velocities had been picked, and the
Z values to describe the velocity at each picked time. In this
case there would only be one Z value at each (X1, X2, Y)
location.

X1

Surface locations of
CDP bins
X2

Marks a time at which a velocity is stored

Velocity functions stored at CDP bin locations in a table

Other Docs Search Page Known Problems


Overview of Parameter Tables204 Developer’s Programming Guide

Table Rules
Some important rules about the structure of tables are as
follows:.

• The number of X1, X2 locations in a table can vary from


table to table and can also be changed within a table (points
can be added and deleted).

• There can be any number of Y locations at any X1, X2


location.

• The number of Z values stored at X1, X2, Y locations is


fixed for a table.

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?”

Other Docs Search Page Known Problems


Overview of Parameter Tables205 Developer’s Programming Guide

X1

P(X1p, X2p)

X2

Points scattered in the X1, X2 plane of a ProMAX table

The answer to this question in ProMAX tables begins by


dividing the X1, X2 plane into a set of triangles, as shown in the
following figure.

The triangles used to divide the X1, X2 plane are called


Delaunay triangles, which is a unique set of triangles for a
given set of points that comes as close as possible to making all
of the triangles equilateral. The Delaunay triangles method tries
to avoid creating long skinny triangles because they make
interpolation inaccurate.

Other Docs Search Page Known Problems


Overview of Parameter Tables206 Developer’s Programming Guide

X1

X2

Delaunay triangles divide the X1, X2 plane


of a ProMAX table

Suppose that interpolation is needed for a Z value at coordinates


(X1p, X2p, Y). The table interpolation routines first determine
which triangle contains P. The following figure shows the point
P in the X1, X2 plane along with the triangle that contains P.
The vertices of the triangle in the figure are A, B, and C, and
have X1, X2 coordinates (X1a,X2a), (X1b, X2b), and
(X1c, X2c), respectively. The Y axis extends downward from
the X1-X2 plane.

The next step in the interpolation of Z(X1p, X2p, Y) is to


linearly interpolate values of Z(X1a, X2a, Y), Z(X1b, X2b, Y),
and Z(X1c, X2c, Y) along the Y axis of the respective points of
A, B, and C. Points of known Z(X1, X2, Y) are shown as dark
circles in the figure and interpolated points are shown as open
circles.

Other Docs Search Page Known Problems


Overview of Parameter Tables207 Developer’s Programming Guide

X1
B

X2
P
A C

(X1a, X2a, Y)

Interpolated Z(X1, X2, Y )


Known Z(X1, X2, Y)

Interpolation of Z(X1, X2, Y) along the Y axis from the


triangle vertices A, B, and C

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.

Other Docs Search Page Known Problems


Overview of Parameter Tables208 Developer’s Programming Guide

X1
B

X2
P
A C

(X1a, X2a, Z)

Interpolated (X1, X2, Z)


Vertex of triangle

Interpolation of (X1p, X2p, Z) from nearby points

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.

When there is a 1-to-1 mapping between ensemble number and


spatial coordinates, ProMAX table information can be referred
to by either ensemble number or by the X1, X2 coordinates. For
example, interpolation of parameters can be done with the
subroutine tblInterpXY using just the ensemble number, which
is referred to as X in the calling arguments. The interpolation

Other Docs Search Page Known Problems


Overview of Parameter Tables209 Developer’s Programming Guide

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.

Precision of Key Values


Beginning with the Linux-only release of ProMAX/SeisSpace
2003.19.1 the structure of parameter tables has changed
slightly. The primary table key is now a 64-bit (double) floating
point number but the secondary key remains a 32-bit (real)
floating point number. The XY coordinates in the parameter
tables are now also doubles as well. Although at the time of this
writing the ProMAX database only supports 32-bit floating
point XY coordinates, and the ProMAX traces headers only 32-
bit floating point numbers, the parameter tables are higher
precision.

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.

All of the source code examples in this document have been


converted to use the 64-bit routines.

Note: Parameter tables created in ProMAX/SeisSpace


2003.19.1 and beyond are not backwards compatable with
previous releases of ProMAX/SeisSpace.

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.

Other Docs Search Page Known Problems


Overview of Parameter Tables210 Developer’s Programming Guide

Extrapolation in the X1, X2 plane: The rules for extrapolation


in the X1, X2 plane are simple. If interpolation is requested for
an X1, X2 location outside the table, then the point on the table
that is nearest the requested point is found. The Y and Z values
at the requested point are set equal to the Y and Z values of the
nearest point. Note that the nearest point might be (probably
will be) an interpolated point. See the following figure.

X1

Requested point

Nearest point on table

X2 indicates a point in the table

The nearest point on the table is used to set values at


exterior points

Extrapolation along Y: Extrapolation in Y can be done either


by setting the Y value equal to the nearest defined Y value or by
linearly interpolating based on the slope between the last two
defined points along Y. The method of extrapolation is set by
running the routine tblSetExtrap in C or TBL_SET_EXTRAP
in FORTRAN.

Table Subroutine Categories


Four general categories of table subroutines are available to the
ProMAX programmer:

• table initialization and creation routines to input/output


data to/from disk files

• table value editing routines for adding, deleting, and


changing table values

Other Docs Search Page Known Problems


Overview of Parameter Tables211 Developer’s Programming Guide

• routines to find values at locations in the table and to find


global minimum and maximum values

• interpolation routines

A set of routines in each of these categories that be called from


the C programming language, with an analogous set for
FORTRAN (with one important exception which is discussed
later). Use the command

aman -k tbl

to print a list of all of the ProMAX table routines and a brief


description of their purpose.

In order to access the on-line manual pages for ProMAX


routines, you must have the path to PROMAX_HOME/port/bin,
where PROMAX_HOME is the path name where the ProMAX
directory structure is installed. To see documentation on an
individual table routine, such as tblCountX, type

aman tblCountX.

This provides an explanation of calling arguments, along with a


description of the function of the subroutine.

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.

Other Docs Search Page Known Problems


Examples of Table Routines212 Developer’s Programming Guide

Examples of Table Routines

One of the best ways to demonstrate the use of the ProMAX


table routines is through example code. The following examples
are in both FORTRAN and C. You will not miss anything if you
read the code examples in one language and not in the other.
Both sets of code accomplish the same tasks; a discussion
accompanies each code fragment.

FORTRAN Code Examples


This section contains two examples of FORTRAN table
routines.

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 )

C ..... Get the gate table from the database


CALL DB_TBL_GET( 'GAT', CGATENAME, ITBL_HANDLE,
IERR )
IF ( IERR .NE. 0 ) THEN
CALL REPORT_PROMAX_ERR( IERR )
CALL EX_ERR_FATAL(
& 'Cannot open time gate ' //CGATENAME )
ENDIF

Other Docs Search Page Known Problems


Examples of Table Routines213 Developer’s Programming Guide

C ......Get info on the gate table


CALL TBL_INFO( .TRUE., ITBL_HANDLE, CPRIM_KEY,\
CSCND_KEY,
& CZ_DESC, CTABLE_DESC, IDUMMY(1), IDUMMY(2),\
IDUMMY(3),
& NTIMES, RDUMMY(1), RDUMMY(2), RDUMMY(3),\
RDUMMY(4),
& RDUMMY(5), RDUMMY(6) )

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' )

CALL HDR_NAMINFO( CSCND_KEY, CDESC_DB, LENGTH,\


IFORMAT_SKEY,
& IH_SKEY, IERR )
IF ( IERR .NE. 0 ) CALL EX_ERR_FATAL(
& 'The secondary key of the time gate\
(' //CSCND_KEY
& //') is not in the header' )

After the table is created with DB_TBL_GET, information


about the table is retrieved from the table by use of the program
TBL_INFO. You can investigate the other calling arguments for
this subroutine by typing aman tbl_info.

Most of the arguments returned in this code are dummy


variables. The only information about the table that is needed is
the primary and secondary keys on which the table is based (the
X and Y axes of the table) and the number of Z values in the
table, represented here as the argument NTIMES.

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.

This piece of code came from the initialization subroutine in


amp_ratio. The table is read into memory only one time. It will
be preserved there until it is intentionally closed by the

Other Docs Search Page Known Problems


Examples of Table Routines214 Developer’s Programming Guide

programmer, or until the routine fails through EX_ERR_FATAL


or some other means of stopping execution.

Next we see where the table that is created is used in the


subroutine EXEC_AMP_RATIO, which can also be found in
the example code file amp_ratio.f. The subroutine
EXEC_AMP_RATIO is given one data trace at a time to
process, and the time gate is interpolated for that trace. The
trace for which the time gate is interpolated is referred to as the
current trace in the following discussion. The subroutine
EX_GET_DBLEKEY is used to get a double representation of
the primary key value (the table’s X axis value) and
EX_GET_REALKEY is used to get a floating point value of the
secondary key value (the table’s Y axis value). This is because
the table interpolation routines only work with double and
floating point values.

FLOAT SKEYVAL, TGATE(2)


REAL*8 PKEYVAL
INTEGER IERR

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 TBL2_INTERP_XY( ITBL_HANDLE, PKEYVAL,\
SKEYVAL, TGATE, NOINTERP )

The routine TBL2_INTERP_XY is called next; it interpolates


the time gate values from the table. Note that the calling
arguments include ITBL_HANDLE, which was passed from
INIT_AMP_RATIO through the common block in
amp_ratio.inc. The input arguments PKEYVAL and SKEYVAL
are the X and Y locations in the table at which interpolation of
the time gate values will be done. The routine
TBL2_INTERP_XY returns the start and end time of the time
gate TGATE. It also returns the value of NOINTERP, which is
used in control of extrapolation.

We could also do the interpolation by direct use of the X1, X2


coordinates. This is only desirable if X1 and X2 are readily
available through trace headers or accessible , as occurs in the
following code:

C ......... Get the X1,X2 coordinates from the headers\


and interpolate
X1 = (double)RTHDR( IH_X1 )
X2 = (double)RTHDR( IH_X2 )

Other Docs Search Page Known Problems


Examples of Table Routines215 Developer’s Programming Guide

CALL TBL2_INTERP_Z( ITBL_HANDLE, X1, X2, 2,


1,\ SKEYVAL, SKEYVAL,
& TIMES, NOINTERP )

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.

The following code shows a working ProMAX module which


writes a new velocity table to the database.

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-------------------------------------------------------
-----------------------

SUBROUTINE INIT_DUMMYA( LEN_SAV, ITOOLTYPE )

#include "dummya.inc"

INTEGER LEN_SAV, ITOOLTYPE


INTEGER NCHARS, IERR

C ..... declare variable for user-given descriptive table


name
CHARACTER CTABLE_DESC*128
C ..... declare variable for lable or name created from\
CTABLE_DESC
CHARACTER CHASH_NAME*8

Other Docs Search Page Known Problems


Examples of Table Routines216 Developer’s Programming Guide

C ..... Call for the input parameter by name. Note the\


padding in the
C ..... character constant. It is the programmers\
responsibility to
C ..... provide the correct type of return argument.
CALL EX_CGETPARM( 'VEL_FILE', 1, CHASH_NAME,\
NCHARS )

C ..... Get the table description from the hash name.\


The description is
C ..... needed both when the table is allocated and\
written to the data base
CALL TBL_DESC_FROM_DB( 'VEL', CHASH_NAME,\
CTABLE_DESC, IERR );
IF( IERR .NE. 0 ) THEN
CALL EX_ERR_FATAL('Table description not\
found.')
END IF

C ..... Allocate space for a new table


CALL TBL_ALLOCATE( ID_TABLE, 1, 'CDP', 'VEL',\
'TIME',
& CTABLE_DESC, IERR )

C ..... Set the number of words that need to be saved\


for re-entrancy.
C ..... to avoid oversights
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-------------------------------------------------------
-----------------------

SUBROUTINE EXEC_DUMMYA( TRACE, ITHDR, RTHDR )

#include "dummya.inc"

REAL TRACE(NUMSMPz), RTHDR(NTHz)


REAL YVALUE, ZVALUE
REAL*8 XVALUE
INTEGER ITHDR(NTHz), IERR

Other Docs Search Page Known Problems


Examples of Table Routines217 Developer’s Programming Guide

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

C ..... Add values to the table


XVALUE = 1.0;
YVALUE = 2.0;
ZVALUE = 3.0;
CALL TBL2_ADD_XY( ID_TABLE, XVALUE, YVALUE, \
ZVALUE )

RETURN
END

C-------------------------------------------------------
-----------------------
C Include file for DUMMYA
C-------------------------------------------------------
-----------------------

IMPLICIT NONE
#include "global.inc"

COMMON /SAVED_PARMS/ SAVE1z, ID_TABLE, END1z

INTEGER ID_TABLE

C ..... ID_TABLE memory handle for the velocity 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

Other Docs Search Page Known Problems


Examples of Table Routines218 Developer’s Programming Guide

location. The returned value is the way in which the table is


referenced. Any subroutines that make use of the table require
this pointer value as an argument to allow the table to be
uniquely identified.

char *tblName, *xKeyName, *yKeyName;


void* tblPointer;
int xIndex, yIndex;

/* Get the name of the time gate file from the menu */
exParGetString( "TBLNAME", tblName );

/* Get the gate from the database */


tblPointer = tblFromDatabase( "MUT", tblName );
if( tblPointer == NULL ){
exErrFatal("Cannot open time gate");
}

/* Get the name of X and Y axes of the table and the\


header indicies */
xKeyName = tblDescX( tblPointer );
yKeyName = tblDescY( tblPointer );
if( xKeyName == NULL || yKeyName == NULL ){
exErrFatal("Table X or Y header names do not exist\
in the dataset.");
}
xIndex = hdrIndex( xKeyName);
yIndex = hdrIndex( yKeyName);

/* Get the number of Z values (times), it should be 2 */


if( tblCountZ( tblPointer ) != 2 ){
exErrFatal("Time gate must have a start and end\
time.");
}

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.

This piece of code came from the initialization subroutine in


ampRatio.c. The table is read into memory only one time. It
will be preserved there until it is intentionally closed by the
programmer, or until the routine fails through exErrFatal or
some other means of stopping execution.

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

Other Docs Search Page Known Problems


Examples of Table Routines219 Developer’s Programming Guide

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.

In the following code segment, double representation of the


primary key value and a floating point representation of the
secondary key value are found (the table interpolation routines
only work with double and floating point values for X and Y
coordinates) and the time gate is interpolated. The values of
xKeyName, etc., from init_amp_ratio were passed to
exec_amp_ratio through the external parms structure.

float skeyVal, tgate[2];


double pkeyVal;
int iErr;

/* get the primary and secondary key values */


pkeyVal = (double)rthdr[xIndex];
if( hdrFormat( xKeyName ) == HDRINT ) pkeyVal =\
(double)ithdr[xIndex];

skeyVal = rthdr[yIndex];
if( hdrFormat( yKeyName ) == HDRINT ) skeyVal =\
(float)ithdr[yIndex];

/* interpolate the time gates */


iErr = tbl2InterpXY( tblPointer, pkeyVal, skeyVal,\
tgate );
if( iErr != 0 ){
exErrFatal("Error interpolating time gate.");
}

The routine tbl2InterpXY is called which interpolates the time


gate values from the table. tlb2InterpXY also returns an error
code to iErr which must be 0, else the interpolation could not be
done for some reason.

We could also do the interpolation by direct use of the X1, X2


coordinates. This is only desirable if X1 and X2 are readily
available through trace headers, as occurs in the following code:

/* Get the X1,X2 coordinates from the headers and


interpolate */
x1 = (double)rthdr[ indexX1 ];
x2 = (double)rthdr[ indexX2 ];
iErr = tbl2InterpZ( tblPointer, x1, x2, 1, 1, 1,\
&skeyVal, tgate );
if( iErr != 0 ){
exErrFatal("Error interpolating table value.");
}

Other Docs Search Page Known Problems


Examples of Table Routines220 Developer’s Programming Guide

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.

The following code shows a working ProMAX module which


writes a new velocity table to the database.

/* This example shows how to create a new table in the


database. */
/* The example if for adding a new RMS velocity table */

/* include ProMAX prototypes and globals */


#include "cpromax.h"
#include "cglobal.h"

/* define saved parameters */


BEGINPARMS

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
*/

Other Docs Search Page Known Problems


Examples of Table Routines221 Developer’s Programming Guide

char *tblHashName; /* 8-character name created from\


tblDesc */

/* get the table hash name from a menu, this is an\


8-character */
/* string created from the original user-given table\
name */
exParGetString("VEL_FILE", &tblHashName );

/* get the table description from the hash name. The\


description is */
/* needed when the table is written to the data base */
tblDesc = tblDescFromDatabase( "VEL", tblHashName );
if( tblDesc == NULL ){
exErrFatal("Table description not found.");
}

/* allocate space for a new table, one z value per


x1,x2,y location */
parms->tblPntr = tblAllocate( 1, "CDP", "TIME",\
"VEL", tblDesc );
if( parms->tblPntr == NULL ){
exErrFatal("couldn’t allocate space for a new\
table.");
}

/* Set the number of words that need to be saved for


re-entrancy. */
*len_sav = NPARMS (parms);

/* set the tool type */


*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)
*
********************************************************
**************/

void exec_dummya_(float *trace, int *ithdr, float *rthdr)


{
float yValue, zValue;
double xValue;
int iErr;

if( globalRuntime->cleanup ){

Other Docs Search Page Known Problems


Examples of Table Routines222 Developer’s Programming Guide

/* .. The last trace has been processed, write the table


to the database */
tblToDatabase( parms->tblPntr, "VEL" );
return;
}

/* add values to the table */


xValue = 1.0;
yValue = 2.0;
zValue = 3.0;
tbl2AddXY( parms->tblPntr, xValue, yValue, &zValue );

Other Docs Search Page Known Problems


223 Developer’s Programming Guide

Memory Management

This chapter describes memory-related routines within the


ProMAX system.

Topics covered in this chapter:


➲ Overview of Memory Management
➲ C Memory Management
➲ Multi-dimensional Arrays
➲ Multi-Dimensional Routine Names
➲ FORTRAN Memory Management
➲ Big Vector Routines

Other Docs Search Page Known Problems


Overview of Memory Management224 Developer’s Programming Guide

Overview of Memory Management

There are three groups of memory-related routines within the


ProMAX system. The first group of routines are to be called
from the C programming language and are for allocating multi-
dimensional arrays in single calls. The second group of routines
is for use in pseudo-dynamic memory allocation in FORTRAN.
The third group of routines is used for manipulating arrays that
are larger than the available memory. In this case disk space is
used as slow memory for data storage. All three groups of
routines are discussed separately in the following sections.

The environmental variable $PROMAX_HOME is used in this


document. This variable is equal to the path name of the
directory at which the ProMAX directory tree is installed on
your system. The default installation directory is /advance.

Other Docs Search Page Known Problems


C Memory Management225 Developer’s Programming Guide

C Memory Management

The C programming language provides a number of very


flexible capabilities for handling different kinds of data. C
structures, for example, allow associated data to be placed in a
data object that can be named and passed from one routine to
another. Because of the flexibility of C, there are several general
types of memory management routines within ProMAX which
handle different collections of data. The types of data
collections which are handled include:

• multi-dimensional arrays
• deques
• heaps
• queues
• stacks

These data types and the memory management routines that


handle them are discussed in the following sections.

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;
}

However, the following function IS valid in C:

void goodFunc(a,n1,n2)
float **a;
{
a[n2-1][n1-1] = 1.0;
}

Therefore, the memory functions do not allocate true


multi-dimensional arrays, as described in the C specification.

Other Docs Search Page Known Problems


C Memory Management226 Developer’s Programming Guide

Instead, they allocate and initialize pointers (and pointers to


pointers) so that, for example,

a[i2][i1]

behaves like a 2D array.

The array dimensions are numbered, which makes it easy to add


functions for arrays of higher dimensions. In particular, the 1st
dimension of length n1 is always the fastest dimension, the 2nd
dimension of length n2 is the next fastest dimension, and so on.
Note that the 1st (fastest) dimension n1 is the first argument to
the memory functions, but that the 1st dimension is the last
subscript in a[i2][i1].

The allocation of pointers to pointers implies that more storage


is required than is necessary to hold a true multi-dimensional
array. The fraction of the total storage allocated that is used to
hold pointers is approximately 1/(n1+1). This extra storage is
unlikely to represent a significant waste for large n1.

The memory management functions are significantly different


from similar functions described by Press et al in Numerical
Recipes in C, 1988—particularly the following functions:

• allocate arrays of arbitrary size elements


• allocate contiguous storage for arrays
• abort if allocation fails (unlike malloc)
• do not provide arbitrary lower and upper bounds for arrays

Contiguous storage enables an allocated multi-dimensional


array to be passed to a C function that expects a one-
dimensional array. For example, to allocate and zero an n1 by
n2 two-dimensional array of floats, one could use

a = memAlloc2(n1,n2,sizeof(float));
zeroFloatArray(n1*n2,a[0]);

where zeroFloatArray is a function defined as

void zeroFloatArray(int n, float *a)


{ int i;
for (i=0; i<n; i++){
a[i] = 0.0;
}
}

Other Docs Search Page Known Problems


C Memory Management227 Developer’s Programming Guide

Internal error handling and arbitrary array bounds, if desired,


should be implemented in functions that call the functions
defined below, with the understanding that these enhancements
may limit portability.

Multi-dimensional Routine Names


There are three sets of routines for handling multi-dimensional
arrays which can be identified by their names:

• _mem
• alloc
• deque

The following sections describe these routines.

_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.

Other Docs Search Page Known Problems


C Memory Management228 Developer’s Programming Guide

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().

Other Docs Search Page Known Problems


C Memory Management229 Developer’s Programming Guide

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.

Sedgewick, R., 1990. Algorithms in C. Addison-Wesley,


p. 148-156.

Other Docs Search Page Known Problems


FORTRAN Memory Management230 Developer’s Programming Guide

FORTRAN Memory Management

The FORTRAN programming language does not offer the same


dynamic memory allocation capabilities as that of the C or C++
programming languages. A result of not having the ability to
dynamically allocate memory is that sometimes programmers
will hard code array lengths to some fixed size that is large
enough to handle any data likely to enter the system. This
approach can lead to limitations in the usability of programs
when a large data array is input to the system. Hard coding
array sizes also wastes memory when the data arrays are
smaller than the hard coded limit. The ProMAX system
provides a type of dynamic memory allocation for the
FORTRAN programming language.

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.

Another memory space that is available to the programmer is


the set of equivalenced 1-dimensional arrays RTEMPz,
ITEMPz, and CTEMPz for REAL, INTEGER, and CHAR data
types respectively. The TEMPz arrays are not managed memory
in the sense that array bounds are not checked; they are intended
to serve as a convenient place to put temporary results. The size
of the TEMPz array is 50000 four-byte words at the time of this
writing, but the programmer should check the array size by
looking at the value of the PARAMETER LTEMPpz in
$PROMAX_HOME/port/include/mem.inc if a question of the
size is important.

Other Docs Search Page Known Problems


FORTRAN Memory Management231 Developer’s Programming Guide

A third array that is available is a 2-dimensional character array


called CCTEMPz, which is actually equivalenced with
CTEMPz but is conveniently sized for 2-dimensional use.

RSPACEz and ISPACEz


Pieces of the RSPACEz array can be reserved through use of the
routine MEMORY_RESBUFF. That memory can be returned to
the system through use of the routine MEMORY_FREEBUFF.
An important feature of the RSPACEz and ISPACEz arrays are
that they can be expanded if the initial array size specified in
mem.inc is not large enough to handle the memory requested by
a program. Memory expansion is done either automatically by
ProMAX when a call to MEMORY_RESBUFF exceeds the
available memory, or the memory space can be expanded by a
call to MEMORY_GROWBUFF.

The array bounds of RSPACEz and ISPACEz are checked after


each return from an INIT or EXEC subroutine. If an array
overrun is detected at that time, ProMAX stops execution and
delivers an error message ****SEVERE MEMORY
ERROR***. A programmer can cause all array bounds to be
checked within a routine though by calling MEMORY_CHECK
or MEMORY_TRAP.

Fortran Indexing For RSPACEz and ISPACEz


Beginning with the ProMAX/SeisSpace 2003.19.1 Linux-only
release programmers can make use of 64-bit memory
addressing in Fortran.

The original 32-bit Fortran memory addressing subroutines had


names like MEM_RESBUFF. These subroutines can still be
used, except the developer does not have access to 64-bit
memory addressing on 64-bit machines running 64-bit
operating systems. The newer subroutines have names like
MEMORY_RESBUFF. A macro in the mem.inc file determines
the architecture of the compilation platform and substitutes in
either MEM_RESBUFF (32-bit) or MMEM_RESBUFF (64-
bit). Here is what this looks like:

C ..... Definitions for 32 vs 64 bit machine memory


allocation
#if defined(SGIMIPS4) || defined(__x86_64)
#define PTRDIFF_T INTEGER*8

Other Docs Search Page Known Problems


FORTRAN Memory Management232 Developer’s Programming Guide

#define ptrdiff_t INTEGER*8


#define SIZEOF_PTRDIFF_T 8
#define sizeof_ptrdiff_t 8
#define MEMORY_RESBUFF MEMM_RESBUFF
#define memory_resbuff MEMM_RESBUFF
#define MEMORY_RESBUFF_ERR MEMM_RESBUFF_ERR
#define memory_resbuff_err MEMM_RESBUFF_ERR
.
.
#else
#define PTRDIFF_T INTEGER
#define ptrdiff_t INTEGER
#define SIZEOF_PTRDIFF_T 4
#define sizeof_ptrdiff_t 4
#define MEMORY_RESBUFF MEM_RESBUFF
#define memory_resbuff MEM_RESBUFF
#define MEMORY_RESBUFF_ERR MEM_RESBUFF_ERR
#endif

Developers writing Fortran memory management code should


classify Fortran memory pointers as PTRDIFF_T. The mem.inc
macro will reclassify this memory pointer as type INTEGER or
INTEGER*8, depending upon the system architecure. For
example:

COMMON /SAVED_PARMS/ SAVE1z, NFREQS, IX_FREQS,


& NENS, IENS,
& ITRACE_IN_ENS, FIRST_VISIT, END1z

PTRDIFF_T IX_FREQS

Other Docs Search Page Known Problems


Big Vector Routines233 Developer’s Programming Guide

Big Vector Routines

Vectors are occasionally too large to fit into available memory


and, therefore, must be written to temporary files on disk.
ProMAX provides a set of routines for handling large vectors
that appear to the programmer to be memory-like routines
rather than disk access routines. For example, the name of the
routine for creating a disk file is BV_ALLOC, suggesting
allocation of space. Actually, the routine BV_ALLOC has the
capability of checking to see if real memory is available to
satisfy the request. If that memory is not available then a disk
file will be used.

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.

Other Docs Search Page Known Problems


Big Vector Routines234 Developer’s Programming Guide

Other Docs Search Page Known Problems


235 Developer’s Programming Guide

Debugging with gdb

This chapter describes debugging ProMAX tools using the gdb


program.

Topics covered in this chapter:


➲ Overview of gdb
➲ System Review
➲ Debugging Exec and IPC Tools

Other Docs Search Page Known Problems


Overview of gdb236 Developer’s Programming Guide

Overview of gdb

Debugging ProMAX programs can be done in a number of


ways, such as by using print statements in the code to report
variable values. However, experienced programmers find that
the use of programming tools like gdb is one of the most
efficient ways of debugging a program. This allows
programmers to step through computer programs and check
variable values at any point in the execution.

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.

Other Docs Search Page Known Problems


System Review237 Developer’s Programming Guide

System Review

Before we discuss the use of gdb with ProMAX, we will review


the components that make a process. The following figure
shows the sequence of events that occurs when a ProMAX job
is created and executed. The Job Builder is the part of the
ProMAX User Interface where the user builds a job flow, telling
ProMAX which data processing steps to run. A binary file is
written by the Job Builder when either the Execute or Exit
buttons are clicked. This file is called a packet file which, in
addition to the processing steps in the flow, contains the
ProMAX Area, Line, and dataset to be processed. The packet
file is written to the file

$PROMAX_DATA_HOME/Area/Line/Flow/packet.job

where

• $PROMAX_DATA_HOME is an environmental variable


pointing to the directory where the ProMAX data
directories begin

• Area is the directory containing the ProMAX Area,

• Line is the directory containing the ProMAX line

• Flow is the directory containing packet.job and the job


report in a file called job.output

Other Docs Search Page Known Problems


System Review238 Developer’s Programming Guide

Job Builder
(promax)

Batch
Queue

Super Executive
(superExec)

Stand-alone Executive
Programs (exec.exe)

Tool Caller

Diskread AGC Mute

NMO Filter

Line Database
Information
(datasets, parameter tables, Packet File
ordered database files, etc.)

ProMAX system overview

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.

Other Docs Search Page Known Problems


Debugging Exec and IPC Tools239 Developer’s Programming Guide

Debugging Exec and IPC Tools

The following basic steps for debugging ProMAX exec and IPC
tools are described in the next subsections.

• Compile and link an exec or IPC tool in debug mode


• Build a ProMAX flow using the new tool menu
• Execute the ProMAX flow using the exec tool libraries or
IPC tool executable
• Debug the exec or IPC tool using gdb

Many of the steps in debugging exec and IPC tools are identical.

Debugging a ProMAX Exec Tool


The procedure by which new ProMAX exec tools are added has
changed beginning with the ProMAX 2003.12.1 release. In
previous releases of the ProMAX SDK new exec tools were
added to a library in the user’s development environment called
libmaxtoolc.so, then this library was linked with other object
modules and libraries to build a new exec.exe, which is
dynamically linked.

Beginning with the ProMAX 2003.12.1 release the


libmaxtoolc.so library is still built in the user development
environment, but so is a library called libtoolcall.so, which
contains the calling routines for all exec tools, including any
new ones added by the user. We no longer build a new binary
file exec.exe, but do build an exec.exe script described later in
this document. The point of this new method is to simplify
adding new exec tools without generating a large exec.exe file,
or possibly interrupting production processing by introducing a
corrupt or bad exec.

The idea is to either copy the new libmaxtoolc.so and


libtoolcall.so files to the production tree
$PROMAX_HOME/sys/lib directory, or by adjusting the
$LD_LIBRARY_PATH environment variable used by
ProMAX, depending upon your platform.

Starting a ProMAX exec job from the ProMAX UI for


debugging

Other Docs Search Page Known Problems


Debugging Exec and IPC Tools240 Developer’s Programming Guide

This method of starting a ProMAX exec job for debugging


purposes assumes you have a working menu, and this menu is
included in your personal Processes list. Here are the steps to
start the ProMAX exec from the ProMAX UI:

1. When making the new exec tool be sure to use the


"debug=yes" flag:

> Makeexec debug=yes

2. Set up your $HOME/.promax file to include directories to


search when looking for development and production libraries.

Beginning in the ProMAX 2003.12.1 release we added a ninth


entry to the $PROMAX_HOME/etc/product and
$HOME/.promax files. This ninth entry allows for the
specification of a library path. Typically the Linux platform
uses $LD_LIBRARY_PATH.

Here is an example entry from a .promax file, which has the


exact same format as the ProMAX product file:

("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 )

The ninth entry tells ProMAX to look in


~/promax/2003.12/sys/lib for shared libraries, then look in the
standard production location.

3. Start the ProMAX UI and make sure it reads the


$HOME/.promax to set search paths properly. Here is an
example output from a started ProMAX UI using the above
information from a .promax file:

**Setting or Changing Product (ProMAX 2D Testing)**


PROCESSES file =
/lair/genew/promax/2003.12/port/menu/promax/Processes
MISC directory search path =
/products/landmark/ProMAX/Linux/v2003.12.1/ProMAX/port/m
isc

Other Docs Search Page Known Problems


Debugging Exec and IPC Tools241 Developer’s Programming Guide

EXEC directory search path =


/lair/genew/promax/2003.12/sys/exe:/products/landmark/Pr
oMAX/Linux/v2003.12.1/ProMAX/sys/exe
MENU directory search path =
/lair/genew/promax/2003.12/port/menu/promax:/products/la
ndmark/ProMAX/Linux/v2003.12.1/ProMAX/port/menu/promax
HELP directory search path =
/products/landmark/ProMAX/Linux/v2003.12.1/ProMAX/port/h
elp
DATA HOME =
/network/integra/export/d02/genew/promax_data
LD_LIBRARY_PATH =
/lair/genew/promax/2003.12/sys/lib:/products/landmark/Pr
oMAX/Linux/v2003.12.1/ProMAX/sys/lib:/products/landmark/
ProMAX/Linux/v2003.12.1/ProMAX/sys/lib/xdb:/products/lan
dmark/ProMAX/Linux/v2003.12.1/ProMAX/sys/lib/syslibs:/us
r/lib

Note that in the .promax file we only needed to specify


<path>/lib and the ProMAX UI adds entries for lib32 and lib64
on IRIX64 machines,

4. Build and run a ProMAX exec tool flow containing your


tool.

5. Debug the exec using gdb. See the subsection on "Using


gdb with a ProMAX Exec Tool".

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:

1. Follow steps 1-4 outlined in the section "Starting a


ProMAX exec job from the ProMAX UI for debugging".

2. Copy or link the packet.job file from the flow you built to a
convenient location.

3. Generate a script or set environment variables to mimic


that set by the ProMAX UI at runtime. Here is an example:

#!/bin/ksh
# This script is called DebugPromaxExec

export MY_PROMAX_HOME=/promax/2003.12

Other Docs Search Page Known Problems


Debugging Exec and IPC Tools242 Developer’s Programming Guide

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.

4. Start the ProMAX exec.exe using the debug script. Here is


an example:

> DebugPromaxExec <path>/packet.job

5. Debug the exec using gdb. See next section.

Using gdb with a ProMAX Exec Tool


The actual debugging of an exec tool is performed outside the
ProMAX UI using a tool like gdb.

Starting a ProMAX exec job for debugging purposes can be


accomplished using the ProMAX UI, or from the command
line. Both methods of starting an exec job are discussed in this
document.

The way we debug exec tools here at Landmark is described in


detail below. We first add a call to a routine by the name of
AttatchDebugger. The routine is called in the beginning of the
init phase as seen here in the ampRatio.c example:

void init_amp_ratio_(int *len_sav, int *itooltype)


{
extern int n_trc;
float gatelen;
char *cgatename ;

Other Docs Search Page Known Problems


Debugging Exec and IPC Tools243 Developer’s Programming Guide

n_trc = 0;

AttachDebugger("PROMAX_AMP_RATIO_DEBUG");

.
.
.

The calling argument "PROMAX_AMP_RATIO_DEBUG" is


an environment variable passed to AttachDebugger. If this
variable is set in the environment where the exec is running then
the routine AttachDebugger will run in a loop until the variable
"attached" is set to a value of 1. Here is an example of the
output from a running exec with the environment variable
$PROMAX_AMP_RATIO_DEBUG set to "t" using the
DebugExecTool script described in this document. If your start
your job from the ProMAX UI then check the job.output file to
determine the PID of your exec.exe.

Version of libmaxtool1 is: LGC_PM_ID_092905_145049


Version of libmaxtool2 is: LGC_PM_ID_101805_012559
Version of libmaxtool3 is: LGC_PM_ID_093005_011942

Starting initialization phase


Reading ProMAX config_file
/products/landmark/ProMAX/Linux/v2003.12.1/ProMAX/etc/co
nfig_file ...
***** You may now attach a debugger to 27680 *****

At this point you would type the following at the command line:

> gdb -pid 283463

The following output is produced:

genew(integra) > gdb -pid 26311


GNU gdb Red Hat Linux (6.1post-1.20040607.17rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public
License, and you are
welcome to change it and/or distribute copies of it under
certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show
warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu".
Attaching to process 26311
Reading symbols from
/export/d01/apps/2003.19.1/ProMAX/linux/exe/exec.exe...d
one.

Other Docs Search Page Known Problems


Debugging Exec and IPC Tools244 Developer’s Programming Guide

Using host libthread_db library


"/lib/tls/libthread_db.so.1".
Reading symbols from
/export/d01/apps/2003.19.1/ProMAX/linux/lib/libesi.so...
done.
Loaded symbols for
/export/d01/apps/2003.19.1/ProMAX/sys/lib/libesi.so
Reading symbols from
/lair/genew/promax/2003.19.1/linux/lib/libtoolcall.so...
done.
Loaded symbols for
/lair/genew/promax/2003.19.1/linux/lib/libtoolcall.so
Reading symbols from
/lair/genew/promax/2003.19.1/linux/lib/libmaxtoolc.so...
done.
Loaded symbols for
/lair/genew/promax/2003.19.1/linux/lib/libmaxtoolc.so
Reading symbols from
/export/d01/apps/2003.19.1/ProMAX/linux/lib/libmaxtool1.
so...done.
Loaded symbols for
/export/d01/apps/2003.19.1/ProMAX/sys/lib/libmaxtool1.so
Reading symbols from
/export/d01/apps/2003.19.1/ProMAX/linux/lib/libmaxtool2.
so...done.
Loaded symbols for
/export/d01/apps/2003.19.1/ProMAX/sys/lib/libmaxtool2.so
Reading symbols from
/export/d01/apps/2003.19.1/ProMAX/linux/lib/libmaxtool3.
so...done.
Loaded symbols for
/export/d01/apps/2003.19.1/ProMAX/sys/lib/libmaxtool3.so
Reading symbols from
/export/d01/apps/2003.19.1/ProMAX/linux/lib/libagPilite.
so...done.
Loaded symbols for
/export/d01/apps/2003.19.1/ProMAX/sys/lib/libagPilite.so
.
.
.
.

Loaded symbols for /lib/libgcc_s.so.1


Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /lib/libdl.so.2...done.
Loaded symbols for /lib/libdl.so.2
0x41f137dc in __nanosleep_nocancel () from
/lib/tls/libc.so.6
(gdb)

By typing "where" you can see where the exec.exe is halted in


its execution:

Other Docs Search Page Known Problems


Debugging Exec and IPC Tools245 Developer’s Programming Guide

((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

The exec.exe is halted in the AttachDebugger routine. Now we


need to set the variable "attached" to 1.

(gdb) set attached=1

Now we will step through the program till we get to the


ampRatio.c code:

(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)

Now we can set break points and debug our code.

Other Docs Search Page Known Problems


Debugging Exec and IPC Tools246 Developer’s Programming Guide

What is the new exec.exe script?


Q. What is the exec.exe script generated in a personal
development environment?

A. This is a script that can be used as an Alternate Executive in


a ProMAX exec flow. When executed in a flow containing an
Alternate Executive this script sets the
$LD_LIBRARY(N32,64)_PATH environment variable to point
to a location in $PROMAX_SCRATCH_HOME where the
script places the user’s development libmaxtoolc.so and
libtoolcall.so files. This forces ProMAX to use the development
libraries containing the users new exec tool code. You cannot
use gdb to debug this script, just the libraries used by the master
exec.exe.

Debugging A ProMAX IPC Tool


This method of starting a ProMAX IPC tool job for debugging
purposes assumes you have a working menu, and this menu is
included in your personal Processes list. Here are the steps to
start the ProMAX IPC tool job from the ProMAX UI:

1. When making the new IPC tool be sure to use the


"debug=yes" flag:

> gmake debug=yes

2. Build an IPC tool menu that has an option to toggle the


debug mode. For example:

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

Other Docs Search Page Known Problems


Debugging Exec and IPC Tools247 Developer’s Programming Guide

3. Set up your $HOME/.promax file to include directories to


search when looking for development and production
executables.

Here is an example entry from a .promax file, which has the


exact same format as the ProMAX product file:

("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 )

4. Start the ProMAX UI and make sure it reads the


$HOME/.promax to set search paths properly. Here is an
example output from a started ProMAX UI using the above
information from a .promax file:

**Setting or Changing Product (ProMAX 2D Testing)**


PROCESSES file =
/lair/genew/promax/2003.12/port/menu/promax/Processes
MISC directory search path =
/products/landmark/ProMAX/Linux/v2003.12.1.1/ProMAX/port
/misc
EXEC directory search path =
/lair/genew/promax/2003.12/sys/exe:/products/landmark/Pr
oMAX/Linux/v2003.12.1.1/ProMAX/sys/exe
MENU directory search path =
/lair/genew/promax/2003.12/port/menu/promax:/products/la
ndmark/ProMAX/Linux/v2003.12.1.1/ProMAX/port/menu/promax
HELP directory search path =
/products/landmark/ProMAX/Linux/v2003.12.1.1/ProMAX/port
/help
DATA HOME =
/network/integra/export/d02/genew/promax_data
LD_LIBRARY_PATH =
/lair/genew/promax/2003.12/sys/lib:/products/landmark/Pr
oMAX/Linux/v2003.12.1.1/ProMAX/sys/lib:/products/landmar
k/ProMAX/Linux/v2003.12.1.1/ProMAX/sys/lib/syslibs:/usr/
lib

5. Build a flow which has your IPC tool and debug turned on.

6. Execute the flow and follow the instructions in the view


file, here is an example output from the job.output:

Verifying existence of packet file

Other Docs Search Page Known Problems


Debugging Exec and IPC Tools248 Developer’s Programming Guide

-rw-rw---- 1 prouser develop 3360 Jun 13 08:40


/tmp/pFile_23169_1
DEBUG mode.
If not in debug mode, this command would be executed:
’( ampRatio.exe /tmp/pFile_23169_1; rm -f /tmp/ps_23169
) &’
You must execute this command yourself.

7. Attatch the debugger to the executing IPC tool from a


command line window.

> gdb /lair/genew/promax/2003.12/sys/exe/ampRatio.exe

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

9. Start the ampRatio.exe IPC tool providing it the temporary


packet file listed in the job.output (view) file.

(gdb) run /tmp/pFile_23648_1


Starting program:
/data/home/prouser/promax/2003.12.1/linux/exe/ampRatio.e
xe /tmp/pFile_23648_1
[Thread debugging using libthread_db enabled]
[New Thread 182931821120 (LWP 23911)]
[Switching to Thread 182931821120 (LWP 23911)]

Breakpoint 1, main (ac=2, av=0x7fbffff648) at


/data/home/prouser/promax/2003.12.1/port/src/exe/ampRati
o/ampRatio.c:35
35 initStandAlone (ac, av, "SOCKET_TOOL");

10. Set breakpoints and debug as usual.

Starting and debugging a ProMAX exec job from the command line

Other Docs Search Page Known Problems


Debugging Exec and IPC Tools249 Developer’s Programming Guide

If you have a flow built (packet.job), you can execute a script


outside the ProMAX IU to debug IPC tools as well. You would
need to update the environment information to match your
system. Here is an example script called
ExecutePromaxFlowIPC.sh:

#!/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:

> ExecutePromaxFlowIPC.sh exec.exe <path>/packet.job

Version of libmaxutil is: LGC_PM_ID_032907_051927


Version of libmaxtool1 is: LGC_PM_ID_031707_012142
Version of libmaxtool2 is: LGC_PM_ID_031707_012327
Version of libmaxtool3 is: LGC_PM_ID_031707_012546

Starting initialization phase


Reading ProMAX config_file
/apps/2003.12.1/ProMAX/etc/config_file ...

.
.
.

_______________________________________________________

Verifying existence of packet file


-rw-rw-r-- 1 prouser develop 3360 Jun 13 08:56
/tmp/pFile_24323_1
DEBUG mode.
If not in debug mode, this command would be executed:

Other Docs Search Page Known Problems


Debugging Exec and IPC Tools250 Developer’s Programming Guide

’( ampRatio.exe /tmp/pFile_24323_1; rm -f /tmp/ps_24323


) &’
You must execute this command yourself.

Run steps 7-10 from above.

Other Docs Search Page Known Problems


251 Developer’s Programming Guide

Menus

This chapter describes ProMAX menu files.

Topics covered in this chapter:


➲ Overview of ProMAX Menus and Landmark Lisp
➲ Parts of a ProMAX Menu
➲ Menu Heading
➲ Parameter Specifications
➲ exec_data
➲ Rules
➲ Tips on Writing Menus
➲ Usable Lisp Functions
➲ Lisp Primitives
➲ Access and Assignment Functions
➲ Callable Database Access Functions
➲ ProMAX Lisp Extentions
➲ Parameter Menu System
➲ pwin
➲ Example Macro: Display Shots with AGC

Other Docs Search Page Known Problems


Overview of ProMAX Menus and Landmark Lisp252 Developer’s Programming Guide

Overview of ProMAX Menus and Landmark Lisp

A ProMAX menu file is the program that controls what appears


to the user of a ProMAX module; it controls the user’s access to
a ProMAX module. Every ProMAX module must have a menu
file if it is to be used within the ProMAX user interface.

ProMAX menus are written in the Lisp programming language;


an expert knowledge of Lisp is not required to write new
ProMAX menus. Of course, because more can be accomplished
with greater knowledge, the following two texts are
recommended for further study:

• Lisp (3rd Edition), by Winston and Horn

• Common Lisp: The Language, by Guy L. Steele, Jr.

Fortunately, even a superficial knowledge of Lisp can go a long


way in ProMAX menu programming.

Landmark’s menu system is built around a proprietary Lisp


interpreter. The interpreter reads the code directly, rather than
having to go through a compile and link stage as would be done
with C or FORTRAN. The Landmark Lisp interpreter supports
a subset of the full Lisp language which consists of lists,
symbols, keywords, strings, and numbers (integer and floating).
The system does not support vectors, arrays, property_lists,
dotted lists, bignums, rationals, macros and multiple_value
returns and binds. ProMAX menu files can include other
ProMAX menu files.

Other Docs Search Page Known Problems


Parts of a ProMAX menu253 Developer’s Programming Guide

Parts of a ProMAX menu

A ProMAX menu consists of four parts:

• Menu Heading
• Parameter Specifications
• exec_data
• rules

The following simple menu shows these four parts.

'(
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))
)
)

These parts are described in the following sections.

Other Docs Search Page Known Problems


Parts of a ProMAX menu254 Developer’s Programming Guide

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.

The fourth line in the Menu Heading is the value_tab. This


value specifies how many character spaces from the right end of
the menu text to place the input boxes in the menu.

The fifth line is the optional plot_label: keyword. In the menu


heading this parameter controls whether or not this process
appears in side label processing history plots. The default is nil,
i.e. not to include this process in the plot history. Set to t to
override the default. Individual process parameters may then
use the plot_label: keyword to provide further details in the
processing history.

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 first line in the Parameter Specification is parameter:. The


parameter: line acts to declare a variable name, so the first

Other Docs Search Page Known Problems


Parts of a ProMAX menu255 Developer’s Programming Guide

parameter is named NUMTO_DO and the second parameter is


named PARM_VAL.

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 attribute type_desc appears in PARM_VAL but not in


NUMTO_DO, because the type int carries with it an implied
description. In the parameter PARM_VAL, type_desc states that

• the parameter is a floating point number

• the number of allowable characters in the input is 6

• there is no lower limit on input values (indicated by nil)


except that the number cannot have more than 6 characters
(-99999)

• the upper limit on input is 999999.

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.

The final attribute in the example above is mouse_text: which


specifies the text that appears in a box at the bottom of the
ProMAX screen when the mouse pointer is on a parameter.

There are many variations of type and type_desc; for example,


the type can be a function, and the description of the function is
that it gets a list of header names and displays them to the
screen. An example of all the menu parameter types,
descriptions, etc., can be found in the Lisp Menu Code
Examples appendix..

Other Docs Search Page Known Problems


Parts of a ProMAX menu256 Developer’s Programming Guide

exec_data
The first line in the exec_data section is

exec_data: ("PROGRAM_NAME"

The opening parenthesis is the beginning of the exec_data


grouping; there is a closing parenthesis at the end of the section.
The string inside the quotes is the name of the program; it must
match the name of the init and exec subroutines. For example, if
the init and exec subroutines in a FORTRAN ProMAX module
are INIT_MY_PROG and EXEC_MY_PROG, then the string
inside the quotes above would be MY_PROG. Letters in this
string must be upper case.

The purpose of the following two lines in the menu

("NUMTO_DO" implicit: (value 'NUMTO_DO))


("PARM_VAL" implicit: (value 'PARM_VAL))

is related to how parameters get from the menu into the


ProMAX module. Recall that the processing flow containing
one or more menus is written to a binary file called packet.job
when the Execute button is pushed on the ProMAX screen. The
ProMAX parameter-getting routines, such as EX_GETPARM
(FORTRAN), search the packet.job file for the character string
in double quotes at the beginning of the line and return the value
of the parameter. For example, EX_GETPARM might be called
from within the subroutine INIT_PROGRAM_NAME as
follows:

CALL EX_GETPARM( "NUMTO_DO", 1, VALUE_PARM )

The routine EX_GETPARM reads the part of the packet.job file


containing parameters for PROGRAM_NAME until it finds the
string NUMTO_DO. The parameter NUMTO_DO is then
evaluated for its value (the value input to the menu by the user)
and that value is passed back to the variable VALUE_PARM in
the subroutine INIT_PROGRAM_NAME.

The calling argument in quotes in EX_GETPARM has to match


the string in quotes in the exec_data section of the menu.
Therefore, the line in the menu

("NUMTO_DO" implicit: (value 'NUMTO_DO))

could be also be written as

Other Docs Search Page Known Problems


Parts of a ProMAX menu257 Developer’s Programming Guide

("FOO " implicit: (value 'NUMTO_DO))

as long as the call to EX_GETPARM is written as follows:

CALL EX_GETPARM( "FOO ", 1, VALUE_PARM ).

Note that the string "FOO " is padded to 8 characters


between the quotation marks. The padding is a requirement
when ProMAX runs on IBM machines and is recommended for
programs written on other machines to make the code portable.

The word implicit: exec_data section indicates that the value to


be output to the packet file is of the type specified in the
Parameter Specifications. Note that in order to get the value of
the parameter NUMTO_DO, the word value must be put in
front of NUMTO_DO. The word value indicates that the value
of the parameter (which is one of its attributes) is to be
evaluated.

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

( ruleName ( conditional statement )


(action if conditional statement is true)
(action if conditional statement is false)
)

The string ruleName represents a character string without blank


spaces that can contain anything. It serves as a label to give
some documentation as to what the rule accomplishes. The
string has no length limit except that it has to contain at least
one character. Note that additional documentation can be added
in a Lisp menu by preceding the documentation line with a
semi-colon. For example:

;this is a comment line

in a menu file would be ignored by the Lisp interpreter.

Other Docs Search Page Known Problems


Parts of a ProMAX menu258 Developer’s Programming Guide

The conditional statement following the rule name is commonly


an evaluation of a parameter. Evaluation in the Lisp interpreter
is done with the following form:

( type of evaluation (thing being evaluated) comparison


value)

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.

In the preceeding example menu, the value of NUMTO_DO is


evaluated to see if it is greater than 3 by the statement:

( > ( value 'NUMTO_DO ) 3 ).

If we wanted to see if NUMTO_DO was less than 3, we could


write:

( < ( value 'NUMTO_DO ) 3 )

and to check for NUMTO_DO equal to 3, we would write:

( = ( 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.

The conditional statement need not be as simple as the one in


the menu file example above. It can contain compound state-
ments such as and or if, as well as functions. For example, the
following rules section sets the condition that in order for the
parameter SHOW_PAR to be shown on the menu, the value of
parameter PARM1 must be equal to 1, the value of PARM2
must be equal to the value of PARM1, and the value of PARM3
must be equal to the sum of the values of PARM1 and PARM2.
The action statements can also have conditional and compound
statements within them.

rules:(
(rule1
(and
( = (value 'PARM1 ) 1 )
(and
(= (value 'PARM2 ) (value 'PARM1) )
(= (value 'PARM3 ) (+(value'PARM1) (value\
'PARM2)) )

Other Docs Search Page Known Problems


Parts of a ProMAX menu259 Developer’s Programming Guide

)
)
(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.

Other Docs Search Page Known Problems


Tips on Writing Menus260 Developer’s Programming Guide

Tips on Writing Menus

Keep the following tips in mind when writing ProMAX menus.

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.

Other Docs Search Page Known Problems


Usable Lisp Functions261 Developer’s Programming Guide

Usable Lisp Functions

Three functions are usable from the menu system: Lisp


primitives, menu access and assignment functions, and the
callable database access functions. The following sections
describe these functions.

Lisp Primitives
We do not document the Lisp primitives in this manual; instead,
we direct you to two references:

• Lisp (3rd Edition), by Winston and Horn


• Common Lisp: The Language, by Guy L. Steele, Jr.

If you are unfamiliar with Lisp, we urge you to acquire at least


the first reference. If you have used any Lisp dialect, you should
be comfortable with most of these forms and probably already
have both these documents.

The following table lists the Lisp primitives. Please note that:

• The ** symbol indicates functions that are destructive list


operations; if you are new to Lisp, we caution against their
use before careful study

• The ? symbol indicates a wildcard for the test equal; that


is:
(equal ? anything) => t therefore (member ? '(1 2 3)) => (1
2 3)

• Lisp keywords are symbols beginning with colons, such as


:test. Parameter attributes are symbols ending in colons,
such as type:. Symbols beginning or ending with colons
are, in fact, both Lisp keywords and are ‘eq’; for example,
(eq :test test:) => t. Keywords eval to themselves and will
printout in the manner they were first encountered; that is,
colon at the start or end.

Other Docs Search Page Known Problems


Usable Lisp Functions262 Developer’s Programming Guide

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)

remove Almost 1, :test fixed as equal (see remq)

remq No like remove with :test fixed as eq

delete Almost a=1, :test fixed as equal (see delq)

delq No like delete with :test fixed as eq

copy No same as copy-list

copy-list Yes 1

eq Yes 1

equal Yes 1

= Yes 1

Other Docs Search Page Known Problems


Usable Lisp Functions263 Developer’s Programming Guide

Lisp Primitives (Continued)


Lisp Primitive Common Lisp Reference
> Yes 2

>= Yes 2

< Yes 2

<= Yes 2
member Almost 1, :test fixed as equal (see memq)

memq No like member with :test fixed as eq

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

assoc Almost 1, :test fixed as equal (see assq)

assq No like assoc with :test fixed as eq

eval Yes 1

print Yes 1

makunbound Yes 2
+ Yes 1

- Yes 1

* Yes 1

/ Yes 1

quote Yes 1

' Yes 1

` Almost 2, is not implemented as a macro

if Yes 1

cond Yes 1

setq Yes 1

Other Docs Search Page Known Problems


Usable Lisp Functions264 Developer’s Programming Guide

Lisp Primitives (Continued)


Lisp Primitive Common Lisp Reference
set Almost 1, operates only on symbols

setf Almost 1, operates only on symbols

progn Almost 1, break not recognized

let Almost 1, is in fact let*


defun Almost 1, &rest, &key, and any variable number of args not supported

do Yes 1

load Yes 1

Access & Assignment Functions


Each of the following functions evaluate their arguments; in
order to get the value of a parameter with symbol name foobar,
you would write (value 'foobar).

Access & Assignment Functions


Function Description

value parm Returns contents of value: attribute of parameter named parm.

set_value parm sexp Set contents of value: attribute of parameter named parm to sexp.

type parm Returns contents of type: attribute of parameter named parm.

set_type parm type_kwd Set contents of type: attribute of parameter named parm to one of the
supported type keywords.

type_desc parm Returns contents of type_desc: attribute of parameter named parm.


set_type_desc parm sexp Set contents of type_desc: attribute of parameter named parm to
sexp.

text parm Returns contents of text: attribute of parameter named parm.

set_text parm string Set contents of text: attribute of parameter named parm to string.

selected_item parm Returns contents of selected_item: attribute of parameter named


parm.

set_selected_item parm sexp Set contents of selected_item: attribute of parameter named parm to
sexp.

mouse_text parm Returns contents of mouse_text: attribute of parameter named parm.

set_mouse_text parm string Set contents of mouse_text: attribute of parameter named parm to
string.

error_list parm Returns contents of error_list: attribute of parameter named parm.

Other Docs Search Page Known Problems


Usable Lisp Functions265 Developer’s Programming Guide

Access & Assignment Functions (Continued)


Function Description
add_error parm string Adds error to error_list: attribute of parameter named parm with text
of string.

delete_error parm string Deletes error from error_list: attribute of parameter named parm
with text of string.

warning_list parm Returns contents of warning_list: attribute of parameter named parm.

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.

value_tab parm Returns contents of value_tab: attribute of parameter named parm.

set_value_tab parm integer Set contents of value_tab: attribute of parameter named parm to
integer.

showing parm Returns contents of showp: attribute of parameter named parm.

do_show parm Set contents of showp: attribute of parameter named parm to t.

do_not_show parm Set contents of showp: attribute of parameter named parm to nil.

Callable Database Access Functions


There are currently only four database access functions callable
from Lisp. The first three are of questionable usefulness
because they return the UNIX name for things, not the
descriptive user name.

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.

Other Docs Search Page Known Problems


Usable Lisp Functions266 Developer’s Programming Guide

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.)

ProMAX Lisp Extentions


ProMAX defines some additional functions that are useful in
menus. The following table lists some of those you may
encounter perusing in the master ProMAX menus.

Extended ProMAX Lisp Functions


Function Description

(string_out var) Return a string representation of the given Lisp variable.

(string_shorten var) Remove extra white space and return the result.

(string_upcase var) Return string argument converted to upper case text.

(string_downcase var) Return string argument converted to lower case text

(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.

(promax_path "partial_path") Returns a string prefixing the current $PROMAX_HOME to the


given partial path.

(current_area) Returns the current area.

(current_line) Returns the current line.

(current_flow) Returns the current flow.

Other Docs Search Page Known Problems


Usable Lisp Functions267 Developer’s Programming Guide

Extended ProMAX Lisp Functions


Function Description
(flow_directory) Returns pathname ofdirectory containing current flow.

(where_promax_is) Returns the name of the host on which the ProMAX UI is running.

(where_promax_displays) Returns the X Window DISPLAY string being used by the


ProMAX UI.

(set_environment var value) Set an environment variable to the given string value.
(unset_environment var) Unset the specified environment variable

New Lisp functions can be defined by using defun with any of


the supported Lisp primitives or other functions. New functions
that are defined by using defun do not require recompilation.
These forms should be placed in a file and loaded by adding a
load call to $PROMAX_HOME/port/misc/extend.lisp.

As an example, assume that we are creating a menu called


framus and need a function that can be called from the rules to
perform some needed action. We would create the file
$PROMAX_HOME/port/misc/framus.lisp, the code of which
is:

(defun framus_simple_function (arg1)


(if
(and (listp (type_desc 'parm1))
(member arg1 (type_desc 'parm1)))
(set_type_desc 'parm1 (remove arg1 (type_desc
'parm1)))
)
)

We can then cause this file to be loaded by adding the following


line to the file $PROMAX_HOME/port/misc/extend.lisp:

(load (promax_path "port/misc/framus.lisp"))

Other Docs Search Page Known Problems


Parameter Menu System268 Developer’s Programming Guide

Parameter Menu System

Parameter menus are driven and developed by manipulating an


ASCII text file, called the Menu Description File (MDF), which
is read by the Lisp interpreter. The MDF is a list of keyword
value pairs (KVPs) and always begin with '( and end with ).

Keywords may be written :keyword or keyword: (see the Lisp


Primitives section at the beginning of this chapter). Therefore,
each of the following lines are exactly equivalent:

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

name: symbol NONE


label: string name: Menu Label coerce to string.
attribute

value_tab: integer 40 Default parameter value_tab: (see value_tab


parameter attribute in the following table).

plot_label: nil or t NONE Include parameters in plot sidelabel history.

rules: list NONE List of Lisp production rules used to provide context
sensitivity.

exec_data: list NONE Causes parameter data to be written to packet_file for


execution.

Other Docs Search Page Known Problems


Parameter Menu System269 Developer’s Programming Guide

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

parameter: symbol None Defines new parameter.

type: keyword None Type of parameter.

type_desc: list nil Extended type info.

selected_item: string or list nil See choose: below.

value: depends on type nil Contains selected value.

text: string parameter: Symbol text of parameter coerce to string.

value_tab: integer menu Horiz space in chrs for text.


value_tab:

showp: nil or t t Visibility predicate.

mouse_text: string nil Pointer help text.

plot_label: nil or t nil Include item in plot sidelabel history.

error_list list nil Errors not set directly.


warn_list list nil Warnings not set directly.

Of these keywords, the type and type_desc attributes are the


most important and the most complicated. They determine the
appearance and allowed user actions on a parameter.

Parameter Types and Attributes


The parameter types break down into 2 general categories:
Type-ins and Choose-parameters from a list of choices,
although Other Parameter Attributes exist.

Other Docs Search Page Known Problems


Parameter Menu System270 Developer’s Programming Guide

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

For each of these types, selected_item and type_desc are not


used, and the value attribute is set to the integer (real, or string,
respectively) that the user typed in.

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

Other Docs Search Page Known Problems


Parameter Menu System271 Developer’s Programming Guide

placed in the value attribute of the parameter, and selected_item


is not used.

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 from Parameters List


Choose-parameters presents a list of choices from which the
user can pick. The choices that will appear are registered in the
type_desc attribute.

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

Other Docs Search Page Known Problems


Parameter Menu System272 Developer’s Programming Guide

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

The attributes type_desc, value, and selected_item are exactly


as specified for type: :choose, except

-return keyword is not handled or needed


-selected_item: :none is not supported and\
selected_item must be set or will default as\
covered in type 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

The attributes type_desc, value, and selected_item are exactly


as specified for type: :choose, except

-return keyword is not handled or needed


-selected_item :none is not supported and must be\
set or will default as covered in type choose.

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.

Other Docs Search Page Known Problems


Parameter Menu System273 Developer’s Programming Guide

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

The attributes type_desc, value, and selected_item are exactly


as specified for type: :choose, except

-return keyword is not handled or needed


-selected_item :none is not supported and must be\
set or will default as covered in type 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.

Action list are normally used as a middle ground between a


regular choose parameter, supplying a predetermined selection
list and a value, and a :function type requiring special functions
or programs to initialize its entries. Action lists typically have
no default :type_desc and these items are dependent upon other
user parameter settings.

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)

Other Docs Search Page Known Problems


Parameter Menu System274 Developer’s Programming Guide

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.

There is no flexibility in the function type parameter; that is, the


only three options are those shown above. Function type
parameters act as follows:

1. Check the value attribute of the parameter against the list


of dataset_list, header_list, or parm_list, respectively.

2. If not there, indicate some type of problem to the user by


way of a warning or error.

3. A single mouse sensitive entry appears on the menu which


is either INVALID or selected_item string. When clicked
on, the menu for selection of the corresponding type pops
up.

4. Selection from the popup menu causes the value attribute


to be set to the system internal name for the choice, and the
selected_item attribute to be set to the descriptive name of
the choice.

Other Parameter Attributes


This section describes additional parameter attributes.

Value Tab Attribute


Value_tab tabs the values (choices, type-ins, etc.) the specified
number of characters over.

value_tab: integer

In essence, the number is approximately the amount of space


that will be reserved on the left for the parameter text set with
the text keyword. If not set, value_tab for an individual parame-
ter defaults to value_tab: attribute for the menu, which defaults
to 40. Increase this value if you encounter mysterious blank
lines when the menu is displayed.

If value_tab is set to zero or text is set to :none, the values will


appear at the left edge of the menu under the text if text is

Other Docs Search Page Known Problems


Parameter Menu System275 Developer’s Programming Guide

supplied, or in place of text if text is set to :none. The space for


text and values are set to 1.6 times the process value_tab. Using
this feature, it is possible to create what appears to be mouse
sensitive text. For example, try this:

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.

text: string or text: :none

As discussed in the preceeding section, there is value_tab space


in characters for text against the left side of the menu. Text can
be longer than this, however, which will cause the text to
occupy multiple lines, each value_tab long.

If text is set to the keyword :none, a text window is omitted and


values will appear up against the left side of the menu, ignoring
value_tab.

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.

Other Docs Search Page Known Problems


Parameter Menu System276 Developer’s Programming Guide

Mouse Help Attribute


If a mouse_text is specified, string will appear in the mouse-
help line at the bottom of the screen when the mouse is pointing
at this parameter:

mouse_text: string

For certain choose-types, this mouse-help may be over-ridden


by some other mouse_text specified for individual choices.

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.

Error_list and Warning_list Attributes


The error_list and warning_list attributes are both:

• a list of strings (which is the text to be displayed beneath


the text)
• the value section of a parameter

They are seldom specified; instead, they are manipulated by the


rules using the add_error, delete_error, add_warning, and
delete_warning functions. There is intentionally no set_error or
set_warning functions.

Other Docs Search Page Known Problems


Parameter Menu System277 Developer’s Programming Guide

Exec_Data Process-Level Keyword


The exec_data process attribute is not strictly a menu system
attribute. Instead, it is a list which is read and interpreted by the
user interface when saving flow changes or executing a job, if
that job causes executable packets to be written out to the trace
processing Executive’s packet file. Its structure is as follows:

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.

exec_data Examples and Explanation


If exec_data is present and the process is not commented out in
the flow editor, the packet_list value of the KVP exec_data will
cause one executable packet to be written to the packet_file for
reading by the Executive. The exec_data KVP can be a list of
packet_list’s in which multiple executable packets will be
output. In this manner, a single menu can be constructed (as a
macro) that will cause multiple processes to be executed by the
trace Executive.

Each packet_list is a list of the string name of a processing tool,


such as AGC or FILTER, followed by the group_list or lists for
that tool. Most tools have only one group, typically GENERAL.

Each group_list is a list of the string name of the group, such as


GENERAL, followed by n parameter_list’s where n is the
number of parameters the tool expects to read from this group
in the packet_file.

Other Docs Search Page Known Problems


Parameter Menu System278 Developer’s Programming Guide

Each parameter_list is a list of the string name of a single


parameter that will be output to this group, followed by a format
specifier (output_form) and a value expression (value_sexp).

The value_sexp is a Lisp expression that will be evaluated.


After evaluating, its value will be output, or coerced into a form
specified in output_form, according to the following rules:

Lisp Expression Evaluation


output_form (eval value_sexp) returns parameter value output
:implicit real, float, or string corresponding type at left

:implicit list, keyword, or symbol ERROR


:real real Returned value

:real integer Float the value returned

:real not float or integer ERROR

:integer integer Returned value

:integer real Truncate value to integer

:integer not float or integer ERROR

:string string String padded with blanks to even multiple of 4 byte


words

:string not a string ERROR

(: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 ))
)
)

Other Docs Search Page Known Problems


Parameter Menu System279 Developer’s Programming Guide

When this exec_data KVP is in a menu included in a flow, a


single packet will be output that will cause the AGC process to
be executed by the trace Executive. The AGC process expects to
find all its critical parameters in one group called GENERAL,
and will find 4 parameters available in the packet file for
retrieval: MODE_AMP, AGCLEN, MODE_WIN, and
MODEZERO.

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.

As just mentioned, exec_data may be a list of packet_lists, as


illustrated in the following code. This would cause two packets
to be output, with the first initiating AGC execution, followed
by FILTER. In essence, a menu with this type of exec_data that
also manipulates all the pertinent parameters correctly is a
macro; that is, it is a single menu item that causes the trace
Executive to execute multiple processes.

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))

Other Docs Search Page Known Problems


Parameter Menu System280 Developer’s Programming Guide

("REMUTE" :implicit (if (value 'remute_option)\


1 0 ))
)
)

Including Other Menus


A ProMAX menu may include another ProMAX menu using
the :include directive. Parameters, exec data and rules are all
included. The syntax is:

:include [PARAM] "inc.menu" ("CALLER" "EXECNAME")

where the optional PARAM field is the name of a parameter in the


current menu above which you wish the newly included
parameters to appear. If no parameter is given, the included
parameters go at the end of the current menu. The list of strings
directs unnamed included exec_data to the proper place in the
current menu. For example in the menu example above, this list
could be ("AGC" "GENERAL") or ("FILTER" "GENERAL").

If the menu to be included is not a fully-qualified pathname,


ProMAX uses the setting of $PROMAX_PORT_MENU_HOME
(which defaults to $PROMAX_HOME/port/menu) as the include
search directory.

Rules and Context Sensitivity


The menu system provides for the reconfiguration of a menu
based on user action by way of rules. Formally, the rule system
is a forward-chaining production rule inference engine, which is
provided as part of the menu system; therefore, each menu with
rules can be considered a small expert system. Such systems are
well documented in the literature (see the Handbook of
Artificial Intelligence by Barr and Feigenbaum: William
Kaufmann, publisher). Here is how it works.

Each rule is a list which is supplied in one of the following


forms.

( rule_name if_clause then_clause )


( rule_name if_clause then_clause else_clause )
or
( index_list rule_name if_clause then_clause )
( index_list rule_name if_clause then_clause\
else_clause )
where-

Other Docs Search Page Known Problems


Parameter Menu System281 Developer’s Programming Guide

index_list is an optional list of state_variable(s).


rule_name is an unused Lisp symbol used only as a\
place holder and for the authors expressive\
needs.
if_clause is a valid Lisp expression which will be\
eval'ed each time any of the state\
variables ( read parameter attributes) that\
it tests or involves change.
then_clause is a valid Lisp expression which will be\
eval'ed if its corresponding tested\
if_clause eval'ed non-nil.
else_clause is an optional valid Lisp expression\
which will be eval'ed if its corresponding\
tested if_clause eval'ed to nil.

As this is a forward-chaining system, the key to rule execution


is the if_clause. Each parameter attribute can be considered a
state variable; that is, the values of the parameter attributes at
any moment in time define the current state of the system.
Every user action on a menu causes some change in a parameter
attribute, usually value or selected_item. In addition, action
clauses (such as then_clause’s and else_clause’s) which call any
of the menu assignment functions will cause changes in these
state variables. Instances of state variables will hereafter be
written state_variable and represented by a two element list of
the form ( attribute_symbol parameter_name ). Therefore, the
state_variable representing the value attribute of parameter
framus would be the list '(value framus).

Each change is recorded in a change_list by appending the


state_variable corresponding to that change to the end of the
change_list. The index_list is a list of all state_variables
referred to in a rules if_clause. It is always present at rule
execution time, and automatically generated by the rule reader
(usual case) if not provided by the rule author.

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

Other Docs Search Page Known Problems


Parameter Menu System282 Developer’s Programming Guide

(not (= 2 (value 'framus))) ;if clause


(set_value 'framus 2) ;then clause
) ;end of rule framus_rule
) ;end of rules

The index_list was not provided by the author; therefore, the


rule reader automatically set the index_list for rule framus_rule
to:

( (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) )

As soon as a state_variable appears on the change_list, the rule


interpreter runs. The actions of the rule interpreter are described
in Lisp code (valid in some dialects of Lisp, but not ours for
lack of a loop macro) and comments below.

1 (loop for change in change_lis bind a variable change\


one at a
;time to state_variable elements
;of change_list until change_list
;is exhausted.
2 (loop for rule in rule_lis ;bind a variable rule one\
at a
;time to elements of rule_list
;until rule_list is exhausted.
3 (if (member change (first rule)) ;if state_variable\
changed is a
;member of rule's index_list,
;i.e., referred to in rules\
if_clause
;if member then
4 (if (eval (third rule)) ;evaluate rules\
if_clause
; if non-nil then
5 (eval (fourth rule)) ;evaluate rules\
then_clause
;else
6 (eval (fifth rule)) ;evaluate rules\
then_clause
;Remember that if there is no
;else_clause, (fifth rule)=>nil
;and nil eval's to nil so no action
;is taken
)
)

Other Docs Search Page Known Problems


Parameter Menu System283 Developer’s Programming Guide

)
)

In this example, we have one parameter, one rule, one change in


the change_list. You might guess there would only be one pass
through the steps of the rule interpreter. What actually happens
is as follows.

At step 1, change is bound to our only change '(value framus).


At step 2, rule is bound to the first (and only) rule.

( ((value framus)) ;rule index_list auto generated


framus_rule ;rule name start of rule
(not (= 2 (value 'framus))) ;if clause
(set_value 'framus 2) ;then clause
) end of rule framus_rule

Step 3 checks to see if change '(value framus) is a member of


the index_list:

((value framus))

It is, so at step 4, noting (third rule) is if_clause:

(not (= 2 (value 'framus)))

However, in this example, the value of framus is not equal to 2.


If the user had typed in the integer 2 as the initial value, it would
not have been detected as a change; therefore, no change in
state would have occurred, and we would not have gotten this
far. This is because the if_clause would have eval’ed to t, and at
step 5 the then_clause would eval (set_value 'framus 2). The
set_value function is a menu assignment function which
immediately set the value of framus back to 2; you might guess
that the process would end, but it does not.

The menu assignment functions have a side effect which


assumes they actually make a change in the state_variable to
which they correspond, and they push that change on to the end
of change_list. There are assignment functions for manipulating
all the attributes of a parameter. The only thing that cannot be
changed is the order of parameters. Therefore, (set_value
'framus 2) when the value of framus was not 2; it caused a
state_variable change (value framus) to be pushed onto the
change_list:

( (value framus) )

Other Docs Search Page Known Problems


Parameter Menu System284 Developer’s Programming Guide

resulting in the change_list becoming

( (value framus) (value framus) )

When we get back to our top level, we loop over change_list to


see if it is exhausted. We remove the first element and check for
more, which there now is. So the process continues. We find the
same rule and evaluate its if_clause again, which eval’s nil this
time, so we eval its else_clause (nil in this case, which does
nothing). Now back at the top again, we remove the change just
handled and find the change_list indeed empty this time. So rule
execution stops, and the menu is redisplayed. This is, of course,
a quite worthless menu because the user variable cannot be
changed by the user. The rule will immediately undo anything
he or she does. But the example does illustrate how rules and
lists interact.

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.

Procedural vs. Production


The important point in the preceding example and verbose
explanation is recognizing that when we got back to the top of
the outermost loop, we found there were more changes on the
change_list that resulted from actions taken inside the loop.
This is the advantage of a production rule system over
procedural type programming. Each rule—called a production
or a production rule inference engine—stands alone,
unconcerned about how or if the state variables in its if_clauses
came to be in any particular condition. The structure driving the
rules assures that whenever any change that any rule cares about
occurs, the conditions and actions called for in that production
are tested and taken. Contrast this to procedural programming,
where, if we want to call procedure ACTION whenever A = B,
we must make the test and call at every point in the program
where A could become equal to B.

Other Docs Search Page Known Problems


Parameter Menu System285 Developer’s Programming Guide

The process of rule interpretation, which is described iteratively


in code and example above, can more elegantly be written
recursively. We illustrate it in this form because we believe you
may be more familiar with iteration than recursion.

We hasten to add that while technically this is expert system


technology, it is the oldest, most primitive and limited variant. It
cannot deal with ambiguity or uncertainty, nor is it directed at or
assured of some type of answer. It also can not explain how it
arrived at a particular conclusion after the fact, as can most
modern expert system shells.

Rules and Tips For Writing Rules


The following sections provide rule-writing tips.

Use Rule Names and Parameter Names Expressively


Rule names are not used by the system except as place holders.
They exist only to make a large collection of rules more
readable, which they will if you use them expressively. The
same applies to parameter_names, despite the use of names like
parm1 and parm2 in the examples. You should choose names
that express content, use, and actions.

Avoid Conditionals In Action Clauses


The following example illustrates the most common error in
rule-writing, where one rule is structured as follows:

(visibility_of_parm3
(= (value 'parm1) 1)
(if (= (value 'parm2) 1)
(do_show 'parm3)
(do_not_show 'parm3)
)
)

In this example, parm1 and parm2 can both be equal to 1 and


parm3 still not show. To understand why, assume at some point
in time parm1 and parm2 both equal 2. An action clause in
some other rule caused parm1 to be set to 1. Because value of
parm1 changed, and this rule’s if_clause involves the
state_variable (value parm1), this rule’s if_clause will be tested.
The if_clause eval’s, so the then_clause is eval’ed. The
then_clause is an if conditional, the second form of which is

Other Docs Search Page Known Problems


Parameter Menu System286 Developer’s Programming Guide

eval’ed because parm2 is still 2, so parm3 is made not-visible.


Assume after this that some other rule action changes parm2 to
be 1. If this rule was ever executed again it would produce the
desired result, but the only thing that will cause this rule to
execute is a change in value parm1, not a change in value
parm2.

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)
)

In this case, the if_clause involves both parm1 and parm2


values so any change in either will cause this rule to execute
again and take the intended action. This type of badly formed
rule often leads to rule order dependency, the subject of the next
tip about writing rules.

The other way to fix this dilemma is not recommended, but is


included for completeness sake only. We could hand index the
original visibility_of_parm3 rule as follows:

( ((value parm1)(value parm2)) ;author customized


index_list
visibility_of_parm3
(= (value 'parm1) 1)
(if (= (value 'parm2) 1)
(do_show 'parm3)
(do_not_show 'parm3))
)

In this case, whenever the value of either parm1 or parm2


changes, this rule would be executed.

A third, more distasteful solution is to force the state variable


(value parm2) into the if_clause without changing the return
value of the expression. This could be accomplished by making
(value 'parm1) the first expression inside a progn statement and
returns only the last form it evaluates, which we would make
the actual if_clause.

Other Docs Search Page Known Problems


Parameter Menu System287 Developer’s Programming Guide

Rule Order Should Never Matter


In the previous example, if both the rules that set parm1 and
parm2 equal to 1 occurred before the visibility_of_parm3 rule,
the first execution of this rule would have produced the
expected answer. The example illustrates how almost all
unexpected behavior is caused by one or more badly formed
rules.

Of course, achieving the desired behavior is most important, but


for maintenance programming reasons (when someone a year
from now tries to figure out what these two dozen rules where
supposed to do), it is best to assure that the rules are all well
formed and unambiguously express intent. One easy way to
almost guarantee this is to change the order of rules in the rule
list from time to time and see if the behavior is still as desired.
Develop a rule at the end of the rule list, then when thought to
be correct, move it to the top; if the behavior of the menu is still
correct, that rule is unlikely to have any unforeseen
peculiarities.

Think THEN, Then IF


In building up rules, think first about the action that needs to
take place. This may sound backwards, but it is perfectly
reasonable and less error prone. For example:

sometimes this parm should not show


or
sometimes this value should be recalculated

Each action which is determined in this way will usually best


become a then_clause in a rule. Avoid trying to think about all
the other things that should or could be set in conjunction with
the one under consideration. Once a needed action is fixed in
your mind, then and only then formalize the conditions that
describe the situations when the action should be taken. This
will form the if_clause of the rule. If, in considering an action,
you then recognize the conditions necessary for that action to be
taken are the same conditions as for some other rule, you may
bundle the two or more actions within a progn statement in the
action_clause. This approach leads to simple action clauses and
collections of rules that are much easier to read, understand, and
maintain.

Other Docs Search Page Known Problems


Parameter Menu System288 Developer’s Programming Guide

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.

Keep Rules As Simple As Possible (Simple = Small)


In using the preceding tips, you may often find yourself writing
if_clauses involving many and’s, or’s, if’s, and cond’s. These
can become difficult to comprehend, as illustrated in this
example:

(and (= 2 (value 'parm1))


(or (equal (value 'string_var) "one for the money")
(not (member '("Data" 1 "get some data")\
(type_desc 'parm4)))
(and (eq (error_list 'parm3) nil)
(or (= (value 'parm4) (* (value 'parm5)\
(value 'parm6)))
(= (value 'parm5) (value 'parm6))
)
)
)
)

It is hard to tell when or if the then_clause following an


if_clause, as illustrated above, would ever be called. This rule
would be better broken into several rules, each with identical
action and if clauses, as follows:

(and (= 2 (value 'parm1))


(equal (value 'string_var) "one for the money")
)
(and (= 2 (value 'parm1))
(not (member '("Data" 1 "get some data") (type_desc\
'parm4)))
)
(and (= 2 (value 'parm1))
(eq (error_list 'parm3) nil)
(= (value 'parm4) (* (value 'parm5) (value 'parm6)))
)
(and (= 2 (value 'parm1))
(eq (error_list 'parm3) nil)
(= (value 'parm5) (value 'parm6))
)

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

Other Docs Search Page Known Problems


Parameter Menu System289 Developer’s Programming Guide

course, a number of other ways this clause could have been


broken up besides the way that is illustrated in this example.)

Do Not Use else_clauses


Except to Negate the Action of a Rules if_clause
When reading rules written by someone els, one of the most
confusing things to determine is the effect of else_clauses that
do something completely different than the then_clause did. If
the actions that are needed when the if_clause is non-nil are
completely different and unrelated to those that are needed if it
is nil, separate these actions clauses into two separate rules. One
should look just like the original with no else_clause, and the
second should look like this, relative to the original:

(negation_rule13 (not if_clause) else_clause )

Avoid Side Effects in If Clause


Assume you have a number of rules, each with only if and then
clauses, and all if clauses evaluate to nil. You might expect that
nothing could happen. But remember, if_clauses are eval’ed
often to see what action clause to act on. Beware that if the
if_clause itself calls assignment functions or has other side
effects, confusing things can begin to happen.

Other Docs Search Page Known Problems


pwin290 Developer’s Programming Guide

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:

• XFILESEARCHPATH (for all systems)


• LM_LICENSE_FILE (for all systems)
• PROMAX_DATA_HOME (for all systems)
• PROMAX_HOME (for all systems)
• LD_LIBRARY_PATH (for Linux)

You may also need to set PROMAX_PORT_MENU_HOME if


your menu includes another menu. For more information about
setting up a ProMAX environment, refer to the System
Administration guide and/or the Promax command script.

Once you have set up a ProMAX environment, you can type:

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.

You can also execute pwin by typing:

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

Other Docs Search Page Known Problems


pwin291 Developer’s Programming Guide

mouse pointer into the pwin window. Remember to save the


new edits to the disk file or pwin will not see them, since pwin
reads the menu disk file each time you return to the menu
window.

Other Docs Search Page Known Problems


Example Macro: Display Shots with AGC292 Developer’s Programming Guide

Example Macro: Display Shots with AGC

A ProMAX macro is a menu file which combines previously-


existing ProMAX menus into a new menu file. A macro can
show any, none, or all of the parameters from the original
menus to the user. The value of parameters that are not shown to
the user are set within the menu.

The purpose of a macro is to combine several processing steps


into a single menu and to require the user to select only the
minimum number of processing parameters. An example
ProMAX macro is shown below. This macro is called Display
Shots with AGC; it combines Disk Data Input, Automatic Gain
Control, and Screen Display into a single menu. The menu only
has four parameters that need to be selected. The rest of the
parameters are set within the menu to values that are
appropriate to a flow which is used to quickly check the quality
of seismic shot records. Even a relatively unexperienced data
processor or unexperienced ProMAX operator could set up and
parameterize Display Shots with AGC, while that same
operator might have difficulty selecting the 50 parameters in a
flow that had Disk Data Input, AGC, and Screen Display.

'(
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

Other Docs Search Page Known Problems


Example Macro: Display Shots with AGC293 Developer’s Programming Guide

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: "1-10000"
mouse_text: "Use Mouse Button 1 to access the editor and\
define your desired input source order list."

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 )

Other Docs Search Page Known Problems


Example Macro: Display Shots with AGC294 Developer’s Programming Guide

)
)
("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)
)
)
)

Other Docs Search Page Known Problems


Example Macro: Display Shots with AGC295 Developer’s Programming Guide

The form of a macro menu is very similar to that of a regular


menu. There is a Menu Heading and a section for Parameter
Specifications, which only specifies those parameters that the
user is to be shown. There is an exec_data section, in which
modules to be executed are listed and the parameter values for
each module are set, either via the menu parameters or by being
explicitly specified with a numerical value or character string.
Finally, there is a rules section, which primarily governs the
behavior of the parameters, such as which parameters will be
shown to the user. Writing a macro normally involves cutting
and pasting existing menus and filling in appropriate values for
those parameters that are not shown to the user.

Other Docs Search Page Known Problems


Example Macro: Display Shots with AGC296 Developer’s Programming Guide

Other Docs Search Page Known Problems


297 Developer’s Programming Guide

Helpfiles

Documentation is an important part of the ProMAX system.


You should write a helpfile for your new process if it is going to
be used in a production processing environment. Please contact
any member of the Documentation Department for assistance.

This chapter describes how to make a helpfile for your new


process and display it in the ProMAX help system.

Topics covered in this chapter:


➲ How Helpfiles Are Accessed
➲ FrameMaker-formatted Helpfiles
➲ Starting FrameMaker
➲ Creating a New Helpfile
➲ Editing a Helpfile
➲ Working with FrameMaker Files
➲ Helpfile Organization
➲ Example Helpfile
➲ Theory
➲ Usage
➲ References
➲ Parameters
➲ Interactive Display
➲ Common Error Messages
➲ Customizing the User Interface
➲ Hypertext

Other Docs Search Page Known Problems


How Helpfiles Are Accessed298 Developer’s Programming Guide

How Helpfiles Are Accessed

The ProMAX and SeisSpace User Interfaces access helpfiles


based upon the menu name defined in the Processes list for
ProMAX, and the ProcessesPM list for SeisSpace.

Here is an example snip from a ProMAX Processes list:

("Amplitude ___________________________________"
("Automatic Gain Control" "agc")
("Time-Variant Scaling" "tvs")

("True Amplitude Recovery" "tar")

In this example the name of the agc menu file is agc.menu as


the extension of .menu is implied. When a user requests help on
a process from either ProMAX or SeisSpace, the script
$PROMAX_HOME/port/bin/PromaxHelp is involked, and the
base name (i.e. agc) is passed to this script. Here is a portion of
that script:

function promaxhelpinternal # sticky type name file geom


link
{
if [ $1 = "yes" ]; then
sticky="-s"
fi
case $2 in
lok) ‘promaxpath sys/exe/aviewer‘ -f $4 $6;;
pdf) LANG=C ACRO_INSTALL_DIR=‘promaxpath
sys/bin/AcrobatReader/Reader‘ ‘promaxpath
sys/bin/AcrobatReader/bin/acroread‘ -tempFile -
useFrontEndProgram -name ProMAX -geometry $5 $4;;
help) ‘promaxpath port/bin/Showfile‘ -t $3 -X '-
geometry $5' $sticky $4 ;;
html) netscape $4;;
*) print -u2 "Unknown type $2"
esac
}

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.

Other Docs Search Page Known Problems


FrameMaker-formatted Helpfiles299 Developer’s Programming Guide

FrameMaker-formatted Helpfiles

At Landmark, we use Adobe FrameMaker to generate and edit


most of our online and printed software documentation. This
chapter describes how to create and edit FrameMaker-formatted
helpfiles and save them as Adobe Acrobat PDF files.

Starting FrameMaker
Follow these steps to start FrameMaker at Landmark:

1. Login to charon

2. cd /usr/local/frame/bin

3. setenv DISPLAY your_workstation:0

4. maker

Creating a New Helpfile


Follow these steps to create a new helpfile from a template:

1. Click on Open and select any helpfile from the latest


working directory.

2. Select Save As from the File menu and enter a unique


file name. The filename should have the format
process_name.fm

3. Replace the contents of the helpfile template with your


text.

4. Create a PDF version of your help and place it in the


$PROMAX_HOME/port/help/product_name directory.
The helpfile name should match the name of the menu
which calls it. Example: agc.pdf is the help for agc.menu.

Editing a Helpfile
Follow these steps to edit an existing helpfile:

Other Docs Search Page Known Problems


FrameMaker-formatted Helpfiles300 Developer’s Programming Guide

1. Click on Open and select the helpfile.

2. Unlock the file (if it is locked) with the following keystroke


sequence:

<Ctrl>-r, <shift>-F, l, k (commas separate


keystrokes)

You can tell a helpfile is locked if it appears without the


menu options across the top of the window. If you want to
edit the document, the file must be unlocked; if you want to
activate the hypertext, it must be locked (use the same
keystroke sequence lock the file).

3. Make your changes and save the file.

4. Create a PDF version of your help and place it in the


$PROMAX_HOME/port/help/product_name directory.
The helpfile name should match the name of the menu
which calls it. Example: agc.pdf is the help for agc.menu.

Working with FrameMaker Files


Always edit the master copies of the helpfiles in the latest
release directory of $PROMAX_HOME/port/help. Please do
not make a personal copy of a helpfile, edit it at your leisure,
and then return the copy to $PROMAX_HOME/port/help.
While you are working on your copy, someone else may edit the
original; when you return yours to the directory, you will wipe
out the other person’s edits.

In the course of working with helpfiles, you may encounter a


number of files that FrameMaker automatically generates. The
following sections describe these files.

Other Docs Search Page Known Problems


FrameMaker-formatted Helpfiles301 Developer’s Programming Guide

Lock Status Files (*.lck)


The built in file locking feature in FrameMaker prevents
parallel edits. If someone attempts to open a file you are editing,
they will get the following message:

File In Use Message

This information comes from a lock status file that is written


when you open the file. When someone else attempts to open
the file, FrameMaker displays the contents of the lock status
file.

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.

Other Docs Search Page Known Problems


FrameMaker-formatted Helpfiles302 Developer’s Programming Guide

Recover files (*.recover)


Sometimes when you open a FrameMaker file, you will get a
message stating, “A recover file exists.” This warning means
that a recover file was made while frame was crashing during an
earlier editing session. Since the integrity of this file unreliable,
do no open the recover file.

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.

Backup Files (*.backup)


FrameMaker documents are set so that whenever a file is saved,
the previous version of the file is renamed to
helpfile_name.lok.backup. This file is usually present, even if
the document is exited normally. You can open the backup file
using Open.

Other Docs Search Page Known Problems


Helpfile Organization303 Developer’s Programming Guide

Helpfile Organization

The following pages describe the organization of a helpfile. We


have included examples to make writing your helpfile easier.

FrameMaker helps you organize your information with


paragraph and character formats. Paragraph formats have names
that correspond to the sections to which they are typically
applied. For example, the title of a helpfile uses the paragraph
format Helpfile Title. The list of predefined paragraph formats
should handle most of the documentation formatting issues that
you might experience when creating a ProMAX helpfile. Please
try to avoid customizing the formats. The actual body of the
document—such as the text that you are reading now—uses the
text or body paragraph format. You can modify the text with
character formats, but use these modifications sparingly and
only as needed for clarity.

Other Docs Search Page Known Problems


Example Helpfile304 Developer’s Programming Guide

Example Helpfile

This section provides the purpose and a short description of a


process. Begin the first sentence with the exact process name
and bold it. The following paragraph provides an example:

Differential Autostatics measures time shifts between


unstacked traces in common receiver and shot gathers.

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:

A = Convolution Matrix, (rows ≥ columns)

Other Docs Search Page Known Problems


Example Helpfile305 Developer’s Programming Guide

T
A = transpose of A

W = diagonal weighting matrix

X = column vector of filter coefficients

Y = trace values being predicted

The elements of W are computed from the prediction error of


the past iteration. Each Y is predicted by the filter X vector
dotted into the corresponding row of A (past trace values).

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 )

The above system becomes:

C X = D where the main diagonal of C is augmented by


white noise, and then solved for X by Gauss-Seidel iteration.

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:

Header Output: Tau-P creates new header entries called


SLOWNESS, TAUMIN, and TAUPIN. SLOWNESS is the P
value for the trace, TAUMIN is the Tau value of sample one of
the trace, and TAUPIN contains information used by the inverse
transform. Required input trace headers are CDP and OFFSET
for prestack data and CDP, CDP_X and CDP_Y for stacked
data.

References
If you use the 90% rule discussed in the preceeding theory
section, you can use the References section to supply our clients

Other Docs Search Page Known Problems


Example Helpfile306 Developer’s Programming Guide

with the remaining 10% of the information about a process. Cite


any important or relevant publications that you used in the
research of your process. Use the following formats for
references:

Paper from journal


Author’s last name, initials, year. Title of paper (capitalize only
proper nouns). Journal, v. x, p.xx-xx.

Books
Author’s last name, initials, year. Book title (capitalize only
proper nouns). City of publication, publisher, xxx p.

Refer to the SEG Instructions to Authors for more information


on references.

Parameters
Write the parameter exactly as it appears in the process.

The parameter explanation should be as clear and concise as


possible. Our clients should know what input is expected for
any given parameter within the first two sentences. It is also
helpful if you include the default or expected input range for all
parameters. For clarity, we are using the following styles:

The parameter requires hand entered information, such as:


Maximum trace length to display

Enter the maximum trace length in ms.

The parameter requires a selection, such as:


Has NMO been applied

Select Yes to display NMO applied data.

or

Other Docs Search Page Known Problems


Example Helpfile307 Developer’s Programming Guide

Types of trace statistics to compute

Select trace statistics to compute and write to the TRC database.


The statistics include:

• TRC_AMPL: average trace energy

• FB_AMPL: average first break energy

• PRE_FB_A: average pre-first break energy

The parameter appears after another parameter is selected, such as:


Percent velocity scale factor

This appears if Yes to Adjust output velocities by


percentages?. Enter the percentages to scale velocities in
time and space. An example of the format is given in the edit
window.

or

Minimum velocity

This appears if Calculated or 1/v2 to Velocity input.


Enter a minimum velocity.......

The preceeding sentences are not grammatically correct, but we


use the structure in order to give our audience a concise
statement of when this parameter appears in a process.

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.

Common Error Messages


Common Errors Message is another optional section that
follows the Parameters section. For an example, see GeoQuest
Horizon Output.

Other Docs Search Page Known Problems


Example Helpfile308 Developer’s Programming Guide

Customizing the User Interface


Customizing the User Interface is another optional section. The
System Administration manual covers most of the information
that our clients will need for customizing their user interface,
but if you need to include additional information, see Trace
Display.

Other Docs Search Page Known Problems


Hypertext309 Developer’s Programming Guide

Hypertext

Hypertext links documents in the online help system. Hypertext


is a word or group of words that, when clicked upon, will cause
a jump to a different part of the current document or to an
entirely different document. The hypertext character format
(which appears as red italics) helps the reader identify
hyperactive text. However, in addition to marking the text with
the hypertext character format, you will also have to embed the
actual hypertext jump commands in your document.

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.

Other Docs Search Page Known Problems


Hypertext310 Developer’s Programming Guide

Other Docs Search Page Known Problems


311 Developer’s Programming Guide

Code Standards

This chapter outlnes the standard coding practices that should


be used in ProMAX coding. The goal is to produce source code
that is standardized and easy to maintain. The most important
guideline is this: write your code with the expectation that
someone else will be trying to understand it.

Topics covered in this chapter:


➲ C Coding Standards
➲ FORTRAN Coding Standards
➲ Portable Code

Other Docs Search Page Known Problems


C Coding Standards312 Developer’s Programming Guide

C Coding Standards

At Landmark, we use Recommended C Style and Coding


Standards by Cannon et. al. as a general coding guideline and
make the following additions:

1. Comment the code liberally but intelligently. Very few C


programmers provide enough comments in their code to
allow other programmers to easily understand it.
Comments should answer the question “What is going on
in this block of code?” On the other hand, comments
should not state the obvious or repeat what is in the code. If
you spend much time explaining yourself during code
walk-throughs, your comments are inadequate.

2. 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.

3. Always choose clarity over efficiency on the initial


development of an application. Code can be modified later
if speed improvements are necessary. In general, only
processes that are performed on a sample by sample or
pixel by pixel basis need to be optimized. If the program
does not work or is not maintainable, it does not matter
how fast it is.

4. Always measure program speed before attempting to make


efficiency changes (which may not be required). Use the
profiler to find slow code structures. If too much
modification is needed to make code efficient, a new
algorithm is probably needed.

5. Functions should be simple and singular in purpose. The


length of functions should generally be less than about four
pages each. If they are longer, you may be combining
functionality that should be separated.

6. If you use the same code in several places, make it a


function. Some discretion is warranted; for example, three
lines of code used in two places should not be replaced by
a function. In many cases, a routine already exists that
would do the job. Also, when you create a new routine,
consider whether it would be of use to the rest of the

Other Docs Search Page Known Problems


C Coding Standards313 Developer’s Programming Guide

programming staff; if so, include it in the libraries and the


documentation.

7. Never make a copy of a function and then modify it


slightly. If the original function is not quite what you want,
it is better to add the desired functionality than to have two
copies that are nearly the same.

8. If a function returns a special value for error conditions


(such as a NULL pointer), it should also set the external
variable errno with a value that does not overlap the system
values or the values of any other ProMAX function. See
/advance/port/include/*err.inc and
/advance/port/include/*err.h for error values that are
already reserved. New error values should be handled in
the function reportPromaxErr().

9. Variable and function names should be long enough to


clearly express their meaning. When naming subroutines
and functions, avoid obvious names that might be defined
elsewhere in the system.

10. Use underscores OR mixed case consistently to delimit


words within a function or variable name, but not both.

11. In addition to using the assert facility, include fprintf’s to


stderr that can be used later to diagnose problems, and
leave them in the production code. These statements should
be disabled by default, but should be enabled by setting the
environmental variable PROMAX_DEBUG.

12. If you are developing anything that is somewhat


complicated, include a main() that can be used to test the
functions later (do not forget to #ifdef out the main() for
production purposes). The main should contain internal
checks that can be used to determine if the functions are
producing good results.

13. Use Purify on your code as standard procedure before you


check it in to the production libraries.

ProMAX C Routine Documentation


When writing a C language routine intended for general
usage, please use the following source layout for

Other Docs Search Page Known Problems


C Coding Standards314 Developer’s Programming Guide

documenting its purpose, arguments, return values and


special notes:
• Place the return value (if any) on the same line as the
function body declaration, i.e. use
float cvtibm(float ibm_in)

and not
float
cvtibm(float ibm_int)

• Place the documentation as a comment block immedi-


ately after the function declaration. Begin the comment
lines with /********** (a forward slash followed by at least
10 asterisks) and end the block of lines with **********/
(at least 10 asterisks followed by a forward slash.) Inter-
nal sections of the documentation should be separated
by a row of (at least 5) asterisks.
• Begin the documentation comments with one or more
lines describing the purpose of the routine.
• Follow the purpose section with a description of the
arguments and return value. Do not describe more than
one argument per line. Divide this section into up to
three groups separated by blank lines, entitled "Input:",
"Output:" and "Returned:". If an argument is both an
input and an output, list it in both sections.
• After the argument section, place any further sections
you may want, for example Notes, References, and
Author sections.
The following code shows an example of recommended C
documentation style.
float cvtibm(long ibm_in)
/*******************************************************
Convert IBM hexadecimal floating point numbers
********************************************************
Input:
in_ibm IBM floating point number to be converted

Returned:native floating point equivalent


********************************************************
Notes:
Converts to IEEE standard format and uses the xdr library
to convert from there.
********************************************************
Author:Anonymous, Jan. 24, 2000
*******************************************************/
{ /* begin function body ... */

Other Docs Search Page Known Problems


FORTRAN Coding Standards315 Developer’s Programming Guide

FORTRAN Coding Standards

This section outlines general FORTRAN coding practices.

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.

Avoid hidden interdependencies, particularly FORTRAN


common blocks. As a rule of thumb, do not create a common
block until the number of calling arguments to a routine is 20 or
more. If you do break down and use a common block, be sure
that it is placed in an include file and not directly in the code.
This ensures that you will not give the same variable different
names in different places, and that you will not change the
common block in one place and forget to change it in another.

Avoid fixed length arrays. Not only do they waste memory


resources, but they are rarely assured to be long enough in all
cases. Use the memory management routines, even in stand-
alone programs. One of the features of ProMAX is that there are
virtually no built-in limits.

When you use the memory management routines, you should


normally pass the buffers into routines where they can be
assigned a meaningful name and indexed starting at array
element 1. In other words, avoid this type of code:

CALL MEMORY_RESBUFF( LENGTH, IX_WORK, IERR )


DO 100 I=1,LENGTH
ISPACEz(IX_WORK+I-1) = X(I)
100 CONTINUE

Always choose clarity over efficiency on the initial development


of an application. Code can be modified later if speed
improvements are necessary. In general, only processes that are
performed on a sample by sample or pixel by pixel basis need to
be optimized. If the program does not work or is not
maintainable, it does not matter how fast it is.

Always measure program speed before attempting to make


efficiency changes (which may not be required).

If too much modification is need to make code efficient, a new


algorithm is probably needed.

Other Docs Search Page Known Problems


FORTRAN Coding Standards316 Developer’s Programming Guide

Subroutines and functions should be simple and singular in


purpose. The length of a subroutine or function should
generally be less than about four pages. If they are longer, you
may be combining functionality that should be separated.

If you use the same code in several places, make it a subroutine


or a function. Some discretion is warranted; however, three
lines of code used in two places should not be replaced by a
subroutine. In many cases, a routine already exists that would
do the job. Also, when you create a new routine, consider
whether it would be of use to the rest of the programming staff.

True constants should be set using the PARAMETER statment,


as should any immutable values such as PI or E (or any other
magic numbers).

If you have a very complicated expression having many levels


of parentheses, break it up into two or more expressions.

Do not rely too heavily on FORTRAN precedence among


operations; use parentheses instead. The precedence is:
exponentiation, multiplication and division, and then addition
and subtraction.

Never mix variables types in an expression. Always use type


conversion functions such FLOAT, INT, NINT, etc.

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

General Text File Format


The maximum line length is 72 columns.

Use fortran-mode in emacs when writing FORTRAN code.

No tabs should exist in any FORTRAN code or include files.


When you are using fortran-mode in emacs, tabs will be
converted to spaces.

All indentations (in loops and IF structures) should be 4 spaces.


If your code is deeply nested and you run out of space, you

Other Docs Search Page Known Problems


FORTRAN Coding Standards317 Developer’s Programming Guide

probably have a design problem and should be breaking


segments of the code into individual routines.

Statement labels should be used on all DO loops, and each DO


statement should reference a unique statement label. Bad
example:

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

Statement labels should appear in ascending order in the code


and should have an increment of 10 or more to allow insertion
of new labels without destroying the ordering.

Variable Naming and Declarations


All FORTRAN code should be in upper case, with comments in
lower case. On occasions when you make a temporary change
to some code, reverse this convention to make the code stand
out as temporary.

Variable names should be long enough to clearly express their


meaning. We do not adhere to the maximum variable name
length of 8 as specified in the FORTRAN 77 Standard. The
same is true for subroutine and function names. When naming
subroutines and functions, avoid obvious names that might be
defined elsewhere in the system.

The IMPLICIT NONE statement must appear in all code,


forcing all variables to be declared.

Despite all variables being declared, the FORTRAN default


types should be adhered to. All integer variables should begin
with I-N, and all others are real, with the exception that only
character variables should begin with C.

Other Docs Search Page Known Problems


FORTRAN Coding Standards318 Developer’s Programming Guide

Avoid non-standard variable types, such as I*2, I*1, etc. If you


need to use these variables types, you probably should be
programming in C.

Know the difference between character strings and character


arrays. A character string is declared as:

CHARACTER CWORK*8

while a character array is declared as:

CHARACTER CWORK(8)

These variable types are as different from each other as


LOGICAL is from REAL*8. The important difference is that a
character string has an associated length. Character arrays can
be safely passed to C routines, while character strings cannot
(there is no way to know where the length will go when a
character string is passed). In general character strings create
portability problems and should be used sparingly.

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.

If a routine takes a character string as an input argument and the


routine will need to recognize the character string (a name for
example), be sure that character constants are padded out to the
correct length. For example, this code will fail on some
machines (8 characters are expected):

CALL EX_GETPARM( 'XLOC', 1, XLOCATION )

but this will always work:

CALL EX_GETPARM( 'XLOC ', 1, XLOCATION )

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"

Other Docs Search Page Known Problems


FORTRAN Coding Standards319 Developer’s Programming Guide

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).

Be aware that the C preprocessor knows nothing about Fortran


source code format and will happily generate lines longer than
72 characters. Judicious use of continuation lines are suggested.
For example:

#define VLONG 'a very very long string to substitute...'


CHARACTER*(*) TITLE
PARAMETER(TITLE=
&VLONG
&)

maximizes the space available for the VLONG text string.

Another thing to avoid within Fortran source is the character


combination /*, i.e. the beginning of a C comment. Most C
preprocessors will by default remove C comments. All
characters from that /* up to any following */ will disappear,
leading to very confusing Fortran compiler error reports.

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.

Comments should begin with “C ..... “ for readability. The first


letter of the comment should always line up with the code that
follows. Put comments inside the part of an IF structure that
applies to the comments.

Each subroutine should have a reasonable description that


explains it basic purpose.

Other Docs Search Page Known Problems


FORTRAN Coding Standards320 Developer’s Programming Guide

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

is easier to read than:

IF(GL.LT.0.0.AND.GE.GE.GMAX) THEN

just like:

“Source code statements should read like sentences”

is easier to read than:

“Amassofcharacterswithoutblanksisdifficulttoread”

Avoid too many blank lines; however, it is nice to be able to see


a reasonable number of lines of source code on the screen at the
same time.

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:

IF ( NSAMPS .EQ. 1 ) THEN


X = Y
J0 = 0
ELSEIF ( NSAMPS .EQ. 2 ) THEN

Other Docs Search Page Known Problems


FORTRAN Coding Standards321 Developer’s Programming Guide

X = Y2
ENDIF

GOTO statements should be avoided and computed GOTO


statements are forbidden. Multiple RETURN statements within
a routine should also be avoided.

Miscellaneous
The source code for a particular processing tool should be kept
in a unique directory and include the associated include file.

Keep FORMAT statements close to the code where they are


being used, or preferably imbed them in the code like this:

READ (*,’(A8,3I8)’) CWORK, I, J, K

In general, you should not need to use many FORMAT


statements, since most I/O is handled for you by the Executive,
the error routines, and the graphical user interface.

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.

ProMAX Fortran Routine Documentation


When writing a Fortran language routine intended for general
usage, please use the following source layout for document-
ing its purpose, arguments, return values and special notes:
• Place the documentation as a comment block immedi-
ately before the FUNCTION or SUBROUTINE definition.

Other Docs Search Page Known Problems


FORTRAN Coding Standards322 Developer’s Programming Guide

• Begin each line of the documentation block with the two


character sequence CX. Use CX-prefixed blank lines to
improve readability between sections of the documenta-
tion.
• Begin the documentation comments with a duplicate of
the SUBROUTINE or FUNCTION statement complete
with all its arguments. For internal readability, bracket
this between 'CX-----------------------------' lines.
• Follow this with a Description: section bfirefly giving the
purpose of the routine.
• Next document the routine’s arguments and return
value. Do not describe more than one argument per line.
Divide this section into up to three groups separated by
blank lines, entitled "Input:", "Output:" and "Returned:".
If an argument is both an input and an output, list it in
both sections.
• After the argument section, place any further sections
you may want, for example Notes, References, Author
and See Also sections.
• Finish with a final ‘CX----------------------------------’ for
consistency.
The following code shows an example of recommended
Fortrandocumentation style.float cvtibm(long ibm_in)
CX------------------------------------------------------
CX REAL FUNCTION CVTIBM(IBM_IN)
CX------------------------------------------------------
CX Description:
CX Convert IBM hexadecimal floating point numbers
CX
CX Input:
CX IN_IBMIBM floating point number to be converted
CX
CX Return value: Native floating point equivalent
CX
CX See Also:
CX CVTIEEE
CX
CX Author:Anonymous, Jan. 24, 2000
CX------------------------------------------------------

REAL FUNCTION CVTIMB(IBM_IN)


INTEGER IBM_IN
etc.

Other Docs Search Page Known Problems


Portable Code323 Developer’s Programming Guide

Portable Code

Since ProMAX products are offered on multiple hardware


platforms, it is important to make your code a portable as
possible. Portable code minimizes compiler and runtime errors
with new compiler releases, new hardware platforms, and new
operating systems. Here are some rules that have been derived
from experience.

1. Never hard-code the size of any numerical type; always use


the sizeof() operator when programming in C.

2. The size of a pointer is not the same as other numerical


types on all machines; do not make this assumption in your
code (particularly true on SGI 64-bit machines).

3. Do not assume that a divide-by-zero operation is


acceptable to all machines. On some platforms this is a
hard error. Always protect from dividing by zero in your
code.

4. Do not assume that all FORTRAN compilers initialize


automatic variables to 0 (particularly true on SGI 64-bit
machines).

5. Be watchful for argument aliasing whereby the same


variable or array is passed to a subroutine under two
different names. In particular do not do this for output
arguments if there is a possibility that the same location
may be changed in both arguments. Note that ProMAX
does use argument aliasing when it passes the header array
twice, once as INTEGER and once as REAL. This
particular usage is safe because no location in the trace
header is simultaneously an INTEGER and a REAL.

Other Docs Search Page Known Problems


Portable Code324 Developer’s Programming Guide

Other Docs Search Page Known Problems


325 Developer’s Programming Guide

Man Page Reference

This appendix provides an overview of the UNIX man facility.

Topics covered in this chapter:


➲ Using the Man Pages
➲ Finding What You Want

Other Docs Search Page Known Problems


Using the Man Pages326 Developer’s Programming Guide

Using the Man Pages

The man pages contain online information for selected C++, C,


and Fortran routines. You may use the UNIX man command if
you add $PROMAX_HOME/port/man to your MANPATH
environmental variable. You can access man pages via the
command:

$PROMAX_HOME/port/bin/aman

or simply aman if this directory exists in your path. aman is a


script that calls man after adding $PROMAX_HOME/port/man
to your man path.

The following list describes the key man pages:

• c_promax: This man page will give you an overview of


the C ProMAX routines.

• fortran_promax: This man page will give you an


overview of the Fortran ProMAX routines.

• cs#: These man pages will give you information pertaining


to the C Section # of the man pages. Note that # represents
the section number to be referenced.

• fs#: These man pages will give you information pertaining


to the Fortran Section # of the man pages. There may also
be an introduction section in the Fortran version.

Other Docs Search Page Known Problems


Finding what you want327 Developer’s Programming Guide

Finding what you want

If you are not sure which routine you are looking for, you can
type the command

aman -k keyword

where “keyword” is the descriptive word for which you are


looking. For example, to find all of the routines that deal with
ProMAX tables, type aman -k table. This will give you a
long list of all of the C and FORTRAN routines. In this case, to
further limit the list, you can type the command

aman -k table | fgrep "C routine" | fgrep -i add

to list all C table routines that deal with adding points.

To see all ProMAX routines at once, type aman c_promax if


you are programming in C, or aman f_promax if you are
programming in FORTRAN.

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.

Other Docs Search Page Known Problems


Finding what you want328 Developer’s Programming Guide

Other Docs Search Page Known Problems


329 Developer’s Programming Guide

Appendix: Expanded Directory


Structure

This appendix lists the ProMAX Expanded Directory Structure.

Topics covered in this appendix:


➲ Expanded Directory Structure

Other Docs Search Page Known Problems


Expanded Directory Structure330 Developer’s Programming Guide

Expanded Directory Structure

$PROMAX_HOME

. linux/ (sys/ -> linux/ on Linux 32-bit machines)

. linux64/ (sys/ -> linux64/ on Linux 64-bit machines)

. . bin/

. . . promax

. . . promaxvsp

. . . promax3d

. . . promax4d

. . . emacs

. . . .

. . exe/

. . . exec.exe

. . . superExec

. . . autostat.exe

. . . dbmath.exe

. . . .

. . . showfile

. . . .

. . lib/

. . . libmaxexec.so

. . . libmaxtool1.so

Other Docs Search Page Known Problems


Expanded Directory Structure331 Developer’s Programming Guide

. . . libmaxtool2.so

. . . libmaxtool3.so

. . . libmaxutil.so

. . . libmaxui.so

. . . libagfc.so

. . . libXaw.so

. . . libXhp.so

. . . sdi/ (-> ../nodist/lib/sdi/)

. . . . libxcgm.a

. . . .

. . obj/

. . . bin/

. . . . promax/

. . . . . .

. . . . .

. . . exe/

. . . . exec/

. . . . . c_exec.o

. . . . . exec.o

. . . . . toolcall.o

. . . . . .

. . . . autostat/

. . . . . .

Other Docs Search Page Known Problems


Expanded Directory Structure332 Developer’s Programming Guide

. . . . .

. . . lib/

. . . . maxtool/

. . . . . cgmplot/

. . . . . cgmplot.o

. . . . . c_cgmplot.o

. . . . . cgmplot_combined.o

. . . . . rf/

. . . . . cfstack.o

. . . . . .

. . . . . .

. . . . .

. . nodist/

. . . lib/

. . . . sdi/

. . . . . libxcgm.a

. . .

. .

. port/

. . bin/

. . . Makeexec

. . . .

. . misc/

Other Docs Search Page Known Problems


Expanded Directory Structure333 Developer’s Programming Guide

. . . header.inc

. . . color_tbl_b

. . . .

. . . fontimage0

. . . fontimage1

. . . .

. . menu/

. . . promax/

. . . . Processes

. . . . agc.menu

. . . . .

. . . promaxvsp/

. . . . Processes

. . . . agc.menu

. . . . .

. . . promax3d/

. . . . Processes

. . . . agc.menu

. . . . .

. . help/

. . . promax/

. . . . agc.pdf

. . . . .

Other Docs Search Page Known Problems


Expanded Directory Structure334 Developer’s Programming Guide

. . . promaxvsp/

. . . . agc.pdf

. . . . .

. . . promax3d/

. . . . agc.pdf

. . . . .

. . man/

. . . man1/

. . . . .

. . . .

. . include/

. . . header.inc

. . . cglobal.h

. . . cpromax.h

. . . cwp.h

. . . .

. . . private/

. . . . .

. . . interface/

. . . . .

. . . make/

. . . . advance.make

. . . . maxexec.make

Other Docs Search Page Known Problems


Expanded Directory Structure335 Developer’s Programming Guide

. . . . maxprog.make

. . . .

. . . X11/

. . . . Xaw/

. . . . . Box.h

. . . . . .

. . . sdi/ ( -> ../nodist/include/sdi/)

. . . . cgm.h

. . . . portable.h

. . . .

. . src/

. . . bin/

. . . . promax/

. . . . . .

. . . . emacs/

. . . . . ./

. . . . . .

. . . exe/

. . . . exec/

. . . . . Makefile

. . . . . c_exec.c

. . . . . exec.f

. . . . . toolcall.f or toolcall.c

Other Docs Search Page Known Problems


Expanded Directory Structure336 Developer’s Programming Guide

. . . . . .

. . . . 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/

Other Docs Search Page Known Problems


Expanded Directory Structure337 Developer’s Programming Guide

. . . . . .table.f

. . . . . .

. . . . maxui/

. . . . . Makefile

. . . . . .

. . . . cwp/

. . . . . Makefile

. . . . . .

. . . . X11/

. . . . . Xaw/

. . . . . Makefile

. . . . . Box.c

. . . . . .

. . nodist/

. . . include/

. . . . sdi/

. . . . . cgm.h

. . . . . portable.h

. etc/

. . config_file

. . .

Other Docs Search Page Known Problems


Expanded Directory Structure338 Developer’s Programming Guide

Other Docs Search Page Known Problems


339 Developer’s Programming Guide

Appendix: C Programming Examples

This appendix provides examples of introductory C


programming processes.

Topics covered in this appendix:


➲ Example include files
➲ cglobal.h
➲ cpromax.h
➲ Example simple processes
➲ simple.menu
➲ simple.c
➲ ampRatio.c

Other Docs Search Page Known Problems


Example Include Files340 Developer’s Programming Guide

Example Include Files

The following pages contain samples of two important .h files


in the ProMAX C environment, cglobal.h and cpromax.h. Both
files are kept in the ProMAX environment under the
$PROMAX_HOME/port/include directory. We encourage you
to look at the files sent with the release because they will reflect
the most recent changes.

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.

Other Docs Search Page Known Problems


cglobal.h341 Developer’s Programming Guide

cglobal.h

/* C globals for ProMAX - equivalent to global.inc */

#ifndef CGLOBAL_H
#define CGLOBAL_H

#include <sys/types.h>

/* define logical variables as integers */


typedef int logical;

/* 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

#if defined (CRAY)


GlobalChar GLOBAL_CHARCZ;
GlobalChar *globalChar = &GLOBAL_CHARCZ;
#elif defined (CONVEX)
extern GlobalChar _global_charcz_;
GlobalChar *globalChar = &_global_charcz_;
#elif defined SOLARIS
extern GlobalChar global_charcz_;
GlobalChar *globalChar = &global_charcz_;
#else
extern GlobalChar global_charcz_;
GlobalChar *globalChar = &global_charcz_;
#endif

#else

#if defined (CRAY)


extern GlobalChar GLOBAL_CHARCZ, *globalChar;
#elif defined (CONVEX)
extern GlobalChar _global_charcz_, *globalChar;
#else
extern GlobalChar global_charcz_, *globalChar;
#endif

#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 */

Other Docs Search Page Known Problems


cglobal.h342 Developer’s Programming Guide

logical imultc; /* true if data is multi-component */


int ntrace; /* number of traces used to initialize database */
logical icdpasn; /* true if CDP bins have been assigned */
logical igeoasn; /* true if geometry has been assigned */
logical imarine; /* true if data is marine */
logical inoexit; /* SAJ true if executive is no exiting */
int ipad[6]; /* padding to 16 words */
} GlobalMisc;

#ifdef DEFINE_CGLOBALS

#if defined (CRAY)


GlobalMisc GLOBAL_MISCCZ;
GlobalMisc *globalMisc = &GLOBAL_MISCCZ;
#elif defined (CONVEX)
extern GlobalMisc _global_misccz_;
GlobalMisc *globalMisc = &_global_misccz_;
#elif defined SOLARIS
extern GlobalMisc global_misccz_;
GlobalMisc *globalMisc = &global_misccz_;
#else
extern GlobalMisc global_misccz_;
GlobalMisc *globalMisc = &global_misccz_;
#endif

#else

#if defined (CRAY)


extern GlobalMisc GLOBAL_MISCCZ, *globalMisc;
#elif defined (CONVEX)
extern GlobalMisc _global_misccz_, *globalMisc;
#else
extern GlobalMisc global_misccz_, *globalMisc;
#endif

#endif /* DEFINE_CGLOBALS */

/* choices for globalMisc->iunits - type of units */


#define IENGLISH 1
#define IMETRIC 3
/* shorthand for easier typing and reading of code */
#define IUNITSz (globalMisc->iunits)

/* 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) */

Other Docs Search Page Known Problems


cglobal.h343 Developer’s Programming Guide

logical igeom_match; /* true if header geometry matches database */


logical itrno_valid; /* true if trace number can index database */
logical init_only; /* true if initialization phase only */
int num_execs; /* the number of execs in a disributed job */
int exec_num; /* the index of the current execs in a distributed job */
int ipad[13]; /* padding to 32 words */
} GlobalRuntime;

#ifdef DEFINE_CGLOBALS

#if defined (CRAY)


GlobalRuntime GLOBAL_RUNTIMECZ;
GlobalRuntime *globalRuntime = &GLOBAL_RUNTIMECZ;
#elif defined (CONVEX)
extern GlobalRuntime _global_runtimecz_;
GlobalRuntime *globalRuntime = &_global_runtimecz_;
#elif defined SOLARIS
extern GlobalRuntime global_runtimecz_;
GlobalRuntime *globalRuntime = &global_runtimecz_;
#else
extern GlobalRuntime global_runtimecz_;
GlobalRuntime *globalRuntime = &global_runtimecz_;
#endif

#else

#if defined (CRAY)


extern GlobalRuntime GLOBAL_RUNTIMECZ, *globalRuntime;
#elif defined (CONVEX)
extern GlobalRuntime _global_runtimecz_, *globalRuntime;
#else
extern GlobalRuntime global_runtimecz_, *globalRuntime;
#endif

#endif /* DEFINE_CGLOBALS */

/* shorthand for easier typing and reading of code */


#define NUMSMPz (globalRuntime->numsmp)
#define SAMPRATz (globalRuntime->samprat)
#define NTHz (globalRuntime->nth)
#define MAXDTRz (globalRuntime->maxdtr)

/* choices for globalRuntime->ipsort - physical primary sort key */


#define ICDP 1 /* cdp bin */
#define ISIN 2 /* source index number */
#define IRECSLOC 3 /* receiver surface location */
#define IOFFSET 4 /* offset */
#define ICHAN 5 /* channel number */
#define IUNKNOWN 6 /* none of the above */
#define IILINE 7 /* 3D inline number */
#define IXLINE 8 /* 3D cross line number */

/* choices for globalRuntime->idtyp - primary data type */


#define INORMAL 0 /* normal unstacked data */
#define IUP_HOLES 1 /* uphole data */
#define IUS_TRANS 2 /* transformed unstacked (e.g., frequency domain) data */
#define IST_TRANS 3 /* transformed stacked (e.g., frequency domain) data */
#define ISTACKED 7 /* normal stacked data */
#define ISNAPSHOTS 8 /* Movie Snap shots from finite difference modeling */

Other Docs Search Page Known Problems


cglobal.h344 Developer’s Programming Guide

/* tape types (should NOT overlap with primary data types) */


#define IFIELD 9
#define IARCHIVE 10
#define IOTHER_TAPE 11

/* globalRuntime->mode - processing executive mode */


#define FROM_SHELL 1 /* job run from the command line */
#define FROM_UI 2 /* job run from the ProMAX user interface */
#define FROM_QUEUE 3 /* job run from a queue */
#define FROM_PROWESS 4 /* ProMAX launched by ProWESS */
/* for historic reasons (avoid) */
#define INTER 1 /* interactive */
#define IBACKG 2 /* background */
#define IBATCH 3 /* batch */

/* globalRuntime->idomain - domain type */


#define ITX 0 /* normal time-space domain */
#define IFX 1 /* frequency-space domain */
#define IFT 2 /* frequency-time domain */
#define IFK 3 /* frequency-wavenumber domain */
#define ITAUP 4 /* tau-p domain */
#define ISEMB 5 /* semblance domain */
#define IMBT 6 /* model-based transform */
#define IDEPTH 7 /* depth-space domain */
#define TSLICE 8 /* time-slice domain */
#define FLEXED 9 /* flex bin data after trace duplication */

/* 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 */

Other Docs Search Page Known Problems


cglobal.h345 Developer’s Programming Guide

char traceLabel[16]; /* the name of the trace axis, usually a header


name */
char frameLabel[16]; /* the name of the frame axis, usually a header
name */
char volumeLabel[16]; /* the name of the volume axis, usually a header
name */
char hypercubeLabel[16]; /* the name of the hypercube axis, usually a
header name */
char sampleDomain[16]; /* the domain of the sample axis */
char traceDomain[16]; /* the domain of the trace axis */
char frameDomain[16]; /* the domain of the frame axis */
char volumeDomain[16]; /* the domain of the volume axis */
char hypercubeDomain[16]; /* the domain of the hypercube axis */
char sampleUnits[16]; /* the units of the sample axis */
char traceUnits[16]; /* the units of the sample axis */
char frameUnits[16]; /* the units of the sample axis */
char volumeUnits[16]; /* the units of the sample axis */
char hypercubeUnits[16]; /* the units of the sample axis */
char cpad[128]; /* the units of the sample axis */
} GlobalSmartFramework;

#ifdef DEFINE_CGLOBALS

#if defined (CRAY)


GlobalSmartFramework SMART_FRAMEWORKCZ;
GlobalSmartFramework *globalSmartFramework = &SMART_FRAMEWORKCZ;
#elif defined (CONVEX)
extern GlobalSmartFramework _smart_frameworkcz_;
GlobalSmartFramework *globalSmartFramework = &_smart_frameworkcz_;
#elif defined SOLARIS
extern GlobalSmartFramework smart_frameworkcz_;
GlobalSmartFramework *globalSmartFramework = &smart_frameworkcz_;
#else
extern GlobalSmartFramework smart_frameworkcz_;
GlobalSmartFramework *globalSmartFramework = &smart_frameworkcz_;
#endif

#else

#if defined (CRAY)


extern GlobalSmartFramework SMART_FRAMEWORKCZ, *globalSmartFramework;
#elif defined (CONVEX)
extern GlobalSmartFramework _smart_frameworkcz_, *globalSmartFramework;
#else
extern GlobalSmartFramework smart_frameworkcz_, *globalSmartFramework;
#endif

#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 */

Other Docs Search Page Known Problems


cglobal.h346 Developer’s Programming Guide

int ntrcdp; /* maximum cdp fold */


int minsin; /* minimum source index number */
int maxsin; /* maximum source index number */
int incsin; /* source index number increment (always 1) */
int nsins; /* total number of SINs (records of all types) */
int maxcps; /* maximum channels per source */
int nshots; /* total number of live sources */
int minofb; /* minimum offset bin number */
int maxofb; /* maximum offset bin number */
int incofb; /* offset bin number increment (always 1) */
int nofbins; /* number of offset bins */
float offbinc; /* offset increment between bins */
float offmax; /* longest offset of line */
int minchn; /* minimum channel number */
int maxchn; /* maximum channel number */
int incchn; /* increment between channel numbers (always 1) */
int nslocs; /* total number of surface locations of all types */
float x3dorig; /* x coordinate of origin of 3D grid (rel. to xref) */
float y3dorig; /* y coordinate of origin of 3D grid (rel. to yref) */
int nilines; /* number of inlines */
int minilin; /* minimum inline number */
int maxilin; /* maximum inline number */
float xilnend; /* x coordinate of far end of first inline */
float yilnend; /* y coordinate of far end of first inline */
float dcdpiln; /* distance between CDPs in the inline direction for
* 3D; mean distance between CDPs for 2D */
int nxlines; /* number of crosslines */
int minxlin; /* minimum crossline number */
int maxxlin; /* maximum crossline number */
float xxlnend; /* x coordinate of far end of first crossline */
float yxlnend; /* y coordinate of far end of first crossline */
float dcdpxln; /* distance between CDPs in the crossline direction */
int incdp_e; /* CDP increment in the inline direction (external) */
int mncdp_e; /* minimum CDP number in survey (external) */
int nxlin_e; /* number of xlines (CDPs per inline) (external) */
int nilin_e; /* number of ilines (inlines per xline) (external) */
int ipad[20]; /* padding to 64 words */
} GlobalGeom;

#ifdef DEFINE_CGLOBALS

#if defined (CRAY)


GlobalGeom GLOBAL_GEOMCZ;
GlobalGeom *globalGeom = &GLOBAL_GEOMCZ;
#elif defined (CONVEX)
extern GlobalGeom _global_geomcz_;
GlobalGeom *globalGeom = &_global_geomcz_;
#elif defined SOLARIS
extern GlobalGeom global_geomcz_;
GlobalGeom *globalGeom = &global_geomcz_;
#else
extern GlobalGeom global_geomcz_;
GlobalGeom *globalGeom = &global_geomcz_;
#endif

#else

#if defined (CRAY)


extern GlobalGeom GLOBAL_GEOMCZ, *globalGeom;

Other Docs Search Page Known Problems


cglobal.h347 Developer’s Programming Guide

#elif defined (CONVEX)


extern GlobalGeom _global_geomcz_, *globalGeom;
#else
extern GlobalGeom global_geomcz_, *globalGeom;
#endif

#endif /* DEFINE_CGLOBALS */

/* ***** ADD 3D STUFF HERE WHEN IT IS READY ***** */

/* 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

#if defined (CRAY)


GlobalCoord GLOBAL_COORDCZ;
GlobalCoord *globalCoord = &GLOBAL_COORDCZ;
#elif defined (CONVEX)
extern GlobalCoord _global_coordcz_;
GlobalCoord *globalCoord = &_global_coordcz_;
#elif defined SOLARIS
extern GlobalCoord global_coordcz_;
GlobalCoord *globalCoord = &global_coordcz_;
#else
extern GlobalCoord global_coordcz_;
GlobalCoord *globalCoord = &global_coordcz_;
#endif

#else

#if defined (CRAY)


extern GlobalCoord GLOBAL_COORDCZ, *globalCoord;
#elif defined (CONVEX)
extern GlobalCoord _global_coordcz_, *globalCoord;
#else
extern GlobalCoord global_coordcz_, *globalCoord;
#endif
#endif

typedef struct globalXYStruct {


double xref; /* X reference point for the line */
double yref; /* Y reference point for the line */
int ipad[4]; /* pad to 8 words */
} GlobalXY;

#ifdef DEFINE_CGLOBALS

#if defined (CRAY)


GlobalXY GLOBAL_XYCZ;
GlobalXY *globalXY = &GLOBAL_XYCZ;
#elif defined (CONVEX)
extern GlobalXY _global_xycz_;
GlobalXY *globalXY = &_global_xycz_;

Other Docs Search Page Known Problems


cglobal.h348 Developer’s Programming Guide

#elif defined SOLARIS


extern GlobalXY global_xycz_;
GlobalXY *globalXY = &global_xycz_;
#else
extern GlobalXY global_xycz_;
GlobalXY *globalXY = &global_xycz_;
#endif

#else

#if defined (CRAY)


extern GlobalXY GLOBAL_XYCZ, *globalXY;
#elif defined (CONVEX)
extern GlobalXY _global_xycz_, *globalXY;
#else
extern GlobalXY global_xycz_, *globalXY;
#endif

#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

#if defined (CRAY)


GlobalAcquis GLOBAL_AQUISCZ;
GlobalAcquis *globalAcquis = &GLOBAL_AQUISCZ;
#elif defined (CONVEX)
extern GlobalAcquis _global_aquiscz_;
GlobalAcquis *globalAcquis = &_global_aquiscz_;
#elif defined SOLARIS
extern GlobalAcquis global_aquiscz_;
GlobalAcquis *globalAcquis = &global_aquiscz_;
#else
extern GlobalAcquis global_aquiscz_;
GlobalAcquis *globalAcquis = &global_aquiscz_;

Other Docs Search Page Known Problems


cglobal.h349 Developer’s Programming Guide

#endif

#else

#if defined (CONVEX)


extern GlobalAcquis GLOBAL_AQUISCZ, *globalAcquis;
#elif defined (CONVEX)
extern GlobalAcquis _global_aquiscz_, *globalAcquis;
#else
extern GlobalAcquis global_aquiscz_, *globalAcquis;
#endif

#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

#if defined (CRAY)


StdHdr STD_HDRCZ;
StdHdr *stdHdr = &STD_HDRCZ;
#elif defined (CONVEX)
extern StdHdr _std_hdrcz_;
StdHdr *stdHdr = &_std_hdrcz_;
#elif defined SOLARIS
extern StdHdr std_hdrcz_;
StdHdr *stdHdr = &std_hdrcz_;
#else

Other Docs Search Page Known Problems


cglobal.h350 Developer’s Programming Guide

extern StdHdr std_hdrcz_;


StdHdr *stdHdr = &std_hdrcz_;
#endif

#else

#if defined (CRAY)


extern StdHdr STD_HDRCZ, *stdHdr;
#elif defined (CONVEX)
extern StdHdr _std_hdrcz_, *stdHdr;
#else
extern StdHdr std_hdrcz_, *stdHdr;
#endif

#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

#if defined (CRAY)


GlobalSpace SPACEZ;
GlobalSpace *globalSpace = &SPACEZ;
#elif defined (CONVEX)
extern GlobalSpace _spacez_;
GlobalSpace *globalSpace = &_spacez_;
#elif defined SOLARIS
extern GlobalSpace spacez_;
GlobalSpace *globalSpace = &spacez_;
#else
extern GlobalSpace spacez_;
GlobalSpace *globalSpace = &spacez_;
#endif

#else

#if defined (CRAY)


extern GlobalSpace SPACEZ, *globalSpace;
#elif defined (CONVEX)
extern GlobalSpace _spacez_, *globalSpace;
#else
extern GlobalSpace spacez_, *globalSpace;
#endif
#endif

/* macros to assist C programmer in declaring saved parameters */


/* Note: NSAVEDPARMS must match dimension of SAVE_AR in global.inc */
#define NSAVEDPARMS 1000

#if defined (CRAY)


struct {
float buffer[NSAVEDPARMS];

Other Docs Search Page Known Problems


cglobal.h351 Developer’s Programming Guide

} 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

#define BEGINPARMS static struct { float _save1z_;

#define NPARMS(p) (1+sizeof(*p)/sizeof(float));

/* 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 */

/* The following numbers might be better in cpromax.h */


/* system-wide formats */
#define INT4 1
#define IREAL4 2
#define IREAL8 3
#define INTCHAR 4
#define ICHAR 5
#define ICHARR 6
#define ILOGIC 7
#define INT8L 8

/* system-wide NULL numbers. */

Other Docs Search Page Known Problems


cglobal.h352 Developer’s Programming Guide

#include <cnull.h>

/* include the resource type definitions */


#include "resource.inc"

/* release numbers */
#define SOFTRL 601000 /* software */
#define GEORLS 601000 /* geometry */

/* Global errno set by system after error on calling a UNIX function */


#include <errno.h>

#endif /* CGLOBAL_H */

Other Docs Search Page Known Problems


cpromax.h353 Developer’s Programming Guide

cpromax.h

/* Created by Dave Hale, 9/91 */


/* Additions by Christof Stork */

/* include file for C interface to ProMAX */


#ifndef CPROMAX_H
#define 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

/* For compatability with Xlib */


#ifndef Bool
#define Bool int
#endif
#undef True
#define True 1
#undef False
#define False 0

#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

Other Docs Search Page Known Problems


cpromax.h354 Developer’s Programming Guide

/****
Typedefs of old structures which are no longer
public. They are now defined in cpromaxP.h

Note that if a user defines a Database *, this will


be typedef’d to a void *, which is OK if he doesn’t access
the members of the structure. But if a
user tries to create a structure of Database, or tries to
dereference his Database* pointer, the compiler will complain.
****/
/* Don’t define these if a user includes cpromaxP.h first */
#ifndef CPROMAXP_H
typedef void Table;
typedef void Database;
typedef void DomainProject;
typedef void EnsembleMap;
typedef void TraceMap;
typedef void BufGet;
typedef void BufPut;
typedef void GetXY;
typedef void DataSetInfo;
typedef void SRFtpCDPmapping;
#endif

/*********************************************/
/* C defines and functions useful for ProMAX */
/*********************************************/

/* FUNCTION PROTOTYPES */

/* If C++, specify external linkage to C functions. */


#ifdef __cplusplus
extern "C" {
#endif

/* executive control functions */


void exFillMode (void);
void exFlushMode (void);
void exPipeMode (void);
void exPushMode (void);
void exQuitMode (void);
void exTraceHeadersOnlyOK (void);
void exSetPanels (int *, int *, int *, int *);
void exPanelParms (int *npanel_size, int *npanel_edge, int *npanel_mix,
int *npanel_tpad, int *npanel_spad);

void qualifyForIda(void);

/* input parameter formats */


#define PARINT 1
#define PARFLOAT 2
#define PARDOUBLE 3
#define PARCHAR 4
#define PARLONG 8

/* input parameter functions */


int exParNOccurs (char *name);
int exParNValues (char *name);

Other Docs Search Page Known Problems


cpromax.h355 Developer’s Programming Guide

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 exParGet3dGlobals( char *nameOfCallingTool );


int exRequiredHdr( char *hdrName );

/* trace header entry formats */


/* note that these values and INT4, IREAL4, etc. values defined in cglobal.h
* are used interchangeably and must agree
*/
#define HDRUNDEFINED 0
#define HDRINT 1
#define HDRFLOAT 2
#define HDRDOUBLE 3
#define HDRCHAR 4
#define HDRLONG 8

/* trace header functions */


#define STDHDR(x) ((stdHdr->x) - 1)
void hdrInfo (char *name, char **desc,
int *length, int *format, int *index, int *err);
int hdrExists (char *name);
char *hdrDesc (char *name);
int hdrLength (char *name);
int hdrFormat (char *name);
int hdrIndex (char *name);
int hdrAdd (char *name, char *desc, int length, int format);
void hdrIndexInfo (int index, char **name, char **desc,
int *length, int *format, int *err);
int hdrIndexExists (int index);
char *hdrIndexDesc (int index);
char *hdrIndexName (int index);
int hdrIndexLength (int index);
int hdrIndexFormat (int index);
void padn(const char *,char *, int);
void padname8(const char *,char *);
void stripn(const char *,char **, int);
void addNull(char *, int);
void hdrAddStd(char *);
void defStdHdr(void);
void initStdHdr (int *ihead, float *rhead);
void initHdrs(int *ihead, float *rhead, int nth);
int isStdHdrName( char* hdrName );

/* header state (catalog) functions */

Other Docs Search Page Known Problems


cpromax.h356 Developer’s Programming Guide

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);

/* virtual trace header functions (data from OPFs) */


void *vhdrAlloc( char *hdrName );
void vhdrFree( void *vh );
int vhdrFormat( void *vh );
int vhdrInt( void *vh, int traceno, int *value );
int vhdrFloat( void *vh, int traceno, float *value );

void headerStackN(void *hip, void **heads, int nheads, void *headOut);


void headerStack(void *hip, void *head1, float weight1, void *head2, float
weight2, void *head3);
void headerInterpolate(void *hip, void *head1, float loc1, void *head2, float
loc2, void *head3,
float loc3);
void *initHeaderManip(int nth);
#ifndef __CFORTRAN_LOADED
void psk2_str_( int *ihdr, float *rhdr, char *cstring );
#endif

/* string utilities from libuiutils */


void str_lower(char *);
void str_upper(char *);
int string_number_type(char *);
char *str2words(const char *, int);
char *str2ints(char *, int);
int hsec(unsigned char *, int, int);
void str_esc_encode(char *);
char *str_esc_decode(char *);
char *file_to_string(char *);
char *file_to_string_silent(char *);
int string_to_file(char *, char *);
void string_trim_trailing_blanks(char *);
void string_trim_trailing_whitespace(char *);
void string_trim_trailing_char(char *, char);

/* misc utilities */

int uClen(char *c, int lenc);

Other Docs Search Page Known Problems


cpromax.h357 Developer’s Programming Guide

int uStrnglen( char *c, int lenc );


void uChar2Int( char *c, int *i, int nwords );
void uInt2Char( int *i, char *c, int nwords );
int uStrComp( char *c1, int n1, char *c2, int n2 );
int fortranTrue(void);
int fortranFalse(void);
int dbFileName( char *infotype, char *filetype, char *label, int partition,
char *partitionPath, char *filePath );
void u_swapends2(void *, int);
void u_swapmove2(const void *, void *, int);
void u_swapends4(void *, int);
void u_swapmove4(const void *, void *, int);
void u_swapends8(void *, int);
void u_swapmove8(const void *, void *, int);

/* 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);

/* parameter table functions */


void *tblAllocate( int nz, char *xdesc, char *ydesc, char *zdesc, char *desc );
void *tblAllocTb3( char *xdesc, char *ydesc, char *zdesc, char *desc, void *tb3
);
void *tblAllocTmp( int nz );
void tblFree( void *tbl );
void *tblFetchTb3( void *tbl );
void tblSetExtrap( void *tbl, int xExt, int yExt );
int tblResolveX1X2( void *tbl, float x, float *x1, float *x2 );
int tbl2ResolveX1X2( void *tbl, double x, double *x1, double *x2 );
void tblAddXY( void *tbl, float x, float y, float *z );
void tbl2AddXY( void *tbl, double x, float y, float *z );
void tblAddXYs( void *tbl, float x, float *y, int ny, float *z );
void tbl2AddXYs( void *tbl, double x, float *y, int ny, float *z );
int tblGetX( void *tbl, int ix_counter, float *x_loc );
int tbl2GetX( void *tbl, int ix_counter, double *x_loc );
float tblGetEnsemble( void *tbl, float x1, float x2);
double tbl2GetEnsemble( void *tbl, double x1, double x2);
int tblGetXYs( void *tbl, int ix_counter, int ny_max, float *x_loc, float
*y_locs, float *z_vals, int *ny );
int tbl2GetXYs( void *tbl, int ix_counter, int ny_max, double *x_loc, float
*y_locs, float *z_vals, int *ny );
int tblDeleteXY( void *tbl, float x, float y );
int tbl2DeleteXY( void *tbl, double x, float y );
int tblDeleteX( void *tbl, float x );
int tbl2DeleteX( void *tbl, double x );
void tblClear( void *tbl );
int tblCopy( void *tblTo, void *tblFrom );
int tblDIPtoRMS( void *tblRMS, void *tblDIP);

Other Docs Search Page Known Problems


cpromax.h358 Developer’s Programming Guide

int tblRMStoDIP( void *tblDIP, void *tblRMS);


int tblEqual(void *tbl1, void *tbl2);
int tblInterpXY( void *tbl, float x, float y, float *z );
int tbl2InterpXY( void *tbl, double x, float y, float *z );
int tblInterpXYu( void *tbl, float x, float fy, float dy, int ny, float *z );
int tbl2InterpXYu( void *tbl, double x, float fy, float dy, int ny, float *z );
int dbTblUpdate( char *type, char *label, int trustCoords );
const char *tblGetType( void *tbl);
void tblSetType( void *tbl, const char *type);
void *tblFromDatabase( char *type, char *label );
Bool tblExists( char *type, char *label);
Bool tblExistsDesc( char *type, char *description);
void *tblFixHorTbl(void *horTbl);
int tblHeaderFileExists( char *type, char *label);
void tblReadHeaderFile( char *type, char *label, ParmGroup *group );
void tblWriteHeaderFile( void *tbl, char *type, ParmGroup *group );
char *tblDescFromDatabase( char *type, char *label );
int tblToDatabase( void *tbl, char *type );
int tblToDatabaseHashName( void *tbl, char *type, char *label );
void *tblFromVelPar( char *loc, char *vel );
float tblXMax( void *tbl );
double tbl2XMax( void *tbl );
float tblXMin( void *tbl );
double tbl2XMin( void *tbl );
float tblX1Min( void *tbl );
double tbl2X1Min( void *tbl );
float tblX1Max( void *tbl );
double tbl2X1Max( void *tbl );
float tblX2Min( void *tbl );
double tbl2X2Min( void *tbl );
float tblX2Max( void *tbl );
double tbl2X2Max( void *tbl );
float tblYMin( void *tbl );
float tblYMax( void *tbl );
float tblZMin( void *tbl );
float tblZMax( void *tbl );
void tblMinMax( void *tbl , float *x1Min, float *x1Max, float *x2Min,
float *x2Max, float *yMin, float *yMax, float *zMin,
float *zMax);
void tbl2MinMax( void *tbl , double *x1Min, double *x1Max, double *x2Min,
double *x2Max, float *yMin, float *yMax, float *zMin,
float *zMax);
int tblCountX( void *tbl );
int tblCountMaxY( void *tbl );
int tblCountZ( void *tbl );
char *tblDesc( void *tbl );
char *tblDescX( void *tbl );
char *tblDescY( void *tbl );
char *tblDescZ( void *tbl );
int tblIndexX(void *tbl,int ix, float *x1, float *x2);
int tbl2IndexX(void *tbl,int ix, double *x1, double *x2);
int tblGetYZ(void* t, float x1, float x2, int* ny, float* dy, float *fy, float*
y, float* z);
int tbl2GetYZ(void* t, double x1, double x2, int* ny, float* dy, float *fy,
float* y, float* z);
void tblFixX(void *tbl, float *x, int *iout);
void tbl2FixX(void *tbl, double *x, int *iout);

/* 64 bit tbl functions */

Other Docs Search Page Known Problems


cpromax.h359 Developer’s Programming Guide

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);

int datasetHeaderFileExists( const char *label);


void datasetReadHeaderFile( const char *label, ParmGroup *group );
void datasetWriteHeaderFile( const char *label, ParmGroup *group );

/* tbl routines made obsolete by 3D rewrite */


void tblReady( void *tbl );
void tblInfoUpdate( void *tbl );

/* 3D table access functions */

Other Docs Search Page Known Problems


cpromax.h360 Developer’s Programming Guide

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 );

/* Table access through trace headers */


void * hdrResolverAlloc( char * domain );
void * stHdrResolverAlloc( char * domain );
int tblResolveX1X2Hdr( void *tbl, void *hdrResolver, float *rthdr, float x, float
*x1, float *x2 );
int tbl2ResolveX1X2Hdr( void *tbl, void *hdrResolver, float *rthdr, double x,
double *x1, double *x2 );
int resolveX1X2Hdr( void *hdrResolver, float *rthdr, float *x1, float *x2 );
int resolve2X1X2Hdr( void *hdrResolver, float *rthdr, double *x1, double *x2 );

/* 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 );

int makeHorizTbls( void *inTblPtr, void **outTblPtrs );

/* parameter list functions */


void *listAlloc (int );
void *listAllocInts (int );
void listClear (void *list);
void listFree (void *list);
void listReady (void *list);
void listInfoUpdate (void *list);
void listDescribe (void *list, char *desc);
void listAdd (void *list, int igroup, int ilevel, int nvals, float *val1,
float *val2, float *dval);
void listAddInts (void *list, int igroup, int ilevel, int nvals, int *val1,
int *val2, int *dval);
void *listFromDatabase (char *type, char *label);
int listToDatabase (void *list, char *type);
void *listDecode (char *clist, int nlevels);
void *listDecodeInts (char *clist, int nlevels);
void listGet (void *list, float *vals, int nMax, float *val1, float *val2,
float *dval, int *n);
void listGetInts (void *list, int *vals, int nMax, int *val1, int *val2,
int *dval, int *n);
int listCheck (void *list, float *vals);
int listCheckInts (void *list, int *vals);
char *listDesc(void * l);

Other Docs Search Page Known Problems


cpromax.h361 Developer’s Programming Guide

/* parameter string decoding functions */


int pairDecode( char *cList, int nChars, float* val1, float* val2 );
int floatDecode( char *cList, int nChars, float* vals, int gateTimes );
int decodePrep( char *cList, int nCharsIn );

/* mute handling functions */


void *muteAlloc (void);
void *saMuteAlloc (void);
void muteFree (void *mute);
void muteGetTimes (void *mute, void *header,
float *tfl, float *tff, float *tlf, float *tll);
void muteSetTimes (void *mute, void *header,
float tfl, float tff, float tlf, float tll);
void muteApply (void *mute, void *header, float *trace);
void muteSlide (void *mute, void *header, float *trace);
void *muteFindZeros (void *mute, float *trace);
void muteRezero (void *mute, void *zeros, void *header, float *trace);

/* token parsing functions */


void tokensCreate (char *string, const char *delim, int *ntoken, char ***token);
void tokensCompress (int ntoken, char **token);
int tokenInt (const char *token, int *i);
int tokenPairInt (const char *token, int *i1, int *i2);
int tokenReplicatedInt (const char *token, int *n, int *i);
int tokenIteratedInt (const char *token, int *n, int *d, int *i);
int tokenDecodeInts (char *string, int *n, int **i, char **bad);
int tokenFloat (const char *token, float *f);
int tokenPairFloat (const char *token, float *f1, float *f2);
int tokenReplicatedFloat (const char *token, int *n, float *f);
int tokenIteratedFloat (const char *token, int *n, float *d, float *f);
int tokenDecodeFloats (char *string, int *n, float **f, char **bad);

/* 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);

/* utilities for casting pointers */


void *intToPtr( int i );
int ptrToInt( void *p );
void *fltToPtr( float r );
float ptrToFlt( void *p );
void *dblToPtr( double d );
double ptrToDbl( void *p );
float** fVecTo2d( float *vector, int nVects, int nElems );

/* stand alone routines */


void initStandAlone( int, char **, char *);
int checkLicense(char *productName, int warn);
void checkMagicLicense(void);
int uInitOnly(void);
void setPacketID(int id_packet); /* internal */

Other Docs Search Page Known Problems


cpromax.h362 Developer’s Programming Guide

int openDataset(char *);


int dsInfoTrTotal(void);
int dsInfoLocalTrTotal(DataSetInfo *);
int openLocalDataset(char *Clabel, int status, DataSetInfo *dataSet);
int getTraceHdr( int, int *);
int getTrace(int, int *, float *);
int getTraceOnly(int itrace, float *trace);
int getLocalTraceHdr(DataSetInfo *ds, int itrace, int *ihead);
int getLocalTrace(DataSetInfo *ds, int itrace, int *ihead, float *trace);
int getLocalTraceOnly(DataSetInfo *ds, int itrace, float *trace);
int dsDefaultNTraces(void); /* internal */
int dsNTraces(DataSetInfo *dsPtr );
void closeStandAlone(void);
void closeStandAloneQuietly(void);
void uParInfo (char *name, int *format, int *nwrdpval, int *nvals);
int uParExists (char *name);
void uParGetInt (char *name, int *i);
void uParGetFloat (char *name, float *f);
void uParGetString (char *name, char **s);
int uGetPar(char *, char *, void *);
int uParNOccurs (char *name);
int uParNValues (char *name);
int uParWordsPerValue (char *name);
void uParInfo (char *name, int *format, int *nwrdpval, int *nvals);
int uParFormat (char *name);
int uParReturnInt (char *name);
float uParReturnFloat (char *name);
char * uParReturnString (char *name);
void uCheckMenuVersion(const char *name, const char *compat_version);

/* domain mapping modes for dbMapProj.c */


#define DB_ENS_MAP 1
#define DOMAIN_PROJ 2
#define CLEAN_UP 3
#define DB_MAP_INIT 4

/* 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 );

void dbCloseTraceMap( void *ptr );


void *dbInitTraceMap (const char *domain1, const char *domain2, const char
*domain3);
int dbTraceMap( void *ptr, int loc1, int loc2, void *result, int *ierr );

void dbCloseDomainProject( void *ptr );


void *dbInitDomainProject( const char *domain1, const char *domain2 );
float dbDomainProject( void *, int loc );

Other Docs Search Page Known Problems


cpromax.h363 Developer’s Programming Guide

int dbDomainProjectInt( void *, int loc );


void dbMapProj( void**, char*, char*, char*, int, int, void*, int*, int* );

void dbCloseEnsembleMap( void *ptr );


void *dbInitEnsembleMap( const char *domain1, const char *domain2, const char
*domain3 );
int dbEnsembleMap (void *ptr, int loc, void *result, int *ierr);

void *opfOpen( const char *name );


void *opfInfo( const char *name );
int opfPut( void *opf, const char *info, const char *name, int loc, void *value
);
int opfGet( void *opf, const char *info, const char *name, int loc, void *value
);
int opfClose( void *opf );
int opfGetChar( void *opf, const char *info, const char *name, int loc, char
*value );
int opfGetAll( void *opf, const char *info, const char *name, void *parms );
int opfGetRange( void *opf, const char *info, const char *name, void *parms,
int irone, int irlast );
void* opfLock ( const char *name );
int opf( void *opf );
float opfSoftRlse( void *opf );
int opfIgDate( void *opf );
int opfIgTime( void *opf );
int opfHandle( void *opf );
int opfLocMin( void *opf );
int opfLocMax( void *opf );
int opfLocInc( void *opf );
int opfNStored( void* );
int opfParmCreate( void *opf, const char *order, const char *name, const char
*desc,
int length, int type );
int opfParmDelete( void *opf, const char *info, const char *name );
int opfParmExists( void *opf, const char *order, const char *name );
int opfParmFormat( void *opf, const char *info, const char *name );
int opfParmLength( void *opf, const char *order, const char *name );
char *opfParmDesc( void *opf, const char *info, const char *name );
void *opfParmNull( void *opf, const char *info, const char *name );
void *opfInitBufGet( void *opf, const char *cinfo, const char *cname );
void *opfInitBufPut( void *opf, const char *cinfo, const char *cname );
int opfBufGet( void *ptr, int loc, void *value );
int opfBufPut( void *ptr, int loc, void *value );
int opfBufGetFloat( void *ptr, int loc, float *value );
int opfBufPutFloat( void *ptr, int loc, float value );
int opfBufPutFloats( void *ptr, int loc, float *value );
int opfBufGetInt( void *ptr, int loc, int *value );
int opfBufPutInt( void *ptr, int loc, int value );
int opfBufPutInts( void *ptr, int loc, int *value );
int opfBufGetDouble( void *ptr, int loc, double *value );
int opfBufPutDouble( void *ptr, int loc, double value );
int opfBufPutDoubles( void *ptr, int loc, double *value );
int opfCloseBufGet( void *ptr );
int opfCloseBufPut( void *ptr );
void *opfInitGetXY( void *opf );
void opfGetXY( void *ptr, int loc, float *x, float *y );
void opfCloseGetXY( void *ptr );
void dbLineParmPut(const char *name, float value);
char *getHashName(const char *fname, const char *ftype);

Other Docs Search Page Known Problems


cpromax.h364 Developer’s Programming Guide

char *getFullName(const char *fname, const char *ftype);


int opfPutFloat( void *opf, const char *info, const char *name, int loc, float
value);
int opfPutFloats( void *opf, const char *info, const char *name, int loc, float
*value);
int opfPutDouble( void *opf, const char *info, const char *name, int loc,
double value);
int opfPutDoubles( void *opf, const char *info, const char *name, int loc,
double *value);
int opfPutInt( void *opf, const char *info, const char *name, int loc, int
value);
int opfPutInts( void *opf, const char *info, const char *name, int loc, int
*value);
int opfPutChar( void *opf, const char *info, const char *name, int loc, const
char *string);
int opfPutAll( void *opf, const char *info, const char *name, void *parms);
int opfPutRange( void *opf, const char *info, const char *name, void *parms,
int irone, int irlast);
char *opfParmList( void *opf, const char *info );
int opfInitPseudoLine(void);
void opfDeinitPseudoLine( int savedState );
char *opfDomain( void *opf );
int opfLastErr( void *opf );

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);

char **tblGroupRead( char *name, char *type, int *ntbls);


void tblGroupWrite( char *name, char *type, char **names, int ntbls);

float dbProjectXY(void *,float,float);

void *dbInitSRFtoCDPmap(int **, int);


float dbSRFtoCDPmap(void *,float);
float dbCDPtoSRFmap(void *,float);

char **configDevList( char *type, int *n );


char *promaxPathName( const char *);
void promaxPath( const char *, char *);
char *promaxLinePath(char *);
char *promaxFlowPath(char *);
int scratchSpace(void);

/* Velocity Table convenience routines */


void convertVTable(void *t_in, const char *in_type, void *t_out, const char
*out_type, float in_step, float out_step);
void invertV(void *t_in, void *t_out);
void vIntStepConv(void *t_in, void *t_out);
void resampleTbl(void *t_in, void *t_out, float step);
void smoothVelMatrix( float **vel1, int nz, int nx, float hsmooth, float
vsmooth, int slowness);

Other Docs Search Page Known Problems


cpromax.h365 Developer’s Programming Guide

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);

/* packet file manipulation routines */


int pktFileClose(void *ptr);
void * pktFileOpen(char *name);
void * pktFileCreate(char *name);
int pktInit(void *ptr, char *name);
int pktGroupInit(void *ptr, char *gname);
int pktOutParmN(void *ptr, char *name, int format, int nwrdpval, int nvalues,
void *buf);
int pktOutInt(void *ptr, char *name, int val);
int pktOutFloat(void *ptr, char *name, float val);
int pktOutDouble(void *ptr, char *name, double val);
int pktOutString(void *ptr, char *name, char *val);
int pktGetNGroups(void *ptr);
void pktGroupCopy(void *ptrIn, void *ptrOut, char *name);
int pktParmInfo(void *ptr, int gnum, int pnum, char *name, int *format, int
*nwrdpval, int *nvalues)
;
int pktGroupInfo(void *ptr, int gnum, char *name, int *nparms);
int pktGetMaxParmLength(void *ptr);
void *pktGetExecPtr(void);

/* 3D geometry routines */
void d3CDPToXY( int icdp, float *x, float *y);

Other Docs Search Page Known Problems


cpromax.h366 Developer’s Programming Guide

void d32CDPToXY( int icdp, double *x, double *y);


int d3XYToCDP( float x, float y);
int d32XYToCDP( double x, double y);
int d3XYToXline( float x, float y);
int d32XYToXline( double x, double y);
int d3XYToInline( float x, float y);
int d32XYToInline( double x, double y);
int d3LinesToCDP( int iiline, int ixline);
void d3CDPToLines( int icdp, int *iiline, int *ixline);
void d3LinesToXY(int iiline, int ixline, float *x, float *y);
void d32LinesToXY(int iiline, int ixline, double *x, double *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);

/* CRAY routines for reserving memory. */


void uDynMemReserve( int nwords );
void uReserve( int irecourse, int nitems );
#ifndef uStatMemReserve
void uStatMemReserve( int nwords );
#endif

/* end of C++ block for specifing external linkage to C functions. */


#ifdef __cplusplus
}
#endif

/* include the interpolation accessor functions */


#include <maxutil/table/intwrap.h>

#include "misc.h"

#include "db_err.h"
#include "hdr_err.h"

#endif /* CPROMAX_H */

Other Docs Search Page Known Problems


Example Simple Processes367 Developer’s Programming Guide

Example Simple Processes

The simple.menu and simple.c programs on the following pages


provide an example of a simple ProMAX C process and its
menu. While the routine does not do a very important job, it has
the same structure as much more complicated ProMAX C
processes. Pay attention to the following important procedures:

• how the parameters are saved between the BEGINPARMS


and ENDPARMS Macros
• how information is passed through the parms structure by
use of the parms->varName syntax
• how the global variables are accessed by including
cglobal.h and the globalRuntime pointers (in this example,
we get the trace length in samples through the pointer gr-
>numsmp)
• how parameters are brought into the menu by use of the
routine getPar()

The amp_Ratio.c program provides an example of another C


ProMAX process. It is more complicated than the previous
example, but the structure is very similar. This process uses
table interpolation. Note that this routine uses a lot of the error
checking conveniences of ProMAX.

Other Docs Search Page Known Problems


simple.menu368 Developer’s Programming Guide

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 ))
)
)
)

Other Docs Search Page Known Problems


simple.c369 Developer’s Programming Guide

simple.c

/* this is a really simple example of a C promax module */

/* include ProMAX prototypes and globals */


#include "cpromax.h”
#include "cglobal.h”

/* define the saved parameters (user input, etc) */


BEGINPARMS
int sampsPerTrace;
float zmult;
ENDPARMS (parms);

/* declare the functions used internally */


void multTrc( float* trace, float zmult, int sampsPerTrace );

/*-------------------------------------------------------------------*/
/* init_simple_()
/*
/* initialization routine for ProMAX module simple
/*
/*
/*-------------------------------------------------------------------*/

void init_simple_( int *len_sav, int *itooltype )


{

/* declare a local version of an external parameter */


float zmult;

/* set a pointer to the globalRuntime structure */


GlobalRuntime *gr = globalRuntime;

/* get the number of samples per trace, set the external parm too */
parms->sampsPerTrace = gr->numsmp;

/* get the multiplier for the trace from the menu */


exPerGetFloat("ZMULT”, &zmult);
if( zmult < 0.0 ){
exErrFatal("The multiplier cannot be less than 0.0.”);
}
/* now set the external parameter */
parms->zmult = zmult;

/* set the number of words that need to be saved for re-entrancy */


*len_sav = NPARMS(parms);

/* set the tool type to simple, (one trace in one trace out). */
/* ISIMPLE is defined in cglobal.h */
*itooltype = ISIMPLE;

/*-------------------------------------------------------------------*/
/* exec_simple_()

Other Docs Search Page Known Problems


simple.c370 Developer’s Programming Guide

/*
/* execution routine for ProMAX module simple
/*
/*
/*-------------------------------------------------------------------*/

void exec_simple_( float* trace, float* rthdr, int* ithdr )


{

/* set a pointer to the globalRuntime structure */


GlobalRuntime *gr = globalRuntime;

/* see if we are in cleanup phase */


if( gr->cleanup ){
return;
}

/* process the trace */


multTrc( trace, parms->zmult, parms->sampsPerTrace );

/*-------------------------------------------------------------------*/
/*
/* 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
/*
/*-------------------------------------------------------------------*/

void multTrc( float *trace, float zmult, int sampsPerTrace )

{
int i;

for( i = 0; i < sampsPerTrace; i++ ){


trace[i] *= zmult;
}

Other Docs Search Page Known Problems


ampRatio.c371 Developer’s Programming Guide

ampRatio.c

/* include ProMAX prototypes and globals */


#include <cpromax.h>
#include <cglobal.h>

/* define saved parameters */


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)

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 ;

/* get the gate length */


gatelen=-1.0;
exParGetFloat ("GATELEN", &gatelen);

/* convert the gate length from time to samples*/


parms->ngate = (int) (gatelen / globalRuntime->samprat+0.5);

/* check for reasonable input */


if (parms->ngate < 1 || parms->ngate * 2 + 1 >globalRuntime->numsmp)
exErrFatal ("Gate length is illegal");

/* 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 */

Other Docs Search Page Known Problems


ampRatio.c372 Developer’s Programming Guide

parms->gate_tbl = tblFromDatabase ("GAT", cgatename);

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!)");

/* We will need the index of the primary and secondary key */

parms->ih_pkey = hdrIndex (tblDescX(parms->gate_tbl) );


if (parms->ih_pkey < 0)
exErrFatal ("The primary key of the time gate (%s) is not
in the header!", tblDescX(parms->gate_tbl) );
parms->ih_skey= hdrIndex ( tblDescY(parms->gate_tbl) );
if (parms->ih_skey < 0)
exErrFatal ("The secondary key of the time gate is (%s)
is not in the header!", tblDescY(parms->gate_tbl) );

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");
}

Other Docs Search Page Known Problems


ampRatio.c373 Developer’s Programming Guide

}
}

/* 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");

/* Lock the TRC order since we will be writing to it */


parms->db_trc = opfLock ("TRC");
if (!opfExists ( "TRC") )
exErrFatal ("Error locking TRC database.");

/* Create the new entries in the database */


if (!opfParmExists(parms->db_trc, "F_B_PICK", "RATIOMAX") ) {
ierr = opfParmCreate (parms->db_trc , "F_B_PICK",
"RATIOMAX", "Maximum value of amp ratio", 1, PARFLOAT);
if (ierr !=0 )
exErrFatal ("Error creating database entry");
else{
fprintf(stdout,"created new db entry RATIOMAX\n");
}
}

if (!opfParmExists(parms->db_trc, "F_B_PICK", "RATIOTIM") ) {


ierr = opfParmCreate (parms->db_trc, "F_B_PICK",
"RATIOTIM",
"Time of amp ratio maximum", 1, PARFLOAT);
if (ierr !=0 )
exErrFatal ("Error creating database entry");
else{
fprintf(stdout,"created new db entry RATIOTIM\n");
}
}

/* Initialize the token for buffered database I/O */


parms->dbPtr1= opfInitBufPut(parms-
>db_trc,"F_B_PICK","RATIOMAX");
parms->dbPtr2= opfInitBufPut(parms-
>db_trc,"F_B_PICK","RATIOTIM");
}

/* Reserve a scratch buffer that we will need in exec phase */


/* memAlloc functions abort if memory is unavailable */
parms->scratch = memAlloc1Float(globalRuntime->numsmp);
/* Set the number of words that need to be saved for re-entrancy. */
*len_sav = NPARMS (parms);

/* Set the tool type to simple (one trace in, one trace out) */

Other Docs Search Page Known Problems


ampRatio.c374 Developer’s Programming Guide

*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)
*
**********************************************************************/

void exec_amp_ratio_(float *trace, int *ithdr, float *rthdr)


{
int loc_trc, ierr, imin_samp, imax_samp;
float ratio_max, ratio_time, pkeyval, skeyval, tgate[2];
float fltSkey;
double dblPkey;

if (globalRuntime->cleanup) {
if (parms->load_db) {

/* Flush the buffers for buffered database I/O Note that


errors only give rise to warnings in cleanup phase. Also note
that the "location" is now 0. */

if (opfCloseBufPut (parms->dbPtr1) !=0) {


exErrWarn ("Error loading data into database.");
}
if (opfCloseBufPut (parms->dbPtr2) !=0) {
exErrWarn ("Error loading data into database.");
}
opfClose (parms->db_trc);
}

/* Free memory */
/* memFree functions check for memory overruns and
* abort if an overrun is found */
memFree1(parms->scratch);

/* We don’t want control to pass into the main body */


return;
}

/* get the gate length */


if (parms->use_gate){
/* Interpolate the gate times from the table*/
if (parms->iformat_pkey == HDRINT)
dblPkey = (double)ithdr[parms->ih_pkey];
else
dblPkey = (double)rthdr[parms->ih_pkey];
if (parms->iformat_skey == HDRINT)
fltSkey = (float)ithdr[parms->ih_skey];
else
fltSkey = rthdr[parms->ih_skey];

Other Docs Search Page Known Problems


ampRatio.c375 Developer’s Programming Guide

if (tbl2InterpXY (parms->gate_tbl, dblPkey, fltSkey, tgate )){


exErrFatal ("Error interpolating time gate");
}
}
else {
/* use entire trace */
tgate[0]=0.0;
tgate[1]= (globalRuntime->numsmp-1)*globalRuntime->samprat;
}

/* Convert the time gate values to samples */


imin_samp = tgate[0] / globalRuntime->samprat + 0.5;
imax_samp = tgate[1] / globalRuntime->samprat + 0.5;
imin_samp = MAX (imin_samp, 0);
imin_samp = MIN (imin_samp, globalRuntime->numsmp - 1);
imax_samp = MAX (imax_samp, 0);
imax_samp = MIN (imax_samp, globalRuntime->numsmp - 1);
if (imin_samp > imax_samp) {
int isave;
/* assume that they were meant to be reversed */
isave= imin_samp;
imin_samp= imax_samp;
imax_samp=isave;
}

/* 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 */

loc_trc = ithdr [STDHDR (itraceno)];


if (loc_trc != INULL) {
opfBufPutFloat (parms->dbPtr1, loc_trc, ratio_max);
opfBufPutFloat (parms->dbPtr2, loc_trc, ratio_time);
}
}
}
/**
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)

Other Docs Search Page Known Problems


ampRatio.c376 Developer’s Programming Guide

{
int i, ind_max;
float sum_above, sum_below, rabove, rbelow;

/* Sum the first two gates */


sum_above = 0.0;
rabove = 0.0;

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;
}

for (i = 0; i< nsamps; i ++) {

/* Compute the ratio */


if (sum_above > 0.0 && rabove >0.0 && rbelow >0.0) {
scratch [i] = (sum_below/ rbelow) / (sum_above / rabove);
}
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;
}

if (i + ngate + 1 < nsamps) {


sum_below = sum_below - fabs (trace[i + 1])
+ fabs (trace [i + ngate + 1]);
}
else {
if (i + 1 < nsamps) {
sum_below = sum_below - fabs (trace[i + 1]);
rbelow = rbelow - 1.0;
}
}
}

/* Put the final results in place. */


for (i = 0; i < nsamps; i++) {
trace [i] = scratch[i];
}

/* Find the maximum of the ratio function */


*ratio_max = trace [imin_samp ];
ind_max = imin_samp;
for (i = imin_samp ; i<= imax_samp; i++) {
if (trace [i] > *ratio_max) {
ind_max = i;

Other Docs Search Page Known Problems


ampRatio.c377 Developer’s Programming Guide

*ratio_max = trace [i];


}
}

/* Convert the index of the maximum to time*/


*ratio_time = (float) (ind_max ) * samprate;
}

Other Docs Search Page Known Problems


ampRatio.c378 Developer’s Programming Guide

Other Docs Search Page Known Problems


379 Developer’s Programming Guide

Appendix: Simple Tool Examples

This appendix provides an example of a simple tool, a tool that


processes one data trace at a time. It demonstrates the creation
and use of trace headers, ordered parameter files, and database
tables. The program is a crude first break picker. It allows the
option of loading some of the derived parameters into the trace
headers and the database, and limiting the time window in
which the first break picker will search. The menu and
FORTRAN examples are presented first, then the C source code
is presented. The menu file can be used with either the C or
FORTRAN code.

Topics covered in this appendix:


➲ amp_ratio.menu
➲ amp_ratio.inc
➲ amp_ratio.f
➲ ampRatio.c

Other Docs Search Page Known Problems


amp_ratio.menu380 Developer’s Programming Guide

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))
)

Other Docs Search Page Known Problems


amp_ratio.inc381 Developer’s Programming Guide

amp_ratio.inc

C------------------------------------------------------------------------------
C Include file for AMP_RATIO
C------------------------------------------------------------------------------

IMPLICIT NONE
#include <global.inc>
#include <mem.inc>

COMMON /SAVED_PARMS/ SAVE1z, NGATE, IX_SCRATCH, IH_RATIO_MAX,


& IH_RATIO_TIME, LOAD_HDR, LOAD_DB, ID_MAX, ID_TIME,
& IKEY_TRC, USE_GATE, ITBL_HANDLE, IH_PKEY,
& IH_SKEY, IFORMAT_PKEY, IFORMAT_SKEY, END1z

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

C ..... NGATE - number of samples in gate


C ..... IX_SCRATCH - index of scratch buffer
C ..... IH_RATIO_MAX - index in header of amp ratio maximum
C ..... IH_RATIO_TIME - index in header of amp ratio time
C ..... LOAD_HDR - flag for option to load the results into the trace header
C ..... LOAD_DB - flag for option to load the results into the database
C ..... ID_MAX - token for buffered database I/O for amp ratio max
C ..... ID_TIME - token for buffered database I/O for amp ratio time
C ..... IKEY_TRC - key to the trace ordered database
C ..... USE_GATE - logical flag to use a gate to confine the amp ratio max
C ..... ITBL_HANDLE - handle for the time gate table
C ..... IH_PKEY - header index of the primary key of the time gate table
C ..... IH_SKEY - header index of the secondary key of the time gate table
C ..... IFORMAT_PKEY - format of the primary key of the time table
C ..... IFORMAT_SKEY - format of the secondary key of the time table

Other Docs Search Page Known Problems


amp_ratio.f382 Developer’s Programming Guide

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------------------------------------------------------------------------------

SUBROUTINE INIT_AMP_RATIO( LEN_SAV, ITOOLTYPE )

C ..... The include file ’amp_ratio.inc’ contains a nested include


C ..... for the global parameters
#include "amp_ratio.inc"
#include <header.inc>
C ..... Include file with error definitions
#include <hdr_err.inc>
#include <db_err.inc>
INTEGER LEN_SAV, ITOOLTYPE, IERR, LENGTH, IOK_HDR,
& NCHARS, IDUMMY(3), NTIMES
REAL GATELEN, RDUMMY(6)
CHARACTER CDESC_HDR*32, CDESC_DB*80, CGATENAME*8, CPRIM_KEY*8,
& CSCND_KEY*8, CTABLE_DESC*128, CZ_DESC*8

#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 ..... Convert the gate length to samples


NGATE = NINT( GATELEN / SAMPRATz )

C ..... Check for reasonable input


IF ( NGATE .LT. 1 .OR. NGATE*2+1 .GT. NUMSMPz ) THEN
CALL EX_ERR_FATAL( ’Gate length is illegal’ )
ENDIF

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. ’ ’

Other Docs Search Page Known Problems


amp_ratio.f383 Developer’s Programming Guide

& .AND. CGATENAME .NE. ’NO__GATE’ ) THEN


C ......... Something was specified
USE_GATE = .TRUE.

C ......... Get the gate from the database


CALL DB_TBL_GET( ’GAT’, CGATENAME, ITBL_HANDLE, IERR )
IF ( IERR .NE. 0 ) THEN
CALL REPORT_PROMAX_ERR( IERR )
CALL EX_ERR_FATAL(
& ’Cannot open time gate ’ //CGATENAME )
ENDIF

C ......... Get info on the gate table


CALL TBL_INFO( .TRUE., ITBL_HANDLE, CPRIM_KEY, CSCND_KEY,
& CZ_DESC, CTABLE_DESC, IDUMMY(1), IDUMMY(2), IDUMMY(3),
& NTIMES, RDUMMY(1), RDUMMY(2), RDUMMY(3), RDUMMY(4),
& RDUMMY(5), RDUMMY(6) )

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’ )

CALL HDR_NAMINFO( CSCND_KEY, CDESC_DB, LENGTH, IFORMAT_SKEY,


& IH_SKEY, IERR )
IF ( IERR .NE. 0 ) CALL EX_ERR_FATAL(
& ’The secondary key of the time gate (’ //CSCND_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 )

IF ( LOAD_HDR .EQ. 1 ) THEN


C ......... Add new trace header entries

CDESC_HDR = ’Maximum value of amp ratio’


CALL HDR_ADD( ’RATIOMAX’, CDESC_HDR, 1, IREAL4pz,
& IH_RATIO_MAX, IERR )
IF ( IERR .NE. 0 ) THEN
IF ( IERR .EQ. IERR_HDR_EXSTpz ) THEN
C ................. That’s OK, but somewhat unexpected
CALL EX_ERR_WARN(
& ’RATIOMAX already exists in header’ )
ELSE
C ................. This will virtually never happen, but just in case
CALL EX_ERR_FATAL( ’Error adding header entry’ )
ENDIF
ENDIF

CDESC_HDR = ’Time of amp ratio maximum’

Other Docs Search Page Known Problems


amp_ratio.f384 Developer’s Programming Guide

CALL HDR_ADD( ’RATIOTIM’, CDESC_HDR, 1, IREAL4pz,


& IH_RATIO_TIME, IERR )
IF ( IERR .NE. 0 ) THEN
IF ( IERR .EQ. IERR_HDR_EXSTpz ) THEN
C ................. That’s OK, but somewhat unexpected
CALL EX_ERR_WARN(
& ’RATIOTIM already exists in header’ )
ELSE
C ................. This will virtually never happen, but just in case
CALL EX_ERR_FATAL( ’Error adding header entry’ )
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 )

IF ( LOAD_DB .EQ. 1 ) THEN


C ......... Open the database to store the amp ratio information
C against trace

IF ( ITRNO_VALIDz .NE. 1 ) THEN


CALL EX_ERR_FATAL( ’Cannot load data into the TRC order’
& //’ without valid trace numbers (geom assigned)’ )
ENDIF

C ......... We will need the index of the trace number


IF ( IOK_HDR(ITRACENOz) .NE. 1 ) CALL EX_ERR_FATAL(
& ’TRACENO not found in header’ )

C ......... Lock the TRC order since we will be writing to it


CALL DB_ORDLOCK( ’TRC’, IKEY_TRC, IERR )
IF ( IERR .NE. 0 ) THEN
CALL REPORT_PROMAX_ERR( IERR )
CALL EX_ERR_FATAL( ’Error locking TRC database’ )
ENDIF

C ......... Create the new entries in the database


CDESC_DB = ’Maximum value of amp ratio’
CALL DB_PARMCRE( IKEY_TRC, ’ ’, ’F_B_PICK’, ’RATIOMAX’,
& CDESC_DB, 1, IREAL4pz, RNULLpz, IERR )
IF ( IERR .NE. 0 .AND. IERR .NE. IERR_DB_PEXSpz ) THEN
CALL REPORT_PROMAX_ERR( IERR )
CALL EX_ERR_FATAL( ’Error creating database entry’ )
ENDIF

CDESC_DB = ’Time of amp ratio maximum’


CALL DB_PARMCRE( IKEY_TRC, ’ ’, ’F_B_PICK’, ’RATIOTIM’,
& CDESC_DB, 1, IREAL4pz, RNULLpz, IERR )
IF ( IERR .NE. 0 .AND. IERR .NE. IERR_DB_PEXSpz ) THEN
CALL REPORT_PROMAX_ERR( IERR )
CALL EX_ERR_FATAL( ’Error creating database entry’ )
ENDIF

C ......... Initialize the token for buffered database I/O


ID_MAX = 0
ID_TIME = 0

Other Docs Search Page Known Problems


amp_ratio.f385 Developer’s Programming Guide

ENDIF

C ..... Reserve a scratch buffer that we will need in exec phase


CALL MEMORY_RESBUFF( NUMSMPz, IX_SCRATCH, IERR )

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------------------------------------------------------------------------------

SUBROUTINE EXEC_AMP_RATIO( TRACE, ITHDR, RTHDR )

#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

Other Docs Search Page Known Problems


amp_ratio.f386 Developer’s Programming Guide

C ......... We don’t want control to pass into the main body


RETURN
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 ..... Convert the time gate values to samples


IMIN_SAMP = NINT( TGATE(1) / SAMPRATz ) + 1
IMAX_SAMP = NINT( TGATE(2) / SAMPRATz ) + 1

C ..... Don’t let them go out of bounds


IMIN_SAMP = MAX0( IMIN_SAMP, 1 )
IMIN_SAMP = MIN0( IMIN_SAMP, NUMSMPz )
IMAX_SAMP = MAX0( IMAX_SAMP, 1 )
IMAX_SAMP = MIN0( IMAX_SAMP, NUMSMPz )
IF ( IMIN_SAMP .GT. IMAX_SAMP ) THEN
C ......... Let’s assume that they were meant to be reversed
ISAVE = IMIN_SAMP
IMIN_SAMP = IMAX_SAMP
IMAX_SAMP = ISAVE
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 )

IF ( LOAD_HDR .EQ. 1 ) THEN


C ......... Load the values into the header
RTHDR(IH_RATIO_MAX) = RATIO_MAX
RTHDR(IH_RATIO_TIME) = RATIO_TIME
ENDIF

IF ( LOAD_DB .EQ. 1 ) THEN


C ......... Load the values into the database

LOC_TRC = ITHDR( ITRACENOz )


IF ( LOC_TRC .NE. INULLpz ) THEN

CALL DB_BUFFRDPUT( ID_MAX, IKEY_TRC, ’F_B_PICK’,


& ’RATIOMAX’, LOC_TRC, RATIO_MAX, .FALSE., IERR )
IF ( IERR .NE. 0 ) THEN
CALL REPORT_PROMAX_ERR( IERR )
CALL EX_ERR_FATAL(
& ’Error loading data into database’ )
ENDIF

Other Docs Search Page Known Problems


amp_ratio.f387 Developer’s Programming Guide

CALL DB_BUFFRDPUT( ID_TIME, IKEY_TRC, ’F_B_PICK’,


& ’RATIOTIM’, LOC_TRC, RATIO_TIME, .FALSE., IERR )
IF ( IERR .NE. 0 ) THEN
CALL REPORT_PROMAX_ERR( IERR )
CALL EX_ERR_FATAL(
& ’Error loading data into database’ )
ENDIF

ENDIF

ENDIF

RETURN
END

C------------------------------------------------------------------------------
C
C Actual work routine
C
C------------------------------------------------------------------------------

SUBROUTINE AMP_RATIO_WORK( TRACE, SCRATCH, NSAMPS, NGATE,


& IMIN_SAMP, IMAX_SAMP, SAMPRATE, RATIO_MAX, RATIO_TIME )

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

C ..... Sum the first two gates


SUM_ABOVE = 0.0
RABOVE = 0.0

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 ..... Now move down the trace


DO 120 I=1,NSAMPS

C ......... Compute the ratio


IF ( SUM_ABOVE .GT. 0.0 .AND. RABOVE .GT. 0.0
& .AND. RBELOW .GT. 0.0 ) THEN
SCRATCH(I) = (SUM_BELOW/RBELOW) / (SUM_ABOVE/RABOVE)
ELSE
SCRATCH(I) = 0.0
ENDIF

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

Other Docs Search Page Known Problems


amp_ratio.f388 Developer’s Programming Guide

SUM_ABOVE = SUM_ABOVE + ABS( TRACE(I) )


RABOVE = RABOVE + 1.0
ENDIF

IF ( I+NGATE+1 .LE. NSAMPS ) THEN


SUM_BELOW = SUM_BELOW - ABS( TRACE(I+1) )
& + ABS( TRACE(I+NGATE+1) )
ELSE
IF ( I+1 .LE. NSAMPS ) THEN
SUM_BELOW = SUM_BELOW - ABS( TRACE(I+1) )
RBELOW = RBELOW - 1.0
ENDIF
ENDIF

120 CONTINUE

C ..... Put the final results in place.


DO 130 I=1,NSAMPS
TRACE(I) = SCRATCH(I)
130 CONTINUE

C ..... Find the maximum of the ratio function


RATIO_MAX = TRACE(IMIN_SAMP)
IND_MAX = IMIN_SAMP
DO 140 I=IMIN_SAMP,IMAX_SAMP
IF ( TRACE(I) .GT. RATIO_MAX ) THEN
IND_MAX = I
RATIO_MAX = TRACE(I)
ENDIF
140 CONTINUE

C ..... Convert the index of the maximum to time


RATIO_TIME = FLOAT( IND_MAX - 1 ) * SAMPRATE

RETURN
END

Other Docs Search Page Known Problems


ampRatio.c389 Developer’s Programming Guide

ampRatio.c

/* include ProMAX prototypes and globals */


#include <cpromax.h>
#include <cglobal.h>

/* define saved parameters */


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)

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 ;

/* get the gate length */


gatelen=-1.0;
exParGetFloat ("GATELEN", &gatelen);

/* convert the gate length from time to samples*/


parms->ngate = (int) (gatelen / globalRuntime->samprat+0.5);

/* check for reasonable input */


if (parms->ngate < 1 || parms->ngate * 2 + 1 >globalRuntime->numsmp)
exErrFatal ("Gate length is illegal");

/* 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;

Other Docs Search Page Known Problems


ampRatio.c390 Developer’s Programming Guide

/* Get the gate from the database */


parms->gate_tbl = tblFromDatabase ("GAT", cgatename);
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!)");

/* We will need the index of the primary and secondary key */

parms->ih_pkey = hdrIndex (tblDescX(parms->gate_tbl) );


if (parms->ih_pkey < 0)
exErrFatal ("The primary key of the time gate (%s) is not
in the header!", tblDescX(parms->gate_tbl) );
parms->ih_skey= hdrIndex ( tblDescY(parms->gate_tbl) );
if (parms->ih_skey < 0)
exErrFatal ("The secondary key of the time gate is (%s)
is not in the header!", tblDescY(parms->gate_tbl) );

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");
}

Other Docs Search Page Known Problems


ampRatio.c391 Developer’s Programming Guide

}
}

/* 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");

/* Lock the TRC order since we will be writing to it */


parms->db_trc = opfLock ("TRC");
if (!opfExists ( "TRC") )
exErrFatal ("Error locking TRC database.");

/* Create the new entries in the database */


if (!opfParmExists(parms->db_trc, "F_B_PICK", "RATIOMAX") ) {
ierr = opfParmCreate (parms->db_trc , "F_B_PICK",
"RATIOMAX", "Maximum value of amp ratio", 1, PARFLOAT);
if (ierr !=0 )
exErrFatal ("Error creating database entry");
else{
fprintf(stdout,"created new db entry RATIOMAX\n");
}
}

if (!opfParmExists(parms->db_trc, "F_B_PICK", "RATIOTIM") ) {


ierr = opfParmCreate (parms->db_trc, "F_B_PICK",
"RATIOTIM",
"Time of amp ratio maximum", 1, PARFLOAT);
if (ierr !=0 )
exErrFatal ("Error creating database entry");
else{
fprintf(stdout,"created new db entry RATIOTIM\n");
}
}

/* Initialize the token for buffered database I/O */


parms->dbPtr1= opfInitBufPut(parms-
>db_trc,"F_B_PICK","RATIOMAX");
parms->dbPtr2= opfInitBufPut(parms-
>db_trc,"F_B_PICK","RATIOTIM");
}

/* Reserve a scratch buffer that we will need in exec phase */


/* memAlloc functions abort if memory is unavailable */
parms->scratch = memAlloc1Float(globalRuntime->numsmp);

/* Set the number of words that need to be saved for re-entrancy. */


*len_sav = NPARMS (parms);

/* Set the tool type to simple (one trace in, one trace out) */

Other Docs Search Page Known Problems


ampRatio.c392 Developer’s Programming Guide

*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)
*
**********************************************************************/

void exec_amp_ratio_(float *trace, int *ithdr, float *rthdr)


{
int loc_trc, ierr, imin_samp, imax_samp;
float ratio_max, ratio_time, pkeyval, skeyval, tgate[2];
float fltSkey;
double dblPkey;

if (globalRuntime->cleanup) {
if (parms->load_db) {

/* Flush the buffers for buffered database I/O Note that


errors only give rise to warnings in cleanup phase. Also note
that the "location" is now 0. */

if (opfCloseBufPut (parms->dbPtr1) !=0) {


exErrWarn ("Error loading data into database.");
}
if (opfCloseBufPut (parms->dbPtr2) !=0) {
exErrWarn ("Error loading data into database.");
}
opfClose (parms->db_trc);
}

/* Free memory */
/* memFree functions check for memory overruns and
* abort if an overrun is found */
memFree1(parms->scratch);

/* We don’t want control to pass into the main body */


return;
}

/* get the gate length */


if (parms->use_gate){
/* Interpolate the gate times from the table*/
if (parms->iformat_pkey == HDRINT)
dblPkey = (double)ithdr[parms->ih_pkey];
else
dblPkey = (double)rthdr[parms->ih_pkey];
if (parms->iformat_skey == HDRINT)
fltSkey = (float)ithdr[parms->ih_skey];
else
fltSkey = rthdr[parms->ih_skey];

Other Docs Search Page Known Problems


ampRatio.c393 Developer’s Programming Guide

if (tbl2InterpXY (parms->gate_tbl, dblPkey, fltSkey, tgate )){


exErrFatal ("Error interpolating time gate");
}
}
else {
/* use entire trace */
tgate[0]=0.0;
tgate[1]= (globalRuntime->numsmp-1)*globalRuntime->samprat;
}

/* Convert the time gate values to samples */


imin_samp = tgate[0] / globalRuntime->samprat + 0.5;
imax_samp = tgate[1] / globalRuntime->samprat + 0.5;
imin_samp = MAX (imin_samp, 0);
imin_samp = MIN (imin_samp, globalRuntime->numsmp - 1);
imax_samp = MAX (imax_samp, 0);
imax_samp = MIN (imax_samp, globalRuntime->numsmp - 1);
if (imin_samp > imax_samp) {
int isave;
/* assume that they were meant to be reversed */
isave= imin_samp;
imin_samp= imax_samp;
imax_samp=isave;
}

/* 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 */

loc_trc = ithdr [STDHDR (itraceno)];


if (loc_trc != INULL) {
opfBufPutFloat (parms->dbPtr1, loc_trc, ratio_max);
opfBufPutFloat (parms->dbPtr2, loc_trc, ratio_time);
}
}
}

/**
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

Other Docs Search Page Known Problems


ampRatio.c394 Developer’s Programming Guide

*ratio_max, float *ratio_time)


{
int i, ind_max;
float sum_above, sum_below, rabove, rbelow;

/* Sum the first two gates */


sum_above = 0.0;
rabove = 0.0;

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;
}

for (i = 0; i< nsamps; i ++) {

/* Compute the ratio */


if (sum_above > 0.0 && rabove >0.0 && rbelow >0.0) {
scratch [i] = (sum_below/ rbelow) / (sum_above / rabove);
}
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;
}

if (i + ngate + 1 < nsamps) {


sum_below = sum_below - fabs (trace[i + 1])
+ fabs (trace [i + ngate + 1]);
}
else {
if (i + 1 < nsamps) {
sum_below = sum_below - fabs (trace[i + 1]);
rbelow = rbelow - 1.0;
}
}
}

/* Put the final results in place. */


for (i = 0; i < nsamps; i++) {
trace [i] = scratch[i];
}

/* Find the maximum of the ratio function */


*ratio_max = trace [imin_samp ];
ind_max = imin_samp;
for (i = imin_samp ; i<= imax_samp; i++) {
if (trace [i] > *ratio_max) {

Other Docs Search Page Known Problems


ampRatio.c395 Developer’s Programming Guide

ind_max = i;
*ratio_max = trace [i];
}
}

/* Convert the index of the maximum to time*/


*ratio_time = (float) (ind_max ) * samprate;
}

Other Docs Search Page Known Problems


ampRatio.c396 Developer’s Programming Guide

Other Docs Search Page Known Problems


397 Developer’s Programming Guide

Appendix: Ensemble Tool Examples

The appendix provides examples of two types of ProMAX


Ensemble tools: AVO and trace interpolation. The AVO routine
outputs a single trace for each trace ensemble that is input. The
trace interpolation routine creates and outputs a trace between
each of the input traces.

Topics covered in this appendix:


➲ AVO Ensemble Tools
➲ avo.menu
➲ avo.inc
➲ avo.f
➲ avoC.c
➲ Trace Interpolation Tools
➲ prestk_interp.menu
➲ prestk_interp.inc
➲ prestk_interp.f
➲ prestk_interp.c

Other Docs Search Page Known Problems


AVO Ensemble Tools398 Developer’s Programming Guide

AVO Ensemble Tools

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.

Other Docs Search Page Known Problems


avo.menu399 Developer’s Programming Guide

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))
)
)

Other Docs Search Page Known Problems


avo.inc400 Developer’s Programming Guide

avo.inc

C------------------------------------------------------------------------------
C Include file for AVO_DEMO
C------------------------------------------------------------------------------

IMPLICIT NONE
#include <global.inc>
#include <mem.inc>

COMMON /SAVED_PARMS/ SAVE1z, IOPT, IX_X, IX_Y, IX_WT,


& END1z

PTRDIFF_T IX_X, IX_Y, IX_WT


INTEGER IOPT

C ..... IOPT - option for slope or intercept


C ..... IX_X - index of buffer to store X values before linear regression
C ..... IX_Y - index of buffer to store Y values before linear regression
C ..... IX_WT - index of buffer to store weight values before linear regression

Other Docs Search Page Known Problems


avo.f401 Developer’s Programming Guide

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------------------------------------------------------------------------------

SUBROUTINE INIT_AVO_DEMO( LEN_SAV, ITOOLTYPE )

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 ..... Issue a fatal error if the data is already stacked


IF ( IDTYPz .EQ. ISTACKEDpz ) CALL EX_ERR_FATAL(
& ’This process cannot operate on stacked data’ )

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 ..... Get buffers to store the values before linear regression


CALL MEMORY_RESBUFF( MAXDTRz, IX_X, IERR )
CALL MEMORY_RESBUFF( MAXDTRz, IX_Y, IERR )
CALL MEMORY_RESBUFF( MAXDTRz, IX_WT, IERR )

C ..... Check to see if needed standard header entries exist


IF ( IOK_HDR(IOFFSETz) .NE. 1 ) CALL EX_ERR_FATAL(
& ’OFFSET not found in header’ )
IF ( IOK_HDR(IEND_ENSz) .NE. 1 ) CALL EX_ERR_FATAL(
& ’END_ENS not found in header’ )
IF ( IOK_HDR(ITRACENOz) .NE. 1 ) CALL EX_ERR_FATAL(
& ’TRACENO not found in header’ )
IF ( IOK_HDR(ITR_FOLDz) .NE. 1 ) CALL EX_ERR_FATAL(

Other Docs Search Page Known Problems


avo.f402 Developer’s Programming Guide

& ’TR_FOLD not found in header’ )

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

C ..... Set the tool type to ensemble


ITOOLTYPE = IENSEMBLEpz

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------------------------------------------------------------------------------

SUBROUTINE EXEC_AVO_DEMO( TRACES, ITHDRS, RTHDRS, NSTORED )

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)

C ..... No action required in cleanup phase


IF ( CLEANUPz ) RETURN

C ..... Call the actual work routine


CALL AVO_DEMO_WORK( TRACES, ITHDRS, NUMSMPz, NTHz, NSTORED,
& IOFFSETz, IOPT, RSPACEz(IX_X), RSPACEz(IX_Y),
& RSPACEz(IX_WT), TRACES )

C ..... The output trace is the end of a one-trace ensemble


ITHDRS(IEND_ENSz,1) = LASTTRpz
C ..... Assign the "fold"
RTHDRS(ITR_FOLDz,1) = FLOAT(NSTORED)

Other Docs Search Page Known Problems


avo.f403 Developer’s Programming Guide

C ..... Make the trace number null


ITHDRS(ITRACENOz,1) = INULLpz

C ..... Set the number of output traces


NSTORED = 1

RETURN
END

C------------------------------------------------------------------------------
C
C Actual work routine
C
C------------------------------------------------------------------------------

SUBROUTINE AVO_DEMO_WORK( TRACES, RTHDRS, NUMSMP, NTH, NSTORED,


& IH_OFFSET, IOPT, X, Y, WT, TRACE )

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 ..... Special case for one trace


IF ( NSTORED .EQ. 1 ) THEN
IF ( IOPT .EQ. ISLOPEPZ ) THEN
C ............. The slope is undefined, but let’s use zero
CALL VFILL( 0.0, TRACE, 1, NUMSMP )
ELSEIF ( IOPT .EQ. INTERCEPTPZ ) THEN
C ............. The intercept is just the sample values
CALL VMOV( TRACES, 1, TRACE, 1, NUMSMP )
ENDIF
RETURN
ENDIF

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

C ..... Loop over all of the samples in the traces


DO 120 I=1,NUMSMP

C ......... Load the values at a particular time


DO 110 J=1,NSTORED
Y(J) = TRACES(I,J)
110 CONTINUE

C ......... Regress a line through the points


CALL WT_LIN_REG( X, Y, WT, NSTORED, SLOPE, RINTER )

IF ( IOPT .EQ. ISLOPEPZ ) THEN


TRACE(I) = SLOPE
ELSEIF ( IOPT .EQ. INTERCEPTPZ ) THEN

Other Docs Search Page Known Problems


avo.f404 Developer’s Programming Guide

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------------------------------------------------------------------------------

SUBROUTINE WT_LIN_REG( X_IN, Y_IN, WT, NPTS, A, B )

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

C ..... Compute the constants for a weighted linear regression


DO 100 I=1, NPTS
X = WT(I) * X_IN(I)
SWX = SWX + X
SWY = SWY + WT(I) * Y_IN(I)
SW = SW + WT(I)
SWXY = SWXY + X * Y_IN(I)
SWX2 = SWX2 + X * X_IN(I)
100 CONTINUE

C ..... Compute the slope and intercept


A = (SW * SWXY - SWY * SWX) / (SW * SWX2 - SWX * SWX)
B = (SWY - A * SWX) / SW

RETURN
END

Other Docs Search Page Known Problems


avoC.c405 Developer’s Programming Guide

avoC.c

/* include ProMAX prototypes and globals */


#include "cpromax.h"
#include "cglobal.h"

/* define the saved parameters (user input, etc) */


BEGINPARMS
int outputOpt ; /* flag to output slope or intercept */
float *xVals ; /* vector of x values for lin regression */
float *yVals ; /* vector of y values for lin regression */
float *weights; /* vector of weights used in lin regression */
ENDPARMS (parms)

/* functions defined and used internally */


static void avoDemoWork( float*, float*, int );
static void avoDemoWtLinReg( float*, float*, float*,
int, float*, float* );

/* functions defined elsewhere and used here */


float **fVecTo2d( float*, int, int );

/* define option names */


#define ISLOPE 1
#define INTERCEPT 2

/*-------------------------------------------------------------------*/
/* init_avo_exer
/*
/* initialization routine for ProMAX module avo_exer
/*
/*-------------------------------------------------------------------*/

void init_avo_demo_( int *len_sav, int *itooltype )


{

/* local versions of external parameters */


int outputOpt ;
float *xVals ;
float *yVals ;
float *weights ;

/* local variables */
int iErr;

/* connect with global variables */


GlobalRuntime *gr = globalRuntime;

/* issue a fatal error if data is already stacked */


if( gr->idtyp == ISTACKED ){
exErrFatal("This process does not operate on stacked data.");
}

/* see if the user wants to output slope or intercept */


outputOpt = 0;
exParGetInt( "AVO_OPT", &outputOpt );

Other Docs Search Page Known Problems


avoC.c406 Developer’s Programming Guide

if( outputOpt != ISLOPE && outputOpt != INTERCEPT ){


exErrFatal("Output option not recognized.");
}

/* allocate space needed for linear regression */


xVals = (float*)malloc( gr->maxdtr * sizeof(float));
yVals = (float*)malloc( gr->maxdtr * sizeof(float));
weights = (float*)malloc( gr->maxdtr * sizeof(float));
if( xVals == NULL || yVals == NULL || weights == NULL ){
exErrFatal("Memory allocation error in init phase.");
}

/* check for the existance of headers we will need */


if( hdrExists("OFFSET") != 1 ){
exErrFatal(" 'OFFSET' was not found in the trace headers.");
}
if( hdrExists("END_ENS") != 1 ){
exErrFatal(" 'END_ENS' was not found in the trace headers.");
}
if( hdrExists("TRACENO") != 1 ){
exErrFatal(" 'TRACENO' was not found in the trace headers.");
}
if( hdrExists("TR_FOLD") != 1 ){
exErrFatal(" 'TR_FOLD' was not found in the trace headers.");
}

/* the trace number is no longer valid, 1 trace/ensemble output */


gr->itrno_valid = 0;

/* 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;

/* reset the maximum number of data traces output per ensemble. */


/* This value is set for subsequent tools */
gr->maxdtr = 1;

/* set the number of words that need to be saved for re-entrancy */


*len_sav = NPARMS(parms);

/* set the tool type */


*itooltype = IENSEMBLE;

/* set the external saved parameters */


parms->outputOpt = outputOpt;
parms->xVals = xVals ;
parms->yVals = yVals ;
parms->weights = weights ;

/*-------------------------------------------------------------------*/
/* 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

Other Docs Search Page Known Problems


avoC.c407 Developer’s Programming Guide

/* ithdrs - integer trace headers


/* nStored - number of traces in the input array
/*-------------------------------------------------------------------*/

void exec_avo_demo_( float *traces, float *rthdrs, int *ithdrs,


int *nStored )

/* local versions of external parameters */


int outputOpt = parms->outputOpt;
float *xVals = parms->xVals ;
float *yVals = parms->yVals ;
float *weights = parms->weights ;

/* local variables */
int iErr;

/* connect with global variables */


GlobalRuntime *gr = globalRuntime;

/* see if we are in cleanup phase */


if( gr->cleanup ){
free( xVals );
free( yVals );
free( weights );
return;
}

/* call the actual work routine */


avoDemoWork( traces, rthdrs, *nStored );

/* the header being output is the first one in the array. */

/* the output trace is the last one in the ensemble */


ithdrs[hdrIndex("END_ENS")] = LASTTR;

/* assign the fold */


rthdrs[hdrIndex("TR_FOLD")] = (float)(*nStored);

/* make the trace number NULL */


ithdrs[hdrIndex("TRACENO")] = INULL;

/* set the number of output traces to be picked up by the */


/* trace executive and sent to subsequent modules */
*nStored = 1;

/*-------------------------------------------------------------------*/
/* 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
/*-------------------------------------------------------------------*/

Other Docs Search Page Known Problems


avoC.c408 Developer’s Programming Guide

void avoDemoWork( float *traces, float *rthdrs, int nStored )


{

/* local variables */
int i, j, iErr;
float **rhdrs, **tracs;
float slope, intercept;

/* connect with global variables */


GlobalRuntime *gr = globalRuntime;

/* handle the special case of one trace */


if( nStored == 1 ){
if( parms->outputOpt == ISLOPE ){
/* ..... the slope is undefined, use zero for output */
vFill( 0.0, traces, 1, gr->numsmp );
}
else{
/* ..... the intercept is just the sample values in the trace */
return;
}
}

/* put the 1D array into a more convenient form for C */


rhdrs = fVecTo2d( rthdrs, nStored, gr->nth );
tracs = fVecTo2d( traces, nStored, gr->numsmp );

/* 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;
}

/* loop over all the samples */


for( i = 0; i < gr->numsmp; i++ ){

/* .. load the sample amplitudes at the current time */


for( j = 0; j < nStored ; j++ ){
parms->yVals[j] = tracs[j][i];
}

/* .. fit a lsf line through the points */


avoDemoWtLinReg( parms->xVals, parms->yVals, parms->weights,
nStored, &slope, &intercept );

/* .. output the appropriate value */


if( parms->outputOpt == ISLOPE ){
traces[i] = slope;
}
else{
traces[i] = intercept;
}
}

/* free the memory allocated in fVecTo2D */


free( rhdrs );
free( tracs );

Other Docs Search Page Known Problems


avoC.c409 Developer’s Programming Guide

/*-------------------------------------------------------------------*/
/* 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;

/* compute the constants for a linear regression */


for( i= 0; i< npts; i++ ){
x = wt[i] * x_in[i];
swx += x;
swy += wt[i]*y_in[i];
sw += wt[i];
swxy += x*y_in[i];
swx2 += x*x_in[i];
}

/* compute the slope and intercept */


*a = ( (sw*swxy)-(swy*swx))/( (sw*swx2)-(swx*swx));
*b = (swy - (*a * swx) )/sw;

Other Docs Search Page Known Problems


Trace Interpolation Tools410 Developer’s Programming Guide

Trace Interpolation Tools

The following sections show how an ensemble tool can output


more traces than it inputs. The tool simply creates and outputs a
trace between each of the input traces.

Other Docs Search Page Known Problems


prestk_interp.menu411 Developer’s Programming Guide

prestk_interp.menu

'(
name: PRESTK_INTERP
label: "Prestack Interpolation"
value_tab: 35

exec_data: ("PRESTK_INTERP"
("GENERAL"
("dummy" implicit: 1)
)
)
)

Other Docs Search Page Known Problems


prestk_interp.inc412 Developer’s Programming Guide

prestk_interp.inc

C------------------------------------------------------------------------------
C Include file for PRESTK_INTERP
C------------------------------------------------------------------------------

IMPLICIT NONE
#include "global.inc"

COMMON /SAVED_PARMS/ SAVE1z, END1z

Other Docs Search Page Known Problems


prestk_interp.f413 Developer’s Programming Guide

prestk_interp.f

C ..... This is an example of an ensemble tool that outputs MORE traces


C ..... than it inputs. It is a simple minded pre-stack trace interpolator,
C ..... that outputs one traces between every existing pair of traces (as the
C ..... simple mean of the sample values).

SUBROUTINE INIT_PRESTK_INTERP( LEN_SAV, ITOOLTYPE )

#include "prestk_interp.inc"
INTEGER LEN_SAV, ITOOLTYPE

IF ( IDTYPz .EQ. ISTACKEDpz ) CALL EX_ERR_FATAL(


& 'This process not intended for stacked data' )

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 ..... Reset the maximum number of data traces per ensemble


MAXDTRz = MAXDTRz*2 - 1

C ..... Set the number of words for re-entrancy and the tool type
LEN_SAV = CALC_LENSAV
ITOOLTYPE = IENSEMBLEpz

RETURN
END

SUBROUTINE EXEC_PRESTK_INTERP( TRACES, ITHDRS, RTHDRS, NSTORED )

#include "prestk_interp.inc"
INTEGER NSTORED, ITHDRS(NTHz,NSTORED), I, J
REAL TRACES(NUMSMPz,NSTORED), RTHDRS(NTHz,NSTORED)

C ..... No action required in cleanup phase


IF ( CLEANUPz ) RETURN

C ..... Can't interpolate with just one trace in the ensemble


IF ( NSTORED .EQ. 1 ) RETURN

C ..... Interpolate the sample values


DO 110 I=1,NUMSMPz
DO 100 J=NSTORED,2,-1
TRACES(I,J*2-1) = TRACES(I,J)
TRACES(I,J*2-2) = (TRACES(I,J) + TRACES(I,J-1)) / 2.0
100 CONTINUE
110 CONTINUE

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)

Other Docs Search Page Known Problems


prestk_interp.f414 Developer’s Programming Guide

ITHDRS(I,J*2-2) = ITHDRS(I,J-1)
120 CONTINUE
130 CONTINUE

C ..... Set the number of output traces


NSTORED = NSTORED*2 - 1

RETURN
END

Other Docs Search Page Known Problems


prestk_interp.c415 Developer’s Programming Guide

prestk_interp.c

/* include ProMAX prototypes and globals */


#include "cpromax.h"
#include "cglobal.h"

/* define saved parameters */


BEGINPARMS

int dummy; /* doesn't actually have to be here */

ENDPARMS(parms)

void init_prestk_interp_(int *len_sav, int *itooltype);

void exec_prestk_interp_(float *trace, int *ithdr,


float *rthdr, int* nStored);

/*-------------------------------------------------------------------

Description:
Initialization routine for prestack interp

output arguments:
len_save - number of 4-byte words to save for re-entrancy
itooltype - processing tool type

---------------------------------------------------------------------*/

void init_prestk_interp_(int *len_sav, int *itooltype)


{

/* get access to global runtime variables */


GlobalRuntime *gr = globalRuntime;

/* 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;

/* Reset the maximum number of data traces per ensemble */


gr->maxdtr = 2*gr->maxdtr - 1;

/* Set the number of words that need to be saved for re-entrancy. */


*len_sav = NPARMS (parms);

/* set the tool type */


*itooltype = IENSEMBLE;

/*********************************************************************
*
* Description:
* Execution routine for prestack interp

Other Docs Search Page Known Problems


prestk_interp.c416 Developer’s Programming Guide

*
* 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
*
**********************************************************************/

void exec_prestk_interp_(float *traces, int *ithdrs,


float *rthdrs, int*nStored)
{

GlobalRuntime *gr = globalRuntime;

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;

/* No action required in cleanup phase */


if( gr->cleanup ){
return;
}

/* Can't interpolate with just one trace in the ensemble */


if( *nStored == 1 ){
return;
}

/* Put all available trace and header locations into an array */


/* that is easy to handle. */
trcs = fVecTo2d( traces, 2*(*nStored)-1, gr->numsmp );
rhdrs = fVecTo2d( rthdrs, 2*(*nStored)-1, gr->nth );

/* Interpolate the sample values */


for( i = 0; i < gr->numsmp; i++ ){
for( j = *nStored-1; j > 0; j-- ){
trcs[2*j][i] = trcs[j][i];
trcs[2*j-1][i] = (trcs[j][i] + trcs[j-1][i])/2.;
}
}

/* 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];
}
}

/* Set the number of output traces */


*nStored = 2*(*nStored) - 1;

Other Docs Search Page Known Problems


prestk_interp.c417 Developer’s Programming Guide

free( trcs );
free( rhdrs );

Other Docs Search Page Known Problems


prestk_interp.c418 Developer’s Programming Guide

Other Docs Search Page Known Problems


419 Developer’s Programming Guide

Appendix: Panel Tool Examples

This appendix provides examples of panel tools. The examples


demonstrate several important points:

• the panel parameters must be chosen

• the panel parameters must be reported to the trace


executive through the routine EX_PANEL_PARMS, and
the panel parameters can be changed by
EX_PANEL_PARMS

• the programmer should be aware of how to handle the


padded trace array

The examples also demonstrate how panels overlap and mix,


depending upon the panel parameters chosen.

A menu file is presented first, followed by FORTRAN and C


examples. The menu file serves both the C and FORTRAN
code.

Topics covered in this appendix:


➲ panel_test.menu
➲ panel_test.inc
➲ panel_test.f
➲ panelTest.c

Other Docs Search Page Known Problems


panel_test.menu420 Developer’s Programming Guide

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))
)
)
)

Other Docs Search Page Known Problems


panel_test.inc421 Developer’s Programming Guide

panel_test.inc

C------------------------------------------------------------------------------
C Include file for PANEL_TEST
C------------------------------------------------------------------------------

IMPLICIT NONE

#include "global.inc"
#include "mem.inc"

COMMON /SAVED_PARMS/ SAVE1z, RVAL, NPAD_SAMPS, NPAD_TRACES,


& END1z

INTEGER NPAD_SAMPS, NPAD_TRACES


REAL RVAL

Other Docs Search Page Known Problems


panel_test.f422 Developer’s Programming Guide

panel_test.f

SUBROUTINE INIT_PANEL_TEST( LEN_SAV, ITOOLTYPE )

#include "panel_test.inc"
INTEGER LEN_SAV, ITOOLTYPE, NPANEL_SIZE, NPANEL_EDGE,
& NPANEL_MIX
CHARACTER CSCCS_KEY*50

CALL EX_GETPARM( 'PANLSIZE', 1, NPANEL_SIZE )


CALL EX_GETPARM( 'PANLEDGE', 1, NPANEL_EDGE )
CALL EX_GETPARM( 'PANL_MIX', 1, NPANEL_MIX )
C ..... Get padding in time and traces, send through .inc file
CALL EX_GETPARM( 'PANL_TPD', 1, NPAD_TRACES )
CALL EX_GETPARM( 'PANL_SPD', 1, NPAD_SAMPS )

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

SUBROUTINE EXEC_PANEL_TEST( TRACES, ITHDRS, RTHDRS, NSTORED )

#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 ..... increase the sample value for this panel


RVAL = RVAL + 1.0

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

Other Docs Search Page Known Problems


panel_test.f423 Developer’s Programming Guide

130 CONTINUE

RETURN
END

Other Docs Search Page Known Problems


panelTest.c424 Developer’s Programming Guide

panelTest.c

/* include ProMAX prototypes and globals */


#include "cpromax.h"
#include "cglobal.h"

/* define the saved parameters (user input, etc) */


BEGINPARMS

int nPadTraces; /* number of padding traces */


int nPadSamples; /* number of padding samples */
float sampValue; /* value of trace samples */

ENDPARMS (parms)

/*-------------------------------------------------------------------*/
/* init_panel_test
/*
/* initialization routine for ProMAX module sine_wave
/*
/*-------------------------------------------------------------------*/

void init_panel_test_( int *len_sav, int *itooltype )


{

/* local variables */
int panelSize;
int panelEdge;
int panelMix;

/* local versions of external parms */


int nPadTraces;
int nPadSamples;

/* get the panel parameters */


exParGetInt( "PANLSIZE", &panelSize );
exParGetInt( "PANLEDGE", &panelEdge );
exParGetInt( "PANL_MIX", &panelMix );

/* get the padding parameters and pass to exec */


exParGetInt( "PANL_TPD", &nPadTraces );
exParGetInt( "PANL_SPD", &nPadSamples );
parms->nPadTraces = nPadTraces;
parms->nPadSamples = nPadSamples;

/* set the panel parameters. Note that the argument values can be */
/* changed by this routine*/
exPanelParms( &panelSize, &panelEdge, &panelMix,
&nPadTraces, &nPadSamples );

/* initialize the trace sample value */


parms->sampValue = 1.0;

/* set the number of words that need to be saved for re-entrancy */


*len_sav = NPARMS(parms);

Other Docs Search Page Known Problems


panelTest.c425 Developer’s Programming Guide

/* set the tool type to panel */


*itooltype = IPANEL;

/*-------------------------------------------------------------------*/
/* 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
/*-------------------------------------------------------------------*/

void exec_panel_test_( float *traces, float *rthdrs, int *ithdrs,


int *nStored )

/* local variables */
float **tracs;
int i,j;
int nTraces, nSamples;

/* connect with global variables */


GlobalRuntime *gr = globalRuntime;

/* see if we are in cleanup phase */


if( gr->cleanup ){
return;
}

/* calculate the number of samples per trace in the */


/* padded array. The trace length in the padded array is NOT */
/* reflected in the global parameter gr->numsmp. The programmer */
/* must account for the padding.*/
nSamples = gr->numsmp + parms->nPadSamples;

/* calculate the number of traces that are actually in the array. */


/* The value *nStored is the number of live data traces. The */
/* programmer must also keep track of the padding traces. */
nTraces = *nStored + parms->nPadTraces;

/* put the 1D traces array into a more convenient form for C */


tracs = fVecTo2d( traces, 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++ ){

Other Docs Search Page Known Problems


panelTest.c426 Developer’s Programming Guide

for( j = 0; j < nSamples; j++ ){


tracs[i][j] = parms->sampValue;
}
}

/* increase the trace sample value for the next panel */


parms->sampValue += 1.0;

/* free the memory allocated by fVecTo2d() */


free( tracs );

Other Docs Search Page Known Problems


427 Developer’s Programming Guide

Appendix: Single Buffer Tool


Examples

This appendix provides examples of two types of single buffer


tools. The first type is an ensemble definition program in
FORTRAN. The second type is a pre-stack trace interpolation
program that has the same output as prestk_interp, a C language
ensemble tool.

Topics covered in this appendix:


➲ ens_define.menu
➲ ens_define.inc
➲ ens_define.f
➲ interp_sb.menu
➲ interp_sb.c

Other Docs Search Page Known Problems


ens_define.menu428 Developer’s Programming Guide

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))
)
)

Other Docs Search Page Known Problems


ens_define.inc429 Developer’s Programming Guide

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"

COMMON /SAVED_PARMS/ SAVE1z, IH_PRIM, ITRC_COUNT, IX_TRACE,


& IX_THDR, IFIRST_ENTRY, NOUT_EXEC, END1z
INTEGER IH_PRIM, ITRC_COUNT, IX_TRACE, IX_THDR, IFIRST_ENTRY
INTEGER NOUT_EXEC

C ..... IH_PRIM - index of the primary key used to merge ensembles


C ..... ITRC_COUNT - counter for the number of dumped traces in an ensemble
C ..... IX_TRACE - address of the memory used to hold the last trace
C ..... IX_THDR - address of the memory used to hold the last trace header
C ..... IFIRST_ENTRY - value is 1 the very first time the executive is entered
C ..... Number of traces to output in exec phase
C ..... SCCS: @(#)ens_define.inc 31.4 6/18/92

Other Docs Search Page Known Problems


ens_define.f430 Developer’s Programming Guide

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------------------------------------------------------------------------------

SUBROUTINE INIT_ENS_DEFINE( LEN_SAV, ITOOLTYPE )

#include "ens_define.inc"
#include "runtime.inc"

CHARACTER CDESC*32, CPRIM_KEY*8


INTEGER LEN_SAV, ITOOLTYPE, IERR, LENGTH, IFORMAT, NCHARS
INTEGER MAXDTR, IOPTION
CHARACTER CSCCS_KEY*50
DATA CSCCS_KEY /'@(#)ens_define.f 31.5 6/18/92'/

C ..... issue a stern warning if the tool is within an IF conditional


IF (IF_DEPTHrz.NE.0) CALL EX_ERR_HELP( 'Warning: Ensemble '
& // 'Re-define should not be used within IF''s !'
& //'|Click here to CONTINUE (job may fail)'
& //'|Click here to STOP'//CNULLpz, IOPTION )
IF (IOPTION.EQ.3) CALL EX_ERR_STOP(
& 'Stopping execution as requested...' )

C ..... initialize for the exec phase


ITRC_COUNT = 0
IFIRST_ENTRY = 1

C ..... get the primary key name for ensemble redefinition

Other Docs Search Page Known Problems


ens_define.f431 Developer’s Programming Guide

CALL EX_CGETPARM( 'PRIM_KEY', 1, CPRIM_KEY, NCHARS )

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.' )

IF ( CPRIM_KEY(1:4) .EQ. 'NONE' ) THEN


IH_PRIM = 0
ELSE
C ......... get the index in the trace header of the primary key
CALL HDR_NAMINFO( CPRIM_KEY, CDESC, LENGTH, IFORMAT,
& IH_PRIM, IERR )
IF (IERR.NE.0) CALL EX_ERR_FATAL('Primary key '//CPRIM_KEY//
& ' does not occur in the trace header.')
ENDIF

C ..... reset the primary ensemble sort order


IF (CPRIM_KEY(1:3).EQ.'CDP') THEN
IPSORTz = ICDPpz
ELSEIF (CPRIM_KEY(1:6).EQ.'SOURCE') THEN
IPSORTz = ISINpz
ELSEIF (CPRIM_KEY(1:3).EQ.'SIN') THEN
IPSORTz = ISINpz
ELSEIF (CPRIM_KEY(1:4).EQ.'FFID') THEN
IPSORTz = ISINpz
ELSEIF (CPRIM_KEY(1:8).EQ.'REC_SLOC') THEN
IPSORTz = IRECSLOCpz
ELSEIF (CPRIM_KEY(1:4).EQ.'CHAN') THEN
IPSORTz = ICHANpz
ELSEIF (CPRIM_KEY(1:6).EQ.'OFFSET') THEN
IPSORTz = IOFFSETpz
ELSEIF (CPRIM_KEY(1:7).EQ.'AOFFSET') THEN
IPSORTz = IOFFSETpz
ELSE
IPSORTz = IUNKNOWNpz
ENDIF

C ..... get the maximum number of traces per output ensemble


CALL EX_GETPARM( 'MAXTR ', 1, MAXDTR )
IF (MAXDTR.LE.0) CALL EX_ERR_FATAL( 'The maximum number of '
& // 'traces per output ensemble MUST be specified!' )
MAXDTRz = MAXDTR

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 ..... This tool can process trace headers only


CALL EX_THDRONLY_OK

C ..... set the number of words that need to be saved and the tool type
LEN_SAV = CALC_LENSAV
ITOOLTYPE = ISNL_BUFFpz

RETURN
END

Other Docs Search Page Known Problems


ens_define.f432 Developer’s Programming Guide

C------------------------------------------------------------------------------
C Flow routine for ENS_DEFINE.
C------------------------------------------------------------------------------

SUBROUTINE FLOW_ENS_DEFINE( TRACES, ITHDRS, RTHDRS, NSTORED,


& IFOUND_EOJ, NOUTPUT, NOVERLAP )

#include "ens_define.inc"
INTEGER NSTORED, ITHDRS(NTHz,NSTORED), IFOUND_EOJ, NOUTPUT,
& NOVERLAP, J
REAL TRACES(NUMSMPz,NSTORED), RTHDRS(NTHz,NSTORED)

C ..... Initialize the number to output to zero (not ready yet)


NOUTPUT = 0

IF ( IFOUND_EOJ .EQ. 1 ) THEN


C ......... We have reached the end of the data, output whatever we have
NOUTPUT = NSTORED
RETURN
ENDIF

IF ( IH_PRIM .NE. 0 ) THEN


C ......... We are looking for the primary key value to change
DO 100 J=2,NSTORED
IF ( ITHDRS(IH_PRIM,J) .NE. ITHDRS(IH_PRIM,J-1) ) THEN
C ................. Output up to the change
NOUTPUT = J-1
NOUT_EXEC = NOUTPUT
C ................. Save what it not output for next time
NOVERLAP = NSTORED - NOUTPUT
RETURN
ENDIF
100 CONTINUE
ENDIF

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.

Other Docs Search Page Known Problems


ens_define.f433 Developer’s Programming Guide

C Rewritten as a single buffered tools by D.E. Diller, May 12, 1992


C
C------------------------------------------------------------------------------

SUBROUTINE EXEC_ENS_DEFINE( TRACES, ITHDRS, RTHDRS, NTR_BUFF )

#include "ens_define.inc"
#include "header.inc"
INTEGER NTR_BUFF, J, ITHDRS(NTHz,NTR_BUFF)
REAL TRACES(NUMSMPz,NTR_BUFF), RTHDRS(NTHz,NTR_BUFF)

C ..... no action needed for cleanup mode


IF (CLEANUPz) RETURN

C ..... Set the header values


DO 100 J=1,NOUT_EXEC
ITHDRS(ISEQNOz,J) = J
ITHDRS(IEND_ENSz,J) = NLASTpz
100 CONTINUE
ITHDRS(IEND_ENSz,NOUT_EXEC) = LASTTRpz

RETURN
END

Other Docs Search Page Known Problems


interp_sb.menu434 Developer’s Programming Guide

interp_sb.menu

'(
name: INTERP_SB
label: "Single Buffer Trace Interpolation"
value_tab: 35

exec_data: ("INTERP_SB"
("GENERAL"
("dummy" implicit: 1)
)
)
)

Other Docs Search Page Known Problems


interp_sb.c435 Developer’s Programming Guide

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.
/*-------------------------------------------------------------------------*/

/* include promax interface, globals, error codes, etc */


#include "cpromax.h"
#include "cglobal.h"

/* define saved parameters */


BEGINPARMS

int nInEnsemble; /* the number of traces passed to the exec subroutine */


int pKeyHdrIndx; /* index of the primary sort key trace header (FFID, CDP etc)
*/

ENDPARMS(parms)

/*-------------------------------------------------------------------*/
/*
/* description:
/* initialization routine for interp_sb:
/*
/* output arguments:
/* len_sav - length of the saved common block
/* itooltype - type of tool
/*
/*-------------------------------------------------------------------*/

void init_interp_sb_( len_sav, itooltype )

int *len_sav, *itooltype;

int max_to_buffer, nPadTraces, nPadSamples;

/* set the global pointers */


GlobalRuntime *gr = globalRuntime;

/* set the number of words that need to be saved */


*len_sav = NPARMS(parms);

Other Docs Search Page Known Problems


interp_sb.c436 Developer’s Programming Guide

/* 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;

/* set the tool type */


*itooltype = ISNL_BUFF;

/*--------------------------------------------------------------------*/
/*
/* 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

/*
/*
/*--------------------------------------------------------------------*/

flow_interp_sb_( float *traces, int *ithdrs, float *rthdrs,


int *nStored, int *ifound_eoj, int *nOutput, int *nOverlap )

GlobalRuntime *gr = globalRuntime;


float **rhdrs;

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;
}

Other Docs Search Page Known Problems


interp_sb.c437 Developer’s Programming Guide

/* put the trace headers into a 2d array that is easy to handle */


rhdrs = fVecTo2d( rthdrs, *nStored, gr->nth );

/* 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
/*
/*-------------------------------------------------------------------*/

void exec_interp_sb_( float *traces, int *ithdrs,


float *rthdrs, int *nStored )

float **rhdrs, **tracs;

Other Docs Search Page Known Problems


interp_sb.c438 Developer’s Programming Guide

int i,j;

/* set the global pointers */


GlobalRuntime *gr = globalRuntime;

/* if cleaning up release memory, close files, in this case there is nothing to


do */
if( gr->cleanup){
return;
}

/* 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 );

/* Interpolate the sample values */


for( i = 0; i < gr->numsmp; i++ ){
for( j = parms->nInEnsemble-1; j > 0; j-- ){
tracs[2*j][i] = tracs[j][i];
tracs[2*j-1][i] = (tracs[j][i] + tracs[j-1][i])/2.;
}
}

/* 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 );

Other Docs Search Page Known Problems


439 Developer’s Programming Guide

Appendix: Double Buffer Tool


Examples

This appendix provides examples of a double buffer tool. The


FORTRAN example calculates semblance for an input CDP
gather. The C example is a pre-stack interpolation routine that
outputs the same result as interp_sb.c, a single buffer tool.

Topics covered in this appendix:


➲ semblance.menu
➲ semblance.inc
➲ semblance.f
➲ interp_db.menu
➲ interp_db.c

Other Docs Search Page Known Problems


semblance.menu440 Developer’s Programming Guide

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:

Other Docs Search Page Known Problems


semblance.menu441 Developer’s Programming Guide

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: (

(rule1 ( or ( = (value 'NORM) 1 ) ( = (value 'NORM) 2 ) )


(progn (do_show 'RNOISE))
(progn (do_not_show 'RNOISE)))

(VEL_default_rule1 (and ( = ( value 'VSTART) -1.0 )


( = ( db_parmget_line "IUNITSz") 1 ) ) (set_value 'VSTART 4500.0 )
)
(VEL_default_rule2 ( = ( value 'VSTART) -1.0 ) (set_value 'VSTART 1400.0 )
)
(VEL_default_rule3 (and ( = ( value 'VEND) -1.0 )
( = ( db_parmget_line "IUNITSz") 1 ) ) (set_value 'VEND 20000.0 )
)
(VEL_default_rule4 ( = ( value 'VEND) -1.0 ) (set_value 'VEND 7000.0 ) )
)

Other Docs Search Page Known Problems


semblance.inc442 Developer’s Programming Guide

semblance.inc

IMPLICIT NONE

C------------------------------------------------------------------------------
C Include file for SEMBLANCE
C------------------------------------------------------------------------------

#include "global.inc"

COMMON /SAVED_PARMS/ SAVE1z, VSTART, VEND, NVELS, IX_VELSAVE,


& IH_VEL, MIN_FOLD, RNOISE, NORM, STRETCH, NOUT, NFFT,
& IX_WORK2, IX_WORK3, IX_WORK, IX_SAVE, END1z

REAL VSTART, VEND, RNOISE, STRETCH


PTRDIFF_T IX_VELSAVE, IX_WORK, IX_WORK2, IX_WORK3,
& IX_SAVE
INTEGER NVELS, LENSAVED, MIN_FOLD, NORM,
& IH_VEL, NOUT, NFFT

C ..... VSTART - starting velocity


C ..... VEND - ending velocity
C ..... NVELS - number of velocities
C ..... IX_VELS - index of buffer of semblance velocities
C ..... IH_VEL - index of new trace header word
C ..... MIN_FOLD - min fold to calculate semblance
C ..... NORM - semblance normalization option
C ..... RNOISE - noise factor
C ..... STRETCH - maximum stretch allowed for nmo
C ..... NOUT - number of "traces" to output
C ..... NFFT - length of FFT for envelope calculation
C ..... IX_WORK - index of work buffer
C ..... IX_WORK2 - index of work buffer 1
C ..... IX_WORK3 - index of work buffer 2
C ..... IX_SAVE - index of index squared save array

Other Docs Search Page Known Problems


semblance.f443 Developer’s Programming Guide

semblance.f

C------------------------------------------------------------------------------C
Initialization routine for SEMBLANCE
C------------------------------------------------------------------------------

SUBROUTINE INIT_SEMBLANCE( LEN_SAV, ITOOLTYPE )

#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 ..... Input should normally not be stacked data


IF ( IDTYPz .EQ. ISTACKEDpz ) CALL EX_ERR_WARN(
& ’You are operating on STACKED data’ )

C ..... The trace number is no longer valid, and the geometry no longer matches
ITRNO_VALIDz = 0
IGEOM_MATCHz = 0

C ..... Get the starting velocity


VSTART = -1.0
CALL EX_GETPARM( ’VSTART ’, 1, VSTART )
IF ( VSTART .EQ. -1.0 ) CALL EX_ERR_FATAL(
& ’Starting velocity must be specified’ )

C ..... Get the ending velocity


VEND = -1.0
CALL EX_GETPARM( ’VEND ’, 1, VEND )
IF ( VEND .EQ. -1.0 ) CALL EX_ERR_FATAL(
& ’Ending velocity must be specified’ )

C ..... Get the number of velocities


NVELS = 0
CALL EX_GETPARM( ’NVELS ’, 1, NVELS )
IF ( NVELS .LE. 0 ) CALL EX_ERR_FATAL(
& ’Number of velocities must be specified’ )

C ..... We will actually output 3 extra traces


NOUT = NVELS + 3

C ..... get the normalization method


NORM = 0

Other Docs Search Page Known Problems


semblance.f444 Developer’s Programming Guide

CALL EX_GETPARM( ’NORM ’, 1, NORM )


IF ( NORM .LE. 0 ) CALL EX_ERR_FATAL(
& ’Norm method is not specified’ )

C ..... Get the noise factor


RNOISE = 0.1
CALL EX_GETPARM( ’RNOISE ’, 1, RNOISE )
IF ( RNOISE .LT. 0.0 ) CALL EX_ERR_FATAL(
& ’Noise factor must be specified’ )

C ..... Get the minimum fold


MIN_FOLD = 3
CALL EX_GETPARM( ’MIN_FOLD’, 1, MIN_FOLD )
IF ( MIN_FOLD .LT. 0 ) CALL EX_ERR_FATAL(
& ’Minimum fold must be specified’ )

C ..... Get the nmo stretch factor in percent


STRETCH = 50.0
CALL EX_GETPARM( ’STRETCH ’, 1, STRETCH )
IF ( STRETCH .LE. 0 ) STRETCH = 1000.0
STRETCH = 1.0 + STRETCH / 100.0

C ..... Reserve a buffer to save the velocities


CALL MEMORY_RESBUFF( NVELS, IX_VELSAVE, IERR )

C ..... Deal with the maximum number of traces per ensemble


MAXDTRZ_SAVE = MAXDTRz
IF ( NOUT .GT. MAXDTRz ) THEN
MAXDTRz = NOUT
ENDIF

C ..... Get length of FFT for envelope calculation


CALL GET_NFFT(NINT(NUMSMPz*1.25), NFFT)

C ..... Get and keep some small working buffers


CALL MEMORY_RESBUFF( NFFT+2, IX_WORK2, IERR )
CALL MEMORY_RESBUFF( NFFT+2, IX_WORK3, IERR )
CALL MEMORY_RESBUFF( NUMSMPz, IX_WORK, IERR )
CALL MEMORY_RESBUFF( NUMSMPz, IX_SAVE, IERR )
C ..... Load I**2 values for fast nmo
DO 100 I=1,NUMSMPz
RSPACEz(IX_SAVE + I - 1) = FLOAT( (I-1)**2 )
100 CONTINUE

cdd - No, lie so we can use branched flows


cddC ..... Reset the data type to transformed unstacked data
cdd IDTYPz = IUS_TRANSpz

cdd - No, lie so we can use branched flows


cddC ..... Reset the domain to semblance
cdd IDOMAINz = ISEMBpz

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(

Other Docs Search Page Known Problems


semblance.f445 Developer’s Programming Guide

& ’END_ENS not found in trace header’ )


IF ( IOK_HDR(ITRACENOz) .NE. 1 ) CALL EX_ERR_FATAL(
& ’TRACENO not found in trace header’ )

C ..... Create a velocity trace header word


CDESC = ’Semblance velocity’
CALL HDR_ADD( ’SEMB_VEL’, CDESC, 1, IREAL4pz, IH_VEL, IERR )
IF ( IERR .EQ. IERR_HDR_EXSTpz ) THEN
CALL EX_ERR_WARN(
& ’Semblance velocity already exists in trace header’ )
IERR = 0
ELSEIF ( IERR .NE. 0 ) THEN
CALL EX_ERR_FATAL( ’Cannot create new trace header word’ )
ENDIF

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------------------------------------------------------------------------------

SUBROUTINE FLOW_SEMBLANCE( TRACES, ITHDRS, RTHDRS, NSTORED,


& IFOUND_EOJ, NOUTPUT, NOVERLAP )

#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)

C ..... We’re just looking for the end of an ensemble


IF ( IFOUND_EOJ .EQ. 1
& .OR. ITHDRS(IEND_ENSz,NSTORED) .EQ. LASTTRpz ) THEN
NOUTPUT = NOUT
ELSE
NOUTPUT = 0
ENDIF

C ..... We don’t want to see any of the input traces again


NOVERLAP = 0

RETURN
END

Other Docs Search Page Known Problems


semblance.f446 Developer’s Programming Guide

C------------------------------------------------------------------------------
C Execution routine for SEMBLANCE.
C------------------------------------------------------------------------------

SUBROUTINE EXEC_SEMBLANCE( TRACES_IN, ITHDRS_IN, RTHDRS_IN,


& NTR_BUFF_IN, TRACES_OUT, ITHDRS_OUT, RTHDRS_OUT,
& NTR_BUFF_OUT )

#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 )

C ..... Create the output headers


DO 100 J=1,NTR_BUFF_OUT
C ......... Just copy the last header
CALL VMOV( ITHDRS_IN(1,NTR_BUFF_IN), 1,
& ITHDRS_OUT(1,J), 1, NTHz )
C ......... Make the offset zero
RTHDRS_OUT(IAOFFSETz,J) = 0.0
RTHDRS_OUT(IOFFSETz,J) = 0.0
C ......... Set the velocity and round off to nearest 10 for labeling neatness
RTHDRS_OUT(IH_VEL,J) = NINT( RSPACEz(IX_VELSAVE+J-1) )
C ......... Make the trace number null
ITHDRS_OUT(ITRACENOz,J) = INULLpz
C ......... Set the END_ENS flag
ITHDRS_OUT(IEND_ENSz,J) = NLASTpz
IF ( J .EQ. NTR_BUFF_OUT )
& ITHDRS_OUT(IEND_ENSz,J) = LASTTRpz
100 CONTINUE

RETURN
END

SUBROUTINE SEMBLANCE_WORK( TRACES, NSAMPS, RTHDRS, NTH, NSTORED,


& TRWORK, WORK2, WORK3, VELARR, NVELS, NOUT, WORK,
& IH_OFFSET, SAMPRATE, VSTART, VEND, IH_VEL, VELSAVE,
& IH_NA_STAT, NFFT, NORM, RNOISE, MIN_FOLD, STRETCH, SAVE)

Other Docs Search Page Known Problems


semblance.f447 Developer’s Programming Guide

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 ..... Loop thru all of the velocities


DO 200 K=1,NVELS

C ......... Velocity increment based on delta-t


VELT = 1.0 /
& ( 1.0/VSTART - (1.0/VSTART-1.0/VEND) * FLOAT(K-1)
& / FLOAT(NVELS-1) )
C ......... Velocity increment based on delta-v
VELV = VSTART + FLOAT(K-1) * VINC
C ......... Use compromise between delta-t and delta-v
VEL = ( VELT + VELV ) / 2.0
C ......... Store the velocity in the trace header
RTHDRS(IH_VEL,K) = VEL
C ......... Save the velocity
VELSAVE(K) = VEL

C ......... Loop thru all of the traces, applying NMO


DO 110 J=1,NSTORED
OFFSET = ABS( RTHDRS(IH_OFFSET,J) )
STATIC = RTHDRS(IH_NA_STAT,J) / SAMPRATE
XBYV2 = ( 1000. * OFFSET / ( VEL * SAMPRATE ) )**2
C ............. Calculate start sample for output depending on stretch factor
N1 = 1 + NINT( - STATIC +
& SQRT( XBYV2 / ( STRETCH**2 - 1.0 ) ) )
IF( N1 .GT. NSAMPS ) N1 = NSAMPS

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

Other Docs Search Page Known Problems


semblance.f448 Developer’s Programming Guide

C ............. Start at sample with correct stretch and


C ............. NMO correct using nearest sample shift
DO 105 I = N1, N2, 1
IOUT = 1 + NINT( - STATIC + SQRT( SAVE(I) + XBYV2 ) )
TRWORK(I,J) = TRACES(IOUT,J)
105 CONTINUE

110 CONTINUE

C ......... Calculate the semblance


DO 130 I=1,NSAMPS
SUM = 0.0
SUM2 = 0.0
NSUMS = 0
DO 120 J=1,NSTORED
IF ( TRWORK(I,J) .NE. 0.0 ) THEN
C ..................... Stack
SUM = SUM + TRWORK(I,J)
C ..................... Stack the squares
SUM2 = SUM2 + TRWORK(I,J)*TRWORK(I,J)
NSUMS = NSUMS + 1
ENDIF
120 CONTINUE
IF ( NSUMS .GT. MIN_FOLD ) THEN
C ................. signed semblance
C ............. try bias to force down the low fold times
VELARR(I,K) = (SUM*ABS(SUM)) / (FLOAT(NSUMS)*SUM2)
ELSE
VELARR(I,K) = 0.0
ENDIF
130 CONTINUE

C ......... compute envelope of signed semblance


CALL VMOV( VELARR(1,K), 1, WORK, 1, NSAMPS)
C ......... compute the 90 degree phase shifted version of the semb. trace
CALL PHASEFILTER( WORK, NSAMPS, 90.0, NFFT, WORK2, WORK3)
C ......... compute the env of semblance
DO 135 I=1,NSAMPS
VELARR(I,K) = SQRT( WORK(I)**2 + VELARR(I,K)**2 )
135 CONTINUE
C ......... Smooth in time fixed 3 samples - smooth remaining notches
LENHALF = 3 / 2
CALL STAT_AGC_RUNAVG( VELARR(1,K), WORK2, NSAMPS, LENHALF, 1
& )

200 CONTINUE

C ...... calculate power bar on side of plot


C ........ find max semblance
CALL MAXV( VELARR(1,1), 1, RMAX_PANL, J, NVELS*NSAMPS)
DO 210 I=1, NSAMPS
C ......... find max semblance across time slice
CALL MAXV( VELARR(I,1), NSAMPS, RMAX, J, NVELS)
C ......... scale each time slice
IF (RMAX_PANL .GT. 0.0) THEN
VELARR(I,NVELS+1) = 0.0

Other Docs Search Page Known Problems


semblance.f449 Developer’s Programming Guide

VELARR(I,NVELS+2) = RMAX/RMAX_PANL
VELARR(I,NVELS+3) = RMAX/RMAX_PANL
ENDIF
210 CONTINUE

C ...... Scale semblances if necessary


IF ( NORM .EQ. 1 ) THEN
DO 220 I=1, NSAMPS
C ............ find max semblance across time slice
CALL MAXV( VELARR(I,1), NSAMPS, RMAX, J, NVELS)
C ............ scale each time slice individually
IF (RMAX .GT. 0.0) THEN
RMAX = (1.0 + RNOISE) / (RMAX + RNOISE)
CALL VSMUL(VELARR(I,1), NSAMPS, RMAX, VELARR(I,1),
& NSAMPS, NVELS - 2)
ENDIF
220 CONTINUE

ELSEIF ( NORM .EQ. 2) THEN

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

C ..... Error out in init phase


CALL EX_ERR_FATAL(
& ’Semblance Velocity Analysis is no longer supported’ )

END

SUBROUTINE FLOW_SEMBLANCE( TRACES, ITHDRS, RTHDRS, NSTORED,


& IFOUND_EOJ, NOUTPUT, NOVERLAP )

IMPLICIT NONE
#include <global.inc>
INTEGER NSTORED, ITHDRS(NTHz,NSTORED), IFOUND_EOJ, NOUTPUT,
& NOVERLAP
REAL TRACES(NUMSMPz,NSTORED), RTHDRS(NTHz,NSTORED)

RETURN
END

SUBROUTINE EXEC_SEMBLANCE( TRACES_IN, ITHDRS_IN, RTHDRS_IN,


& NTR_BUFF_IN, TRACES_OUT, ITHDRS_OUT, RTHDRS_OUT,
& NTR_BUFF_OUT )

Other Docs Search Page Known Problems


semblance.f450 Developer’s Programming Guide

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

Other Docs Search Page Known Problems


interp_db.menu451 Developer’s Programming Guide

interp_db.menu

'(
name: INTERP_DB
label: "Double Buffer Trace Interpolation"
value_tab: 35

exec_data: ("INTERP_DB"
("GENERAL"
("dummy" implicit: 1)
)
)
)

Other Docs Search Page Known Problems


interp_db.c452 Developer’s Programming Guide

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.
/*-------------------------------------------------------------------------*/

/* include promax interface, globals, error codes, etc */


#include "cpromax.h"
#include "cglobal.h"

/* define saved parameters */


BEGINPARMS

int nInEnsemble; /* the number of traces passed to the exec subroutine */


int pKeyHdrIndx; /* index of the primary sort key trace header (FFID, CDP etc)
*/

ENDPARMS(parms)

/*-------------------------------------------------------------------*/
/*
/* description:
/* initialization routine for interp_sb:
/*
/* output arguments:
/* len_sav - length of the saved common block
/* itooltype - type of tool
/*
/*-------------------------------------------------------------------*/

void init_interp_db_( len_sav, itooltype )

int *len_sav, *itooltype;

int max_to_buffer, nPadTraces, nPadSamples;

/* set the global pointers */


GlobalRuntime *gr = globalRuntime;

/* set the number of words that need to be saved */


*len_sav = NPARMS(parms);

Other Docs Search Page Known Problems


interp_db.c453 Developer’s Programming Guide

/* 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;

/* set the tool type */


*itooltype = IDBL_BUFF;

/*--------------------------------------------------------------------*/
/*
/* flow tool for interp_db
/*
/*
/*
/*--------------------------------------------------------------------*/

flow_interp_db_( float *traces, int *ithdrs, float *rthdrs,


int *nStored, int *ifound_eoj, int *nOutput, int *nOverlap )

GlobalRuntime *gr = globalRuntime;


float **rhdrs;

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;
}

/* put the trace headers into a 2d array that is easy to handle */


rhdrs = fVecTo2d( rthdrs, *nStored, gr->nth );

/* see if the primary key header value of most recent input trace has changed */

Other Docs Search Page Known Problems


interp_db.c454 Developer’s Programming Guide

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;

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 )

float **rhdrs_in, **tracs_in;


float **rhdrs_out, **tracs_out;
int i,j;

Other Docs Search Page Known Problems


interp_db.c455 Developer’s Programming Guide

/* set the global pointers */


GlobalRuntime *gr = globalRuntime;

/* if cleaning up release memory, close files, in this case there is nothing to


do */
if( gr->cleanup){
return;
}

/* 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 );

tracs_out = fVecTo2d( traces_out, *nTrBuffOut, gr->numsmp );


rhdrs_out = fVecTo2d( rthdrs_out, *nTrBuffOut, gr->nth );

/* Interpolate the sample values */


for( i = 0; i < gr->numsmp; i++ ){
for( j = parms->nInEnsemble-1; j > 0; j-- ){
tracs_out[2*j][i] = tracs_in[j][i];
tracs_out[2*j-1][i] = (tracs_in[j][i] + tracs_in[j-1][i])/2.;
}
}

/* 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);

Other Docs Search Page Known Problems


interp_db.c456 Developer’s Programming Guide

Other Docs Search Page Known Problems


457 Developer’s Programming Guide

Appendix: Complex Tool Examples

This appendix provides an example of a complex tool. In this


example, the tool changes the trace length of the output traces
and the number of traces output per ensemble. The program
does not actually do anything useful except to demonstrate how
to use a complex tool.

The program gathers data traces until it has an entire ensemble


of M data traces, each of which is N data samples in length. The
program outputs N data traces, each of which is M samples
long, outputting the transpose of the 2-dimensional input
ensemble matrix.

The menu file is presented first, followed by the FORTRAN


version and then the C version. The menu file serves both the C
and FORTRAN versions.

Topics covered in this appendix:


➲ transform.menu
➲ transform.inc
➲ transform.f
➲ transform.c

Other Docs Search Page Known Problems


transform.menu458 Developer’s Programming Guide

transform.menu

'(
name: TRANSFORM
label: "Transform"
value_tab: 35

exec_data: ("TRANSFORM"
("GENERAL"
("dummy" implicit: nil)
)
)
)

Other Docs Search Page Known Problems


transform.inc459 Developer’s Programming Guide

transform.inc

C------------------------------------------------------------------------------C
Include file for TRANSFORM
C------------------------------------------------------------------------------

IMPLICIT NONE
#include <global.inc>
#include <mem.inc>

COMMON /SAVED_PARMS/ SAVE1z, MAXDTRZ_OLD, NUMSMPZ_OLD, NSTORED,


& NDUMPED, DUMPING, IX_TRACES, IX_THDRS, END1z

INTEGER MAXDTRZ_OLD, NUMSMPZ_OLD, NSTORED, NDUMPED


PTRDIFF_T IX_TRACES, IX_THDRS
LOGICAL DUMPING

C ..... MAXDTRZ_OLD - previous value of MAXDTRz


C ..... NUMSMPZ_OLD - previous value of NUMSMPz
C ..... NSTORED - current number of traces stored
C ..... NDUMPED - current number of traces dumped
C ..... DUMPING - logical flag for dumping mode
C ..... IX_TRACES - index of buffer of traces
C ..... IX_THDRS - index of buffer of trace headers

Other Docs Search Page Known Problems


transform.f460 Developer’s Programming Guide

transform.f

SUBROUTINE INIT_TRANSFORM( LEN_SAV, ITOOLTYPE )

#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 data type to transformed unstacked data


IDTYPz = IUS_TRANSpz

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 ..... Check the needed header entries


IF ( IOK_HDR(IEND_ENSz) .NE. 1 ) CALL EX_ERR_FATAL(
& ’ENS_ENS not found in header’ )
IF ( IOK_HDR(ITRACENOz) .NE. 1 ) CALL EX_ERR_FATAL(
& ’TRACENO not found in header’ )
IF ( IOK_HDR(ISEQNOz) .NE. 1 ) CALL EX_ERR_FATAL(
& ’SEQNO not found in header’ )

C ..... Initialize for execution phase


NSTORED = 0
NDUMPED = 0
DUMPING = .FALSE.

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

Other Docs Search Page Known Problems


transform.f461 Developer’s Programming Guide

RETURN
END

SUBROUTINE EXEC_TRANSFORM( TRACE, ITHDR, RTHDR )

#include "transform.inc"
#include <header.inc>
INTEGER ITHDR(NTHz)
REAL TRACE(*), RTHDR(NTHz)

INTEGER IDUM, IERR, NDUM


PTRDIFF_T IND, IX_WORK

C ..... No action needed for cleanup phase


IF ( CLEANUPz ) RETURN

IF ( .NOT. DUMPING ) THEN


C ......... Filling the buffer before the transform

C ......... Increment the number of traces stored


NSTORED = NSTORED + 1

IF ( NSTORED .EQ. 1 ) THEN


C ............. Get a buffer to fill
CALL MEMORY_RESBUFF( MAXDTRZ_OLD*NUMSMPZ_OLD, IX_TRACES,
& IERR )
CALL MEMORY_RESBUFF( MAXDTRZ_OLD*NTHz, IX_THDRS, IERR )
ENDIF

C ......... Store the current trace and header


IND = IX_TRACES + (NSTORED-1)*NUMSMPZ_OLD
CALL VMOV( TRACE, 1, RSPACEz(IND), 1, NUMSMPZ_OLD )
IND = IX_THDRS + (NSTORED-1)*NTHz
CALL VMOV( ITHDR, 1, ISPACEz(IND), 1, NTHz )

C ......... If this is the end of the ensemble, time to process


IF ( ITHDR( IEND_ENSz ) .EQ. LASTTRpz ) THEN

C ............. Call the actual work routine


CALL MEMORY_RESBUFF( MAXDTRZ_OLD*NUMSMPZ_OLD, IX_WORK,
& IERR )
CALL TRANSFORM_WORK( RSPACEz(IX_TRACES),
& RSPACEz(IX_WORK), NUMSMPZ_OLD, MAXDTRZ_OLD )
CALL MEMORY_FREEBUFF( NDUM, IX_TRACES, IDUM )
IX_TRACES = IX_WORK
C ............. Time to start flushing the buffer
DUMPING = .TRUE.

ELSE
C ............. Otherwise, we are still in fill mode
CALL EX_FILLMODE
RETURN

ENDIF

ENDIF

C ..... If control reaches here, we are dumping the buffer

Other Docs Search Page Known Problems


transform.f462 Developer’s Programming Guide

C ..... Increment the number of traces dumped


NDUMPED = NDUMPED + 1

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 )

C ..... Nullify the trace number


ITHDR(ITRACENOz) = INULLpz

C ..... Set the sequence-number-in-ensemble


ITHDR(ISEQNOz) = NDUMPED

C ..... Copy a "trace" from storage


IND = IX_TRACES + (NDUMPED-1)*NUMSMPz
CALL VMOV( RSPACEz(IND), 1, TRACE, 1, NUMSMPz )

IF ( NDUMPED .EQ. NUMSMPZ_OLD ) THEN


C ......... We are finished dumping

C ......... Reset related variables


DUMPING = .FALSE.
NDUMPED = 0
NSTORED = 0

C ......... Scratch the memory so that another process can use it


C ......... The first and last arguments are no longer used
CALL MEMORY_FREEBUFF( NDUM, IX_TRACES, IDUM )
CALL MEMORY_FREEBUFF( NDUM, IX_THDRS, IDUM )

C ......... This is the last trace in the ensemble


ITHDR(IEND_ENSz) = LASTTRpz

C ......... We are in pipe mode momentarily


CALL EX_PIPEMODE

ELSE

C ......... We still have more traces to dump


ITHDR(IEND_ENSz) = NLASTpz

C ......... We are still in flush mode


CALL EX_FLUSHMODE

ENDIF

RETURN
END

SUBROUTINE TRANSFORM_WORK( TRACES_OLD, TRACES_NEW, NUMSMPZ_OLD,


& MAXDTRZ_OLD )

IMPLICIT NONE
INTEGER NUMSMPZ_OLD, MAXDTRZ_OLD, I, J
REAL TRACES_OLD(NUMSMPZ_OLD,MAXDTRZ_OLD),
& TRACES_NEW(MAXDTRZ_OLD,NUMSMPZ_OLD)

Other Docs Search Page Known Problems


transform.f463 Developer’s Programming Guide

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

Other Docs Search Page Known Problems


transform.c464 Developer’s Programming Guide

transform.c

/* include ProMAX prototypes and globals */


#include "cpromax.h"
#include "cglobal.h"
#include "alloc.h"
#include "memalloc.h"
#include "agfc.h"

/* define saved parameters */


BEGINPARMS

/* saved parms related to sample interval and trace length */


int maxdtr_old;
int numsmp_old;

/* saved parms related to control of trace I/O */


int nstored;
int ndumped;
int dumping;

/* saved parms related to trace and header storage */


float **storedTrcs;
float **storedHdrs;
float **transTrcs;

ENDPARMS(parms)

void init_transform_(int *len_sav, int *itooltype);

void exec_transform_(float *trace, int *ithdr, float *rthdr);

float **transform_work( float**, int, int, int );

/*-------------------------------------------------------------------

Description:
Initialization routine for transform

output arguments:
len_save - number of 4-byte words to save for re-entrancy
itooltype - processing tool type

---------------------------------------------------------------------*/

void init_transform_(int *len_sav, int *itooltype)


{

/* 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;

/* Reset the data type to transformed unstacked data */


gr->idtyp = IUS_TRANS;

Other Docs Search Page Known Problems


transform.c465 Developer’s Programming Guide

/* Reset the domain. We will have to make up something new, since */


/* nothing appropriate exists */
gr->idomain = 100;

/* 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;

/* Make sure the needed header entries exist */


if( hdrExists( "END_ENS" ) != 1 ){
exErrFatal("END_ENS header not found in trace headers.");
}
if( hdrExists( "TRACENO" ) != 1 ){
exErrFatal("TRACENO header not found in trace headers.");
}
if( hdrExists( "SEQNO" ) != 1 ){
exErrFatal("SEQNO header not found in trace headers.");
}

/* Initialize for execution phase, TRUE and FALSE */


/* are #define'd in cpromax.h, TRUE = 1, FALSE = 0 */
parms->nstored = 0;
parms->ndumped = 0;
parms->dumping = FALSE;

/* Set the number of words that need to be saved for re-entrancy. */


*len_sav = NPARMS (parms);

/* set the tool type */


*itooltype = ICOMPLEX;

/*********************************************************************
*
* Description:
* Execution routine for transform
*
* Input/output arguments:
* trace - array of trace samples
* ithdr - trace header (as integer)
* rthdr - trace header (as floating [point)
*
**********************************************************************/

void exec_transform_(float *trace, int *ithdr, float *rthdr)


{

GlobalRuntime *gr = globalRuntime;


int indx;

Other Docs Search Page Known Problems


transform.c466 Developer’s Programming Guide

/* No action needed for cleanup phase */


if( gr->cleanup ) return;

if( parms->dumping == FALSE ){


/* .. Filling the buffer before the transform */

/* .. Increment the number of traces stored */


parms->nstored++;

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. */

parms->storedTrcs = _memAlloc2Float( parms->numsmp_old,


parms->maxdtr_old, "transform.c", 129 );

parms->storedHdrs = _memAlloc2Float( gr->nth, parms->maxdtr_old,


"transform.c", 132 );

/* .. Store the current trace and header */


indx = parms->nstored - 1;
vMov( trace, 1, parms->storedTrcs[indx], 1, parms->numsmp_old );
vMov( ithdr, 1, parms->storedHdrs[indx], 1, gr->nth );

/*... If this is the end of the ensemble it is time to process. */


if ( ithdr[ hdrIndex("END_ENS") ] == LASTTR ){

/* ...... Call the actual work routine that transforms traces */


parms->transTrcs = transform_work( parms->storedTrcs, parms->nstored,
gr->numsmp, parms->numsmp_old );

/* ...... free the memory that stored the original input traces */
_memFree2Float( parms->storedTrcs, "transform.c", 150 );

/* ...... Time to start flushing the buffer */


parms->dumping = TRUE;
}
else{
/* ...... We are still loading traces until we get an entire ensemble. */
/* ...... Set the mode to not output a trace on this call and get */
/* ...... another trace on the next call to exec_transform. */
exFillMode();
return;
}
}

/* If control reaches here, we are dumping the buffer */

/* Increment the number of traces dumped */


parms->ndumped++;

/* Copy a header from storage (same one every time for this exercise) */
vMov( parms->storedHdrs[0], 1, rthdr, 1, gr->nth );

/* Nullify the trace number */


ithdr[hdrIndex("TRACENO")] = INULL;

Other Docs Search Page Known Problems


transform.c467 Developer’s Programming Guide

/* Set the sequence-number-in-ensemble */


ithdr[hdrIndex("SEQNO")] = parms->ndumped;

/* Copy a "trace" from storage */


indx = parms->ndumped - 1;
vMov( parms->transTrcs[indx], 1, trace, 1, gr->numsmp );

if( parms->ndumped == parms->numsmp_old){


/* .. We are finished dumping */

/* .. Reset related variables */


parms->dumping = FALSE;
parms->ndumped = 0;
parms->nstored = 0;

/* .. Free the memory so that another process can use it */


_memFree2Float( parms->transTrcs, "transform", 189 );
_memFree2Float( parms->storedHdrs, "transform,c", 190 );

/* .. This is the last trace in the ensemble */


ithdr[hdrIndex("END_ENS")] = LASTTR;

/* .. We are in pipe mode momentarily, output the current trace and */


/* .. tell the trace executive to give exec_tranform a new trace on the */
/* .. next call */
exPipeMode();

}
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();
}

float **transform_work( float **storedTrcs, int nstored,


int outTrcLen, int numOutTrcs )

/****************************************************************
/*
/* 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
/*
/****************************************************************/

Other Docs Search Page Known Problems


transform.c468 Developer’s Programming Guide

int i, j;
float **t;

/* allocate space for the transformed traces */


t = _memAlloc2Float( outTrcLen, numOutTrcs, "transform.c", 218 );

for( i = 0; i < nstored; i++ ){


for( j = 0; j < numOutTrcs; j++ ){
t[j][i] = storedTrcs[i][j];
}
}

return(t);

Other Docs Search Page Known Problems


469 Developer’s Programming Guide

Appendix: Input Tool Examples

This appendix provides a template for new input tools. Most


input tools will look very much like this tool, except for the
code that actually gets data from tape, disk, or generates the
data internally.

The INIT_ subroutine in this example shows how the trace


headers are created and initialized. It also shows the global
parameters that must be set by the programmer, as well as those
global parameters that must not be set by the programmer. The
EXEC subroutine shows that input tools feed one trace at a time
into the processing flow. The EXEC routine also shows how the
tool tells the trace executive if it has a trace to input to the flow;
namely, through use of calls to EX_FLUSHMODE and
EX_QUITMODE in FORTRAN and exFlushMode and
exQuitMode in C.

The menu file is presented first, followed by the FORTRAN and


C examples.

Topics covered in this appendix:


➲ sine_wave.menu
➲ sine_wave.inc
➲ sine_wave.f
➲ sineWave.c

Other Docs Search Page Known Problems


sine_wave.menu470 Developer’s Programming Guide

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

Other Docs Search Page Known Problems


sine_wave.menu471 Developer’s Programming Guide

E: Ctrl-D Delete one character to the RIGHT of the cursor


E: Ctrl-K KILL to the end of the line (from the cursor)
E: Ctrl-Y YANK back the contents of the kill buffer; 'Cut and
paste'; (Can move the cursor first) " 3 )
value: "60.0,125.0"
mouse_text: "Use B1 to open up and edit field and enter the list of frequencies."

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))
)
)

Other Docs Search Page Known Problems


sine_wave.inc472 Developer’s Programming Guide

sine_wave.inc

C------------------------------------------------------------------------------C
Include file for SINE_WAVE
C------------------------------------------------------------------------------

IMPLICIT NONE
#include <global.inc>
#include <mem.inc>

COMMON /SAVED_PARMS/ SAVE1z, NFREQS, IX_FREQS, NENS, IENS,


& ITRACE_IN_ENS, FIRST_VISIT, END1z

PTRDIFF_T IX_FREQS
INTEGER NFREQS, NENS, IENS, ITRACE_IN_ENS
LOGICAL FIRST_VISIT

C ..... NFREQS - number of frequencies to generate sine waves for


C ..... IX_FREQS - index of buffer of frequencies
C ..... NENS - number of input ensembles
C ..... IENS - current ensemble number
C ..... ITRACE_IN_ENS - current trace in ensemble
C ..... FIRST_VISIT - logical flag for first visit to exec phase

Other Docs Search Page Known Problems


sine_wave.f473 Developer’s Programming Guide

sine_wave.f

C ..... This tool is a template for an input tool


cdd - short-hand header manipulation

cdd - no missing code

SUBROUTINE INIT_SINE_WAVE( LEN_SAV, ITOOLTYPE )

#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 primary key name


CALL EX_CGETPARM( ’PKEYNAM ’, 1, CPKEYNAM, NCHARS )
IF ( CPKEYNAM(1:6) .NE. ’SOURCE’
& .AND. CPKEYNAM(1:3) .NE. ’CDP’ ) CALL EX_ERR_FATAL(
& ’Only SOURCE or CDP can be primary keys’ )

C ..... Get and decode the list for frequencies


CALL EX_CGETPARM( ’FREQS ’, 1, CTEMPz, NCHARS )
IF ( NCHARS .LT. 1 ) CALL EX_ERR_FATAL(
& ’No frequencies were input’ )
CALL DECODE_PREP( CTEMPz, NCHARS, NS )
CALL FLOAT_DECODE( CTEMPz, NS, RTEMPz, NFREQS, .FALSE. )
IF ( NFREQS .LT. 1 ) CALL EX_ERR_FATAL(
& ’No frequencies were input’ )

C ..... Get a buffer and save the frequencies


CALL MEMORY_RESBUFF( NFREQS, IX_FREQS, IERR )
CALL VMOV( RTEMPz, 1, RSPACEz(IX_FREQS), 1, NFREQS )

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 ..... Check and set the number of traces per ensemble

Other Docs Search Page Known Problems


sine_wave.f474 Developer’s Programming Guide

IF ( NTR_PER_ENS .LE. 0 ) THEN


CALL EX_ERR_FATAL(

& ’Number of traces per ensemble < 1’ )


ELSE
MAXDTRz = NTR_PER_ENS
ENDIF

C ..... Assign the sample interval


IF ( SAMPRATE .EQ. 0.0 ) THEN
CALL EX_ERR_FATAL( ’Sample interval must be > 0.0’ )
ELSE
SAMPRATz = SAMPRATE
ENDIF

C ..... Check and set the trace length


IF ( TRACELEN .LE. 0.0 ) THEN
CALL EX_ERR_FATAL(
& ’Input trace length is not greater than zero’ )
ELSE
NUMSMPz = NINT( TRACELEN / SAMPRATz ) + 1
ENDIF

C ..... Check the number of ensembles


IF ( NENS .LT. 1 ) CALL EX_ERR_FATAL(
& ’Number of ensembles < 1’ )

C ..... Define the minimum standard header entries


CALL HDR_STD_MINIMUM

C ..... Set the primary sort flag depending on the primary key name
IF ( CPKEYNAM(1:3) .EQ. ’CDP’ ) THEN

C ......... Add CDP, OFFSET, and AOFFSET to the header


CNAMES(1) = ’OFFSET ’
CNAMES(2) = ’CDP ’
CNAMES(3) = ’AOFFSET ’
CALL HDR_STD_ADD( CNAMES, 3 )

C ......... Set the primary sort FLAG to CDP


IPSORTz = ICDPpz

C ......... Set the primary sort INDEX to CDP


IPKEYz = ICDPz

C ......... Set the secondary sort index to OFFSET


ISKEYz = IOFFSETz

ELSEIF ( CPKEYNAM(1:6) .EQ. ’SOURCE’ ) THEN

C ......... Add SIN, SOURCE, CHAN, and FFID to the header


CNAMES(1) = ’SIN ’
CNAMES(2) = ’SOURCE ’
CNAMES(3) = ’CHAN ’
CNAMES(4) = ’FFID ’
CALL HDR_STD_ADD( CNAMES, 4 )

C ......... Set the primary sort FLAG to source

Other Docs Search Page Known Problems


sine_wave.f475 Developer’s Programming Guide

IPSORTz = ISINpz

C ......... Set the primary sort index to source


IPKEYz = ISOURCEz

C ......... Set the secondary sort index to channel


ISKEYz = ICHANz

ENDIF

C ..... Set the domain to normal space-time


IDOMAINz = ITXpz

C ..... Check to be sure that SEQNO, TRACENO, and END_ENS exist


IF ( IOK_HDR(ISEQNOz) .NE. 1 ) CALL EX_ERR_FATAL(
& ’SEQNO not found in header’ )
IF ( IOK_HDR(ITRACENOz) .NE. 1 ) CALL EX_ERR_FATAL(
& ’TRACENO not found in header’ )
IF ( IOK_HDR(IEND_ENSz) .NE. 1 ) CALL EX_ERR_FATAL(
& ’END_ENS not found in header’ )

C ..... It is impossible for the geometry to match or the trace number to be


C ..... valid (must be set by the program INIT_DATABASE)
IGEOM_MATCHz = 0
ITRNO_VALIDz = 0

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)

C ..... Initialize for exec phase


IENS = 1
ITRACE_IN_ENS = 1
FIRST_VISIT = .TRUE.

C ..... This is an input tool


ITOOLTYPE = INPUTpz

C ..... Set the saved buffer length


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

SUBROUTINE EXEC_SINE_WAVE( TRACE, ITHDR, RTHDR )

Other Docs Search Page Known Problems


sine_wave.f476 Developer’s Programming Guide

#include "sine_wave.inc"
REAL TRACE(NUMSMPz), RTHDR(NTHz)
INTEGER ITHDR(NTHz)
LOGICAL NO_DATA_FOUND

C ..... No action needed for cleanup phase


IF ( CLEANUPz ) RETURN

C ..... Fill the trace


CALL SINE_WAVE_NEXT_TR( TRACE, ITHDR, RTHDR,
& RSPACEz(IX_FREQS), 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

SUBROUTINE SINE_WAVE_NEXT_TR( TRACE, ITHDR, RTHDR, FREQS,


& NO_DATA_FOUND )

#include "sine_wave.inc"
#include <header.inc>
INTEGER ITHDR(NTHz), I
REAL TRACE(NUMSMPz), FREQS(NFREQS), RTHDR(NTHz)
LOGICAL NO_DATA_FOUND

IF ( IENS .GT. NENS ) THEN


C ......... We have no more data to output. This is equivalent to failing
C ......... to read a trace from disk or tape
NO_DATA_FOUND = .TRUE.
RETURN

ELSE
NO_DATA_FOUND = .FALSE.
ENDIF

C ..... If control reaches here, we need to build a new trace

C ..... Initialize the trace with zeros


CALL VCLR( TRACE, 1, NUMSMPz )

C ..... Add the sine wave data to the traces

Other Docs Search Page Known Problems


sine_wave.f477 Developer’s Programming Guide

DO 100 I=1,NFREQS
CALL SINE_WAVE_ADD( FREQS(I), SAMPRATz, NUMSMPz, TRACE )
100 CONTINUE

C ..... Inititalize the values of the minimum standard header entries


CALL HDR_STD_INIT_VALS( ITHDR, RTHDR )

C ..... Take care of other header entries


IF ( IPSORTz .EQ. ISINpz ) THEN
C ......... Inputting shots

C ......... The source index number should be null until geometry is assigned
ITHDR( ISINz ) = INULLpz

C ......... Set the live source number


ITHDR( ISOURCEz ) = IENS

C ......... Set the channel number


ITHDR( ICHANz ) = ITRACE_IN_ENS

C ......... Set the field file ID


ITHDR( IFFIDz ) = IENS

ELSEIF ( IPSORTz .EQ. ICDPpz ) THEN


C ......... Inputting CDPs

C ......... Set the CDP bin number


ITHDR( ICDPz ) = IENS

C ......... Set OFFSET and AOFFSET (doesn’t make much sense)


RTHDR( IOFFSETz ) = FLOAT(ITRACE_IN_ENS)
RTHDR( IAOFFSETz ) = ABS( RTHDR(IOFFSETz) )

ENDIF

C ..... Set the sequence-number-in-ensemble


ITHDR( ISEQNOz ) = ITRACE_IN_ENS

C ..... Set the sequential trace number (null until geometry assignment)
ITHDR( ITRACENOz ) = INULLpz

IF ( ITRACE_IN_ENS .EQ. MAXDTRz ) THEN


C ......... This is the last trace in the ensemble

C ......... Since this is the last trace, set the last-trace-in-ensemble flag
ITHDR( IEND_ENSz ) = LASTTRpz

C ......... Reset the trace-in-ensemble counter to zero


ITRACE_IN_ENS = 0

C ......... Increment the ensemble number for next time


IENS = IENS + 1

ELSE

C ......... This is not the last trace in the ensemble, so set the flag as such
ITHDR( IEND_ENSz ) = NLASTpz

ENDIF

Other Docs Search Page Known Problems


sine_wave.f478 Developer’s Programming Guide

C ..... Increment the trace-in-ensemble number counter for next time


ITRACE_IN_ENS = ITRACE_IN_ENS + 1

RETURN
END

SUBROUTINE SINE_WAVE_ADD( FREQ, SAMPRAT, NUMSMP, TRACE )

IMPLICIT NONE
INTEGER NUMSMP, I
REAL TRACE(NUMSMP), FREQ, SAMPRAT, TIME, ANGLE, TWO_PI

TWO_PI = ASIN(1.0) * 4.0

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

Other Docs Search Page Known Problems


sineWave.c479 Developer’s Programming Guide

sineWave.c

/* this tool is a template for an input tool */

/* include ProMAX prototypes and globals */


#include "cpromax.h"
#include "cglobal.h"

/* define the saved parameters (user input, etc) */


BEGINPARMS

int nens; /* number of trace ensembles to generate */


int nfreqs; /* number of frequencies in output traces */
float *freqs; /* list of frequencies in output traces */
int currEns; /* the current ensemble number */
int currTrcInEns; /* current trace number in ensemble */
logical firstVisit; /* flag for first visit to exec */

ENDPARMS (parms)

/* functions defined and used internally */


static void sineWaveAdd( float, float, int, float* );
static int sineWaveNextTr( float*, int*, float*, float* );

/*-------------------------------------------------------------------*/
/* init_sine_wave
/*
/* initialization routine for ProMAX module sine_wave
/*
/*-------------------------------------------------------------------*/

void init_sine_wave_( int *len_sav, int *itooltype )


{

/* declare local variables */


char *pkeyName;
char *freqList;
int nChars;
int ntrPerEns;
int ns;
int iErr;
int okHdrOnly;
logical gatesFlag;
float sampRate;
float traceLen;

/* declare local versions of external parameters */


int nens;
int nfreqs;
float *freqs;
char *newList;
int lenFreqList;
int currEns;
int currTrcInEns;
logical firstVisit;

Other Docs Search Page Known Problems


sineWave.c480 Developer’s Programming Guide

/* set a pointer to the global structures */


GlobalRuntime *gr = globalRuntime;

/* get the primary key name */


exParGetString( "PKEYNAM", &pkeyName );

if( strcmp( pkeyName, "SOURCE" ) != 0 && strcmp( pkeyName, "CDP" ) != 0 ){


exErrFatal("Only SOURCE and CDP can be primary keys.");
}

/* get and decode the list of frequencies */


exParGetString("FREQS", &freqList );
if( strlen( freqList ) < 1 ){
exErrFatal("No frequencies were input!");
}

/* put freqList into a bigger array since decodePrep can */


/* require more space than is required by the input array */
lenFreqList = strlen( freqList );
newList = (char*)realloc( (void*)freqList, (2*(size_t)lenFreqList) );
nChars = decodePrep( newList, lenFreqList );

/* allocate enough space for the frequency list at max length */


freqs = (float*)malloc( nChars * sizeof(float));

gatesFlag = FALSE;
nfreqs = floatDecode( newList, nChars, freqs, gatesFlag );

/* free the newList space */


free( newList );

/* 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;

exParGetInt( "NTRACES", &ntrPerEns );


exParGetInt( "NENS", &nens );
exParGetFloat( "TRACELEN", &traceLen );
exParGetFloat( "SAMPRATE", &sampRate );

/* check and set the number of traces per ensemble */


if( ntrPerEns <= 0 ){
exErrFatal("Number of traces per ensemble is < 1.");
}
else{
gr->maxdtr = ntrPerEns;
}

/* assign the sample interval */


if( sampRate <= 0.0 ){
exErrFatal("The sample interval cannot be 0.0 or less.");
}
else{
gr->samprat = sampRate;
}

Other Docs Search Page Known Problems


sineWave.c481 Developer’s Programming Guide

/* assign the trace length, use the agfc.h NINT macro */


if( traceLen <= 0.0 ){
exErrFatal("The trace length cannot be 0.0 or less.");
}
else{
gr->numsmp = NINT( traceLen/sampRate ) + 1;
}

/* check the number of ensembles */


if( nens < 1 ){
exErrFatal("Number of ensembles is less than 1.");
}

/* define the minimum standard header entries */


defStdHdr();

/* set the primary sort flag depending on primary key name */


if( strncmp( pkeyName, "CDP", 3 ) == 0 ){

/* .. add CDP, OFFSET, and AOFFSET to headers */


hdrAddStd("CDP");
hdrAddStd("OFFSET");
hdrAddStd("AOFFSET");

/* .. set the primary sort flag to CDP */


gr->ipsort = ICDP;

/* .. set the primary sort trace header index to cdp */


/* .. IMPORTANT NOTE, the standard header structure contains */
/* .. header index values that are appropriate for FORTRAN, a */
/* .. result of the trace executive being in FORTRAN. When you */
/* .. set gr->ipkey, use FORTRAN-appropriate values. When you */
/* .. need C header indicies, use the hdrIndex function or */
/* .. subtract 1 from the standard header value in stdHdr. */
gr->ipkey = stdHdr->icdp;

/* .. set the secondary key sort index to OFFSET */


gr->iskey = stdHdr->ioffset;
}
else{
/* .. add SIN, SOURCE, CHAN, and FFID to the header */
hdrAddStd("SIN");
hdrAddStd("SOURCE");
hdrAddStd("CHAN");
hdrAddStd("FFID");

/* .. set the primary sort flag to source */


gr->ipsort = ISIN;

/* .. set the primery sort index to source */


gr->ipkey = stdHdr->isource;

/* .. set the secondary sort index to channel */


gr->iskey = stdHdr->ichan;
}

/* set the domain to normal space-time */


gr->idomain = ITX;

Other Docs Search Page Known Problems


sineWave.c482 Developer’s Programming Guide

/* it is impossible for the geometry to match or the trace number */


/* to be valid */
gr->igeom_match = FALSE;
gr->itrno_valid = FALSE;

/* here are the globalRuntime variables that you do not set: */


/* gr->nth - the number of 4-byte words in the trace header
/* gr->mode - the run mode (INTER, IBACKG, IBATCH)
/* gr->iounit - the I/O unit for output diagnostics
/* gr->idate - the current date (seconds since 00:00:00 GMT, Jan 1, 1970)
/* gr->npriorf - number of prior processing flows
/* gr->cleanup - flag indicating the system is in cleaup mode
/* gr->ierror - flag indicating the system is running under an error
/* condition and trying to cleanup
/* gr->init_only - flag indicating that only initialization phase is
/* being executed
/* */

/* initialize some values for exec phase */


currEns = 1;
currTrcInEns = 1;
firstVisit = TRUE;

/* set the number of words that need to be saved for re-entrancy */


*len_sav = NPARMS(parms);

/* set the tool type to simple, (one trace in one trace out). */
*itooltype = INPUT;

/* set the external parameters */


parms->nens = nens ;
parms->nfreqs = nfreqs ;
parms->freqs = freqs ;
parms->currEns = currEns ;
parms->currTrcInEns = currTrcInEns ;
parms->firstVisit = firstVisit ;

/*-------------------------------------------------------------------*/
/* exec_sine_wave
/*
/* execution routine for ProMAX module sine_wave
/*
/*
/*-------------------------------------------------------------------*/

void exec_sine_wave_( float* trace, float* rthdr, int* ithdr )


{

/* declare local versions of external variables */


int nens = parms->nens ;
int nfreqs = parms->nfreqs ;
float *freqs = parms->freqs ;
int currEns = parms->currEns ;
int currTrcInEns = parms->currTrcInEns ;
logical firstVisit = parms->firstVisit ;

Other Docs Search Page Known Problems


sineWave.c483 Developer’s Programming Guide

/* declare local variables */


logical noDataFound;
int iErr;

/* set a pointer to the globalRuntime structure */


GlobalRuntime *gr = globalRuntime;

/* see if we are in cleanup phase */


if( gr->cleanup ){
free( parms->freqs );
return;
}

/* fill the current trace and header buffers */


noDataFound = sineWaveNextTr( trace, ithdr, rthdr, freqs );

if( parms->firstVisit == TRUE ){


/* .. we only want to do this once */
parms->firstVisit = FALSE;
if( noDataFound == TRUE ){
exErrFatal("Unable to create any traces.");
}
}

if( noDataFound == TRUE ){


/* .. we have no data to output, this is analogous to hitting the end */
/* .. of a disk file or the end of a tape */
exQuitMode();
}
else{
/* .. we have a trace to give to the executive */
exFlushMode();
}

/*-------------------------------------------------------------------*/
/* 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
/*
/*-------------------------------------------------------------------*/

static int sineWaveNextTr( float *trace, int *ithdr, float *rthdr,


float *freqs )

/* local variables */

Other Docs Search Page Known Problems


sineWave.c484 Developer’s Programming Guide

int i;
int iErr;
float offset;

/* global variables */
GlobalRuntime *gr = globalRuntime;

if( parms->currEns > parms->nens ){


/* .. we have no more data to output, this is equivalent to */
/* .. failing to read a trace from tape or disk */
return(TRUE);
}

/* if control reaches here we need to build a trace */

/* clear the input data trace */


vClr( trace, 1, gr->numsmp );

/* add the sine_wave data to the trace */


for( i = 0; i < parms->nfreqs; i++ ){
sineWaveAdd( freqs[i], gr->samprat, gr->numsmp, trace );
}

/* initialize the values of the minimum standard header values */


initStdHdr( ithdr, rthdr );

/* take care of other header entries */


if( gr->ipsort == ISIN ){
/* .. inputting shots */

/* .. the source index number should be null until geom is assigned */


ithdr[ hdrIndex("SIN") ] = INULL;

/* .. set the live source number */


ithdr[ hdrIndex("SOURCE") ] = parms->currEns;

/* .. set the channel number */


ithdr[ hdrIndex("CHAN") ] = parms->currTrcInEns;

/* .. set the field file id number, FFID */


ithdr[ hdrIndex("FFID") ] = parms->currEns;

}
else{
/* .. inputting CDPs */

/* .. set the CDP bin number */


ithdr[ hdrIndex("CDP") ] = parms->currEns;

/* .. 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 );
}

/* set the sequence number in the ensemble */


ithdr[ hdrIndex("SEQNO") ] = parms->currTrcInEns;

/* set the sequential trace number (null until geometry is assigned) */

Other Docs Search Page Known Problems


sineWave.c485 Developer’s Programming Guide

ithdr[ hdrIndex("TRACENO")] = INULL;

if( parms->currTrcInEns == gr->maxdtr ){


/* .. this is the last trace in the ensemble, set end of ens flag */
ithdr[ hdrIndex("END_ENS") ] = LASTTR;

/* .. reset the trace-in-ensemble counter, it gets incremented below */


parms->currTrcInEns = 0;

/* .. increment the ensemble number for next time */


parms->currEns += 1;
}
else{
/* .. this is not the last trace in the ensembel */
ithdr[ hdrIndex("END_ENS") ] = NLAST;
}

/* increment the trace in ensemble counter for the next trace */


parms->currTrcInEns += 1;

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
/*
/*-------------------------------------------------------------------*/

static void sineWaveAdd( float freq, float sampInt, int numsmp,


float *trace )
{

/* local variables */
int i;
double angle, twoPi, time;

twoPi = asin(1.0)*4.0;

for( i = 0; i < numsmp; i++ ){


time = (float)i * sampInt/1000.;
angle = freq*time*twoPi;
trace[i] += (float)sin( angle );
}
}

Other Docs Search Page Known Problems


sineWave.c486 Developer’s Programming Guide

Other Docs Search Page Known Problems


487 Developer’s Programming Guide

Appendix: Disk Iteration Examples

The appendix demonstrates the use of the disk iteration


capabilities of ProMAX tools. The following examples present
a prototype for a surface-consistent amplitude correction
program. A FORTRAN example is presented first, followed by
a C example.

The critical subroutine in this disk iteration program is


EX_SET_DISKITER() in FORTRAN and ex_set_diskiter_() in
C. Note that in C, the program is simply calling the FORTRAN
code directly. Since there is only one calling argument, this is
not difficult to do.

Topics covered in this chapter:


➲ sc_amp.menu
➲ sc_amp.inc
➲ sc_amp.f
➲ disk_iter.menu
➲ disk_iter.c

Other Docs Search Page Known Problems


sc_amp.menu488 Developer’s Programming Guide

sc_amp.menu

'(
name: SC_AMP
label: "Sc Amp"
value_tab: 35

exec_data: ("SC_AMP"
("GENERAL"
("dummy" implicit: nil)
)
)
)

Other Docs Search Page Known Problems


sc_amp.inc489 Developer’s Programming Guide

sc_amp.inc

C------------------------------------------------------------------------------
C Include file for SC_AMP
C------------------------------------------------------------------------------

IMPLICIT NONE
#include "global.inc"

COMMON /SAVED_PARMS/ SAVE1z, PROCESSING, NSHOTS, NRECS,


& IX_SHOT_SUM, IX_SHOT_NORM, IX_REC_SUM, IX_REC_NORM, IX_TR,
& END1z

LOGICAL PROCESSING
INTEGER NSHOTS, NRECS
PTRDIFF_T IX_SHOT_SUM, IX_SHOT_NORM, IX_REC_SUM, IX_REC_NORM,
& IX_TR

Other Docs Search Page Known Problems


sc_amp.f490 Developer’s Programming Guide

sc_amp.f

C ..... This is a working model for a surface consistent gain module. It


C ..... makes no attempt for true separation of source and receiver.

SUBROUTINE INIT_SC_AMP_EXER( LEN_SAV, ITOOLTYPE )

#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 ..... Get a work buffer to hold one trace


CALL MEMORY_RESBUFF( NUMSMPz, IX_TR, IERR )

C ..... Check for needed header entries


IF ( IOK_HDR(ISINz) .NE. 1 )
& CALL EX_ERR_FATAL( ’SIN not found in header’ )
IF ( IOK_HDR(IREC_SLOCz) .NE. 1 )
& CALL EX_ERR_FATAL( ’REC_SLOC not found in header’ )
IF ( IOK_HDR(IDISKITERz) .NE. 1 ) CALL EX_ERR_FATAL(
& ’DISKITER not found in header (not using Disk Data Input?)’ )

C ..... Initialize for execution phase


PROCESSING = .FALSE.

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

Other Docs Search Page Known Problems


sc_amp.f491 Developer’s Programming Guide

LEN_SAV = CALC_LENSAV
ITOOLTYPE = ICOMPLEXpz

RETURN
END

SUBROUTINE EXEC_SC_AMP_EXER( TRACE, ITHDR, RTHDR )

#include "sc_amp_exer.inc"
#include <header.inc>
INTEGER ITHDR(NTHz), ISHOT, IREC
REAL TRACE(NUMSMPz), RTHDR(NTHz), SCALAR

C ..... No action required in cleanup phase


IF ( CLEANUPz ) RETURN

IF ( ITHDR(ISINz) .GE. MINSINz


& .AND. ITHDR(ISINz) .LE. MAXSINz
& .AND. ITHDR(IREC_SLOCz) .GE. MINSLOCz
& .AND. ITHDR(IREC_SLOCz) .LE. MAXSLOCz ) THEN
C ......... This is a valid trace

C ......... Compute the sequential shot and receiver mem offset


ISHOT = (ITHDR(ISINz)-MINSINz) / INCSINz + 1
IREC = (ITHDR(IREC_SLOCz)-MINSLOCz) / INCSLOCz + 1

IF ( ITHDR(IDISKITERz) .EQ. 1 ) THEN


C ............. Still analyzing the data
C ............. Call the routine to accumulate the statistics
CALL SC_AMP_ACCUM( ISHOT, IREC, TRACE, RSPACEz(IX_TR),
& NUMSMPz, RSPACEz(IX_SHOT_SUM),
& RSPACEz(IX_SHOT_NORM), RSPACEz(IX_REC_SUM),
& RSPACEz(IX_REC_NORM) )
ELSE
C ............. Processing the data
IF ( .NOT. PROCESSING ) THEN
C ................. Just started processing
PROCESSING = .TRUE.
C ................. Normalize the values
CALL SC_AMP_NORM( NSHOTS, NRECS,
& RSPACEz(IX_SHOT_SUM), RSPACEz(IX_SHOT_NORM),
& RSPACEz(IX_REC_SUM), RSPACEz(IX_REC_NORM) )
ENDIF
C ............. Apply the scalar to this trace
SCALAR = ( RSPACEz(IX_SHOT_SUM+ISHOT-1)
& + RSPACEz(IX_REC_SUM+IREC-1) ) / 2.0
CALL VSDIV( TRACE, 1, SCALAR, TRACE, 1, NUMSMPz )

ENDIF
ENDIF

IF ( ITHDR(IDISKITERz) .EQ. 1 ) THEN


C ......... Still analyzing the data, so act as a black hole
CALL EX_FILLMODE
ELSE
CALL EX_PIPEMODE

Other Docs Search Page Known Problems


sc_amp.f492 Developer’s Programming Guide

ENDIF

RETURN
END

SUBROUTINE SC_AMP_ACCUM( ISHOT, IREC, TRACE, TR_WORK,


& NUMSMP, SHOT_SUM, SHOT_NORM, REC_SUM, REC_NORM )

C ..... Routine to accumulate the statistics

IMPLICIT NONE
INTEGER ISHOT, IREC, NUMSMP
REAL TRACE(NUMSMP), TR_WORK(NUMSMP), SHOT_SUM(*), SHOT_NORM(*),
& REC_SUM(*), REC_NORM(*), SUM, AVEAMP

C ..... Convert the trace to absolute values


CALL VABS( TRACE, 1, TR_WORK, 1, NUMSMP )
C ..... Take the sum
CALL SVE( TR_WORK, 1, SUM, NUMSMP )
C ..... Normalize to the number of samples (ignore hard zeros)
AVEAMP = SUM / FLOAT(NUMSMP)
C ..... Add this value to the respective shot and receiver
SHOT_SUM(ISHOT) = SHOT_SUM(ISHOT) + AVEAMP
SHOT_NORM(ISHOT) = SHOT_NORM(ISHOT) + 1.0
REC_SUM(IREC) = REC_SUM(IREC) + AVEAMP
REC_NORM(IREC) = REC_NORM(IREC) + 1.0

RETURN
END

SUBROUTINE SC_AMP_NORM( NSHOTS, NRECS, SHOT_SUM, SHOT_NORM,


& REC_SUM, REC_NORM )

C ..... Routine to normalize the values

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

Other Docs Search Page Known Problems


sc_amp.f493 Developer’s Programming Guide

110 CONTINUE

RETURN
END

Other Docs Search Page Known Problems


disk_iter.menu494 Developer’s Programming Guide

disk_iter.menu

'(
name: DISK_ITER
label: "Disk Iteration Demo"
value_tab: 50

exec_data: ("DISK_ITER"
("GENERAL"
("DUMMY" implicit: 0)
)
)

Other Docs Search Page Known Problems


disk_iter.c495 Developer’s Programming Guide

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.
/*
/*--------------------------------------------------------------------*/

/* include promax interface, globals, error codes, etc */


#include "cpromax.h"
#include "cglobal.h"

/* define saved parameters */


BEGINPARMS

float *scalVals; /* scalar values */


int hdrIndexSIN;

ENDPARMS(parms)

/*-------------------------------------------------------------------*/
/*
/* description:
/* initialization routine for disk_iter
/*
/* output arguments:
/* len_sav - length of the saved common block
/* itooltype - type of tool
/*
/*
/*-------------------------------------------------------------------*/

void init_disk_iter_( int *len_sav, int *itooltype )

int nShots, numIters, i;

/* set the global pointers */


GlobalRuntime *gr = globalRuntime;
GlobalGeom *gg = globalGeom;

/* make sure the data are sorted by source */


if( gr->ipsort != ISIN ){
exErrFatal("Data must be sorted by SIN for this program to operate.");
}

/* allocate and initialize enough memory to store shot scalar values */


nShots = gg->maxsin - gg->minsin + 1;
if( nShots <= 0 ){
exErrFatal("Number of shots must be greater than 0. Have you "
"assigned geometry yet?");
}

parms->scalVals = (float*)malloc( nShots * sizeof(float));


if( parms->scalVals == NULL ){

Other Docs Search Page Known Problems


disk_iter.c496 Developer’s Programming Guide

exErrFatal("Memory allocation error, %d bytes requested.",


nShots * sizeof(float));
}

for( i = 0; i < nShots; i++ ){


parms->scalVals[i] = 0.0;
}

/* set the number of disk iterations, note that this is a call to a */


/* FORTRAN routine so the address of numIters has to be passed. */
numIters = 2;
ex_set_diskiter_( &numIters );

/* get the trace header index of SIN */


if( hdrExists("SIN") ){
parms->hdrIndexSIN = hdrIndex("SIN");
}
else{
exErrFatal("The header SIN does not exist in the dataset."
"Assign geometry to the data.");
}

/* set the number of words that need to be saved */


*len_sav = NPARMS(parms);

/* set the tool type */


*itooltype = ICOMPLEX;

/*-------------------------------------------------------------------*/
/*
/* description:
/* exectution routine for disk_iter
/*
/* input/output arguments:
/* trace - data trace
/* ithdr - int header array
/* rthdr - float header array
/*
/*-------------------------------------------------------------------*/

void exec_disk_iter_( float *trace, int *ithdr, float *rthdr)

{
int i;
float val;

/* set the global pointers */


GlobalRuntime *gr = globalRuntime;
GlobalGeom *gg = globalGeom;

if( ithdr[ hdrIndex("DISKITER") ] == 1 ){


/* .. this is the first pass of the data */

/* .. sum the amplitudes */


if( ithdr[ parms->hdrIndexSIN ] < gg->maxsin ){
for( i = 0; i < gr->numsmp; i++ ){

Other Docs Search Page Known Problems


disk_iter.c497 Developer’s Programming Guide

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 */

/* .. scale the trace */


if( val = parms->scalVals[parms->hdrIndexSIN] != 0.0 ){
for( i = 0; i < gr->numsmp; i++ ){
trace[i] /= val;
}
}

/* .. put this trace back into the flow and receive one on the next call */
exPipeMode();
}

Other Docs Search Page Known Problems


disk_iter.c498 Developer’s Programming Guide

Other Docs Search Page Known Problems


499 Developer’s Programming Guide

Appendix: Stand-alone Tool


Examples

This appendix provides examples of stand-alone programs. The


first group of programs shows how to read data from a ProMAX
disk dataset. It includes two FORTRAN examples (prestack.f
and poststack.f) and one C example (poststack.c). Note that the
FORTRAN routines require a C program, or wrapper, to allow
the program to pass command line arguments. The C program
does not require a wrapper, since command line arguments can
be passed directly to the program.

The next program (vel_io.f) demonstrates how to input and


output velocities to the ProMAX database.

Topics covered in this appendix:


➲ prestack_menu
➲ prestack.f
➲ Makefile_prestack
➲ poststack.f
➲ Makefile_poststack
➲ poststack.c
➲ vel_io.f

Other Docs Search Page Known Problems


prestack.menu500 Developer’s Programming Guide

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))
)
)
)

Other Docs Search Page Known Problems


prestack.f501 Developer’s Programming Guide

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.

SUBROUTINE PRESTACK( NARGS, CINPUT )

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

IF ( NARGS .LT. 2 ) THEN


C ......... Nothing was entered on the command line
CALL U_ERR_FATAL( ’Packet file must be specified’ )
ENDIF

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 )

Other Docs Search Page Known Problems


prestack.f502 Developer’s Programming Guide

CALL U_ERR_FATAL( ’Unable to initialize the database’ )


ENDIF

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 the requested domain: 1=CDP, 2=SIN, 3=SRF


CALL U_GETPARM( ID_PACKET, ’DOMAIN ’, 1, INPUT_DOMAIN )
IF ( INPUT_DOMAIN .EQ. 1 ) THEN
CENS_FLAG = ’CDP’
ELSEIF ( INPUT_DOMAIN .EQ. 2 ) THEN
CENS_FLAG = ’SIN’
ELSEIF ( INPUT_DOMAIN .EQ. 3 ) THEN
CENS_FLAG = ’SRF’
ENDIF

C ..... Open the dataset (status=readonly)


IREAD_ONLY = 1
CALL DISKIO_OPEN( CLABEL, IREAD_ONLY, ID_DATASET, IERR )
IF ( IERR .NE. 0 ) THEN
CALL U_ERR_FATAL(
& ’Unable to open the trace dataset ’ // CLABEL )
ENDIF

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’ )

Other Docs Search Page Known Problems


prestack.f503 Developer’s Programming Guide

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

IF ( NENS .LT. 1 ) CALL U_ERR_FATAL(


& ’Less than 1 ensemble exists’ )
IF ( MAXFOLD .LT. 1 ) CALL U_ERR_FATAL(
& ’Maximum fold is less than 1’ )

C ..... Call the routine that does the actual work.


CALL STAND_ALONE_WORK( RSPACEz(IX_TRACE), ISPACEz(IX_THDR),
& RSPACEz(IX_THDR), NUMSMP, NTH, NENS, IH_PKEY,
& ID_DATASET, CENS_FLAG )

C ..... Free buffers


CALL MEMORY_FREEBUFF( NUMSMP, IX_TRACE, IERR )
CALL MEMORY_FREEBUFF( NTH, IX_THDR, IERR )

C ..... Close the packet file


CALL PKT_FILCLOSE( ID_PACKET, IERR )

C ..... Close the dataset


CALL DISKIO_CLOSE( ID_DATASET )

C ..... Report normal completion


CALL U_COMP_NORMAL

END

SUBROUTINE STAND_ALONE_WORK( TRACE, ITHDR, RTHDR, NUMSMP, NTH,


& NENS, IH_PKEY, ID_DATASET, CENS_FLAG )

IMPLICIT NONE

#include "global.inc"

INTEGER NUMSMP, NTH, NENS, IFOUND_VAL, ITRACENO, ITHDR(NTH),


& IFOLD, IERR, J, I, IH_PKEY, ITOKEN1, ID_DATASET, IENS,
& ITOKEN2
REAL RTHDR(NTH), TRACE(NUMSMP)
CHARACTER CENS_FLAG*3, CS_DOMAIN*8, CPKEYNAM*8

Other Docs Search Page Known Problems


prestack.f504 Developer’s Programming Guide

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 ..... Loop over the ensembles


DO 110 J=1,NENS

C ......... Determine which ensemble this is


IF ( CENS_FLAG .EQ. ’CDP’ ) THEN
IENS = MINCDPz + (J-1) * INCCDPz
ELSEIF ( CENS_FLAG .EQ. ’SIN’ ) THEN
IENS = MINSINz + (J-1) * INCSINz
ELSEIF ( CENS_FLAG .EQ. ’SRF’ ) THEN
IENS = MINSLOCz + (J-1) * INCSLOCz
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 )

Other Docs Search Page Known Problems


prestack.f505 Developer’s Programming Guide

C ............. These had BETTER be the same


IF ( IENS .NE. ITHDR(IH_PKEY) ) THEN
WRITE (*,*) I, J, IENS, ITHDR(IH_PKEY)
CALL U_ERR_FATAL( ’IENS != ITHDR(IH_PKEY)’ )
ENDIF

WRITE (*,*) ’IENS= ’, IENS, ’ ITHDR= ’,


& ITHDR(IH_PKEY)

100 CONTINUE

110 CONTINUE

RETURN
END

Other Docs Search Page Known Problems


Makefile_prestack506 Developer’s Programming Guide

Makefile_prestack

##############################################################################
# RCS ProMAX 7.0 @(#) Makefile_example_for_exe 70.2 06/26/97
##############################################################################

# Standard definitions

include advance.make

# Insert some source code.


# The define_* functions assume that there is
# a variable $(srcs) containing the name of the sources. Don’t change
# the variable name.
srcs = prestack.f prestack_main.c
$(newsrcs)

# Where object files will go and where source code is.


# This sets up a couple of variable names representing where our object
# files will go and where our source code is. At first glance this looks
# like it should be objdir := $(objexedir) and srcdir := $(srcexedir) but
# it’s no mistype. The routines create the path via $($(objdir)) and
# $($(srcdir)) so we may also access the master and advance tree’s via
# something like: $(m$(srcdir)) $(m$(objdir)) and $(a$(srcdir)) $(a$(objdir)),
# respectively.
objdir := objexedir
srcdir := srcexedir

# This is the name of our parent directory.


# It’s appended to our source
# and object directories. It doesn’t have to correspond to the name of
# the destination executable (As in the old make system).
parentdir := stand_alone

# Defining the include file holding amakedepend dependencies.

# 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

# Figure out user and actual srcs and objs.


# Set $(uobjs) to what the function $(define_uobjs) returns. define_uobjs
# figures out what source code the user has in his directory, then translates
# it into an absolute pathed object file (taking into account what objdir
# is set to). This allows us to have only the source code we are working on
# in our current directory.
uobjs := $(define_uobjs)

# Set $(usrcs) to what the function $(define_usrcs) returns. define_usrcs


# figures out what source code the user has and returns a relatively pathed
# list of them.
usrcs := $(define_usrcs)

# Set $(aobjs) to what the function $(define_aobjs) returns. define_aobjs


# figures out what source the user has creates a list of absolutely pathed
# filenames pointing to the user’s $(objdir). If a source file isn’t in the
# user’s directory but is in the master or advance directories, an absolute

Other Docs Search Page Known Problems


Makefile_prestack507 Developer’s Programming Guide

# 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)

# Set exe to the destination executable name.


exe := $(exedir)/prestack.exe

# Libraries needed for linking.


# Set libs to contain all the libraries our executable depends on. Here
# I use AGCLIBS so that I can set AGCLIBS in 1 place. Thus if we add another
# library to the system, I can change AGCLIBS in 1 place instead of libs in
# each individual Makefile. It can be argued that this isn’t the way to do
# it because we undoubtably do not need every library in AGCLIBS in our
# dependency chain (Those arguing don’t have to change the 100 or so
# Makefiles and I do so right or wrong, this is the method I’ve taken).
# "libs" used for advance libraries:
libs := $(AGCLITELIBS)

# 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...

# The top level rule.


# UPDATE_LIBRARIES is a canned command sequence which
# operates on the contents of $(libs). If it finds a lib called libfoo.a,
# it attempts to call a canned command sequence called UPDATE_foo which
# updates the library. If UPDATE_foo doesn’t exist, nothing happens.
#
# After everything is updated, we recurse the make because our time/date
# stamps might have changed and something might need to be relinked.
all :
$(UPDATE_LIBRARIES)
$(MAKE) $(exe)

# A general rule for creating a depend include file.


# It requires depend_include to be set.
depend: $(usrcs)
$(AMAKEDEPEND)

# Backup and link the executable.


# A description of how to backup and link our executable. We first make
# a copy of our executable, then link it. If the link succeeds, we remove
# the copy. Otherwise the copy is moved back into place. This way we can
# be sure to have an existing version of our executable.

$(exe) : $(aobjs) $(libs)


$(MAKETARGETDIR)
$(C_LINK) $(lgclibs) $(other_libs) \
$(XMLIBS) $(CLIBS) $(SYSLIBS) || $(BACKUP_ON_ERROR)

# Other rules.
# Put other rules here, like for copying things or other special things, like:

Other Docs Search Page Known Problems


Makefile_prestack508 Developer’s Programming Guide

$(bitmapdir)/%: %
$(COPYFILE)

$(manpage): pixmap.man
$(COPYFILE)

# Implicit rule to compile C++ source code.


$(objexedir)/$(parentdir)/%.o : %.C
$(CXX_COMPILE)

# Implicit rule to compile K&R c source code.


#$(objexedir)/$(parentdir)/%.o : %.c
# $(KRC_COMPILE)

# Implicit rule to compile ansi c source code.


$(objexedir)/$(parentdir)/%.o : %.c
$(ANSIC_COMPILE)

# Implicit rule to compile FORTRAN source code.


$(objexedir)/$(parentdir)/%.o : %.f
$(F_COMPILE)

# Generic rules to clean up.


cleanexe:
@echo "Removing: $(exe)"; \
/bin/rm -f $(exe) 2> /dev/null

cleanobjs:
@echo "Removing: $(objexedir)/$(parentdir)"; \
/bin/rm -rf $(objexedir)/$(parentdir) 2> /dev/null

clean: cleanexe cleanobjs

# Include the dependency include file if it exists.


ifneq ($(wildcard $(depend_include)),)
include $(depend_include)
endif

# be quiet
.SILENT:
.PHONY: all depend cleanexe cleanobjs clean

Other Docs Search Page Known Problems


poststack.f509 Developer’s Programming Guide

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)

SUBROUTINE POSTSTACK( NARGS, CINPUT )

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

IF ( NARGS .LT. 2 ) THEN


C ......... Nothing was entered on the command line
CALL U_ERR_FATAL( ’Packet file must be specified’ )
ENDIF

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

Other Docs Search Page Known Problems


poststack.f510 Developer’s Programming Guide

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 ..... Open the dataset, status=readonly


IREAD_ONLY = 1
CALL DISKIO_OPEN( CLABEL, IREAD_ONLY, ID_DATASET, IERR )
IF ( IERR .NE. 0 ) THEN
CALL U_ERR_FATAL(
& ’Unable to open the trace dataset ’ // CLABEL )
ENDIF

C ..... Get misc. info on the dataset.


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 )

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 ..... Get the index of CDP


CALL HDR_NAMINFO( ’CDP ’, CDESC, LENGTH, IFORMAT,
& IH_CDP, IERR )
IF ( IERR .NE. 0 ) CALL U_ERR_FATAL(
& ’CDP not found in header’ )

C ..... Allocate buffers for a trace and a trace header


CALL MEMORY_RESBUFF( NUMSMP, IX_TRACE, IERR )
CALL MEMORY_RESBUFF( NTH, IX_THDR, IERR )

C ..... Call the routine that does the actual work.


CALL STAND_ALONE_WORK( RSPACEz(IX_TRACE), ISPACEz(IX_THDR),
& IH_CDP, ID_DATASET, ITRTOTAL )

C ..... Free buffers


CALL MEMORY_FREEBUFF( NUMSMP, IX_TRACE, IERR )
CALL MEMORY_FREEBUFF( NTH, IX_THDR, IERR )

C ..... Close the packet file


CALL PKT_FILCLOSE( ID_PACKET, IERR )

C ..... Close the dataset


CALL DISKIO_CLOSE( ID_DATASET )

C ..... Report normal completion


CALL U_COMP_NORMAL

END

SUBROUTINE STAND_ALONE_WORK( TRACE, ITHDR, IH_CDP, ID_DATASET,

Other Docs Search Page Known Problems


poststack.f511 Developer’s Programming Guide

& 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 )

IF ( IERR .NE. 0 ) THEN


WRITE (*,*) ’*** ERROR *** ’, J, IERR
ELSE
WRITE (*,*) ’CDP= ’, ITHDR(IH_CDP)
ENDIF

100 CONTINUE

RETURN
END

Other Docs Search Page Known Problems


Makefile_poststack512 Developer’s Programming Guide

Makefile_poststack

##############################################################################
# RCS ProMAX 7.0 @(#) Makefile_example_for_exe 70.2 06/26/97
##############################################################################

# Standard definitions

include advance.make

# Insert some source code.


# The define_* functions assume that there is
# a variable $(srcs) containing the name of the sources. Don’t change
# the variable name.
srcs = poststack.f poststack_main.c
$(newsrcs)

# Where object files will go and where source code is.


# This sets up a couple of variable names representing where our object
# files will go and where our source code is. At first glance this looks
# like it should be objdir := $(objexedir) and srcdir := $(srcexedir) but
# it’s no mistype. The routines create the path via $($(objdir)) and
# $($(srcdir)) so we may also access the master and advance tree’s via
# something like: $(m$(srcdir)) $(m$(objdir)) and $(a$(srcdir)) $(a$(objdir)),
# respectively.
objdir := objexedir
srcdir := srcexedir

# This is the name of our parent directory.


# It’s appended to our source
# and object directories. It doesn’t have to correspond to the name of
# the destination executable (As in the old make system).
parentdir := stand_alone

# Defining the include file holding amakedepend dependencies.

# 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

# Figure out user and actual srcs and objs.


# Set $(uobjs) to what the function $(define_uobjs) returns. define_uobjs
# figures out what source code the user has in his directory, then translates
# it into an absolute pathed object file (taking into account what objdir
# is set to). This allows us to have only the source code we are working on
# in our current directory.
uobjs := $(define_uobjs)

# Set $(usrcs) to what the function $(define_usrcs) returns. define_usrcs


# figures out what source code the user has and returns a relatively pathed
# list of them.
usrcs := $(define_usrcs)

# Set $(aobjs) to what the function $(define_aobjs) returns. define_aobjs


# figures out what source the user has creates a list of absolutely pathed
# filenames pointing to the user’s $(objdir). If a source file isn’t in the
# user’s directory but is in the master or advance directories, an absolute

Other Docs Search Page Known Problems


Makefile_poststack513 Developer’s Programming Guide

# 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)

# Set exe to the destination executable name.


exe := $(exedir)/poststack.exe

# Libraries needed for linking.


# Set libs to contain all the libraries our executable depends on. Here
# I use AGCLIBS so that I can set AGCLIBS in 1 place. Thus if we add another
# library to the system, I can change AGCLIBS in 1 place instead of libs in
# each individual Makefile. It can be argued that this isn’t the way to do
# it because we undoubtably do not need every library in AGCLIBS in our
# dependency chain (Those arguing don’t have to change the 100 or so
# Makefiles and I do so right or wrong, this is the method I’ve taken).
# "libs" used for advance libraries:
libs := $(AGCLITELIBS)

# 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...

# The top level rule.


# UPDATE_LIBRARIES is a canned command sequence which
# operates on the contents of $(libs). If it finds a lib called libfoo.a,
# it attempts to call a canned command sequence called UPDATE_foo which
# updates the library. If UPDATE_foo doesn’t exist, nothing happens.
#
# After everything is updated, we recurse the make because our time/date
# stamps might have changed and something might need to be relinked.
all :
$(UPDATE_LIBRARIES)
$(MAKE) $(exe)

# A general rule for creating a depend include file.


# It requires depend_include to be set.
depend: $(usrcs)
$(AMAKEDEPEND)

# Backup and link the executable.


# A description of how to backup and link our executable. We first make
# a copy of our executable, then link it. If the link succeeds, we remove
# the copy. Otherwise the copy is moved back into place. This way we can
# be sure to have an existing version of our executable.

$(exe) : $(aobjs) $(libs)


$(MAKETARGETDIR)
$(C_LINK) $(lgclibs) $(other_libs) \
$(XMLIBS) $(CLIBS) $(SYSLIBS) || $(BACKUP_ON_ERROR)

# Other rules.
# Put other rules here, like for copying things or other special things, like:

Other Docs Search Page Known Problems


Makefile_poststack514 Developer’s Programming Guide

$(bitmapdir)/%: %
$(COPYFILE)

$(manpage): pixmap.man
$(COPYFILE)

# Implicit rule to compile ansi c source code.


$(objexedir)/$(parentdir)/%.o : %.c
$(ANSIC_COMPILE)

# Implicit rule to compile FORTRAN source code.


$(objexedir)/$(parentdir)/%.o : %.f
$(F_COMPILE)

# Generic rules to clean up.


cleanexe:
@echo "Removing: $(exe)"; \
/bin/rm -f $(exe) 2> /dev/null

cleanobjs:
@echo "Removing: $(objexedir)/$(parentdir)"; \
/bin/rm -rf $(objexedir)/$(parentdir) 2> /dev/null

clean: cleanexe cleanobjs

# Include the dependency include file if it exists.


ifneq ($(wildcard $(depend_include)),)
include $(depend_include)
endif

# be quiet
.SILENT:
.PHONY: all depend cleanexe cleanobjs clean

Other Docs Search Page Known Problems


poststack.c515 Developer’s Programming Guide

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 main( int argc, char **argv )

/* declare local variables */

void *tblPntr;

char cpacket_file[129], carea[17], cline[17];


char *dsetLabel;
int read_only;
int id_dataset, errCode, ih_cdp;
int i_128 = 128;

/* variables realated to the dataset */


int ndfiles, iswapends;
int trtotal, numsmp, nth, maxdtr;
int maxatr, ipsort, ipkey, iskey, idtyp, idomain;
int ntraces, igeom_match, itrno_valid, npriorf;
float samprat, softrlp, georlsp;

/* pointers to memory to hold a data trace and its header */


float *trace;
int *ihdr;

/* function used in the main program */


void stand_alone_work( float *trace, int *ithdr, int ih_cdp,
int id_dataset, int itrtotal );

/* set the global pointers */


GlobalRuntime *gr = globalRuntime;
GlobalGeom *gg = globalGeom;
GlobalMisc *gm = globalMisc;

/* Put argv[1] into a string called cpacket_file, this is a FORTRAN call */


u_carr2str_( argv[1], cpacket_file, &i_128, strlen(argv[1]) );

/* null terminate the string at the end */


cpacket_file[128] = '\0';

/* Open the parameter packet file and initialize the database */


/* This gives access to opf files, not actually used in this program. */
/* Note that the character string must be padded to 16 characters. */

Other Docs Search Page Known Problems


poststack.c516 Developer’s Programming Guide

/* 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 );

/* Open the dataset, status=readonly, note we are calling a FORTRAN routine */


read_only = 1;
diskio_open_( dsetLabel, &read_only, &id_dataset, &errCode );

if( errCode != 0 ){
uErrFatal("Unable to open the trace dataset %s", id_dataset );
}

/* Get misc. info about the dataset */


diskio_info_( &id_dataset, &ndfiles, &iswapends,
&trtotal, &samprat, &numsmp, &nth, &maxdtr,
&maxatr, &ipsort, &ipkey, &iskey, &idtyp, &idomain,
&ntraces, &igeom_match, &itrno_valid, &npriorf, &softrlp,
&georlsp );

/* Set up the trace headers (this will cause a bunch of calls to */


/* HDR_ADD, creating all of the header entries that were found in */
/* the dataset). Complete header description info (list of names, */
/* format, length, etc) is now available using the same in-line */
/* executive header subroutines. */
diskio_thdr_setup_( &id_dataset, &errCode );
if( errCode != 0 ){
uErrFatal("Error setting up trace headers for dataset.");
}

/* Get the index of CDP */


if( hdrExists("CDP") ){
ih_cdp = hdrIndex("CDP");
}
else{
uErrFatal("Primary key header CDP does not exist in the data .");
}

/* Allocate buffers for a trace and a trace header */


trace = (float*)malloc( numsmp * sizeof(float));
ihdr = (int*)malloc( nth * sizeof(float));

if( trace == NULL || ihdr == NULL ){


uErrFatal("Error allocating memory for trace and header.");
}

/* Call the routine that does the actual work */


stand_alone_work( trace, ihdr, ih_cdp, id_dataset, trtotal );

/* Close the dataset */


diskio_close_( &id_dataset );

/* notify the system of a normal completion */


u_comp_normal_();

Other Docs Search Page Known Problems


poststack.c517 Developer’s Programming Guide

void stand_alone_work( float *trace, int *ithdr, int ih_cdp,


int id_dataset, int itrtotal )
{

/* 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] );
}
}

Other Docs Search Page Known Problems


vel_io.f518 Developer’s Programming Guide

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 ..... Normally you would not want these to be hard-dimensioned arrays


INTEGER ICDP(100), NPAIRS(100), IMOD_TIMES(25)
REAL TIME(100,100), VEL(100,100), VELARR(5000)
CHARACTER COWNERS(32,25), CTBLNAMES(144,25)

C ..... See what the user wants to do


WRITE (*,*)
WRITE (*,*) 'Read (1) or write (2) velocities'
READ (*,'(A1)') CREPLY
IF ( CREPLY .EQ. '1' ) THEN
WRITE_TABLE = .FALSE.
ELSE
WRITE_TABLE = .TRUE.
ENDIF

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 )

C ..... If return status is not 0, act accordingly


IF ( IRETURN .EQ. 1 ) THEN
WRITE (*,*) 'No areas exist'
STOP
ELSEIF ( IRETURN .EQ. 2 ) THEN
C ......... User wants to quit
STOP
ENDIF

C ..... Initialize the area and line


CALL DB_INIT_LINE( CAREA, CLINE, IERR )

IF ( .NOT. WRITE_TABLE ) THEN


C ......... User wants to read a table.

C ......... Get a list of the tables. Normal applications don't have to


C ......... go fishing for this type of info, it is selected from the
C ......... menus (these routines don't appear in your manual).

C ......... First count the number of tables in the database

Other Docs Search Page Known Problems


vel_io.f519 Developer’s Programming Guide

CALL U_STR2CARR( 'VEL', CTBLTYPE, 3 )


CALL DB_TBL_COUNT( CAREA, CLINE, CTBLTYPE, NTABLES,
& LX_NAM, LX_DSC, IERR )
IF ( IERR .NE. 0 ) CALL U_ERR_FATAL(
& 'Error counting tables' )

C ......... Get the list of tables


CALL DB_TBL_LIST( CAREA, CLINE, CTBLTYPE, CTBLNAMES,
& NTABLES, LX_NAM, LX_DSC, IMOD_TIMES, COWNERS, IERR )

C ......... Allow the user to select one


WRITE (*,*)
DO 90 J=1,NTABLES
CALL U_CARR2STR( CTBLNAMES(1,J), CLABEL, 8 )
CALL U_CARR2STR( CTBLNAMES(LX_NAM+1,J), CDESC, 128 )
WRITE (*,'(I2,1X,A8,1X,A60)') J, CLABEL, CDESC(1:60)
90 CONTINUE
WRITE (*,*)
WRITE (*,*) 'Please select one'
READ (*,'(I2)') ISELECT
CALL U_CARR2STR( CTBLNAMES(1,ISELECT), CLABEL, 8 )

ENDIF

IF ( WRITE_TABLE ) THEN

C ......... This is a totally new table


MODE = 1

C ......... Set the descriptions


CX_DESC = 'CDP '
CY_DESC = 'TIME '
CZ_DESC = 'VELOCITY'
CTABLE_DESC = 'Test input to velocity table'

C ......... Make a new table in memory


CALL TBL_INIT( MODE, CX_DESC, CY_DESC, CZ_DESC,
& CTABLE_DESC, IHANDLE )

C ......... Hard-code some input velocities

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

Other Docs Search Page Known Problems


vel_io.f520 Developer’s Programming Guide

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

C ............. X is the CDP in this case


X = DBLE( ICDP(J) )

C ............. Add the data to the table


CALL TBL2_ADD( IHANDLE, X, TIME(1,J), NPAIRS(J),
& VEL(1,J), 1 )

100 CONTINUE

C ......... Close the table in memory (compress the buffers, etc.)


CALL TBL_END( IHANDLE )

C ......... Put the table into the database


CLABEL = 'VELTEST '
CALL DB_TBL_PUT( 'VEL', CLABEL, IHANDLE, IERR )
IF ( IERR .NE. 0 ) THEN
WRITE (*,*) 'IERR= ', IERR
CALL U_ERR_FATAL(
& 'Error putting velocity table into database' )
ENDIF

ELSEIF ( .NOT. WRITE_TABLE ) THEN

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 ......... Loop over the functions


DO 120 J=1,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),

Other Docs Search Page Known Problems


vel_io.f521 Developer’s Programming Guide

& NPAIRS(J), VEL(1,J), IERR )

IF ( IERR .NE. 0 .OR. NPAIRS(J) .LT. 1 )


& CALL U_ERR_FATAL(
& 'Error getting info from velocity table' )

C ............. Show the user what was in the table


WRITE (*,*)
WRITE (*,*) 'CDP= ', X
DO 110 I=1,NPAIRS(J)
WRITE (*,*) J, TIME(I,J), VEL(I,J)
110 CONTINUE

120 CONTINUE

C ......... Here is an example of interpolating a velocity function


WRITE (*,*)
WRITE (*,*)
& 'Do you want to interpolate a velocity function (y/n)?'
READ (*,'(A1)') CREPLY

IF ( CREPLY .EQ. 'Y' .OR. CREPLY .EQ. 'y' ) THEN

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 )

C ............. Increment by 10 or we will be here all day


DO 130 I=1,NUMSMP,10
WRITE (*,*) I, VELARR(I)
130 CONTINUE

ENDIF

C ......... Here is an example of interpolating at a particular time


WRITE (*,*)
WRITE (*,*)
& 'Do you want to interpolate at a particular time (y/n)?'
READ (*,'(A1)') CREPLY

IF ( CREPLY .EQ. 'Y' .OR. CREPLY .EQ. 'y' ) THEN

WRITE (*,*)
WRITE (*,*) 'Enter the CDP'
READ (*,'(F10.0)') RCDP
WRITE (*,*) 'Enter the time (ms)'
READ (*,'(F10.0)') TIMEIN

CALL INT2_GET( IHANDLE, 0, 0, RCDP, TIMEIN, VELARR(1),


& IDUMB )

WRITE (*,*) VELARR(1)

Other Docs Search Page Known Problems


vel_io.f522 Developer’s Programming Guide

ENDIF

ENDIF

END

Other Docs Search Page Known Problems


vel_io.f523 Developer’s Programming Guide

Other Docs Search Page Known Problems


vel_io.f524 Developer’s Programming Guide

Other Docs Search Page Known Problems


525 Developer’s Programming Guide

Appendix: IPC Tool Examples

This appendix describes IPC (interprocess communication)


tools.

Topics covered in this appendix:


➲ IPC Menu Code
➲ IPC C Code
➲ IPC FORTRAN Code
➲ amp_ratio Menu Code
➲ ampRatio C Code
➲ amp_ratio FORTRAN Code

Other Docs Search Page Known Problems


IPC Menu Code526 Developer’s Programming Guide

IPC Menu Code

; This is a comment

; Sample menu for executing a IPC tool

'(
name: stand_alone
label: "Test IPC tool"
value_tab: 55

;These are normal menu parameters.....

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
)

Other Docs Search Page Known Problems


IPC C Code527 Developer’s Programming Guide

IPC C Code

#include <stdio.h>
#include <math.h>
#include "cglobal.h"
#include "cpromax.h"
#include "cSocketTool.h"

main(int ac,char **av)


{
int i,nt,nth,nx,iMyHeader ;
float dt;
int *ihead;
float *rhead, *trace;
int ivalue;
float value, value2;
char *mfile;

/* 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();

/* Start initialization portion of program */

stSetToolName("Simple test program for ProMAX IPC tool");


/* This name is stored and printed out before messages printed
with stErrMessage(). This helps the user determine where
mesages in the printout are coming from. */

/* Access packet file, using standalone parameter subroutines */


exParGetFloat("max_frequency", &value);

/* read global variables see cglobal.h */


dt=globalRuntime->samprat; /* Sample rate */
nt= globalRuntime->numsmp; /* Number of samples per trace */
nx= globalRuntime->maxdtr; /* Number of traces per ensemble */
nth= globalRuntime->nth; /* Length of trace header in
words */

/* allocate necessary space in program */


trace= (float *) malloc( nt*sizeof(float));
ihead= (int *)(rhead= (float *) malloc( nth*sizeof(float)) );

/* 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);

Other Docs Search Page Known Problems


IPC C Code528 Developer’s Programming Guide

} else { /* Header exists. Get the index. */


/* What is the location of the header */
iMyHeader=stHdrIndex("MY_header");
}
/* In future releases you will also be able to use the more standard
routines: hdrExists(), hdrAdd(), hdrIndex(), etc. */

/* Print the location of headers in the trace header array */


stErrMessage("Header locations: IEOJ=%d IEND_ENS=%d,
MY_header: %d",
STDHDR(ieoj),STDHDR(iend_ens), iMyHeader);
/* STDHDR(ieoj) lets you access commonly used headers through a
global structure. */

/* Change global parameters if we wish


globalRuntime->samprat*= 1.1 ;
globalRuntime->numsmp/= 2;
*/

/**
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();

/* Read in a trace. Traces are transferred from


the proper location in the ProMAX flow. Ensembles of traces are
read in with stGetEnsemble(). */
while (stGetTrace(trace,ihead) ) {

/* access header information */


stErrMessage("CDP: %d, offset: %g", ihead[STDHDR(icdp)],
rhead[STDHDR(ioffset)] );

do_work_on_trace(trace,ihead);

/* Write out a trace back to the ProMAX flow.


Traces are transferred back to the proper location in the ProMAX flow.
Ensembles of traces are written with stPutEnsemble().
Note that stGetTrace() can be called in any order with stPutTrace().
*/
stPutTrace(trace,ihead);

} ; /* end while( stGetTrace() loop ) */

/* Perform cleanup operations here */

stCloseSocketLink();
}

do_work_on_trace()
{
}

Other Docs Search Page Known Problems


IPC FORTRAN Code529 Developer’s Programming Guide

IPC FORTRAN Code

C /* this is the C "wrapper" that passes command


C line args to FORTRAN */
C
C void main( argc, argv )
C int argc;
C char **argv;
C {
C socket_tool_( &argc, argv[1] );
C }

SUBROUTINE SOCKET_TOOL( NARGS, CINPUT )

IMPLICIT NONE

INTEGER NARGS
CHARACTER CINPUT*128, CPACKET_FILE*128, CAREA*16, CLINE*16
INTEGER ID_PACKET

C ..... Include ProMAX global declarations


#include "global.inc"
#include "header.inc"

C ..... Include the file that allows use of the "space array" and memory
C ..... management routines.
#include "mem.inc"

C ... #include "socket_tool.inc"

C ..... Include file with error definitions


#include "hdr_err.inc"
#include "db_err.inc"
INTEGER IERR, LENGTH, IFORMAT, NCHARS, EOF_REACHED,
& NT, NTH, NX, MY_HEADER
CHARACTER CDESC_HDR*32, CDESC_DB*80, CGATENAME*8, CPRIM_KEY*8,
& CSCND_KEY*8, CTABLE_DESC*128, CZ_DESC*8, CMFILE*80

PTRDIFF_T IX_HEADER, IX_TRACE


INTEGER IVALUE, IH_MY_HEADER, IDUM
REAL VALUE, VALUE2

INTEGER ITHDR(1000), LOC_TRC, ISAVE, IMIN_SAMP, IMAX_SAMP


REAL TRACE(10000), RTHDR(1000), DT,
& PKEYVAL, SKEYVAL, TGATE(2)
EQUIVALENCE (ITHDR,RTHDR)

C .... These first few lines are typical of a stand alone program

IF ( NARGS .LT. 2 ) THEN


C ......... Nothing was entered on the command line
CALL U_ERR_FATAL( 'Packet file must be specified' )
ENDIF

C ..... Load the character ARRAY into a character STRING.


C Be sure that you understand the difference.

Other Docs Search Page Known Problems


IPC FORTRAN Code530 Developer’s Programming Guide

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, '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 ..... Establish connection with server module in the processing flow


C ..... All the global parameters are transferred in from the Executive.
C ..... They are accessible through the GLOBAL_RUNTIME common
C ..... block members
CALL ST_CONNECT_TO_SERVER(ID_PACKET)

C ..... Give IPC tool a name


CALL ST_SET_TOOL_NAME('FORTRAN IPC tool example')
C ..... This name is stored and printed out before messages printed
C ..... with stErrMessage(). This helps the user determine where
C ..... mesages in the printout are coming from.

C ..... Use standard Executive parameter input routines


CALL EX_GETPARM( 'max_freq', 1, VALUE )

C ..... Access global parameters as you would normally


DT = SAMPRATz
NT= NUMSMPz
NX= MAXDTRz
NTH= NTHz

C .... Create headers using functions similar to that in the Executive


C .... Note the name change with the "ST_" prefix
CDESC_HDR = 'Description of what MY_header is'
CALL ST_HDR_ADD( 'MY_header', CDESC_HDR, 1, INT4pz,
& IH_MY_HEADER, IERR )
IF ( IERR .NE. 0 ) THEN
IF ( IERR .EQ. IERR_HDR_EXSTpz ) THEN
C ................. Error routines start with ST_
CALL ST_ERR_WARN(
& 'RATIOMAX already exists in header' )
CALL ST_HDR_NAMINFO( 'MY_header ', CDESC_HDR, LENGTH, IFORMAT,
& IH_MY_HEADER, IERR )
ELSE
CALL ST_ERR_FATAL( 'Error adding header entry' )
ENDIF
ENDIF

CALL ST_HDR_NAMINFO( 'CDP ', CDESC_HDR, LENGTH, IFORMAT,

Other Docs Search Page Known Problems


IPC FORTRAN Code531 Developer’s Programming Guide

& IDUM, IERR )


IF ( IERR .NE. 0 ) THEN
CALL ST_ERR_FATAL( 'Header CDP does not exist.')
ENDIF

C .... In future releases you will also be able to use the


C more standard routines HDR_ADD etc

WRITE(*,*) 'EOJ header pos: ', IEOJz,


& 'END_ENS header pos: ',IEND_ENSz,
& 'MY_HEADER pos:', IH_MY_HEADER

C ..... Reserve a buffers for the trace and headers


C ..... note how the memory is passed to the subroutine
C ..... DO_WORK_ON_TRACE().
C .... We could just as well have used the static memory
C buffer "TRACE()"
CALL MEMORY_RESBUFF( NT, IX_TRACE, IERR )
CALL MEMORY_RESBUFF( NTH, IX_Header, IERR )

C ..... Possibly change the global parameters


SAMPRATz= SAMPRATz*1.1
NUMSMPz= NUMSMPz/2

C .... End initialization phase. this subroutine send back the


C possibly altered global parameters back to the Executive
CALL ST_END_INIT()

C .... loop over traces

C ..... prime the loop


CALL ST_GET_TRACE(RSPACEz(IX_TRACE), RSPACEz(IX_HEADER),
& RSPACEz(IX_HEADER), EOF_REACHED)
DO WHILE ( EOF_REACHED .EQ. 0 )

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) )

C .... send the trace back to the Executive


CALL ST_PUT_TRACE(RSPACEz(IX_TRACE), RSPACEz(IX_HEADER))

C ..... Get the next trace


CALL ST_GET_TRACE(RSPACEz(IX_TRACE), RSPACEz(IX_HEADER),
& RSPACEz(IX_HEADER), EOF_REACHED)

C .... end while loop over traces


ENDDO

C ..... This is where the normal clean up phase goes

C ...... Close stand alone program in the normal fasion


C ..... This routine also closes the packet file and calls U_COMP_NORMAL
CALL ST_CLOSE_SOCKET_LINK()

END

Other Docs Search Page Known Problems


IPC FORTRAN Code532 Developer’s Programming Guide

SUBROUTINE DO_WORK_ON_TRACE( TRACE, IHEADER , RHEADER)

IMPLICIT NONE

#include "header.inc"

INTEGER TRACE(1), IHEADER(1)


REAL RHEADER(1)

C .... Write certain header locations


WRITE(*, * ) 'CDP: ', IHEADER(ICDPz),
& 'Offset: ', RHEADER(IOFFSETz)

END

Other Docs Search Page Known Problems


amp_ratio Menu Code533 Developer’s Programming Guide

amp_ratio Menu Code

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"

Other Docs Search Page Known Problems


amp_ratio Menu Code534 Developer’s Programming Guide

("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))
)

Other Docs Search Page Known Problems


ampRatio C Code535 Developer’s Programming Guide

ampRatio C Code

/* include ProMAX prototypes and globals */

#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)
{

int ngate, use_gate, ih_ratio_max, ih_ratio_time, load_hdr, load_opf;


int ih_pkey, ih_skey, iformat_pkey, iformat_skey;
float *scratch;
void *gate_tbl;
void *opf_trc, *opfPtr1, *opfPtr2;

float gatelen;
char *cgatename;

float *trace;
int *ithdr;
float *rthdr;

initStandAlone (ac, av, "SOCKET_TOOL");

stConnectToServer ();

stSetToolName ("Amplitude Ratio");

/* get the gate length */


gatelen = -1.0;
uParGetFloat ("GATELEN", &gatelen);

/* convert the gate length from time to samples */


ngate = (int) (gatelen / globalRuntime->samprat + 0.5);

/* check for reasonable input */


if (ngate < 1 || ngate * 2 + 1 > globalRuntime->numsmp)
stErrFatal ("Gate length is illegal");

/* 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)

Other Docs Search Page Known Problems


ampRatio C Code536 Developer’s Programming Guide

stErrFatal ("Cannot open time gate %s !!", cgatename);

if (tblCountZ(gate_tbl) != 2)
stErrFatal ("invalid gate (Gate must have an upper and lower gate!)");

/* We will need the index of the primary and secondary key */


ih_pkey = stHdrIndex (tblDescX(gate_tbl) );
if (ih_pkey < 0)
stErrFatal ("The primary key of the time gate (%s) is not in the
header!", tblDescX(gate_tbl) );
ih_skey = stHdrIndex (tblDescY(gate_tbl) );
if (ih_skey < 0)
stErrFatal ("The secondary key of the time gate is (%s) is not in the
header!", tblDescY(gate_tbl) );

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");
}
}
}

Other Docs Search Page Known Problems


ampRatio C Code537 Developer’s Programming Guide

/* 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");

/* Lock the TRC order since we will be writing to it */


if (!opfExists ("TRC"))
stErrFatal ("TRC database does not exist.");
opf_trc = opfLock ("TRC");
if (opf_trc==NULL )
stErrFatal ("Could not lock TRC database order.");

/* Create the new entries in the database */


if (!opfParmExists (opf_trc, "F_B_PICK", "RATIOMAX")) {
ierr = opfParmCreate (opf_trc, "F_B_PICK",
"RATIOMAX", "Maximum value of amp ratio", 1, PARFLOAT);
if (ierr != 0)
stErrFatal ("Error creating database entry");
}

if (!opfParmExists (opf_trc, "F_B_PICK", "RATIOTIM")) {


ierr = opfParmCreate (opf_trc, "F_B_PICK", "RATIOTIM",
"Time of amp ratio maximum", 1, PARFLOAT);
if (ierr != 0)
stErrFatal ("Error creating database entry");
}

/* Initialize the token for buffered database I/O */


opfPtr1 = opfInitBufPut (opf_trc, "F_B_PICK", "RATIOMAX");
opfPtr2 = opfInitBufPut (opf_trc, "F_B_PICK", "RATIOTIM");
}

/* Reserve memory for one trace and header */


/* memAlloc functions abort if memory is unavailable */
trace = memAlloc1Float(globalRuntime->numsmp);
ithdr = memAlloc1Int(globalRuntime->nth);
rthdr = (float *) ithdr;

/* Reserve a scratch buffer that we will need in exec phase */


scratch = memAlloc1Float(globalRuntime->numsmp);

stEndInitialization ();

/* Loop while traces still exist */


while (stGetTrace (trace, ithdr)) {
int loc_trc, imin_samp, imax_samp;
float ratio_max, ratio_time, skeyval, tgate[2];
double pkeyval;

if (use_gate) {

Other Docs Search Page Known Problems


ampRatio C Code538 Developer’s Programming Guide

/* Interpolate the gate times from the table */


if (iformat_pkey == HDRINT)
pkeyval = (double)ithdr[ih_pkey];
else
pkeyval = (double)rthdr[ih_pkey];
if (iformat_skey == HDRINT)
skeyval = (float)ithdr[ih_skey];
else
skeyval = rthdr[ih_skey];
if (tbl2InterpXY (gate_tbl, pkeyval, skeyval, tgate)) {
stErrFatal ("Error interpolating time gate");
}
}
else {
/* use entire trace */
tgate[0] = 0.0;
tgate[1] = (globalRuntime->numsmp - 1) * globalRuntime->samprat;
}

/* Convert the time gate values to samples */


imin_samp = tgate[0] / globalRuntime->samprat + 0.5;
imax_samp = tgate[1] / globalRuntime->samprat + 0.5;
imin_samp = MAX (imin_samp, 0);
imin_samp = MIN (imin_samp, globalRuntime->numsmp - 1);
imax_samp = MAX (imax_samp, 0);
imax_samp = MIN (imax_samp, globalRuntime->numsmp - 1);
if (imin_samp > imax_samp) {
int isave;
/* assume that they were meant to be reversed */
isave = imin_samp;
imin_samp = imax_samp;
imax_samp = isave;
}

/* 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);
}
}

stPutTrace (trace, ithdr);


}
/* End loop over traces. */
if (load_opf) {

Other Docs Search Page Known Problems


ampRatio C Code539 Developer’s Programming Guide

/* 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 the first two gates */


sum_above = 0.0;
rabove = 0.0;

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;

for (i = 0; i < nsamps; i++) {

/* Compute the ratio */


if (sum_above > 0.0 && rabove > 0.0 && rbelow > 0.0) {
scratch[i] = (sum_below / rbelow) / (sum_above / rabove);

Other Docs Search Page Known Problems


ampRatio C Code540 Developer’s Programming Guide

}
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;
}

if (i + ngate + 1 < nsamps) {


sum_below = sum_below - fabs (trace[i + 1])
+ fabs (trace[i + ngate + 1]);
}
else if (i + 1 < nsamps) {
sum_below = sum_below - fabs (trace[i + 1]);
rbelow = rbelow - 1.0;
}
}

/* Put the final results in place. */


for (i = 0; i < nsamps; i++) {
trace[i] = scratch[i];
}

/* Find the maximum of the ratio function */


*ratio_max = trace[imin_samp];
ind_max = imin_samp;
for (i = imin_samp; i <= imax_samp; i++) {
if (trace[i] > *ratio_max) {
ind_max = i;
*ratio_max = trace[i];
}
}

/* Convert the index of the maximum to time */


*ratio_time = (float) (ind_max) * samprate;
}

Other Docs Search Page Known Problems


amp_ratio FORTRAN Code541 Developer’s Programming Guide

amp_ratio FORTRAN Code

C /* this is the C "wrapper" that passes command


C line args to FORTRAN */
C
C void main( argc, argv )
C int argc;
C char **argv;
C {
C socket_tool_( &argc, argv[1] );
C }

SUBROUTINE SOCKET_TOOL( NARGS, CINPUT )

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"

CHARACTER CDESC_HDR*32, CDESC_DB*80, CGATENAME*8, CPRIM_KEY*8,


& CSCND_KEY*8, CTABLE_DESC*128, CZ_DESC*8

REAL TRACE(10000), RTHDR(1000), RATIO_MAX, RATIO_TIME,


& PKEYVAL, SKEYVAL, TGATE(2), GATELEN, RDUMMY(6)
EQUIVALENCE (ITHDR,RTHDR)

INTEGER NGATE, IH_RATIO_MAX,


& IH_RATIO_TIME, LOAD_HDR, LOAD_DB, ID_MAX, ID_TIME,
& IH_TRACENO, IKEY_TRC, ITBL_HANDLE, IH_PKEY, IH_SKEY,
& IFORMAT_PKEY, IFORMAT_SKEY, IERR, LENGTH, IFORMAT,
& NCHARS, EOF_REACHED, IDUMMY(3), NTIMES,
& ITHDR(1000), LOC_TRC, ISAVE, IMIN_SAMP, IMAX_SAMP

PTRDIFF IX_SCRATCH

LOGICAL USE_GATE

IF ( NARGS .LT. 2 ) THEN


C ......... Nothing was entered on the command line
CALL ST_ERR_FATAL( 'Packet file must be specified' )
ENDIF

C ..... Load the character ARRAY into a character STRING.


C Be sure that you understand the difference.
CALL U_CARR2STR( CINPUT, CPACKET_FILE, 128 )

Other Docs Search Page Known Problems


amp_ratio FORTRAN Code542 Developer’s Programming Guide

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 ..... Open connect to Executive


CALL ST_CONNECT_TO_SERVER(ID_PACKET)

C ..... Give IPC tool a name


CALL ST_SET_TOOL_NAME('FORTRAN amplitude ratio')

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 ..... Convert the gate length to samples. Globals are available.


NGATE = NINT( GATELEN / SAMPRATz )

C ..... Check for reasonable input


IF ( NGATE .LT. 1 .OR. NGATE*2+1 .GT. NUMSMPz ) THEN
CALL ST_ERR_FATAL( 'Gate length is illegal' )
ENDIF

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 ......... Get the gate from the database


CALL DB_TBL_GET( 'GAT', CGATENAME, ITBL_HANDLE, IERR )
IF ( IERR .NE. 0 ) THEN
CALL REPORT_DB_ERR( IERR )
CALL ST_ERR_FATAL(
& 'Cannot open time gate ' //CGATENAME )
ENDIF

C ......... Get info on the gate table

Other Docs Search Page Known Problems


amp_ratio FORTRAN Code543 Developer’s Programming Guide

CALL TBL_INFO( .TRUE., ITBL_HANDLE, CPRIM_KEY, CSCND_KEY,


& CZ_DESC, CTABLE_DESC, IDUMMY(1), IDUMMY(2), IDUMMY(3),
& NTIMES, RDUMMY(1), RDUMMY(2), RDUMMY(3), RDUMMY(4),
& RDUMMY(5), RDUMMY(6) )

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' )

CALL ST_HDR_NAMINFO( CSCND_KEY, CDESC_DB, LENGTH,


& IFORMAT_SKEY,
& IH_SKEY, IERR )
IF ( IERR .NE. 0 ) CALL ST_ERR_FATAL(
& 'The secondary key of the time gate (' //CSCND_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 )

IF ( LOAD_HDR .EQ. 1 ) THEN


C ......... Add new trace header entries

CDESC_HDR = 'Maximum value of amp ratio'


CALL ST_HDR_ADD( 'RATIOMAX', CDESC_HDR, 1, IREAL4pz,
& IH_RATIO_MAX, IERR )
IF ( IERR .NE. 0 ) THEN
IF ( IERR .EQ. IERR_HDR_EXSTpz ) THEN
C ................. That's OK, but somewhat unexpected
CALL ST_ERR_WARN(
& 'RATIOMAX already exists in header' )
ELSE
C ................. This will virtually never happen, but just in case
CALL ST_ERR_FATAL( 'Error adding header entry' )
ENDIF
ENDIF

CDESC_HDR = 'Time of amp ratio maximum'


CALL ST_HDR_ADD( 'RATIOTIM', CDESC_HDR, 1, IREAL4pz,
& IH_RATIO_TIME, IERR )
IF ( IERR .NE. 0 ) THEN
IF ( IERR .EQ. IERR_HDR_EXSTpz ) THEN
C ................. That's OK, but somewhat unexpected
CALL ST_ERR_WARN(
& 'RATIOTIM already exists in header' )
ELSE
C ................. This will virtually never happen, but just in case
CALL ST_ERR_FATAL( 'Error adding header entry' )

Other Docs Search Page Known Problems


amp_ratio FORTRAN Code544 Developer’s Programming Guide

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 )

IF ( LOAD_DB .EQ. 1 ) THEN


C ......... Open the database to store the amp ratio information
C against trace
C ......... Note: ST_ instead of EX_ERR_FATAL
IF ( ITRNO_VALIDz .NE. 1 ) THEN
CALL ST_ERR_FATAL( 'Cannot load data into the TRC order'
& //' without valid trace numbers (geom assigned)' )
ENDIF

C ......... We will need the index of the trace number


CALL ST_HDR_NAMINFO( 'TRACENO ', CDESC_HDR, LENGTH, IFORMAT,
& IH_TRACENO, IERR )
IF ( IERR .NE. 0 ) CALL ST_ERR_FATAL(
& 'TRACENO not found in header' )

C ......... Lock the TRC order since we will be writing to it


C ......... Note: normal database calls
CALL DB_ORDLOCK( 'TRC', IKEY_TRC, IERR )
IF ( IERR .NE. 0 ) THEN
CALL REPORT_DB_ERR( IERR )
CALL ST_ERR_FATAL( 'Error locking TRC database' )
ENDIF

C ......... Create the new entries in the database


CDESC_DB = 'Maximum value of amp ratio'
CALL DB_PARMCRE( IKEY_TRC, ' ', 'F_B_PICK', 'RATIOMAX',
& CDESC_DB, 1, IREAL4pz, RNULLpz, IERR )
IF ( IERR .NE. 0 .AND. IERR .NE. IERR_DB_PEXSpz ) THEN
CALL REPORT_DB_ERR( IERR )
CALL ST_ERR_FATAL( 'Error creating database entry' )
ENDIF

CDESC_DB = 'Time of amp ratio maximum'


CALL DB_PARMCRE( IKEY_TRC, ' ', 'F_B_PICK', 'RATIOTIM',
& CDESC_DB, 1, IREAL4pz, RNULLpz, IERR )
IF ( IERR .NE. 0 .AND. IERR .NE. IERR_DB_PEXSpz ) THEN
CALL REPORT_DB_ERR( IERR )
CALL ST_ERR_FATAL( 'Error creating database entry' )
ENDIF

C ......... Initialize the token for buffered database I/O


ID_MAX = 0
ID_TIME = 0

ENDIF

C ..... Reserve a scratch buffer that we will need in exec phase


CALL MEMORY_RESBUFF( NUMSMPz, IX_SCRATCH, IERR )

C .... End initialization phase

Other Docs Search Page Known Problems


amp_ratio FORTRAN Code545 Developer’s Programming Guide

CALL ST_END_INIT()

C .... loop over traces


CALL ST_GET_TRACE(TRACE, ITHDR, RTHDR, EOF_REACHED)
DO WHILE ( EOF_REACHED .NE. 1 )

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 ..... Convert the time gate values to samples


IMIN_SAMP = NINT( TGATE(1) / SAMPRATz ) + 1
IMAX_SAMP = NINT( TGATE(2) / SAMPRATz ) + 1

C ..... Don't let them go out of bounds


IMIN_SAMP = MAX0( IMIN_SAMP, 1 )
IMIN_SAMP = MIN0( IMIN_SAMP, NUMSMPz )
IMAX_SAMP = MAX0( IMAX_SAMP, 1 )
IMAX_SAMP = MIN0( IMAX_SAMP, NUMSMPz )
IF ( IMIN_SAMP .GT. IMAX_SAMP ) THEN
C ......... Let's assume that they were meant to be reversed
ISAVE = IMIN_SAMP
IMIN_SAMP = IMAX_SAMP
IMAX_SAMP = ISAVE
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 )

IF ( LOAD_HDR .EQ. 1 ) THEN


C ......... Load the values into the header
RTHDR(IH_RATIO_MAX) = RATIO_MAX
RTHDR(IH_RATIO_TIME) = RATIO_TIME
ENDIF

IF ( LOAD_DB .EQ. 1 ) THEN


C ......... Load the values into the database

LOC_TRC = ITHDR( IH_TRACENO )


IF ( LOC_TRC .NE. INULLpz ) THEN

CALL DB_BUFFRDPUT( ID_MAX, IKEY_TRC, 'F_B_PICK',


& 'RATIOMAX', LOC_TRC, RATIO_MAX, .FALSE., IERR )
IF ( IERR .NE. 0 ) THEN

Other Docs Search Page Known Problems


amp_ratio FORTRAN Code546 Developer’s Programming Guide

CALL REPORT_DB_ERR( IERR )


CALL ST_ERR_FATAL(
& 'Error loading data into database' )
ENDIF

CALL DB_BUFFRDPUT( ID_TIME, IKEY_TRC, 'F_B_PICK',


& 'RATIOTIM', LOC_TRC, RATIO_TIME, .FALSE., IERR )
IF ( IERR .NE. 0 ) THEN
CALL REPORT_DB_ERR( IERR )
CALL ST_ERR_FATAL(
& 'Error loading data into database' )
ENDIF

ENDIF

ENDIF

C .... Send the trace back to the Executive


CALL ST_PUT_TRACE(TRACE, ITHDR)

C .... get the next trace


CALL ST_GET_TRACE(TRACE, ITHDR, RTHDR, EOF_REACHED)
C .... end while loop over traces
ENDDO

IF ( LOAD_DB .EQ. 1 ) THEN


C ............. Flush the buffers for buffered database I/O
C ............. Note that errors only give rise to
C 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_DB_ERR( IERR )
CALL ST_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_DB_ERR( IERR )
CALL ST_ERR_WARN(
& 'Error loading data into database' )
ENDIF
ENDIF

C ..... Close the packet file


CALL PKT_FILCLOSE( ID_PACKET, IERR )

C ..... Report normal completion


CALL ST_CLOSE_SOCKET_LINK

END

C------------------------------------------------------------------------------
C
C Actual work routine
C

Other Docs Search Page Known Problems


amp_ratio FORTRAN Code547 Developer’s Programming Guide

C------------------------------------------------------------------------------

SUBROUTINE AMP_RATIO_WORK( TRACE, SCRATCH, NSAMPS, NGATE,


& IMIN_SAMP, IMAX_SAMP, SAMPRATE, RATIO_MAX, RATIO_TIME )

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

C ..... Set the starting and end of the zone of interest


ISTART = 1 - NGATE
IEND = NSAMPS + NGATE

C ..... Sum the first two gates


SUM_ABOVE = 0.0
RABOVE = 0.0

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 ..... Now move down the trace


DO 120 I=ISTART+NGATE,IEND-NGATE

C ......... Compute the ratio


IF ( SUM_ABOVE .GT. 0.0 .AND. RABOVE .GT. 0.0
& .AND. RBELOW .GT. 0.0 ) THEN
SCRATCH(I) = (SUM_BELOW/RBELOW) / (SUM_ABOVE/RABOVE)
ELSE
SCRATCH(I) = 0.0
ENDIF

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

IF ( I+NGATE+1 .LE. NSAMPS ) THEN


SUM_BELOW = SUM_BELOW - ABS( TRACE(I+1) )
& + ABS( TRACE(I+NGATE+1) )
ELSE
IF ( I+1 .LE. NSAMPS ) THEN
SUM_BELOW = SUM_BELOW - ABS( TRACE(I+1) )
RBELOW = RBELOW - 1.0
ENDIF
ENDIF

120 CONTINUE

Other Docs Search Page Known Problems


amp_ratio FORTRAN Code548 Developer’s Programming Guide

C ..... Put the final results in place.


C Note that we have not handled the
C ..... edge problem, we have simply made the function undefined.
DO 130 I=1,NSAMPS
IF ( I .LE. ISTART+NGATE-1 ) THEN
TRACE(I) = 0.0
ELSEIF ( I .GE. IEND-NGATE+1 ) THEN
TRACE(I) = 0.0
ELSE
TRACE(I) = SCRATCH(I)
ENDIF
130 CONTINUE

C ..... Find the maximum of the ratio function


RATIO_MAX = TRACE(IMIN_SAMP)
IND_MAX = IMIN_SAMP
DO 140 I=IMIN_SAMP,IMAX_SAMP
IF ( TRACE(I) .GT. RATIO_MAX ) THEN
IND_MAX = I
RATIO_MAX = TRACE(I)
ENDIF
140 CONTINUE

C ..... Convert the index of the maximum to time


RATIO_TIME = FLOAT( IND_MAX - 1 ) * SAMPRATE

RETURN
END

Other Docs Search Page Known Problems


549 Developer’s Programming Guide

Appendix: Global Include File


Examples

This appendix provides examples of ProMAX global include


files.

Topics covered in this appendix:


➲ global.inc
➲ global.h

Other Docs Search Page Known Problems


global.inc550 Developer’s Programming Guide

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 ..... These are global character parameters. The common is padded to


C ..... 128 chars to facilitate addition of new parameters.
COMMON /GLOBAL_CHARcz/ CPROJz, CLINEz, CAREAz, CFLOWz,
& CPAD_GLOBAL_CHAR
SAVE /GLOBAL_CHARcz/
CHARACTER CPROJz*16, CLINEz*16, CAREAz*16, CFLOWz*16,
& CPAD_GLOBAL_CHAR*64
C ..... CPROJz - the current project name (C*16)
C ..... CLINEz - the current line name (C*16)
C ..... CAREAz - the current area name (C*16)
C ..... CFLOWz - the current flow name (C*16)

C------------------------------------------------------------------------------

C ..... These are miscellaneous global parameters. The common is padded to


C ..... 16 words to facilitate addition of new parameters.
COMMON /GLOBAL_MISCcz/ EXDATUMz, VXDATUMz, IUNITSz, I3Dz,
& IMULTCz, NTRACEz, ICDPASNz, IGEOASNz, IMARINEz,
& INOEXITz, IPAD_GLOBAL_MISC
SAVE /GLOBAL_MISCcz/
INTEGER IUNITSz, I3Dz, IMULTCz, NTRACEz, ICDPASNz, IGEOASNz,
& IMARINEz, INOEXITz, IPAD_GLOBAL_MISC(6)
REAL EXDATUMz, VXDATUMz
C ..... EXDATUMz - Final processing datum elevation (if not variable)
C ..... VXDATUMz - Final datum replacment velocity (if not variable)
C ..... IUNITSz - Type of units (choices are IENGLISHpz, ISECARCpz
C ..... or IMETRICpz )
C ..... I3Dz - 3-D flag (I3Dz=1 if data is 3-D, otherwise I3Dz=0)
C ..... IMULTCz - Multi-component flag (=1 if data is multi-component)
C ..... NTRACEz - Maximum sequential trace number of unstacked traces
C ..... (this is number of traces that were in the dataset
C ..... that was used to initialize the database)
C ..... ICDPASNz - CDP bin assigned flag (=1 if CDP bins are assigned)
C ..... IGEOASNz - Geometry-assigned flag (=1 if the geometry is assigned)
C ..... IMARINEZ - Flag for marine data (=1 if true)
CSAJ .. INOEXITz - Flag for executive not exiting (=1 if true )

C------------------------------------------------------------------------------

C ..... These are the possible types of units:


#define IENGLISHpz 1 /* flag indicating english units */
#define IMETRICpz 3 /* flag indicating metric units */

C------------------------------------------------------------------------------

C ..... These are the global run-time parameters. The common is padded to

Other Docs Search Page Known Problems


global.inc551 Developer’s Programming Guide

C ..... 32 words to facilitate addition of new parameters.


COMMON /GLOBAL_RUNTIMEcz/ SAMPRATz, NUMSMPz, IPSORTz, MAXDTRz,
& IDTYPz, NTHz, MODEz, IOUNITz, IPKEYz, ISKEYz, IDATEz,
& IDOMAINz, CLEANUPz, IERRORz, IGEOM_MATCHz, ITRNO_VALIDz,
& INIT_ONLYz, NUM_EXECSz, EXEC_NUMz,
& IPAD_GLOBAL_RUNTIME
SAVE /GLOBAL_RUNTIMEcz/
INTEGER NUMSMPz, IPSORTz, MAXDTRz, IDTYPz, NTHz, MODEz, IOUNITz,
& IPKEYz, ISKEYz, IDATEz, IDOMAINz, IGEOM_MATCHz,
& ITRNO_VALIDz, NUM_EXECSz, EXEC_NUMz,
& IPAD_GLOBAL_RUNTIME(13)
REAL SAMPRATz
LOGICAL CLEANUPz, IERRORz, INIT_ONLYz

C ..... SAMPRATz - trace sample rate in milliseconds


C ..... NUMSMPz - number of samples per trace. All traces are assumed to
C ..... begin at time 0.
C ..... IPSORTz - physical primary sort flag (see choices below)
C ..... MAXDTRz - the maximum number of data traces per ensemble
C ..... IDTYPz - primary data type (see choices below)
C ..... NTHz - the current number of 4-byte words in the trace header.
C ..... Note that the number of trace header entries may
C ..... be less than NTHz (some header entries may be more
C ..... than 4 bytes long).
C ..... MODEz - the mode ( INTERpz, IBACKGpz, IBATCHpz )
C ..... IOUNITz - the I/O unit for output diagnostics
C ..... IPKEYz - index in the trace header of the primary sort key
C ..... ISKEYz - index in the trace header of the secondary sort key
C ..... IDATEz - the current date (seconds since 00:00:00 GMT, Jan. 1, 1970)
C ..... IDOMAINz - The domain (see choices below)
C ..... INIT_ONLYz - Flag indicating that only initialization phase is
C ..... being executed (logical)
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 ..... IGEOM_MATCHz - Geometry loaded in the trace headers matches the
C ..... geometry that is stored in the database (=1 if true)
C ..... ITRNO_VALIDz - Trace number is valid flag, i.e. the trace number
C ..... found in the trace header can be used to reference
C ..... the database (=1 if true)
C ..... NUM_EXECSz - the number of execs in a disributed job (a SeisSpace
notion).
C ..... EXEC_NUMz - the index of the current exec in a distributed job.

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:

Other Docs Search Page Known Problems


global.inc552 Developer’s Programming Guide

#define INORMALpz 0 /* normal unstacked data */


#define IUP_HOLESpz 1 /* uphole data */
#define IUS_TRANSpz 2 /* transformed unstacked (e.g., frequency dom.) data */
#define IST_TRANSpz 3 /* transformed stacked (e.g., frequency domain) data */
#define ISTACKEDpz 7 /* normal stacked data */
#define ISNAPSHOTSpz 8 /* movie snapshots from finite difference modeling */
#define IFIELDpz 9 /* tape types should NOT overlap with primary data types */
#define IARCHIVEpz 10
#define IOTHER_TAPEpz 11

C------------------------------------------------------------------------------

C ..... These are the executive mode types:


#define FROM_SHELLpz 1 /* job run from the command line */
#define FROM_UIpz 2 /* job run from the ProMAX user interface */
#define FROM_QUEUEpz 3 /* job run from a queue */
#define FROM_PROWESSpz 4 /* ProMAX launched by ProWESS */
C ..... For historic reasons (avoid)
#define INTERpz 1 /* interactive */
#define IBACKGpz 2 /* background */
#define IBATCHpz 3 /* batch */

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.

C ..... These are SMART non-character parameters. The common is padded to


C ..... 64 words for ints/floats and XXX chars to facilitate addition of new
parameters.

C ..... S_SAMPLES_PER_TRACEz, We do not use this, because we already have


NUMSMPz

Other Docs Search Page Known Problems


global.inc553 Developer’s Programming Guide

C ..... S_TRACES_PER_FRAMEz, We do not use this, because we already have


MAXDTRz
C ..... S_SAMPLE_DELTAz, We do not use this, because we already have
SAMPRATz

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.

Other Docs Search Page Known Problems


global.inc554 Developer’s Programming Guide

C ..... S_MIN_SAMPLEz - the minimum "logical" sample value.


C ..... S_MIN_TRACEz - the minimum "logical" trace value.
C ..... S_MIN_FRAMEz - the minimum "logical" frame value.
C ..... S_MIN_VOLUMEz - the minimum "logical" volume value.
C ..... S_MIN_HYPERCUBEz - the minimum "logical" hypercube value.
C ..... S_SAMPLE_INCz - the "logical" sample value increment.
C ..... S_TRACE_INCz - the "logical" trace value increment.
C ..... S_FRAME_INCz - the "logical" frame value increment.
C ..... S_VOLUME_INCz - the "logical" volume value increment.
C ..... S_HYPERCUBE_INCz - the "logical" hypercube value increment.
C ..... The physical values are actual sampling along the axes.
C ..... S_SAMPLE_ORIGINz - the physical sample origin.
C ..... S_TRACE_ORIGINz - the physical trace origin.
C ..... S_FRAME_ORIGINz - the physical frame origin.
C ..... S_VOLUME_ORIGINz - the physical volume origin.
C ..... S_HYPERCUBE_ORIGINz - the physical hypercube origin.
C ..... S_TRACE_DELTAz - the physical trace delta.
C ..... S_FRAME_DELTAz - the physical frame delta.
C ..... S_VOLUME_DELTAz - the physical volume delta.
C ..... S_HYPERCUBE_DELTAz - the physical hypercube delta.
C ..... S_DATA_TYPEz - the fundamental data type, see choices below.
C ..... S_SAMPLE_LABELz - the name of the sample axis, usually a header name.
C ..... S_TRACE_LABELz - the name of the trace axis, usually a header name.
C ..... S_FRAME_LABELz - the name of the frame axis, usually a header name.
C ..... S_VOLUME_LABELz - the name of the volume axis, usually a header name.
C ..... S_HYPERCUBE_LABELz - the name of the hypercube axis, usually a header
name.
C ..... S_SAMPLE_DOMAINz - the domain of the sample axis, see choices below.
C ..... S_TRACE_DOMAINz - the domain of the trace axis, see choices below.
C ..... S_FRAME_DOMAINz - the domain of the frame axis, see choices below.
C ..... S_VOLUME_DOMAINz - the domain of the volume axis, see choices below.
C ..... S_HYPERCUBE_DOMAINz - the domain of the hypercube axis, see choices
below.
C ..... S_SAMPLE_UNITSz - the units of the sample axis, see choices below.
C ..... S_TRACE_UNITSz - the units of the trace axis, see choices below.
C ..... S_FRAME_UNITSz - the units of the frame axis, see choices below.
C ..... S_VOLUME_UNITSz - the units of the volume axis, see choices below.
C ..... S_HYPERCUBE_UNITSz - the units of the hypercube axis, see choices below.

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 ..... These are the critical global parameters related to geometry.


C ..... The common is padded to 64 words to facilitate addition of new
C ..... parameters.
COMMON /GLOBAL_GEOMcz/
& MINSLOCz, MAXSLOCz, INCSLOCz, NRCVRSz, MAXTPRz,

Other Docs Search Page Known Problems


global.inc555 Developer’s Programming Guide

& MINCDPz, MAXCDPz, INCCDPz, NUMCDPz, NTRCDPz,


& MINSINz, MAXSINz, INCSINz, NSINSz, MAXCPSz, NSHOTSz,
& MINOFBz, MAXOFBz, INCOFBz, NOFBINSz, OFFBINCz, OFFMAXz,
& MINCHNz, MAXCHNz, INCCHNz, NSLOCSz, X3DORIGz, Y3DORIGz,
& NILINESz, MINILINz, MAXILINz, XILNENDz, YILNENDz, DCDPILNz,
& NXLINESz, MINXLINz, MAXXLINz, XXLNENDz, YXLNENDz, DCDPXLNz,
& INCDP_Ez, MNCDP_Ez, NXLIN_Ez, NILIN_Ez,
& IPAD_GLOBAL_GEOM
SAVE /GLOBAL_GEOMcz/

INTEGER MINSLOCz, MAXSLOCz, INCSLOCz, NRCVRSz, MAXTPRz,


& MINCDPz, MAXCDPz, INCCDPz, NUMCDPz, NTRCDPz,
& MINSINz, MAXSINz, INCSINz, NSINSz, MAXCPSz, NSHOTSz,
& MINOFBz, MAXOFBz, INCOFBz, NOFBINSz, MINCHNz, MAXCHNz,
& INCCHNz, NSLOCSz, NILINESz, MINILINz, MAXILINz,
& NXLINESz, MINXLINz, MAXXLINz,
& INCDP_Ez, MNCDP_Ez, NXLIN_Ez, NILIN_Ez,
& IPAD_GLOBAL_GEOM(20)
REAL OFFMAXz, OFFBINCz, XILNENDz, YILNENDz, DCDPILNz,
& XXLNENDz, YXLNENDz, DCDPXLNz, X3DORIGz, Y3DORIGz
C ..... MINSLOCz - Minimum surface location number
C ..... MAXSLOCz - Maximum surface location number
C ..... INCSLOCz - Surface location number increment (always 1)
C ..... NRCVRSz - Total number of live groups
C ..... NSLOCSz - Total number of surface locations of all types
C ..... MAXTPRz - Maximum traces per receiver ensemble
C ..... MINCDPz - Minimum CDP number
C ..... MAXCDPz - Maximum CDP number
C ..... INCCDPz - CDP number increment (always 1)
C ..... NUMCDPz - Total number of CDPs
C ..... NTRCDPz - Maximum CDP fold
C ..... MINSINz - Minimum SIN (source index) number
C ..... MAXSINz - Maximum SIN (source index) number
C ..... INCSINz - SIN (source index) number increment (always 1)
C ..... NSINSz - Total number of SINs (records of all types)
C ..... MAXCPSz - Maximum channels per source
C ..... NSHOTSz - Total number of live sources (excluding test records, etc.)
C ..... MINOFBz - Minimum offset bin number
C ..... MAXOFBz - Maximum offset bin number
C ..... INCOFBz - Offset bin number increment (always 1)
C ..... NOFBINSz - Number of offset bins
C ..... OFFBINCz - Offset increment between bins
C ..... OFFMAXz - Longest offset of line
C ..... MINCHNz - Minimum channel number
C ..... MAXCHNz - Maximum channel number
C ..... INCCHNz - Increment between channel numbers (always 1)
C ..... X3DORIGz - X coordinate of origin of 3D grid (first inline and first
C ..... crossline) (relative to XREFz)
C ..... Y3DORIGz - Y coordinate of origin of 3D grid (first inline and first
C ..... crossline) (relative to YREFz)
C ..... NILINESz - Number of inlines
C ..... MINILINz - Minimum inline number
C ..... MAXILINz - Maximum inline number
C ..... XILNENDz - X coordinate of far end of first inline
C ..... YILNENDz - Y coordinate of far end of first inline
C ..... DCDPILNz - Distance between CDPs in the inline direction (same as the
C ..... distance between crosslines) for 3D; mean distance between
C ..... CDPs for 2d
C ..... NXLINESz - Number of crosslines

Other Docs Search Page Known Problems


global.inc556 Developer’s Programming Guide

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 ..... AZIMX1z - Azimuth towards increasing SURFLOC number


C ..... SLOC1Xz - X coordinate of first surface location
C ..... SLOC1Yz - Y coordinate of first surface location
C ..... XREFz - (R*8) - X reference point for the line
C ..... YREFz - (R*8) - Y reference point for the line

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

Other Docs Search Page Known Problems


global.inc557 Developer’s Programming Guide

C ..... ORIGDTz - Sample rate on field data


C ..... IXFORMz - Recording system format code
C ..... MANFACTz - Recording system manufacturing code
C ..... ISERIALz - Recording system serial number
C ..... NXAUXSz - Number of aux channels on field records
C ..... RCCONSTz - Recording system "dial in" constant

C------------------------------------------------------------------------------

C ..... Include the system-wide null values


#include "nulls.inc"

C------------------------------------------------------------------------------

C ..... This is done for re-entrancy, to ensure that all of the


C ..... common blocks are the same size:
REAL SAVE_ARz(1000), SAVE1z
EQUIVALENCE ( SAVE_ARz, SAVE1z )
C ..... Used by CALC_LENSAV macro to autocalculate common block length
C ..... Programmer places END1Z after last entry in common block
REAL END1z

C ..... This macro works on all current Fortran compilers we use


#ifndef CALC_LENSAV
#define CALC_LENSAV (LOC(END1z)-LOC(SAVE1z)+3)/4
#ifdef calc_lensav
#undef calc_lensav
#endif
#define calc_lensav CALC_LENSAV
#ifdef CALC_LEN_SAV
#undef CALC_LEN_SAV
#endif
#define CALC_LEN_SAV CALC_LENSAV
#ifdef calc_len_sav
#undef calc_len_sav
#endif
#define calc_len_sav CALC_LENSAV
#endif

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 */

Other Docs Search Page Known Problems


global.inc558 Developer’s Programming Guide

#define IWLOGpz 10 /* well log trace */


#define ICORRUPTEDpz 11 /* corrupted header (internal use only) */

C------------------------------------------------------------------------------

C ..... These are the tool types:


#define ISIMPLEpz 1 /* simple (trace in, trace out) tool */
#define IENSEMBLEpz 2 /* ensemble tool */
#define ICOMPLEXpz 3 /* complex tool */
#define IFLOWpz 4 /* flow control tool (not valid for user tools) */
#define INPUTpz 6 /* input tool (implies complex tool) */
#define IROLLGATEpz 7 /* rolling gate tool */
#define IPANELpz 8 /* panel tool */
#define ISNL_BUFFpz 9 /* one-buffer tool */
#define IDBL_BUFFpz 10 /* two-buffer tool */
#define IFLOW_SPLITpz 11 /* flow control tool (not valid for user tools) */

C------------------------------------------------------------------------------

C ..... Include the system formats


#include "formats.inc"

C------------------------------------------------------------------------------

C ..... Include the resource type definitions


#include "resource.inc"

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

Other Docs Search Page Known Problems


cglobal.h559 Developer’s Programming Guide

cglobal.h

/* C globals for ProMAX - equivalent to global.inc */

#ifndef CGLOBAL_H
#define CGLOBAL_H

#include <sys/types.h>

/* define logical variables as integers */


typedef int logical;

/* 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

#if defined (CRAY)


GlobalChar GLOBAL_CHARCZ;
GlobalChar *globalChar = &GLOBAL_CHARCZ;
#elif defined (CONVEX)
extern GlobalChar _global_charcz_;
GlobalChar *globalChar = &_global_charcz_;
#elif defined SOLARIS
extern GlobalChar global_charcz_;
GlobalChar *globalChar = &global_charcz_;
#else
extern GlobalChar global_charcz_;
GlobalChar *globalChar = &global_charcz_;
#endif

#else

#if defined (CRAY)


extern GlobalChar GLOBAL_CHARCZ, *globalChar;
#elif defined (CONVEX)
extern GlobalChar _global_charcz_, *globalChar;
#else
extern GlobalChar global_charcz_, *globalChar;
#endif

#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 */

Other Docs Search Page Known Problems


cglobal.h560 Developer’s Programming Guide

logical icdpasn; /* true if CDP bins have been assigned */


logical igeoasn; /* true if geometry has been assigned */
logical imarine; /* true if data is marine */
logical inoexit; /* SAJ true if executive is no exiting */
int ipad[6]; /* padding to 16 words */
} GlobalMisc;

#ifdef DEFINE_CGLOBALS

#if defined (CRAY)


GlobalMisc GLOBAL_MISCCZ;
GlobalMisc *globalMisc = &GLOBAL_MISCCZ;
#elif defined (CONVEX)
extern GlobalMisc _global_misccz_;
GlobalMisc *globalMisc = &_global_misccz_;
#elif defined SOLARIS
extern GlobalMisc global_misccz_;
GlobalMisc *globalMisc = &global_misccz_;
#else
extern GlobalMisc global_misccz_;
GlobalMisc *globalMisc = &global_misccz_;
#endif

#else

#if defined (CRAY)


extern GlobalMisc GLOBAL_MISCCZ, *globalMisc;
#elif defined (CONVEX)
extern GlobalMisc _global_misccz_, *globalMisc;
#else
extern GlobalMisc global_misccz_, *globalMisc;
#endif

#endif /* DEFINE_CGLOBALS */

/* choices for globalMisc->iunits - type of units */


#define IENGLISH 1
#define IMETRIC 3
/* shorthand for easier typing and reading of code */
#define IUNITSz (globalMisc->iunits)

/* 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 */

Other Docs Search Page Known Problems


cglobal.h561 Developer’s Programming Guide

logical init_only; /* true if initialization phase only */


int num_execs; /* the number of execs in a disributed job */
int exec_num; /* the index of the current execs in a distributed job */
int ipad[13]; /* padding to 32 words */
} GlobalRuntime;

#ifdef DEFINE_CGLOBALS

#if defined (CRAY)


GlobalRuntime GLOBAL_RUNTIMECZ;
GlobalRuntime *globalRuntime = &GLOBAL_RUNTIMECZ;
#elif defined (CONVEX)
extern GlobalRuntime _global_runtimecz_;
GlobalRuntime *globalRuntime = &_global_runtimecz_;
#elif defined SOLARIS
extern GlobalRuntime global_runtimecz_;
GlobalRuntime *globalRuntime = &global_runtimecz_;
#else
extern GlobalRuntime global_runtimecz_;
GlobalRuntime *globalRuntime = &global_runtimecz_;
#endif

#else

#if defined (CRAY)


extern GlobalRuntime GLOBAL_RUNTIMECZ, *globalRuntime;
#elif defined (CONVEX)
extern GlobalRuntime _global_runtimecz_, *globalRuntime;
#else
extern GlobalRuntime global_runtimecz_, *globalRuntime;
#endif

#endif /* DEFINE_CGLOBALS */

/* shorthand for easier typing and reading of code */


#define NUMSMPz (globalRuntime->numsmp)
#define SAMPRATz (globalRuntime->samprat)
#define NTHz (globalRuntime->nth)
#define MAXDTRz (globalRuntime->maxdtr)

/* choices for globalRuntime->ipsort - physical primary sort key */


#define ICDP 1 /* cdp bin */
#define ISIN 2 /* source index number */
#define IRECSLOC 3 /* receiver surface location */
#define IOFFSET 4 /* offset */
#define ICHAN 5 /* channel number */
#define IUNKNOWN 6 /* none of the above */
#define IILINE 7 /* 3D inline number */
#define IXLINE 8 /* 3D cross line number */

/* choices for globalRuntime->idtyp - primary data type */


#define INORMAL 0 /* normal unstacked data */
#define IUP_HOLES 1 /* uphole data */
#define IUS_TRANS 2 /* transformed unstacked (e.g., frequency domain) data */
#define IST_TRANS 3 /* transformed stacked (e.g., frequency domain) data */
#define ISTACKED 7 /* normal stacked data */
#define ISNAPSHOTS 8 /* Movie Snap shots from finite difference modeling */
/* tape types (should NOT overlap with primary data types) */
#define IFIELD 9

Other Docs Search Page Known Problems


cglobal.h562 Developer’s Programming Guide

#define IARCHIVE 10
#define IOTHER_TAPE 11

/* globalRuntime->mode - processing executive mode */


#define FROM_SHELL 1 /* job run from the command line */
#define FROM_UI 2 /* job run from the ProMAX user interface */
#define FROM_QUEUE 3 /* job run from a queue */
#define FROM_PROWESS 4 /* ProMAX launched by ProWESS */
/* for historic reasons (avoid) */
#define INTER 1 /* interactive */
#define IBACKG 2 /* background */
#define IBATCH 3 /* batch */

/* globalRuntime->idomain - domain type */


#define ITX 0 /* normal time-space domain */
#define IFX 1 /* frequency-space domain */
#define IFT 2 /* frequency-time domain */
#define IFK 3 /* frequency-wavenumber domain */
#define ITAUP 4 /* tau-p domain */
#define ISEMB 5 /* semblance domain */
#define IMBT 6 /* model-based transform */
#define IDEPTH 7 /* depth-space domain */
#define TSLICE 8 /* time-slice domain */
#define FLEXED 9 /* flex bin data after trace duplication */

/* 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 */

Other Docs Search Page Known Problems


cglobal.h563 Developer’s Programming Guide

char frameLabel[16]; /* the name of the frame axis, usually a header


name */
char volumeLabel[16]; /* the name of the volume axis, usually a header
name */
char hypercubeLabel[16]; /* the name of the hypercube axis, usually a
header name */
char sampleDomain[16]; /* the domain of the sample axis */
char traceDomain[16]; /* the domain of the trace axis */
char frameDomain[16]; /* the domain of the frame axis */
char volumeDomain[16]; /* the domain of the volume axis */
char hypercubeDomain[16]; /* the domain of the hypercube axis */
char sampleUnits[16]; /* the units of the sample axis */
char traceUnits[16]; /* the units of the sample axis */
char frameUnits[16]; /* the units of the sample axis */
char volumeUnits[16]; /* the units of the sample axis */
char hypercubeUnits[16]; /* the units of the sample axis */
char cpad[128]; /* the units of the sample axis */
} GlobalSmartFramework;

#ifdef DEFINE_CGLOBALS

#if defined (CRAY)


GlobalSmartFramework SMART_FRAMEWORKCZ;
GlobalSmartFramework *globalSmartFramework = &SMART_FRAMEWORKCZ;
#elif defined (CONVEX)
extern GlobalSmartFramework _smart_frameworkcz_;
GlobalSmartFramework *globalSmartFramework = &_smart_frameworkcz_;
#elif defined SOLARIS
extern GlobalSmartFramework smart_frameworkcz_;
GlobalSmartFramework *globalSmartFramework = &smart_frameworkcz_;
#else
extern GlobalSmartFramework smart_frameworkcz_;
GlobalSmartFramework *globalSmartFramework = &smart_frameworkcz_;
#endif

#else

#if defined (CRAY)


extern GlobalSmartFramework SMART_FRAMEWORKCZ, *globalSmartFramework;
#elif defined (CONVEX)
extern GlobalSmartFramework _smart_frameworkcz_, *globalSmartFramework;
#else
extern GlobalSmartFramework smart_frameworkcz_, *globalSmartFramework;
#endif

#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 */

Other Docs Search Page Known Problems


cglobal.h564 Developer’s Programming Guide

int minsin; /* minimum source index number */


int maxsin; /* maximum source index number */
int incsin; /* source index number increment (always 1) */
int nsins; /* total number of SINs (records of all types) */
int maxcps; /* maximum channels per source */
int nshots; /* total number of live sources */
int minofb; /* minimum offset bin number */
int maxofb; /* maximum offset bin number */
int incofb; /* offset bin number increment (always 1) */
int nofbins; /* number of offset bins */
float offbinc; /* offset increment between bins */
float offmax; /* longest offset of line */
int minchn; /* minimum channel number */
int maxchn; /* maximum channel number */
int incchn; /* increment between channel numbers (always 1) */
int nslocs; /* total number of surface locations of all types */
float x3dorig; /* x coordinate of origin of 3D grid (rel. to xref) */
float y3dorig; /* y coordinate of origin of 3D grid (rel. to yref) */
int nilines; /* number of inlines */
int minilin; /* minimum inline number */
int maxilin; /* maximum inline number */
float xilnend; /* x coordinate of far end of first inline */
float yilnend; /* y coordinate of far end of first inline */
float dcdpiln; /* distance between CDPs in the inline direction for
* 3D; mean distance between CDPs for 2D */
int nxlines; /* number of crosslines */
int minxlin; /* minimum crossline number */
int maxxlin; /* maximum crossline number */
float xxlnend; /* x coordinate of far end of first crossline */
float yxlnend; /* y coordinate of far end of first crossline */
float dcdpxln; /* distance between CDPs in the crossline direction */
int incdp_e; /* CDP increment in the inline direction (external) */
int mncdp_e; /* minimum CDP number in survey (external) */

int nxlin_e; /* number of xlines (CDPs per inline) (external) */


int nilin_e; /* number of ilines (inlines per xline) (external) */
int ipad[20]; /* padding to 64 words */
} GlobalGeom;

#ifdef DEFINE_CGLOBALS

#if defined (CRAY)


GlobalGeom GLOBAL_GEOMCZ;
GlobalGeom *globalGeom = &GLOBAL_GEOMCZ;
#elif defined (CONVEX)
extern GlobalGeom _global_geomcz_;
GlobalGeom *globalGeom = &_global_geomcz_;
#elif defined SOLARIS
extern GlobalGeom global_geomcz_;
GlobalGeom *globalGeom = &global_geomcz_;
#else
extern GlobalGeom global_geomcz_;
GlobalGeom *globalGeom = &global_geomcz_;
#endif

#else

#if defined (CRAY)


extern GlobalGeom GLOBAL_GEOMCZ, *globalGeom;

Other Docs Search Page Known Problems


cglobal.h565 Developer’s Programming Guide

#elif defined (CONVEX)


extern GlobalGeom _global_geomcz_, *globalGeom;
#else
extern GlobalGeom global_geomcz_, *globalGeom;
#endif

#endif /* DEFINE_CGLOBALS */

/* ***** ADD 3D STUFF HERE WHEN IT IS READY ***** */

/* 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

#if defined (CRAY)


GlobalCoord GLOBAL_COORDCZ;
GlobalCoord *globalCoord = &GLOBAL_COORDCZ;
#elif defined (CONVEX)
extern GlobalCoord _global_coordcz_;
GlobalCoord *globalCoord = &_global_coordcz_;
#elif defined SOLARIS
extern GlobalCoord global_coordcz_;
GlobalCoord *globalCoord = &global_coordcz_;
#else
extern GlobalCoord global_coordcz_;
GlobalCoord *globalCoord = &global_coordcz_;
#endif

#else

#if defined (CRAY)


extern GlobalCoord GLOBAL_COORDCZ, *globalCoord;
#elif defined (CONVEX)
extern GlobalCoord _global_coordcz_, *globalCoord;
#else
extern GlobalCoord global_coordcz_, *globalCoord;
#endif
#endif

typedef struct globalXYStruct {


double xref; /* X reference point for the line */
double yref; /* Y reference point for the line */
int ipad[4]; /* pad to 8 words */
} GlobalXY;

#ifdef DEFINE_CGLOBALS

#if defined (CRAY)


GlobalXY GLOBAL_XYCZ;
GlobalXY *globalXY = &GLOBAL_XYCZ;
#elif defined (CONVEX)
extern GlobalXY _global_xycz_;
GlobalXY *globalXY = &_global_xycz_;

Other Docs Search Page Known Problems


cglobal.h566 Developer’s Programming Guide

#elif defined SOLARIS


extern GlobalXY global_xycz_;
GlobalXY *globalXY = &global_xycz_;
#else
extern GlobalXY global_xycz_;
GlobalXY *globalXY = &global_xycz_;
#endif

#else

#if defined (CRAY)


extern GlobalXY GLOBAL_XYCZ, *globalXY;
#elif defined (CONVEX)
extern GlobalXY _global_xycz_, *globalXY;
#else
extern GlobalXY global_xycz_, *globalXY;
#endif

#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

#if defined (CRAY)


GlobalAcquis GLOBAL_AQUISCZ;
GlobalAcquis *globalAcquis = &GLOBAL_AQUISCZ;
#elif defined (CONVEX)
extern GlobalAcquis _global_aquiscz_;
GlobalAcquis *globalAcquis = &_global_aquiscz_;
#elif defined SOLARIS
extern GlobalAcquis global_aquiscz_;
GlobalAcquis *globalAcquis = &global_aquiscz_;
#else
extern GlobalAcquis global_aquiscz_;
GlobalAcquis *globalAcquis = &global_aquiscz_;

Other Docs Search Page Known Problems


cglobal.h567 Developer’s Programming Guide

#endif

#else

#if defined (CONVEX)


extern GlobalAcquis GLOBAL_AQUISCZ, *globalAcquis;
#elif defined (CONVEX)
extern GlobalAcquis _global_aquiscz_, *globalAcquis;
#else
extern GlobalAcquis global_aquiscz_, *globalAcquis;
#endif

#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

#if defined (CRAY)


StdHdr STD_HDRCZ;
StdHdr *stdHdr = &STD_HDRCZ;
#elif defined (CONVEX)
extern StdHdr _std_hdrcz_;
StdHdr *stdHdr = &_std_hdrcz_;
#elif defined SOLARIS
extern StdHdr std_hdrcz_;
StdHdr *stdHdr = &std_hdrcz_;
#else
extern StdHdr std_hdrcz_;

Other Docs Search Page Known Problems


cglobal.h568 Developer’s Programming Guide

StdHdr *stdHdr = &std_hdrcz_;


#endif

#else

#if defined (CRAY)


extern StdHdr STD_HDRCZ, *stdHdr;
#elif defined (CONVEX)
extern StdHdr _std_hdrcz_, *stdHdr;
#else
extern StdHdr std_hdrcz_, *stdHdr;
#endif

#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

#if defined (CRAY)


GlobalSpace SPACEZ;
GlobalSpace *globalSpace = &SPACEZ;
#elif defined (CONVEX)
extern GlobalSpace _spacez_;
GlobalSpace *globalSpace = &_spacez_;
#elif defined SOLARIS
extern GlobalSpace spacez_;
GlobalSpace *globalSpace = &spacez_;
#else
extern GlobalSpace spacez_;
GlobalSpace *globalSpace = &spacez_;
#endif

#else

#if defined (CRAY)


extern GlobalSpace SPACEZ, *globalSpace;
#elif defined (CONVEX)
extern GlobalSpace _spacez_, *globalSpace;
#else
extern GlobalSpace spacez_, *globalSpace;
#endif
#endif

/* macros to assist C programmer in declaring saved parameters */


/* Note: NSAVEDPARMS must match dimension of SAVE_AR in global.inc */
#define NSAVEDPARMS 1000

#if defined (CRAY)


struct {
float buffer[NSAVEDPARMS];
} SAVED_PARMS;

Other Docs Search Page Known Problems


cglobal.h569 Developer’s Programming Guide

#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

#define BEGINPARMS static struct { float _save1z_;

#define NPARMS(p) (1+sizeof(*p)/sizeof(float));

/* 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 */

/* The following numbers might be better in cpromax.h */


/* system-wide formats */
#define INT4 1
#define IREAL4 2
#define IREAL8 3
#define INTCHAR 4
#define ICHAR 5
#define ICHARR 6
#define ILOGIC 7
#define INT8L 8

/* system-wide NULL numbers. */


#include <cnull.h>

Other Docs Search Page Known Problems


cglobal.h570 Developer’s Programming Guide

/* include the resource type definitions */


#include "resource.inc"

/* release numbers */
#define SOFTRL 601000 /* software */
#define GEORLS 601000 /* geometry */

/* Global errno set by system after error on calling a UNIX function */


#include <errno.h>

#endif /* CGLOBAL_H */

Other Docs Search Page Known Problems


571 Developer’s Programming Guide

Appendix: Ordered Parameter File


Examples

This appendix provides examples for work with the Ordered


Parameter Files (TRC, SIN, etc). The FORTRAN example is a
stand-alone program which is started from the command line
and which opens and reads files. The C example is a stand-alone
program and menu which compares ordered parameter files in
different ProMAX line directories. This was a prototype
program for the quality control of processes used across
hardware platforms.

Topics covered in this appendix:


➲ db_disp.f
➲ comp_opf.menu
➲ comp_opf.c

Other Docs Search Page Known Problems


db_disp.f572 Developer’s Programming Guide

db_disp.f

PROGRAM DB_DISP

C ..... Utility to poke around in the database

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 )

C ..... If return status is not 0, act accordingly


IF ( IRETURN .EQ. 1 ) THEN
WRITE (*,*) 'No areas exist'
STOP
ELSEIF ( IRETURN .EQ. 2 ) THEN
C ......... User wants to quit
STOP
ENDIF

C ..... Initialize the area and line


CALL DB_INIT_LINE( CAREA, CLINE, IERR )

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 (*,*)

Other Docs Search Page Known Problems


db_disp.f573 Developer’s Programming Guide

WRITE (*,*) 'Enter 1-7 >'


READ (*,'(A1)') CREPLY

IF ( CREPLY .EQ. '1' ) THEN


CORDNAM = 'LIN'
ELSEIF ( CREPLY .EQ. '2' ) THEN
CORDNAM = 'TRC'
ELSEIF ( CREPLY .EQ. '3' ) THEN
CORDNAM = 'SRF'
ELSEIF ( CREPLY .EQ. '4' ) THEN
CORDNAM = 'SIN'
ELSEIF ( CREPLY .EQ. '5' ) THEN
CORDNAM = 'CDP'
ELSEIF ( CREPLY .EQ. '6' ) THEN
CORDNAM = 'CHN'
ELSEIF ( CREPLY .EQ. '7' ) THEN
GO TO 50
ELSE
WRITE (*,*) 'ERROR - invalid response'
GO TO 90
ENDIF

IF ( IKEY .NE. 0 ) THEN


C ......... Better unlock whatever was locked (call DB_ORDUNLK)
CALL DB_ORDUNLK( IKEY, IERR )
IF ( IERR .NE. 0 ) THEN
WRITE (*,*) 'ERROR opening database file, try again'
GO TO 90
ENDIF
ENDIF

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 ..... Get info on the order (call DB_ORDINFO)


CALL DB_ORDINFO( IKEY, ' ', LMIN, LMAX, LINC,
& NSTORED, SOFTRLSE, IGDATE, IGTIME, NGTRACE, IERR )
IF ( IERR .NE. 0 ) THEN
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

110 WRITE (*,*)


WRITE (*,*) 'Select an option:'
WRITE (*,*)
WRITE (*,*) '1) Review ordered database global parameters'

Other Docs Search Page Known Problems


db_disp.f574 Developer’s Programming Guide

WRITE (*,*) '2) Choose a different ordered database'


WRITE (*,*) '3) View list of information types'
WRITE (*,*) '4) View list of all stored parameters'
WRITE (*,*) '5) Select an information type'
WRITE (*,*) '6) Select a parameter'
WRITE (*,*) '7) Retrieve values for the currently'
& //' selected parameter'
WRITE (*,*) '8) Delete the currently selected parameter'
WRITE (*,*) '9) Exit'

WRITE (*,*)
WRITE (*,*) 'Enter 1-8 >'
READ (*,'(A1)') CREPLY

IF ( CREPLY .EQ. '1' ) THEN


C ......... Review ordered database global parameters
WRITE (*,*)
WRITE (*,*) 'First location = ', LMIN
WRITE (*,*) 'Last location = ', LMAX
WRITE (*,*) 'Location increment = ', LINC
WRITE (*,*) 'Number of stored parameters = ', NSTORED

ELSEIF ( CREPLY .EQ. '2' ) THEN


C ......... Choose a different ordered database
GO TO 90

ELSEIF ( CREPLY .EQ. '3' ) THEN


C ......... View list of information types (call DB_INFOTYPS)
CALL DB_INFOTYPS( IKEY, ' ', NSTORED, NFOUND,
& CINFOBUF, IERR )
IF ( IERR .NE. 0 ) THEN
WRITE (*,*) 'Error retrieving list of information types'
ELSE
WRITE (*,*)
WRITE (*,*) 'Names of all existing information types:'
DO 120 I=1,NFOUND
WRITE (*,'(1X,A8)') CINFOBUF(I)
120 CONTINUE
ENDIF

ELSEIF ( CREPLY .EQ. '4' ) THEN


C ......... View list of all stored parameters (call DB_ORDPARM)
CALL DB_ORDPARM( IKEY, CORDNAM, NSTORED, CINFOBUF, CNAMEBUF,
& CDESCBUF, IWORDBUF, IFORMBUF, INULLBUF, IDATEBUF, IERR )

IF ( IERR .NE. 0 ) THEN


WRITE (*,*) 'ERROR retrieving list of stored parameters'

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'

Other Docs Search Page Known Problems


db_disp.f575 Developer’s Programming Guide

ELSEIF ( IFORMBUF(I) .EQ. IREAL8pz ) THEN


CFORMAT = 'REAL*8'
ELSEIF ( IFORMBUF(I) .EQ. INTCHARpz ) THEN
CFORMAT = 'CHAR-INT'
ELSEIF ( IFORMBUF(I) .EQ. ICHARpz ) THEN
CFORMAT = 'CHARACTER'
ELSE
CFORMAT = 'deleted '
ENDIF
IF ( IFORMBUF(I) .EQ. INT4pz ) THEN
WRITE (*,140) CINFOBUF(I), CNAMEBUF(I),
& IWORDBUF(I), CFORMAT, INULLBUF(I),
& IDATEBUF(I)
ELSE
INUL = INULLBUF(I)
WRITE (*,150) CINFOBUF(I), CNAMEBUF(I),
& IWORDBUF(I), CFORMAT, RNUL, IDATEBUF(I)
ENDIF
WRITE (*,'(1X,A13,A80)') 'Description: ',
& CDESCBUF(I)
130 CONTINUE
140 FORMAT(1X,A8,4X,A8,2X,I6,2X,A8,2X,I12, 4X,I12)
150 FORMAT(1X,A8,4X,A8,2X,I6,2X,A8,2X,G12.1,4X,I12)
ENDIF

ELSEIF ( CREPLY .EQ. '5' ) THEN


C ......... Select an information type (call DB_INFOTYPS)
CALL DB_INFOTYPS( IKEY, ' ', NSTORED, NFOUND,
& CINFOBUF, IERR )

IF ( IERR .NE. 0 ) THEN


WRITE (*,*) 'Error retrieving list of information types'
GO TO 110
ENDIF

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 (*,*)

Other Docs Search Page Known Problems


db_disp.f576 Developer’s Programming Guide

DO 170 I=1,NSTORED
WRITE (*,*) 'Name= ', CNAMEBUF(I),
& ' Date created= ', IDATEBUF(I)
WRITE (*,'(1X,A13,A65)') 'Description: ', CDESCBUF(I)
170 CONTINUE

ELSEIF ( CREPLY .EQ. '6' ) THEN


C ......... Select a parameter
IF ( CINFO .EQ. ' ' ) THEN
WRITE (*,*) 'ERROR - no info type is selected'
GO TO 110
ENDIF
C ......... Show the list of all name for the current info
C ......... 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 the current info type:'
DO 180 I=1,NFOUND
CWORK = CDESCBUF(I)
WRITE (*,'(1X,I4,1X,A8,2X,A60)') I, CNAMEBUF(I),
& CWORK(1:60)
180 CONTINUE
WRITE (*,*)
WRITE (*,*) 'Select a parameter (enter number) >'
READ (*,'(I4)') IREPLY
IF ( IREPLY .LT. 1 .OR. IREPLY .GT. NFOUND ) THEN
WRITE (*,*) 'ERROR - invalid response'
CNAME = ' '
GO TO 110
ENDIF
CNAME = CNAMEBUF(IREPLY)

ELSEIF ( CREPLY .EQ. '7' ) THEN


C ......... Retrieve values for the currently selected parameter
IF ( CNAME .EQ. ' ' ) THEN
WRITE (*,*) 'ERROR - no parameter is selected'
GO TO 110
ENDIF
190 WRITE (*,*)
WRITE (*,*) 'Do you wish to select a range of'
& //' values (yes/no) >'
READ (*,'(A1)') CREPLY
IF ( CREPLY .EQ. 'Y' .OR. CREPLY .EQ. 'y' ) THEN
IRFLAG = 1
WRITE (*,*) 'First location available = ', LMIN
WRITE (*,*) 'Last location available = ', LMAX
WRITE (*,*) 'Enter first location >'
READ (*,'(I10)') IRFIRST
IF ( IRFIRST .LT. LMIN .OR. IRFIRST .GT. LMAX ) THEN
WRITE (*,*) 'ERROR - value out of range'
GO TO 190
ENDIF
WRITE (*,*) 'Enter last location >'
READ (*,'(I10)') IRLAST

Other Docs Search Page Known Problems


db_disp.f577 Developer’s Programming Guide

IF ( IRLAST .LT. LMIN .OR. IRLAST .GT. LMAX


& .OR. IRLAST .LT. IRFIRST ) THEN
WRITE (*,*) 'ERROR - value out of range'
GO TO 190
ENDIF
ELSEIF ( CREPLY .EQ. 'N' .OR. CREPLY .EQ. 'n' ) THEN
IRFLAG = 0
IRFIRST = LMIN
IRLAST = LMAX
ELSE
WRITE (*,*) 'ERROR - invalid response'
GO TO 190
ENDIF
C ......... Get the values (call DB_PARMGET)
CALL DB_PARMGET( IKEY, ' ', CINFO, CNAME,
& IRFLAG, IRFIRST, IRLAST, IBUFF, IERR )
IF ( IERR .NE. 0 ) THEN
WRITE (*,*) 'ERROR - getting values from database'
GO TO 110
ENDIF
C ......... Get the format of the parameter (call DB_PARMINFO)
CALL DB_PARMINFO( IKEY, ' ', CINFO, CNAME, CDESCBUF,
& IWORDBUF, IFORMBUF, INULLBUF, IDATEBUF, IERR )
IF ( IERR .NE. 0 ) THEN
WRITE (*,*) 'ERROR - getting info from database'
GO TO 110
ENDIF
NVALS = (IRLAST-IRFIRST) / LINC + 1
DO 200 I=1,NVALS
IND = IRFIRST + (I-1)*LINC
IF ( IFORMBUF(1) .EQ. INT4pz ) THEN
WRITE (*,*) IND, IBUFF(I)
ELSEIF ( IFORMBUF(1) .EQ. IREAL4pz ) THEN
WRITE (*,*) IND, RBUFF(I)
ELSE
WRITE (*,*) 'ERROR - format', IFORMBUF(1),
& ' not supported'
GO TO 110
ENDIF
200 CONTINUE

ELSEIF ( CREPLY .EQ. '8' ) THEN


IF ( CNAME .EQ. ' ' ) THEN
WRITE (*,*) 'ERROR - no parameter is selected'
GO TO 110
ENDIF
WRITE (*,*)
WRITE (*,*) 'Are you sure that you want to delete ',
& CNAME, '?'
WRITE (*,*) 'Enter yes or no >'
READ (*,'(A1)') CREPLY
IF ( CREPLY .NE. 'Y' .AND. CREPLY .NE. 'y' ) GO TO 110
C ......... Delete the parameter (call DB_PARMDEL)
CALL DB_PARMDEL( IKEY, ' ', CINFO, CNAME, IERR )
IF ( IERR .NE. 0 ) THEN
WRITE (*,*) 'ERROR - deleting parameter'
ENDIF

ELSEIF ( CREPLY .EQ. '9' ) THEN

Other Docs Search Page Known Problems


db_disp.f578 Developer’s Programming Guide

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

Other Docs Search Page Known Problems


comp_opf.menu579 Developer’s Programming Guide

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)

Other Docs Search Page Known Problems


comp_opf.menu580 Developer’s Programming Guide

E: Ctrl-YYANK back the contents of the kill buffer; 'Cut and


paste'; (Can move the cursor first) " 3 )
value: "TRC"
mouse_text: "Enter three-letter character string of the OPF to compare. TRC or
SIN for example"

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%")

Other Docs Search Page Known Problems


comp_opf.menu581 Developer’s Programming Guide

("AREA2 " implicit: (value 'AREA2 ))


("LINE2 " implicit: (value 'LINE2 ))
("OPF_NAME" implicit: (value 'OPF_NAME ))
("PARMNAME" implicit: (value 'PARMNAME ))
("INFOTYPE" implicit: (value 'INFOTYPE ))
("TOLERANC" implicit: (value 'TOLERANC ))
)
)

Other Docs Search Page Known Problems


comp_opf.c582 Developer’s Programming Guide

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>

void main( int argc, char **argv )

static char *sccsid = "%Z% %Q% %M% %I% %G%";

/* declare local variables */


char cpacket_file[129], area1[17], line1[17];
char *area2, *line2;
char *opfName, *parmName, *infoType;

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;

void *opfPntr1, *opfPntr2;


void *parmPntr1, *parmPntr2;

/* set the global pointers */


GlobalRuntime *gr = globalRuntime;
GlobalGeom *gg = globalGeom;
GlobalMisc *gm = globalMisc;

/* Put argv[1] into a string called cpacket_file */


u_carr2str_( argv[1], cpacket_file, &i_128, strlen(argv[1]) );

/* null terminate the string at the end */


cpacket_file[128] = '\0';

/* Open the parameter packet file */


initStandAlone(argc, argv, "COMP_OPF");

/* the area and line paramters */


uParGetString("AREA2 ", &area2 );
uParGetString("LINE2 ", &line2 );

Other Docs Search Page Known Problems


comp_opf.c583 Developer’s Programming Guide

uParGetString("OPF_NAME", &opfName );
uParGetString("PARMNAME", &parmName );
uParGetString("INFOTYPE", &infoType );
uParGetFloat ("TOLERANC", &tolerance );

opfPntr1 = opfOpen( opfName );


if( opfPntr1 == NULL ){
uErrFatal("Error opening %s database file in %s %s", opfName, area1, line1
);
}

parmPntr1 = opfInitBufGet( opfPntr1, infoType, parmName );


if( parmPntr1 == NULL ){
uErrFatal("Error opening paramter %s in %s %s \n", parmName, area1, line1
);
}

/* 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);
}

opfPntr2 = opfOpen( opfName );


if( opfPntr2 == NULL ){
uErrFatal("Error opening %s database file in %s %s", opfName, area2, line2
);
}

parmPntr2 = opfInitBufGet( opfPntr2, infoType, parmName );


if( parmPntr2 == NULL ){
uErrFatal("Error opening paramter %s in %s %s \n", parmName, area2, line2
);
}

/* check the format of the opf */


format = opfParmFormat( opfPntr1, infoType, parmName );
if( format != HDRINT ){
if(format != HDRFLOAT ){
uErrFatal("This module only compares FLOAT and INT opf paramters.");
}
}

/* check the boundaries of the opfs */


if( opfLocMin( opfPntr1 ) != opfLocMin( opfPntr2 ) ){
uErrFatal("The minumum opf location doesn't match for the two lines.");
}

if( opfLocMax( opfPntr1 ) != opfLocMax( opfPntr2 ) ){


uErrFatal("The minumum opf location doesn't match for the two lines.");
}

if( opfLocInc( opfPntr1 ) != opfLocInc( opfPntr2 ) ){


uErrFatal("The opf location incrment doesn't match for the two lines.");
}

Other Docs Search Page Known Problems


comp_opf.c584 Developer’s Programming Guide

for( loc = opfLocMin(opfPntr1); loc <= opfLocMax(opfPntr1); loc +=


opfLocInc(opfPntr1) ){
errCode = opfBufGet( parmPntr1, loc, &ival1 );
errCode = opfBufGet( parmPntr2, loc, &ival2 );
if( format == HDRINT ){
if( ival1 != ival2 ){
numErrorsFound++;
totalError += fabs(diff);
}
}
else{
fval1 = (float*)(&ival1);
fval2 = (float*)(&ival2);
diff = *fval1 - *fval2;
if( *fval1 == 0.0 ){
if( fabs(*fval2) > tolerance ){
numErrorsFound++;
totalError += fabs(diff);
}
}
else{
if( fabs(diff/(*fval1)) > tolerance ){
numErrorsFound++;
totalError += fabs(diff);
}
}
}
}

errCode = opfCloseBufGet( opfPntr1 );


errCode = opfCloseBufGet( opfPntr2 );

errCode = opfClose( opfPntr1 );


errCode = opfClose( opfPntr2 );

if( numErrorsFound > 0 ){


uErrFatal("Database comparison failed at %d locations with a mean error of
%f",
numErrorsFound, totalError/numErrorsFound );
}

/* notify the system of a normal completion */


printf("****************************************\n");
printf("****************************************\n");
printf(" NO errors detected in OPF comparison\n");
printf("****************************************\n");
printf("****************************************\n");
u_comp_normal_();

Other Docs Search Page Known Problems


585 Developer’s Programming Guide

Appendix: Lisp Menu Example

This appendix provides an example of a Lisp menu program..

Topics covered in this appendix:


➲ EXAMPLE.menu

Other Docs Search Page Known Problems


EXAMPLE.menu586 Developer’s Programming Guide

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

Other Docs Search Page Known Problems


EXAMPLE.menu587 Developer’s Programming Guide

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.”

Other Docs Search Page Known Problems


EXAMPLE.menu588 Developer’s Programming Guide

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.”

Other Docs Search Page Known Problems


EXAMPLE.menu589 Developer’s Programming Guide

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)))
)

Other Docs Search Page Known Problems


EXAMPLE.menu590 Developer’s Programming Guide

Other Docs Search Page Known Problems


591 Developer’s Programming Guide

Appendix: C Library Summary

This appendix provides a series of tables to describe the C


Library subroutines. To see the complete subroutine
description, use the aman routine to display the man page. For
example, aman DB_AREACOUNT will display the man page for
DB_AREACOUNT. For more information on using the aman
facility see the Man Page Reference chapter.

Topics covered in this appendix:


➲ Error Routines502
➲ Control Functions503
➲ Parameter Input505
➲ Configuration506
➲ Database507
➲ Memory Allocation/Management516
➲ Trace Headers520
➲ Trace Muting522
➲ Velocity (Geophysical Routines)523
➲ Vector Routines525
➲ Parameter Lists525
➲ Packet Files527
➲ Parameter Interpolation528
➲ Unix Interface529
➲ IPCTools531
➲ Parameter Tables537
➲ PVM549
➲ Matrix Functions556
➲ Interpolation Routines559
➲ Math Functions568
➲ Signal Processing573

Other Docs Search Page Known Problems


592 Developer’s Programming Guide

➲ Plotting575
➲ Data Structures576
➲ Sorting and Searching580

Other Docs Search Page Known Problems


Error Routines593 Developer’s Programming Guide

Error Routines

Error Routines
Subroutine Description

exErrFatal Prints error message before killing process


exErrMessage Prints diagnostic message without killing process.

exErrWarn Prints warning message without killing process.

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”).

uErrFatal Prints error message before killing process.

uErrMessage Prints diagnostic message without killing process.

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.

uErrHelp Prompts the user to select an option. An X window automatically pops up


with the possible options. The options are in the string format and are
separated by a vertical bar (|). For example: uErrHelp(“choice 1|choice
2|choice 3”,&ichoice).

Other Docs Search Page Known Problems


Control Functions594 Developer’s Programming Guide

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.)

exPanelParms Called by a processing tool in initialization phase if the tool wants to


process data in panels, either post-stack or pre-stack. This allows very
large stacked sections or common-offset sections to be processed in
panels that can fit in memory.

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.

Other Docs Search Page Known Problems


Parameter Input595 Developer’s Programming Guide

Parameter Input

Parameter Input
Subroutine Description

exParInfo Gets information for a parameter.


exParNOccurs Determines number of occurences of a parameter.

exParNValues Determines number of values of a parameter.

exParExists Determines whether the parameter exists in the packet file.


exParFormat Determines format of a parameter.

exParWordsPerValue Determines number of words per value of a parameter.

exParGetInt Gets integer values of a parameter.

exParGetIntN Gets integer values of a parameter.

exParGetFloat Gets float values of a parameter.

exParGetFloatN Gets float values of a parameter.

exParGetDouble Gets double values of a parameter.

exParGetString Gets character string of a parameter.

exParGetStringN Gets character string of a parameter.

getPar General subroutine for getting a parameter that is compatible with the old
Stanford getpar() routines. The obselete occurence parameter has been
removed.

exParReturnInt Gets integer value of a parameter.

exParReturnFloat Gets float value of a parameter.

exParReturnString Gets String of a parameter from packet files.

Other Docs Search Page Known Problems


Configuration596 Developer’s Programming Guide

Configuration

Configuration
Subroutine Description

configDevList Returns a list of all of the devices of a particular type that are listed in the
configuration file.

Other Docs Search Page Known Problems


Database597 Developer’s Programming Guide

Database

Database
Subroutine Description

opfCreate Creates a new OPF.


opfExists Determines whether an OPF exists.

opfParmInfo Returns the description, length, and format of a parameter.

opfParmFormat Returns the format of a parameter.


opfParmLength Returns the length of a parameter (in words).

opfParmExists Determines whether the parameter exists.

dbCloseDomainProject Closes and frees domain project capability initialized with


dbInitDomainProject().

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.

dbCloseEnsembleMap Closes and frees ensemble mapping capability initialized with


dbInitEnsembleMap().

dbInitEnsembleMap Initializes ensemble mapping capability which 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.

dbCloseTraceMap Closes and frees trace mapping capability initialized with


dbInitTraceMap().

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.

opfOpen Opens a database file; performs error checking.

opfClose Closes a database file.

opfPut Puts a value to the database.

Other Docs Search Page Known Problems


Database598 Developer’s Programming Guide

Database (Continued)
Subroutine Description
opfGet Gets a value from the database.

opfGetChar Gets a string from the database.

opfGetAll Gets a range of values from the database.

opfGetRange Gets a range of values from the database.


opfLock Locks an ordered database file (open read/write).

opfParmCreate Creates a parameter in the data base.

opfParmDelete Deletes a parameter in the data base.


opfInitBufGet Initializes getting a value from the database in a buffered fashion.

opfInitBufPut Initializes putting a float value to the database in a buffered fashion.

opfBufGet Gets values from the database in a buffered fashion.

opfBufPut Puts values into the database in a buffered fashion.

opfBufPutFloat Puts a float value to the database in a buffered fashion.

opfBufPutFloats Puts a float value to the database in a buffered fashion.

opfBufGetInt Gets int values from the database in a buffered fashion.

opfBufPutInt Puts an integer value to the database in a buffered fashion.

opfBufPutInts Puts an integer value to the database in a buffered fashion.

opfBufGetDouble Gets double values from the database in a buffered fashion.

opfBufPutDouble Puts a float value to the database in a buffered fashion.

opfBufPutDoubles Puts a double value to the database in a buffered fashion.

opfCloseBufGet Closes Buffered input.


opfCloseBufPut Closes Buffered output.

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.

dbLineParmPut Puts a global line parameter in the data base.

getHashName Converts a character description to a full path name of the corresponding


type. The pathname has the proper directory of the area and line. The
filename is produced by hashing the character description.

Other Docs Search Page Known Problems


Database599 Developer’s Programming Guide

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.

opfGetParmDesc Gets a description of a parameter from the ordered database.

opfPutFloat Puts a float value to the database.

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.

opfPutInt Puts an integer value to the database.

opfPutInts Puts an array of integer values to one location in the database that has a
length greater than one.

opfPutChar Puts a string to the database.

opfPutAll Puts a range of values to the database.

opfPutRange Puts a range of values from the database.

opfInitPseudoLine

opfDeinitPseudoLine

opfDomain Returns domain of opf pointer.

opfLastErr Returns last error produced from an opf access.

opfLocMin Returns minimum location of opf.

opfLocMax Returns maximum location of opf.


opfNStored Returns number of values stored per location.

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.

Other Docs Search Page Known Problems


Database600 Developer’s Programming Guide

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.

dbInitSRFtoCDPmap Determines mapping between Surface location coordinates and CDP


coordinates from input headers of traces. The mapping is determined
using the SRF_SLOC, SOU_SLOC, & CDP standard headers. Their
header index is taken from the structure *stdHdr.

dbSRFtoCDPmap Converts a surface location to a CDP location.

dbCDPtoSRFmap Converts a CDP location to a surface location.


promaxPath Get a Promax path name.

scratchSpace Returns number of kilobytes in ProMAX scratch space.

opfLocInc Returns the location increment in the ordered paramter file.

opfSoftRlse Returns the software release in use when the OPF was created.

opfIgDate Returns the creation date of the associated geometry.

opfIgTime Returns the creation time of the associated geometry.

opf Returns number of traces on the line when the geometry was created.

datasetHeaderFileExists Specifies whether the table has an associated header file.

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).

d3XYToXline Given an X,Y coordinate, returns the corresponding crossline number


(3D only).
d3XYToInline Given an X,Y coordinate, returns the corresponding inline 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.

Other Docs Search Page Known Problems


Memory Allocation/Management601 Developer’s Programming Guide

Memory Allocation/Management

Memory Allocation/Management
Subroutine Description

promaxCheckmem Checks whether the ends of any of the arrays allocated by


promaxMalloc() or promaxRealloc() have been overwritten.
promaxRealloc Similar to realloc() but checks whether the array has been overwritten and
leaves marks for subsequent checking the ends of the arrays.

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.

alloc1 Allocates a 1-d array.

realloc1 Reallocates a 1-d array.

free1 Frees a 1-d array.

alloc2 Allocates a 2-d array.

free2 Frees a 2-d array.

alloc3 Allocates a 3-d array.

free3 Frees a 3-d array.

alloc4 Allocates a 4-d array.

free4 Frees a 4-d array.

alloc1int Allocates a 1-d array of ints.


realloc1int Reallocates a 1-d array of ints.

free1int Frees a 1-d array of ints.

alloc2int Allocates a 2-d array of ints.

free2int Frees a 2-d array of ints.

alloc3int Allocates a 3-d array of ints.

free3int Frees a 3-d array of ints.

alloc1float Allocates a 1-d array of floats.

realloc1float Reallocates a 1-d array of floats.

free1float Frees a 1-d array of floats.

alloc2float Allocates a 2-d array of floats.

Other Docs Search Page Known Problems


Memory Allocation/Management602 Developer’s Programming Guide

Memory Allocation/Management (Continued)


Subroutine Description
free2float Frees a 2-d array of floats.

alloc3float Allocates a 3-d array of floats.

free3float Frees a 3-d array of floats.

alloc1double Allocates a 1-d array of doubles.


realloc1double Reallocates a 1-d array of doubles.

free1double Frees a 1-d array of doubles.

alloc2double Allocates a 2-d array of doubles.


free2double Frees a 2-d array of doubles.

alloc3double Allocates a 3-d array of doubles.

free3double Frees a 3-d array of doubles.

alloc1complex Allocates a 1-d array of complexes.

realloc1complex Reallocates a 1-d array of complexes.

free1complex Frees a 1-d array of complexes.

alloc2complex Allocates a 2-d array of complexes.

free2complex Frees a 2-d array of complexes.

alloc3complex Allocates a 3-d array of complexes.

free3complex Frees a 3-d array of complexes.

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.

memBytesAllocated Returns number of bytes allocated by this memory allocation package.

memAlloc1 Allocates a 1-d array.

memRealloc1 Reallocates a 1-d array.

memFree1 Frees a 1-d array.

Other Docs Search Page Known Problems


Trace Headers603 Developer’s Programming Guide

Trace Headers

Trace Headers
Subroutine Description

hdrInfo Gets information for a trace header entry specified by name


hdrIndexInfo Gets information for a trace header entry specified by index.

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.

hdrIndexName Returns description of trace header entry specified by index.

hdrIndexDesc Returns description of trace header entry specified by index

hdrLength Returns length (in words) of trace header entry specified by name.

hdrIndexLength Returns length (in words) of trace header entry specified by index.

hdrFormat Returns format of trace header entry specified by name.

hdrIndexFormat Returns format of trace header entry specified by index.

hdrIndex Returns index of trace header entry specified by name.

hdrAdd Adds a new entry to trace header and return index.

hdrAddStd Adds a standard entry to trace header.

defStdHdr Defines the standard headers that must always be present.

initStdHdr Initializes the standard headers that must always be present.

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.

initHeaderManip Initializes for later header interpolation.


headerInterpolate Interpolates a header based on two other headers.

headerStack Averages headers based on weights.

headerStackN Averages serval headers.

isStdHdrName Checks to see if hdrName is one of the standard headers.

Other Docs Search Page Known Problems


Trace Muting604 Developer’s Programming Guide

Trace Muting

Trace Muting
Subroutine Description

muteAlloc Allocates and initializes a mute handler.


stMuteAlloc Allocates and initializes a mute handler in a socket tool.

muteFree Frees a mute handler.

muteGetTimes Gets tapered mute start and end times from trace header.
muteSetTimes Sets tapered mute start and end times in trace header.

muteApply Applies tapered mutes to a trace.

muteSlide Slides and applies tapered mutes according to first and last non-zero
samples.

muteFindZeros Finds locations of zeroed samples in a trace.

muteRezero Re-zeros samples that were previously zero and tapers surgical mutes.

Other Docs Search Page Known Problems


Velocity (Geophysical Routines)605 Developer’s Programming Guide

Velocity (Geophysical Routines)

Velocity (Geophysical Routines)


Subroutine Description

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.

resampleTbl Resamples Table to regular intervals.

convert_v_table_ Fortran wrapper for convert_v_table().


tblToMatrix Creates a matrix of velocities from a velocity table.

matrixToTbl Puts a matrix of velocities into a velocity table.

smoothVelMatrix Smooths a matrix of velocities.

getTblAvg Gets the average value in a table.

getResampTblAvg Gets the average value in table resampled to a regular grid.

tblMixInterpXYu Interpolates a vector of z(x,y) values, uniformly sampled in y for constant


x, but mixed in the X direction. The purpose of this subroutine is to
smooth the velocities for migrations.

avgTbl Obselete function that is replaced by tblAvg().

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.

interpVrmsPairsToVint Computes uniformly sampled interval velocities to fit specified trms,


vrms.

Other Docs Search Page Known Problems


Vector Routines606 Developer’s Programming Guide

Vector Routines

Vector Routines
Subroutine Description

vClr Clears a vector.


vMov Copies elements from one vector to another.

vsMul Vector scalar multiply.

vAdd Vector add: c[incc*i]= a[inca*i] + b[incb*i].


vsMA Vector add: c[incc*i]= a[inca*i] * b + c[incc*i].

vFill Fills a vector with a constant.

Other Docs Search Page Known Problems


Parameter Lists607 Developer’s Programming Guide

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).

listFree Frees parameter List.

listReady Signals List is ready.


listDescribe Sets description of parameter list.

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.

listFromDatabase Gets a parameter list from database.

listToDatabase Puts a parameter list to database.

listDecode Creates a list by decoding a character string.

listInfoUpdate Gets information on a list.

listGet Gets range of values for the bottom level.

listGetInts Gets range of values for the bottom level.

listCheck Checks whether a set of values is within the list range.

listCheckInts Checks whether a set of values is within the list range.

Other Docs Search Page Known Problems


Packet Files608 Developer’s Programming Guide

Packet Files

Packet Files
Subroutine Description

pktFileClose Closes a packet file.


pktFileCreate Creates a packet file.

pktFileOpen Opens a packet file.

pktInit Initializes a packet in a packet file.


pktGroupInit Initializes a group in packet in a packet file.

pktOutParmN Puts multiple values for one parameter into the packet file.

pktOutInt Puts an integer parameter into the packet file.

pktOutFloat Puts a float parameter into the packet file.

pktOutDouble Puts a double parameter into the packet file.

pktOutString Puts a double parameter into the packet file.

pktGetNGroups Gets the number of groups in a packet file.

pktGroupCopy Copies groups from one packet to another.

pktParmInfo Gets information on a parameter in the packet file.

pktGroupInfo Gets information on a group in the packet file.

pktGetMaxParmLength Gets the maximum length of a parameter in a packet.

Other Docs Search Page Known Problems


Parameter Interpolation609 Developer’s Programming Guide

Parameter Interpolation

Parameter Interpolation
Subroutine Description

intGet Interpolates/extrapolates z values at specified x and y.


intVecX1X2 Interpolates/extrapolates z values at specified x1, x2, and uniformly
sampled y. This is similar to intVec(), except the (x1,x2) coordinates are
passed instead of the routine determining them from the ensemble
number using the Ordered Parameter Files.

intVec Interpolates/extrapolates z values at specified x1, x2, and uniformly


sampled y.
interp Interpolates z values at x1, x2, and y, for y = fy, fy+dy, ... fy+(ny-1)*dy.

Other Docs Search Page Known Problems


Unix Interface610 Developer’s Programming Guide

Unix Interface

Unix Interface
Subroutine Description

maybeSearchPath Checks to see if envvar is a search path indicated by containing one or


more “:”. If yes, searches one at a time for the existance of file on
hostname.
promaxHostPath Returns the path to specific directories and files in the ProMAX directory
structure.

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.

promaxLinePath Returns full path name of current ProMAX Line. Calls


promaxPathName() and concatenates the globalChar->carea &
globalChar->cline.

promaxFlowPath Returns full path name of current ProMAX Flow. Calls


promaxPathName() and concatenates the globalChar->carea &
globalChar->cline.

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.

wallsec Returns elapsed time (wall clock time) in seconds.

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.

Other Docs Search Page Known Problems


IPC Tools611 Developer’s Programming Guide

IPC Tools

IPC Tools
Subroutine Description

isParallelTool Specifies whether this module is being executed as a parallel Tool.


pstConnectToServer Establishs connection from a parallel socket tool to the ProMAX
processing flow.

stConnectToServer Establishs connection to the ProMAX processing flow.

stSetToolName Establishes the tool name.


stGetTrace Reads in a trace from the ProMAX flow into a socket tool program.

stEOFReached Determines whether a previous data read reached an EOF.

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.

stPutTrace Writes in a trace to the ProMAX flow.

stPutEnsemble Writes an Ensemble to the ProMAX flow.

pstPutEnsemble Writes an Ensemble to the ProMAX flow.

stCloseSocketLink Closes the socket link to the ProMAX flow.

stStopFlow Stops the ProMAX flow immediately.

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.

stInputTool Specifies that the tool is an input tool.


stEnableExitContinue Enables a socket tool to later call stPassSocketLink(). This routine must
be called in the init phase so that stEnableExitContinue() can be later
called in the exec phase.

stGetStdHdr Gets the standard header indexes.

stHdrAdd Adds a header to the data; see also sHdrAddStd().

stHdrIndexName Gets the name associated with a header index.

stHdrAddStd Adds a ProMAX standard header to the data. The description, length, &
format are read from system files.

stHdrExists Determines whether a header entry exists.

stHdrDesc Gets the description associated with a header entry.

stHdrIndex Gets the index of a header.

Other Docs Search Page Known Problems


IPC Tools612 Developer’s Programming Guide

IPC Tools (Continued)


Subroutine Description
stHdrLength Gets the length of a header word.

stHdrFormat Gets the format of a header.

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.

stGetPanel Reads in a panel of traces.

stPutPanel Writes out a panel of traces.

stErrFatal Prints error message before killing process.

stErrMessage Prints diagnostic message (without killing process).

stErrWarn Prints warning message (without killing process).

stErrHelp Prompts the user to select an option. An X window automatically pops up


with the possible options. The options are in the string text and are
separated by a vertical bar (|). For example: stErrHelp(“choice 1|choice
2|choice 3”).

stCheckConnection Checks whether socket link to the executive is still alive.


stSetDiskIter Causes Disk Data Input to iterate over the list of input traces.

stStatMemReserve Tells the executive how much memory the IPC tools will use. Repeated
calls increment the memory usage.

st_connect_to_server_ Establishes connection to the ProMAX processing flow.

st_set_tool_name_ Establishes the tool name.

st_get_trace_ Reads in a trace from the ProMAX flow into a socket tool program.

st_eof_reached_ Determines whether a previous data read reached an EOF.

st_get_ensemble_ Reads in an Ensemble from the ProMAX flow into a socket tool program.

st_put_trace_ Writes in a trace to the ProMAX flow.

st_put_ensemble_ Writes an Ensemble to the ProMAX flow.

Other Docs Search Page Known Problems


IPC Tools613 Developer’s Programming Guide

IPC Tools (Continued)


Subroutine Description
st_close_socket_link_ Closes the socket link to the ProMAX flow.

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_input_tool_ Specifies this tool as an input tool.

st_hdr_add_ Adds a header to the data; see also ST_HDR_SRD_ADD().


st_hdr_std_add_ Adds a ProMAX standard header to the data. The description, length, &
format are read from system files.

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.

st_get_panel_ Reads in a panel of traces.

st_put_panel_ Writes out a panel of traces.

Other Docs Search Page Known Problems


Parameter Tables614 Developer’s Programming Guide

Parameter Tables

Parameter Tables
Subroutine Description

tblAllocate Allocates and initializes a new parameter table for z(x,y).


tblAllocTb3 Makes a tbl out of a tb3.

tblAllocTmp Allocates and initializes a temporary parameter table for z(x,y), for the
case in which true spatial coordinates can be ignored.

tblFree Frees parameter table.


tblFetchTb3 Returns the underlying tb3 so that the tb3 functions can be used directly.

tblSetExtrap Sets x and y extrapolation methods.

tblResolveX1X2 Given an X (ensemble number), returns the spatial coordinates that are
used within the table functions.

tblAddXY Adds z value(s) at specified (x,y) point.

tblAddXYs Adds z value(s) for an array of y coordinates and constant x.

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.

tblRMStoDIP Converts a azimuthally varying Dip-Vels velocity field to a RMS velocity


field.

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.

tblDeleteX Deletes all z value(s) at specified x coordinate.

tblClear Clears all entrys in a table.

tblInterpXY Interpolates z(x,y) value(s) at specified (x,y) point.

tblInterpXYu Interpolates a vector of z(x,y) values, uniformly sampled in y for constant


x.

dbTblUpdate Updates a table using the OPFs.

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.

Other Docs Search Page Known Problems


Parameter Tables615 Developer’s Programming Guide

Parameter Tables (Continued)


Subroutine Description
tblGetType Gets three letter code that identifies the table type.

tblSetType Sets three letter code that identifies the table type.

tblFromDatabase Gets a parameter table from database.

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.

tblHeaderFileExists Specifies whether the table has an associated heaer file.


tblReadHeaderFile Reads the header file associated with a table into the Parameter Group.

tblWriteHeaderFile Writes a parameter group into a header file associated with a table.

tblFromVelPar Loads a parameter table from a location:times-vels type of parameter


string.

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.

tblX1Min Gets minimum X1 value for table.

tblX1Max Gets maximum X1 value for table.

tblX2Min Gets minimum X2 value for table.


tblX2Max Gets maximum X2 value for table.

tblYMin Gets minimum Y value for table.

tblYMax Gets maximum Y value for table.

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.

tblCountX Gets number of locations in table.

tblCountMaxY Gets maximum number of samples per node in a table.

tblCountZ Gets number of z values per sample in a table.

Other Docs Search Page Known Problems


Parameter Tables616 Developer’s Programming Guide

Parameter Tables (Continued)


Subroutine Description
tblDesc Gets table description.

tblDescX Gets table X description.

tblDescY Gets table Y description.

tblDescZ Gets table Z description.


tblEqual Checks whether two tables have identical values.

tblSetYZ Adds z value(s) for y coordinates and constant (x1,x2) coordinate.

tblDeleteYZ Deletes z value(s) at specified ( (x1,x2),y) point.


tblDelete Deletes all z value(s) at specified (x1,x2) coordinate.

tblInterpZ Interpolates a vector of z( (x1,x2) ,y) values, uniformly sampled in y for


constant x.

tblIndexX Gets node coordinates by index from table.

tblGetYZ Gets sample coordinates and values from an existing node in table.

tb3Alloc Allocates a new empty table.

tb3Free Frees a 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.

tb3SetExtrapY Sets method used to extrapolate in y.

tb3GetTri Gets pointer to the triangulation structure used for the tables.

tb3GetData Gets user-specified data from an existing node of table.


tb3GetYZ Gets sample coordinates and values from an existing node in table.

tb3GetZ Gets sample values from an existing node in table.

tb3GetExtrapY Gets method used to extrapolate in y.

tb3InterpZ Interpolates z values at specified node and sample coordinates.

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.

tb3Delete Deletes an existing node from table.

tb3CleanData Removes nodes with no data, if any exist.

tb3CleanYZ Removes nodes with no samples, if any exist.

Other Docs Search Page Known Problems


Parameter Tables617 Developer’s Programming Guide

Parameter Tables (Continued)


Subroutine Description
tb3NearestX Finds node nearest to specified node coordinates.

tb3NearestY Finds sample nearest to specified sample coordinate in existing node of


table.

tb3UniformY Determines if node is sampled uniformly.

tb3CountX Gets number of nodes in table.


tb3CountY Gets number of samples from an existing node in table.

tb3CountZ Gets number of z values per sample in a table.

tb3CountMaxY Gets maximum number of samples per node in table.


tb3DeltaY Gets sampling interval from an existing node in table.

tb3FirstY Gets first sample coordinate from an existing node in table.

tb3IndexX Gets node coordinates by index from table.

tb3IndexY Gets sample coordinates by index from table.

tb3HasX Determines if a node exists in a table.

tb3HasY Determines if a sample exists in an existing node in a table.

tb3InsideX Determines if point is inside convex hull of nodes in a table.

tb3InsideY Determines if sample is inside the range of sample coordinates in an


existing node in table.

tb3InsideMinY Determines if sample is inside the minimum range of samples in nodes


that would be used to interpolate/extrapolate.

tb3InsideMaxY Determines if sample is inside the maximum range of samples in nodes


that would be used to interpolate/extrapolate.

tb3InsideLinY Determines if sample is inside the linearly-


interpolated/constant-extrapolated range of samples in nodes that would
be used to interpolate/extrapolate.

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.

killSamples Frees samples.

sortSamples Sorts samples by increasing y coordinate.

removeDuplicateSamples Removes duplicate samples (those which have identical y values).

uniformSamples Returns 1 if sampling is uniform; 0, otherwise. If sampling is uniform,


frees space used to store sample coordinates.

Other Docs Search Page Known Problems


Parameter Tables618 Developer’s Programming Guide

Parameter Tables (Continued)


Subroutine Description
setSample Sets sample and returns updated samples.

deleteSample Deletes sample, if it exists, and returns updated samples.

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.

makeSortedNodes Returns array of nodes sorted by x1; if no nodes, returns NULL.

killSortedNodes Deletes array of nodes sorted by x1, if the array exists.

findNode Returns node (x1,x2), if it exists; otherwise, returns NULL.

initNodeState Initializes/resets the roving node and its coordinates.

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.

makeTempBoundaryNodes Creates temporary boundary nodes, if necessary, to facilitate


interpolation.

killTempBoundaryNodes Destroys all temporary boundary nodes.

interpNode Linearly interpolates/extrapolates z values at the specified node.

makeInterpABC Computes interpolation coefficients a,b,c for z = a + b*x1 + c*x2.

updateInterpNodes Updates nodes relevant for interpolation at node coordinates x1,x2.


Returns 1 if nodes were changed; 0, otherwise.

makeInterp Makes table interpolator.

killInterp Kills table interpolator.

updateInterp Updates the table interpolator; if it does not exist, makes it.

Other Docs Search Page Known Problems


PVM619 Developer’s Programming Guide

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_rMaxContext Returns maximum valid value for an context label

pvm_rMinMsgtag Returns minimum valid value for a message tag


pvm_rMaxMsgtag Returns maximum valid value for a message tag

pvm_rmsgtomsg Converts contextualized message tag to ordinary PVM message tag

pvm_rnewContext Generates a unique context number

pvm_rcurrentContext Returns current context number (does not change context number)

pvm_rsetContext Sets context number to new value

pvm_rbufinfo Returns information about the requested message buffer

pvm_rsend Immediately sends the data in the active message buffer

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_rnrecv Non-blocking receive

pvm_rrecvm Accepts one of a list of messages from receive queue

pvm_rnrecvm Accepts one of a list of messages from receive queue (non-blocking)

pvm_rprobe Determines whether specified message is in the receive queue

pvm_rprobem Determines whether one of list of messages is in receive queue

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.

Other Docs Search Page Known Problems


PVM620 Developer’s Programming Guide

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.

pvm_rmrecv Accepts a message from one of a list of tasks

pvm_rmnrecv Accepts a message from one of a list of tasks (non-blocking)


pvm_rcmrecv PVM checking re-entrant multicast receive. This receive acts like a
blocking multi-receive if the sending processes are still alive. If the
message queue is empty and a sending process dies, this function returns
with the error PvmNoTask.

packenvstring Packs an environment into a single null-terminated string. Within the


string, the environmental variable strings are delimited by new-line
characters.

getenvstring Packs the environment into a single null-terminated string. Within the
string, the environmental variable strings are delimited by new-line
characters.

parenviron Parses the packed environment string created by getenvstring() and


returns an array of environmental variable strings

initPvmtool Connects to parent ProMAX processing flow, sets up environment, opens


packet file, and initializes database

setPvmtoolType Sets state to a valid ProMAX tool type

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

ptGetTrace Gets a trace from the parent ProMAX flow

ptPutTrace Sends a trace to the parent ProMAX flow

ptGetEnsemble Gets an ensemble from the parent ProMAX flow

ptPutEnsemble Sends an ensemble to parent ProMAX flow

ptSetPanels Sets panel dimensions for later input and output

ptSetOutPanels Sets output panel dimensions

ptGetPanel Gets a panel of traces from the parent ProMAX flow

ptPutPanel Sends a panel of traces to the parent ProMAX flow

ptSndPromaxHeader Sends ProMAX header to another PVM process

Other Docs Search Page Known Problems


PVM621 Developer’s Programming Guide

PVM (Continued)
Subroutine Description
ptRcvPromaxHeader Receives ProMAX header from another PVM process

ptSndPromaxGlobals Sends ProMAX global data structures

ptRcvPromaxGlobals Receives ProMAX global data structures

ptSndPromaxToolType Sends ProMAX tooltype to another PVM process


ptRcvPromaxToolType Sends ProMAX tooltype to another PVM process

dbInitLine Initializes database for given line and area

rcvProtocolInfo Receives data transfer protocol information from parent process


rcvPacketFile Receives a packet file from parent and opens it for this tool

sndDone Sends a finished signal to the ProMAX exec

socket_send Sends message to another process via socket

socket_recv Receives message from another process via socket

unixSocketConnect Creates a client endpoint of a Unix socket connection and connects to


server

inetSocketConnect Creates a client endpoint of a INET socket connection and connects to


server

pkPromaxHeader PVM pack ProMAX header

upkPromaxHeader Receives ProMAX header from another PVM process

pkGlobalAcquis Sends ProMAX global acquisition info to another PVM process

upkGlobalAcquis Receives ProMAX global acquisition info from another PVM process

pkGlobalChar Sends ProMAX global character info to 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

pkGlobalGeom Sends ProMAX global geometry info to another PVM process

upkGlobalGeom Receives ProMAX global geometry info from another PVM process

pkGlobalMisc Sends ProMAX global misc info to another PVM process

upkGlobalMisc Receives ProMAX global misc info from another PVM process

pkGlobalRuntime Sends ProMAX global runtime info to another PVM process

upkGlobalRuntime Receives ProMAX global runtime info from another PVM process

pkGlobalXY Sends ProMAX global XY info to another PVM process

upkGlobalXY Receives ProMAX global XY info from another PVM process

Other Docs Search Page Known Problems


Matrix Functions622 Developer’s Programming Guide

Matrix Functions

Matrix Functions
Subroutine Description

dgefa Gaussian elimination to obtain the LU factorization of a matrix


dgeco Gaussian elimination to obtain the LU factorization and condition
number of a matrix

dgesl Solves linear system Ax = b or A’x = b after LU factorization

sgefa Gaussian elimination to obtain the LU factorization of a matrix


sgeco Gaussian elimination to obtain the LU factorization and condition
number of a matrix

sgesl Solves linear system Ax = b or A’x = b after LU factorization

sqrdc Uses Householder transformations to compute the QR decomposition of


an n by p matrix x. Column pivoting based on the 2-norms of the reduced
columns may be performed at the user’s option.

sqrsl Uses the output of sqrdc to compute coordinate transformations,


projections, and least squares solutions. For k <= MIN(n,p), let xk be the
matrix xk = (x[jpvt[0]], x[jpvt[1]], ..., x[jpvt[k-1]]) formed from columns
jpvt[0], jpvt[1], ..., jpvt[k-1] of the original n by p matrix x that was input
to sqrdc. (If no pivoting was done, xk consists of the first k columns of x
in their original order.) sqrdc produces a factored orthogonal matrix Q
and an upper triangular matrix R such that xk = Q * (R) (0) This
information is contained in coded form in the arrays x and qraux.

sqrst Computes least squares solutions to the system Xb = y which may be


either under-determined or over-determined. The user may supply a
tolerance to limit the columns of X used in computing the solution. In
effect, a set of columns with a condition number approximately bounded
by 1/tol is used, the other components of b being set to zero.
stoepd Solves a symmetric Toeplitz linear system of equations Rf=g for f (double
version)

tridif Solves a tridiagonal linear system of equations Tu=r for u (float version)

vanded Solves Vandermonde system of equations Vx=b (double version)

vandef Solves Vandermonde system of equations Vx=b (float version)

isamax Returns index of element with maximum absolute value

sasum Returns sum of absolute values

saxpy Computes y[i] = y[i]+a*x[i]

scopy Copies x[i] to y[i] (i.e., set y[i] = x[i])

sdot Returns sum of x[i]*y[i] (i.e., return the dot product of x and y)

Other Docs Search Page Known Problems


Matrix Functions623 Developer’s Programming Guide

Matrix Functions (Continued)


Subroutine Description
snrm2 Returns square root of sum of squares of x[i] (i.e. length of the vector)

sscal Computes x[i] = a*x[i]

sswap Swaps x[i] and y[i]

Other Docs Search Page Known Problems


Interpolation Routines624 Developer’s Programming Guide

Interpolation Routines

Interpolation Routines
Subroutine Description

cmonot Computes cubic interpolation coefficients via the Fritsch-Carlson method


which preserves monotonicity
cakima Computes cubic interpolation coefficients via Akima’s method

csplin Computes cubic spline interpolation coefficients for interpolation with


continuous second derivatives

dsinc Returns sinc(x) = sin(PI*x)/(PI*x) (double version)


fsinc Returns sinc(x) = sin(PI*x)/(PI*x) (float version)

intcub Evaluate y(x), y’(x), y’’(x), ... via piecewise cubic interpolation

intl2b Bilinear interpolation of a 2-D array of bytes

intl2bx Interpolates between input x values (FOR INTERNAL USE by intl2b)

intl2by Interpolates between input y values (FOR INTERNAL USE by intl2b)

intlin Evaluates y(x) via linear interpolation of y(x[0]), y(x[1]), ...

ints8c Interpolation of a uniformly-sampled complex function y(x) via a table of


8-coefficient sinc approximations; maximum error for frequiencies less
than 0.6 nyquist is less than one percent

ints8r Interpolation of a uniformly-sampled real function y(x) via a table of


8-coefficient sinc approximations; maximum error for frequiencies less
than 0.6 nyquist is less than one percent

intt8c Interpolation of a uniformly-sampled complex function y(x) via a table of


8-coefficient interpolators

intt8r Interpolation of a uniformly-sampled real function y(x) via a table of 8-


coefficient interpolators

mksinc Computes least-squares optimal sinc interpolation coefficients

yclip Clips a function y(x) defined by linear interpolation of the uniformly


sampled values: y(fx), y(fx+dx), ..., y(fx+(nx-1)*dx). Returns the number
of samples in the clipped function.

yxtoxy Computes a regularly-sampled, monotonically increasing function x(y)


from a regularly-sampled, monotonically increasing function y(x) by
inverse linear interpolation

tinAlloc Allocates a new (empty) triangulated interpolator

tinFree Frees a triangulated interpolator

tinAdd Adds an array of z values at the specified x,y

tinAddWithData Adds an array of z values and user-specified data at the specified x,y

Other Docs Search Page Known Problems


Interpolation Routines625 Developer’s Programming Guide

Interpolation Routines (Continued)


Subroutine Description
tinData Returns user-specified data nearest to the specified x,y

tinDelete Deletes the array of z values nearest to the specified x,y

tinInterp Interpolates/extrapolates z at specified x,y

tinInterpRange Interpolates/extrapolates a range of z’s at specified x,y


tinInterpZ Interpolates/extrapolates one z value with index iz at specified x,y

tinTri Returns the triangulation for a triangulated interpolator

interp0 Method=0 interpolation of z values at specified x,y


interp1 Method=1 interpolation of z values at 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

killNodeData Frees space for node data

naborNodes Returns null-terminated list of nodes that are nabors of the specified node

makeGradients Computes gradients for one node

shfs8r Shifts a uniformly-sampled real-valued function y(x) via a table of


8-coefficient sinc approximations; maximum error for frequencies less
than 0.6*nyquist is less than one percent.

triAlloc Allocates a new (empty) triangulation

triFree Frees a triangulation

triAddNode Adds point (x,y) to triangulation t and return node

triDeleteNode Deletes node from triangulation


triNearestNode Finds node in triangulation that is nearest to a point (x,y)

triNearestNodes Finds the n nodes in triangulation that are nearest to the point (x,y)

triLocatePoint Locates point (x,y) in triangulation t

triBaryCoords Computes barycentric coordinates of a point (x,y) in a triangle

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

triIsBoundaryNode Determines whether or not a node is a boundary node

triIsTempBoundaryNode Determines whether or not a node is a temporary boundary node

Other Docs Search Page Known Problems


Interpolation Routines626 Developer’s Programming Guide

Interpolation Routines (Continued)


Subroutine Description
insertNodeBefore Inserts node m before node n into node list of triangulation t

killNode Destroys node n in triangulation t

makeNabor Makes node m a neighbor in a new list of neighbors of node n

makeNaborAfter Makes node l a neighbor after node m in list of neighbors of node n


killNabor Deletes node m from list of neighbors of node n

naborForNode Returns neighbor corresponding to node m from list of neighbors of node


n

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

afterMakeNode After adding a new node to a valid triangulation, swaps edges as


necessary to obtain a Delaunay triangulation

beforeKillNodeInside Prepares to kill an interior node of a triangulation. Swaps edges so that a


Delaunay triangulation will result when node is disconnected.

beforeKillNodeOutside Prepares to kill a boundary node of a triangulation. Swaps edges so that a


Delaunay triangulation will result when node is disconnected.
killNodeInside Destroys interior node of a triangulation

killNodeOutside Destroys node on boundary of triangulation, with remaining nodes not


co-linear

killTempBoundaryNodes Kills all temporary nodes on boundary of triangulation

killNodeOnLine Destroys node on line of co-linear nodes

killNodeOffLine Destroys node off line of co-linear nodes

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.

Other Docs Search Page Known Problems


Interpolation Routines627 Developer’s Programming Guide

Interpolation Routines (Continued)


Subroutine Description
swapTestDelete Determines whether or not to swap edge n-n2 with edge n1-n3, where
node n is going to be destroyed and n1, n2, and n3 are three consecutive
nodes now connected to n, ordered counter-clockwise. 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.

locatePoint Locates point (x,y) inside or outside triangulation t

locateOutside Locates point (x,y) outside (or on) boundary of triangulation t


visibleNodes Finds leftmost and rightmost boundary nodes visible from point outside

otherNodesColinear Determines if all nodes except this one are co-linear

circum Computes center and radius-squared of circumcircle of a triangle

nodeInCircum Determines if node is inside circumcircle of triangle

nodeInTri Determines if node is inside triangle

perturb Perturbs a float into a Double with pseudo-random least-significant bits

checkNode Ensures node is valid; used for debugging

checkTri Ensures triangulation is valid; used for debugging

ct2Init Given three pairs of 2D position vectors expressed in two coordinate


systems, determines and saves transformation information to permit
transformation of vectors from one coordinate system to the other, via
calls to ct2Transform()

ct2Transform Transforms a 2D vector from one coordinate system to another

ress8c Resamples a uniformly-sampled complex function y(x) via 8-coefficient


sinc approximations; maximum error for frequiencies less than 0.6
nyquist is less than one percent
ress8r Resamples a uniformly-sampled real function y(x) via 8-coefficient sinc
approximations; maximum error for frequiencies less than 0.6 nyquist is
less than one percent

Other Docs Search Page Known Problems


Math Functions628 Developer’s Programming Guide

Math Functions

Math Functions
Subroutine Description

tokensCreate Splits a string into null-terminated tokens


tokensCompress Removes whitespace from tokens

tokenInt Converts token to int; for example, token=”2” yields i=2

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}

tokenFloat Converts token to float; for example, token=”2.34” yields f=2.34

tokenPairFloat Converts token to pair of floats; for example, token=”2--3.2” yields f1=2,
f2=-3.2

tokenReplicatedFloat Converts token to replicated float; . “2.34(3)” yields n=3, f=2.34

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}

tioOpen Opens a file for buffered “typed” I/O (uses fopen)


tioOpenU Opens a file for unbuffered “typed” I/O (uses open)

tioClose Closes a file that was opened by tioOpen or tioOpenU

stateFromHandle Converts a file handle into a pointer

tioPrintOpenFiles Prints the state of all open files

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.

tioUnsetSwapflag De-establishes the need for byte swapping 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.

tioResizeBuff Ensures that the work buffer is large enough

Other Docs Search Page Known Problems


Math Functions629 Developer’s Programming Guide

Math Functions (Continued)


Subroutine Description
tioEof Checks the end-of-file indicator for a open file

tioSync Performs sync on a file (flushes buffers to disk)

tioSetLock Locks a file (denying access to other processes)

tioCheckLock Checks to see if a file is locked by another process


tioFcntl Does I/O control on an open file

airya Returns approximation to the Airy function Ai(x)

airyap Returns approximation to the derivative of the Airy function Ai’(x)


airyb Returns approximation to the Airy function Bi(x)

airybp Returns approximation to the derivative of the Airy function Bi’(x)

idamax Returns index of element with maximum absolute value

dasum Returns sum of absolute values

daxpy Computes y[i] = y[i]+a*x[i]

dcopy Copies x[i] to y[i] (i.e., set y[i] = x[i])

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)

dscal Computes x[i] = a*x[i]

dswap Swaps x[i] and y[i]

frannor Returns a normally distributed random float

srannor Seed random number generator

franuni Returns a pseudo-random float between 0.0 (inclusive) and 1.0


(exclusive)
sranuni Seed random number generator

quest Returns an estimate of a specified quantile

questalloc Alloc, init, & return pointer to a quantile estimator

questupdate Updates and returns a quantile estimate

questfree Frees quantile estimator

Other Docs Search Page Known Problems


Signal Processing630 Developer’s Programming Guide

Signal Processing

Signal Processing
Subroutine Description

antialias Anti-alias filter; use before increasing the sampling interval


(sub-sampling)
bfdesign Butterworth filter: computes number of poles and -3 db frequency for a
low-pass or high-pass filter, given a frequency response constrained at
two frequencies

bfhighpass Butterworth filter: high-pass

bflowpass Butterworth filter: low-pass


hankelalloc Allocates and returns a pointer to a Hankel transformer

hankelfree Frees a Hankel transformer

hankel0 Computes zero-order Hankel transform

hankel1 Computes first-order Hankel transform

hilbert Computes Hilbert transform y of x

holbergd1 Computes coefficients of Holberg’s 1st derivative filter

mkdiff Makes discrete Taylor series approximation to n’th derivative

mkhdiff Computes filter approximating the bandlimited half-differentiator

abelalloc Allocates and returns a pointer to an Abel transformer

abelfree Frees an Abel transformer

abel Computes Abel transform

xcor Computes z = x cross-correlated with y; that is,


ifx+lx-1 z[i] = sum x[j]*y[i+j] ; i = ifz,...,ifz+lz-1 j=ifx
conv Computes z = x convolved with y; that is,
ifx+lx-1 z[i] = sum x[j]*y[i-j] ; i = ifz,...,ifz+lz-1 j=ifx

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

npfaro Returns optimal n between nmin and nmax for real-to-complex or


complex-to-real prime factor ffts

pfa2cc Prime factor fft: 2-D complex to complex transforms, in place

pfa2cr Prime factor fft: 2-D complex to real transforms

pfa2rc Prime factor fft: 2-D real to complex transforms

Other Docs Search Page Known Problems


Signal Processing631 Developer’s Programming Guide

Signal Processing (Continued)


Subroutine Description
pfacc Prime factor fft: complex to complex transform, in place

pfacr Prime factor fft: complex to real transform

pfamcc Prime factor fft: multiple complex to complex transforms, in place

pfarc Prime factor fft: real to complex transform

Other Docs Search Page Known Problems


Plotting632 Developer’s Programming Guide

Plotting

Plotting
Subroutine Description

scaxis Computes a readable scale for use in plotting axes


pp1d Printer plot of a 1-dimensional array

pplot1 Printer plot of a 1-dimensional array

Other Docs Search Page Known Problems


Data Structures633 Developer’s Programming Guide

Data Structures

Data Structures
Subroutine Description

heapFree Frees a heap previously allocated by heapAlloc()


heapSetGrow Resets the heap length increment

heapIsEmpty Determines whether heap is empty

heapCount Determines # items in heap


heapInsert Inserts an item into the heap

heapRemove Removes the top item from the heap

heapDelete Removes the specified item from the heap

heapReSort Resorts a corrupted heap array to restore the heap condition

llAllocNode Allocates a new list node

llFreeNode Frees a list node

llInit Initializes a linked list

llEmpty Determines whether list contains any elements

llInsert Inserts data at beginning of list

llAppend Appends data to end of list

llDelete Removes data from beginning of list

llGet Retrieves data from beginning of list, without deleting

llNext Returns pointer to next node in a list

llFree Frees a linked list


queueAlloc Allocates a new (empty) queue

queueFree Frees a queue

queueEmpty Determines whether queue is empty

queueAdd Adds data to end of queue

queuePop Deletes data from queue

queueGet Retrieves data from queue, without deleting

queueCount Determines number of items in the queue

dequeAlloc Allocates a new (empty) deque

dequeFree Frees a deque

dequeEmpty Determines whether deque is empty

Other Docs Search Page Known Problems


Data Structures634 Developer’s Programming Guide

Data Structures (Continued)


Subroutine Description
dequeAdd Adds data to end of deque

dequePush Adds data to beginning of deque

dequePop Deletes data from deque

dequeGet Retrieves data from deque, without deleting


dequeCount Determines number of items in the deque

stackAlloc Allocates a new (empty) stack

stackFree Frees a stack


stackEmpty Determines whether stack is empty

stackPush Adds data to stack

stackPop Deletes data from stack

stackGet Retrieves data from stack, without deleting

stackCount Determines number of items in the stack

pqFree Frees a priority queue previously allocated by pqAlloc()

pqSetGrow Resets the priority queue length increment

pqIsEmpty Determines whether priority queue is empty

pqCount Determines # items in priority queue

pqInsert Inserts an item into the priority queue

pqRemove Removes the top item from the priority queue

bmalloc Allocates and returns a pointer to a big matrix

bmfree Frees a big matrix


bmread Reads a vector from a big matrix

bmwrite Writes a vector to a big matrix

rbtFree Free a red-black tree

rbtFind Finds data

rbtMin Finds smallest data

rbtMax Finds largest data

rbtAfter Finds data after specified data

rbtBefore Finds data before specified data

rbtInsert Inserts data into tree. If the same data already exists in tree, another copy
is inserted.

Other Docs Search Page Known Problems


Data Structures635 Developer’s Programming Guide

Data Structures (Continued)


Subroutine Description
rbtInsertUnique Inserts data into tree if it does NOT already exist in tree

rbtDelete Deletes data from tree

Other Docs Search Page Known Problems


Sorting and Searching636 Developer’s Programming Guide

Sorting and Searching

Sorting & Searching


Subroutine Description

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]

xindex Determines index of x with respect to an array of x values

Other Docs Search Page Known Problems


637 Developer’s Programming Guide

Appendix: FORTRAN Library


Summary

This appendix provides a series of tables which describe the


FORTRAN Library Subroutines. To see the complete
subroutine description, use the aman routine to display the man
page. For example, aman DB_AREACOUNT will display the man
page for DB_AREACOUNT. Each subroutine has a man page.
For more information on using the aman facility see the Man
Page Reference chapter.

Topics covered in this chapter:


➲ Area/Line(Survey)/Flow584
➲ Configuration589
➲ Database Orders589
➲ Domain Mapping592
➲ Miscellaneous 1593
➲ Trace I/O594
➲ Trace Executive596
➲ Trace Headers596
➲ Memory Management597
➲ Mute/Kill599
➲ Statics600
➲ Summing600
➲ Error Routines600
➲ Parameter Tables604
➲ Tables Obsolete608
➲ Parameter Interpolation608
➲ Parameter Lists610
➲ String Decoding613
➲ Miscellaneous 2614

Other Docs Search Page Known Problems


638 Developer’s Programming Guide

➲ Parameter Input618
➲ Packet Files619
➲ Character Routines621
➲ Seg-Y Disk622
➲ Geophysical Routines622
➲ Signal Processing627
➲ Disk I/O634
➲ SEG Vector Routines636
➲ Resource Reporting642
➲ UNIX Interface643

Other Docs Search Page Known Problems


Area/Line(Survey)/Flow639 Developer’s Programming Guide

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_CREATE_AREA Creates a new area in the ProMAX database

DB_DELETE_AREA Deletes an area in the ProMAX database


DB_MOVE_AREA Moves (renames) an area in the ProMAX database

DB_COPY_AREA Copies an area 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_CREATE_LINE Creates a new line in an area

DB_DELETE_LINE Deletes a line in an area

DB_COPY_LINE Copies a line in the ProMAX database

DB_MOVE_LINE Moves (renames) a line in the ProMAX database

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_FLOWLIST Returns a list of the (null-terminated) names of all of the flows of a


particular line in an area
DB_CREATE_FLOW Creates a new flow

DB_DELETE_FLOW Deletes a flow

DB_COPY_FLOW Copies a flow in the ProMAX database

DB_MOVE_FLOW Moves (renames) a flow in the ProMAX database

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

Other Docs Search Page Known Problems


Area/Line(Survey)/Flow640 Developer’s Programming Guide

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_DATALIST Returns a list of the (null-terminated) names of all of the datasets in a


particular line in an area.
DB_PARMLIST Returns a list of the (null-terminated) names of all of the parameter sets
(tables/lists) in a particular line in an area

DB_TBL_LIST Returns a list of the (null-terminated) names of all of the tables in a


particular line in an area

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_RE_FILE_LIST Returns a list of the (null-terminated) names of files in a particular line


whose names match a regular expression

DB_LIST_LIST Returns a list of the (null-terminated) names of all of the lists in a


particular line in an area

DB_DELETE_DATA Deletes a dataset in the ProMAX database

DB_INIT_DATA Initializes a dataset in the ProMAX database (stores the description and
nothing else)

DB_MOVE_DATA Moves (renames) a dataset in the ProMAX database

DB_COPY_DATA Copies a dataset in the ProMAX database


DB_DELETE_PARM Deletes a parameter set (table/list) in the ProMAX database

DB_INIT_PARM Initializes a parameter set (table/list) in the ProMAX database (stores the
description and nothing else)

DB_MOVE_PARM Moves (renames) a parameter set (table/list) in the ProMAX database

DB_COPY_PARM Copies a parameter set (table/list) in the ProMAX database

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

Other Docs Search Page Known Problems


Area/Line(Survey)/Flow641 Developer’s Programming Guide

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

DB_DATA_INFO Returns miscellaneous information for a particular dataset

DB_INIT_CHECK Checks to see if an area/survey has been initialized

Other Docs Search Page Known Problems


Configuration642 Developer’s Programming Guide

Configuration

Configuration
Subroutine Description

CONFIG_GET_INT Returns a user-defined integer entry from the configuration file


CONFIG_GET_FLOAT Returns a user-defined floating point entry from the configuration file

CONFIG_GET_STR Returns a user-defined character string entry from the configuration file

CONFIG_INFO Returns information from the configuration file


CONFIG_DEV_COUNT Returns the number of devices for a particular device type

CONFIG_DEV_LIST Returns a list of devices for a particular device type

Other Docs Search Page Known Problems


Database Orders643 Developer’s Programming Guide

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_ORDCRE Creates a new ordered parameter file

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_ORDPARM Returns info for every parameter in an 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_ORDCLOSE Closes an ordered parameter file

DB_ORDUNLK Unlocks an ordered parameter file

DB_PARMCRE Creates a NEW parameter in an existing ordered parameter file

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_PARMDEL Deletes a parameter from an existing ordered parameter file

DB_INFOLIST Returns a list of NAMEs, descriptions, and dates for a unique INFOTYP

DB_INFOTYPS Returns a list of unique INFOTYPs

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.

Other Docs Search Page Known Problems


Database Orders644 Developer’s Programming Guide

Database Orders (Continued)


Subroutine Description
DB_BUFFRDGET Outputs parameter values from the database in a buffered fashion. Values
are output 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.

Other Docs Search Page Known Problems


Domain Mapping645 Developer’s Programming Guide

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.

Other Docs Search Page Known Problems


Miscellaneous 1646 Developer’s Programming Guide

Miscellaneous 1

Miscellaneous 1
Subroutine Description

DB_FILNAME Builds a database literal filename


DB_GLOBAL_GETPATH Gets the contents of cdbpathz out of the global common

DB_MISC_FNAME Builds a database filename for a miscellaneous file

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

DB_CHOOSE_DATA Prompts the user to select a dataset in an area and line

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)

Other Docs Search Page Known Problems


Trace I/O647 Developer’s Programming Guide

Trace I/O

Trace I/O
Subroutine Description

DISKIO_GET_TR Reads a trace and trace header from a dataset


DISKIO_GET_HDR Reads a trace header (only) from a dataset

DISKIO_PUT_HDR Writes a trace header (only) to a dataset

DISKIO_CLOSE Closes all of the files associated with a dataset


DISKIO_OPEN Opens all of the files associated with an existing dataset. Files are opened
FOR READING ONLY.

DISKIO_CREATE Creates a new ProMAX dataset

DISKIO_GET_NDFILES Gets the maximum number of directories used to store a dataset

DISKIO_DESC_GET Returns the description stored within a dataset index file

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

Other Docs Search Page Known Problems


Trace Executive648 Developer’s Programming Guide

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

Other Docs Search Page Known Problems


Trace Headers649 Developer’s Programming Guide

Trace Headers

Trace Headers
Subroutine Description

HDR_ADD Adds a new entry to the trace header


U_HDR_DELETE Removes a trace header entry from the current list of header entries

HDR_DELETE_UPDATE Corrects a trace header after a header entry is removed from the current
list of header entries (via HDR_DELETE)

HDR_NAMINFO Returns information for an existing trace header entry name


HDR_INDINFO Returns information for an existing trace header index number

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.

IS_STD_HDR_NAME Checks to see if a header is one of the standard headers or not

EX_GET_INTKEY Converts any trace header key value into an integer

EX_GET_REALKEY Load up a trace header key value into an real*4 value

EX_GET_DBLEKEY Load up a trace header key value into an real*8 value

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

Other Docs Search Page Known Problems


Memory Management650 Developer’s Programming Guide

Memory Management

Memory Management
Subroutine Description

BV_FREE Frees a Big Vector


BV_PUT Puts values into a Big Vector

BV_GET Gets values from a Big Vector

BV_SORT Sorts the values in a Big Vector


BV_REORDER Reorders the values in a Big Vector, based on a sort that was done
previously using bvSort or BV_SORT

MEM_RESBUFF Reserves a buffer of memory in the SPACE work array—the equivalenced


arrays ISPACEz (INTEGER) and RSPACEz (REAL). These arrays are
accessed via a common block. This is used on a 32-bit O/S.

MEMORY_RESBUFF Reserves a buffer of memory in the SPACE work array—the equivalenced


arrays ISPACEz (INTEGER) and RSPACEz (REAL). These arrays are
accessed via a common block. This is used on a 32-bit or 64-bit O/S.

MEM_FREEBUFF Frees a previously reserved buffer of memory in the SPACE array on a


32-bit O/S

MEMORY_FREEBUFF Frees a previously reserverd buffer of memory in the SPACE array on a


32-bit or 64-bit O/S

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_GROWBUFF Checks to see if a buffer is out of space (MEMNEED=MEMSIZE). If it


is, it reserves a new buffer of double size, moves the data to the new
buffer, and frees the old buffer. Ths is used on a 32-bit O/S

MEMORY_GROWBUFF Checks to see if a buffer is out of space (MEMNEED=MEMSIZE). If it


is, it reserves a new buffer of double size, moves the data to the new
buffer, and frees the old buffer. This is used 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.

Other Docs Search Page Known Problems


Mute/Kill651 Developer’s Programming Guide

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).

Other Docs Search Page Known Problems


Statics652 Developer’s Programming Guide

Statics

Statics
Subroutine Description

STAT_SHIFT Applies a static shift of STATIC milliseconds to TRACE using the


appropriate 8-point sinc function and a fast convolution routine
FRAC_STAT_APPLY Utility subroutine used to apply any remaining fractional static (header
word INA_STATz) to a group of traces

Other Docs Search Page Known Problems


Summing653 Developer’s Programming Guide

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.

HRZ_SMOOTH Smooths horizon values with a triangular smoother, starting at


X_HRZ(ICDP12(1)) and ending at X_HRZ(ICDP12(2)).

Other Docs Search Page Known Problems


Error Routines654 Developer’s Programming Guide

Error Routines

Error Routines
Subroutine Description

REPORT_PROMAX_ERR Reports all types of ProMAX errors (writes to stdout)


U_ERR_STOP 1) Selects the appropriate destination for output messages. 2) Displays the
input message. 3) Stops the process, returning control to the parent
process.

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_POPWARN Displays a warning message via a pop-up window (similar to


U_ERR_HELP). This routine is intended for use by tools that are not
linked into the executive (otherwise use EX_ERR_POPWARN).

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

U_ERR_SUPPRESS_WAR Routine to allow suppression of system-level warnings


N

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_POPWARN Displays a warning message via a pop-up window (similar to


EX_ERR_HELP). This routine is intended for use by tools that are linked
into the executive (otherwise use U_ERR_POPWARN).

Other Docs Search Page Known Problems


Error Routines655 Developer’s Programming Guide

Error Routines (Continued)


Subroutine Description
EX_ERR_WARN 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 warning message. 4) Returns control to the routine that called it.

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.

Other Docs Search Page Known Problems


Parameter Tables656 Developer’s Programming Guide

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_ALLOCATE Allocates and initializes a new parameter table for z(x,y)

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_SET_EXTRAP Sets x and y extrapolation methods

TBL_RESOLVE_X1_X2 Given an X (ensemble number), returns the spatial coordinates that are
used within the table functions

TBL_ADD_XY Adds z value(s) at specified (x,y) point

TBL_ADD_XYS Adds z value(s) for an array of y coordinates and constant x

TBL_GET_X Gets X location from a table

TBL_GET_XYS Gets X-Y-Z group from a table

TBL_DELETE_XY Deletes z value(s) at specified (x,y) point

TBL_DELETE_X Deletes all z value(s) at specified x coordinate


TBL_COPY Copies all groups from tbl2 to tbl1. tbl1 does not have to be empty.

TBL_CLEAR Clears all entries in a table

TBL_INTERP_XY Interpolates z(x,y) value(s) at specified (x,y) points

TBL_INTERP_XY_U Interpolates a vector of z(x,y) values, uniformly sampled in y for constant


x

TBL_FROM_VEL_PAR Loads a parameter table from a location:times-vels type of parameter


strings

TBL_X_MIN Gets minimum X value for table

TBL_X_MAX Gets maximum X value for table

TBL_MIN_MAX Gets several maximum and minimum values for table

TBL_X1_MIN Gets minimum X1 value for table

Other Docs Search Page Known Problems


Parameter Tables657 Developer’s Programming Guide

Parameter Tables (Continued)


Subroutine Description
TBL_X1_MAX Gets maximum X value for table

TBL_X2_MIN Gets minimum X2 value for table

TBL_X2_MAX Gets maximum X2 value for table

TBL_Y_MIN Gets minimum Y value for table


TBL_Y_MAX Gets maximum Y value for table

TBL_Z_MIN Gets minimum Z value for table

TBL_Z_MAX Gets maximum Z value for table


TBL_COUNT_X Gets number of locations in table

TBL_COUNT_MAX_Y Gets maximum number of samples per node in a table

TBL_COUNT_Z Gets number of z values per sample in a table

TBL_DESC Gets table description

TBL_TO_DATABASE Puts a parameter table to database

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.

TBL_SET_YZ Adds z value(s) for y coordinates and constant (x1,x2) coordinate

TBL_DELETE_YZ Adds z value(s) for y coordinates and constant (x1,x2) coordinate

TBL_DELETE_POS_ Deletes all z value(s) at specified (x1, x2) coordinates

TBL_INTERP_Z Interpolates a vector of z( (x1,x2) ,y) values, uniformly sampled in y for


constant x

TBL_INDEX_X Gets node coordinates by index from table


TBL_GET_YZ Gets sample coordinates and values from an existing node in table

EX_TBL_BUILD Sets the primary and secondary header key values (normally used for
table interpolation)

Other Docs Search Page Known Problems


Tables Obsolete658 Developer’s Programming Guide

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/’

Other Docs Search Page Known Problems


Parameter Interpolation659 Developer’s Programming Guide

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.

Source file: /usr/src/lib/table/int.f

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)

Other Docs Search Page Known Problems


Parameter Lists660 Developer’s Programming Guide

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_INFO Provides basic information from a list’s header

LIST_DESC_REPLACE Replaces the description of a list


LIST_FREE Frees up all parameter list memory

LIST_ADD Adds parameter starting value, ending value, and value increment entries
to the parameter list

LIST_DELETE Deletes certain cases of entries VALS(NUM_LEVELS) from a LIST.


Returns IERR = 0 if the LIST entry deletion is successful. Returns IERR
= 1 if the value set is not found in the LIST. Returns IERR = 2 if a
continuous bottom level value set is encountered. For example, it can
delete (1:3) from ‘1:1-5(2)’ but cannot delete (1:3) from ‘1:1-5’. For
cases where VAL1.NE.VAL2, VAL_INC cannot = 0.0 (continuous range
case). Returns IERR = 3 if any value set at a higher level is not single-
valued. For example, it can delete (1:3) from ‘1:1-5(2)’ but cannot delete
(1:3) from ‘1-2:1-5(2)’.

LIST_END Compresses the parameter list, eliminating unused memory

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_DECODE Decodes an ASCII string and creates a parameter list in memory.


LIST_INIT must have been previously called, and LIST_END should be
called after the last call to LIST_DECODE. This routine calls
LIST_ADD.

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

Other Docs Search Page Known Problems


Parameter Lists661 Developer’s Programming Guide

Parameter Lists (Continued)


Subroutine Description
LIST_GL_GRAB Grabs raw values previously entered into a parameter list

LIST_BUILD Decodes a character string and creates a LIST

Other Docs Search Page Known Problems


String Decoding662 Developer’s Programming Guide

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 ‘ ,()./ -*’

HDR_LIST_DECODE Decodes a list of header keys; for example, ‘CDP,OFFSET/’ decodes to


CKEY_NAME(1) = ‘CDP’ and CKEY_NAME(2) = ‘OFFSET’.

Other Docs Search Page Known Problems


Miscellaneous 2663 Developer’s Programming Guide

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

CONVEX_TO_IEEE Converts an array of CONVEX 32 bit floating point numbers to IEEE 32


bit floating point numbers

IEEE_TO_CONVEX Converts an array of IEEE 32 bit floating point numbers to CONVEX 32


bit floating point numbers

CONVEX64_TO_IEEE Converts an array of CONVEX 64 bit floating point numbers to IEEE 32


bit floating point numbers

IEEE_TO_CONVEX64 Converts an array of IEEE 32 bit floating point numbers to CONVEX 64


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)

HEAPSORT2_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). Differs from HEAPSORT in that it
makes the corresponding rearrangement of IB.

IMEDIAN Finds the median of an array of integers

ISWAP Swaps two integer values. On output, I1=I2 and I2=I1.

U_DOUBLE2INT Loads a DOUBLE that is stored in an array (such as a trace header) into a
single INTEGER

U_DOUBLELOAD

U_DOUBLE2REAL

Other Docs Search Page Known Problems


Miscellaneous 2664 Developer’s Programming Guide

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)

QUAD_INTERP Performs a quadratic interpolation on 3 points. The X coordinates of the 3


points are assumed to be -1.0, 0.0, and 1.0, respectively.

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

Other Docs Search Page Known Problems


Parameter Input665 Developer’s Programming Guide

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_PARMINFO_GRP Returns information for an input parameter in Jth occurrence of a group


in the current tool’s parameter packet
EX_GETPARM Returns values for an input parameter in the current tool’s parameter
packet

EX_CGETPARM Returns values for a character input parameter in the current tool’s
parameter packet

U_GETPARM Returns values for an input parameter. Equivalent in functionality to


EX_GETPARM, except that it is intended for use by stand-alone
programs.

U_CGETPARM Returns values for a character input parameter. Equivalent in functionality


to EX_CGETPARM, except that it is intended for use by stand-alone
programs.

EX_GETPARM_GRP Returns values for an input parameter in Jth occurence of a group in the
current tool’s parameter packet

EX_GRP_OCCUR Returns the number of occurrences of a group of parameters

EX_PARM_OCCUR Returns the number of occurrences of an input parameter in the current


tool’s input parameter packet

EX_PARM_OCCUR_GRP Returns the number of occurrences of an input parameter in Jth occurence


of a group in the current tool’s parameter packet

Other Docs Search Page Known Problems


Packet Files666 Developer’s Programming Guide

Packet Files

Packet Files
Subroutine Description

PKT_ENDSWAP Determines if a packet file was written on a machine with a different


endian type
PKT_HANDLE Gets the actual file handle associated with a packet

PKT_INIT Initializes a packet for output of a particular tool’s parameters

PKT_GROUPINIT Initializes a group within a packet


PKT_OUTPARM Outputs a parameter (or parameter list) within the current group

PKT_FILCLOSE Closes the current packet file

PKT_FILOPEN Opens a new or existing packet file

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_GET_PARM Returns a buffer of values for an input parameter

PKT_OPEN_LOAD Opens an existing packet file and loads the packet for a specified tool

PKT_COPY Copies an input parameter packet from one file to another


PKT_SETID Sets the packet id to enable later calls to the parmsubs.f subroutines

PKT_GETID Gets the current packet id

Other Docs Search Page Known Problems


Character Routines667 Developer’s Programming Guide

Character Routines

Character Routines
Subroutine Description

PROMAX_SEGY_OPEN Opens the files for a ProMAX SEGY-like dataset


PROMAX_SEGY_CLOSE Closes the files for a ProMAX SEGY-like dataset

PROMAX_SEGY_INIT Initializes the header file for a ProMAX SEGY-like dataset

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

Other Docs Search Page Known Problems


Seg-Y Disk668 Developer’s Programming Guide

Seg-Y Disk

Seg-Y Disk
Subroutine Description

PROMAX_SEGY_OPEN Opens the files for a ProMAX SEGY-like dataset


PROMAX_SEGY_CLOSE Closes the files for a ProMAX SEGY-like dataset

PROMAX_SEGY_INIT Initializes the header file for a ProMAX SEGY-like dataset

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

Other Docs Search Page Known Problems


Geophysical Routines669 Developer’s Programming Guide

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

MEDIAN_SMOOTH Computes a median smoothed version of VALS_IN and returns it in


VALS_OUT. The output sample at NSMOOTH/2+1 is the median of the
first NSMOOTH samples, and the operator then slides down the trace.
The first/last NSMOOTH/2 output samples use a growing/shrinking
median smoother operator length. The first output sample is the same as
the first input sample, the second output sample is the median of the first
three input samples, the third output sample is the median of the first five
input samples (if NSMOOTH.GE.5), etc.

RAGC_TRACE Performs an Automatic Gain Control amplitude adjustment. The


algorithm used involves integrating the sample amplitude values as a
quick method for determining the average amplitude within any window
of samples.
SUM_AMP must be 2*NUMSMP long.

AGC_TRACE Performs an Automatic Gain Control amplitude adjustment. The


algorithm used involves integrating the sample amplitude values as a
quick method for determining the average amplitude within any window
of samples.
SUM_AMP must be 2*NUMSMP long!!!

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.

INT_MIX_VEC Interpolates a vector of z(x,y) values, uniformly sampled in y for constant


x, but averaged in the X direction. The purpose of this subroutine is to
smooth the velocities for migrations.
OPERDECON Computes a least squares Wiener-Levinson deconvolution operator for 4
cases: 1) Minimum Phase Spiking, 2) Minimum Phase Spiking (phase
correction only), 3) Zero Phase Spiking (amplitude correction only), 4)
Minimum Phase Predictive

MEMCOF Computes coefficients for a power spectra by maximum entropy method

DECON_WORK_TIME Generates and applies a deconvolution operator to a trace. Spiking or


predictive minimum phase options. Works in the time domain.

NMO_APPLY Applies NMO to a trace

NMO_UNAPPLY Inverses (unapplies) a trace’s previously applied NMO

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

Other Docs Search Page Known Problems


Geophysical Routines670 Developer’s Programming Guide

Geophysical Routines (Continued)


Subroutine Description
SPLIN2 Inputs data X,Y pairs in XARR and YARR and the second derivatives in
Y2ARR, and outputs a Y value (ANS) for X

SPLINE1 Inputs X,Y pairs unequally sampled in X, computes the second


derivatives of the interpolation function, and stores them in Y2ARR for
future spline evaluation. This spline assumes the second derivative is zero
at the ends instead of suppling first derivate at each end as boundary
conditions.

SYNTRC General purpose synthetic trace generator

TRGEN Generates a synthetic trace (TRACE) by interpolating into TRACE a


wavelet WAV of amplitude RCF at each time TIM
CONV_JC Performs time domain convolution

QUAD Computes a quadrature filter (90 degree phase shifter)

PHASOR Generates a constant phase shift operator

LOWPASS Generates an Ormsby low pass filter where F1 is the left corner frequency
and F2 is the right stop frequency.

ORMSBAND Generates an Ormsby bandpass filter (wavelet)

POLDIV Divides polynomial ANUM by polynomial DENOM, placing the


resulting quotient into QUO and the remainder into R.

GEOPH Computes a theoretical geophone response for impulses in 1)


Displacement 2) Velocity 3) acceleration. See Seismic Instrumentation by
Maurice Pieuchot, Geophysical Press, vol 2.

RICKER Generates a Ricker wavelet with highest spectral content at frequency


PKFREQ

GET_RICKER_LEN Generates a Ricker wavelet LENGTH for peak frequency PKFREQ,


sample rate. SII in milliseconds, and cutoff amplitude CR.
BUTTERLP Generates Butterworth low pass symmetrical filters

KLAUDER Generates an autocorrelated vibroseis wavelet for a linear sweep

WAVTAPER Tapers a symmetrical wavelet about the (NWAV - 1) / 2 + 1 sample

CMPLX_FILTER_WORK Performs frequency domain convolution of FILTER and CTRACE

FGEN Generates a bandpass filter (optional notch) by editing an all-pass


initialized transform. All frequencies are HZ.

FGEN_BW Generates a Butterworth bandpass filter (optional notch) by editing an all-


pass initialized transform. All frequencies are HZ.

TD_FILTER Applies a time-domain filter to an input trace

FD_FILTER Applies a time-domain filter to an input trace

FILTER_WORK Performs frequency domain convolution of FILTER and CTRACE

Other Docs Search Page Known Problems


Signal Processing671 Developer’s Programming Guide

Signal Processing

Signal Processing
Subroutine Description

CRFFT Complex to real FFT


F_AUTO_COR Performs autocorrelation in the frequency domain

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

PHASEFILTER Applies a constant phase angle shift (PHASEADD) to all frequencies in


TRACE

RCFFT Real to complex FFT

EUREKA Routine to generate a WIENER filter from the autocorrelation and right
hand vector

RMEDIAN Finds the median sample amplitude and returns its address

HILBRT_FILT Applies a time-domain HILBERT filter to an input trace. Faster than


TD_FILTER, since even filter samples are zeroes

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.

Other Docs Search Page Known Problems


Signal Processing672 Developer’s Programming Guide

Signal Processing (Continued)


Subroutine Description
PICK_CORR Picks the maximum correlation coefficient amplitude and time, or the
maximum magnitude correlation coefficient amplitude and time if
IREV_TEST=1. The time is relative to the center of the input correlation
function (CORREL), which SHOULD have an ODD number of samples.
The amplitude and time are parabolically interpolated from the three
nearest samples. If no positive peak is found and IREV_TEST is not set
to 1, values of 0.0 are returned for T_PICK and QUALITY. If
IREV_PICK = 1, the value of QUALITY may be negative. The value of
the time, T_PICK, is in REAL*4 sample shifts relative to the center of
CORREL (whether NS is EVEN or ODD).

RANDOM_VALS This subroutine creates an array of NUM_VALS output values with


random values from VAL_MIN to VAL_MAX. ISEED is the seed value
for the random number generator and is changed on output. It should be
initialized to a large negative INTEGER*4. The random output values are
passed back in the VALS array.

FILT_SPIKE

MEAMGVZ Vector average (NON_ZERO SAMPLES) element magnitude routine


RMSQVZ

DECON_APPLY Computes and applies a least squares Wiener-Levinson decon operator


for 4 cases 1) Minimum Phase Spiking, 2) Minimum Phase Spiking
(phase correction only), 3) Zero Phase Spiking, 4) Minimum Phase
Predictive

FILT_2D_HORZ Horizontal filter (across traces), employing either a median or an alpha-


trimmed mean algorithm

FILT_2D_W_HORZ Horizontal filter (across traces), employing either a WEIGHTED median


or a WEIGHTED alpha-trimmed mean algorithm

FILT_2D_C_HORZ Horizontal filter (across traces), employing a simple correlation filter


(weighted trace mix) algorithm
FILT_2D Relatively fast 2-D spatial filter, using either a median or an
alpha-trimmed mean algorithm

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.

WAT_MEAN Finds the alpha trimmed WEIGHTED mean of a group of values.

Caution: The input arrays are DESTROYED by this routine!

Other Docs Search Page Known Problems


Signal Processing673 Developer’s Programming Guide

Signal Processing (Continued)


Subroutine Description
MED_TRACE_AMP

GATE_AMP_EST This subroutine computes a representave amplitude for a trace between


samples NS1 & NS2. It subdivides the gate into NGATES sub-gates,
computes the average trace amplitude in each sub-gate, then returns
A_PICK as the median of the average gate amplitudes for gates
containing live samples. The value of A_PICK is also tested to protect
from NaN, Infinity or other such invalid numbers. If detected, a value of
0.0 is returned for A_PICK.

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.

DC_FILTER Removes the DC component of an input array of values by computing the


average sample value and subtracting it from the original input array

WINDOW Builds and returns a windowing funtion

Other Docs Search Page Known Problems


Disk I/O674 Developer’s Programming Guide

Disk I/O

Disk I/O
Subroutine Description

FILE_OPEN Routine to open a file


FILE_CLOSE Routine to close a file

FILE_READ Routine to read data from a file

FILE_WRITE Routine to write data to a file


FILE_SEEK Routine to seek in a file

FILE_CHECK Routine to check to see if a file exists

TIO_OPEN Opens a file for buffered typed I/O (uses fopen())

TIO_OPENU Opens a file for unbuffered typed I/O (uses open())

TIO_CLOSE Routine to close a file that was opened by TIO_OPEN

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.

CHAR_WRITE Reads/writes buffers by type. Conversions (such as byte swapping or


Cray->IEEE) are done on the fly.

TIO_SYNC Performs sync on a file (flushes buffers to disk)

TIO_SET_LOCK Locks a file (denying access to other processes)

TIO_CHECK_LOCK Checks to see if a file is locked by another process


TIO_FCNTL Does I/O control on an open file

Other Docs Search Page Known Problems


SEG Vector Routines675 Developer’s Programming Guide

SEG Vector Routines

SEG Vector Routines


Subroutine Description

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

Other Docs Search Page Known Problems


SEG Vector Routines676 Developer’s Programming Guide

SEG Vector Routines (Continued)


Subroutine Description
CVFILL

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

Other Docs Search Page Known Problems


SEG Vector Routines677 Developer’s Programming Guide

SEG Vector Routines (Continued)


Subroutine Description
MVEMG

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

Other Docs Search Page Known Problems


SEG Vector Routines678 Developer’s Programming Guide

SEG Vector Routines (Continued)


Subroutine Description
VAVLIN

VCLIP

VCLR

VCMERG
VCMPRS

VCOS

VDBCON
VDIV

VDIVZ

VERROR

VEXP

VEXP10

VFILL

VFILL8 Double-precision vector fill routine

VFLOAT

VFLOT2

VFRAC

VGATHR

VGEN

VGENP
VICLIP

VINDEX

VINT

VINT2

VINTB

VLINT

VLMERG

VLOG

VLOG10

VLOGZ

Other Docs Search Page Known Problems


SEG Vector Routines679 Developer’s Programming Guide

SEG Vector Routines (Continued)


Subroutine Description
VMA

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

Other Docs Search Page Known Problems


SEG Vector Routines680 Developer’s Programming Guide

SEG Vector Routines (Continued)


Subroutine Description
VSIMPS

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))

VIRAMP INTEGER Vector ramp-building routine

Other Docs Search Page Known Problems


Resource Reporting681 Developer’s Programming Guide

Resource Reporting

Resource Reporting
Subroutine Description

U_STATMEM_RESERVE Reserves static memory. Static memory is defined in this context as


memory that is reserved and not released until completion of the job.
U_DYNMEM_RESERVE Reserves dynamic memory. Dynamic memory is defined in this context
as memory that is reserved for traces within a flow, and is freed as soon as
the traces are passed on (this is allowed to occur many times). In a normal
flow, it is assumed that only two dynamic buffers exist at any one time:
one filling while one is flushing.

U_RESERVE Reserves resources (such as memory and tape drives) for later utilization

Other Docs Search Page Known Problems


UNIX Interface682 Developer’s Programming Guide

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

DISK_SPACE_ADDL Returns the number of Kbytes of space available on a disk partition


SPAWN

ALT_SHELL

C_RWNFLAG Returns the octal open flag for read/write, new

C_RONFLAG Returns the octal open flag for read-only, new

C_WONFLAG Returns the octal open flag for write-only, new

C_RWOFLAG Returns the octal open flag for read/write, old

C_ROOFLAG Returns the octal open flag for read-only, old

C_WOOFLAG Returns the octal open flag for write-only, old

C_RWRRMODE Returns the octal protection mode equivalent to “-rw-r--r--”

C_RWXMODE Returns the octal protection mode equivalent to “drwxrwxrwx”. The


umask value will modify this at the user’s discretion.

C_RWXNMODE Returns the octal protection mode equivalent to “rwx------”

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

C_TMPNAM Returns a temporary (scratch) file name

SHELL_COMMAND Issues a command to the shell. Errors are treated as fatal.

SHELL_COMM_STAT Issues a command to the shell. The status and error flag are returned.

C_SYSTYPE Returns the system type (big or little endian)

CHTIME Returns the current system time as a character string

Other Docs Search Page Known Problems


UNIX Interface683 Developer’s Programming Guide

UNIX Interface (Continued)


Subroutine Description
CHDATE Returns the current system date as a character string

UNIX_COM Issues a UNIX command and returns the message that would normally be
displayed on the screen

Other Docs Search Page Known Problems


UNIX Interface684 Developer’s Programming Guide

Other Docs Search Page Known Problems


Index685 Developer’s Programming Guide

Index

Symbols coding standards


➲ C
$PROMAX_HOME ➲ FORTRAN
.inc file ➲ overview
.promax common blocks
_mem communication
➲ inter-process
A ➲ trace headers
comp_opf.c
aliases comp_opf.menu
alloc complex tools
Alternate Executive ➲ examples
aman ➲ options
amp_ratio (IPC FORTRAN example) configuration
amp_ratio menu code (IPC example) ➲ C subroutines
amp_ratio.f ➲ FORTRAN subroutines
amp_ratio.inc control functions (C)
amp_ratio.menu converting to new system
ampRatio (IPC C example) cpromax.h
ampRatio.c ctopdir
area, line, flow customizing the system
➲ FORTRAN subroutines
areas
atopdir D
AVO ensemble tools data structures (C)
avo.f database
avo.inc ➲ C subroutines
avo.menu ➲ OPF examples
avoC.c ➲ orders (FORTRAN subroutines)
➲ overview
C db_disp.f
dbx
C environment debugging
C library summary defun
C programming examples Delaunay triangles
C structure names deque
canned command sequence (CCS) directory
cglobal.h (global include file example) ➲ hierarchy
cglobal.h (include file example) ➲ Landmark version
character routines (FORTRAN) ➲ machine-dependent
cleanup condition ➲ Makefile options

Other Docs Search Page Known Problems


Index686 Developer’s Programming Guide

➲ Makefile rules flow builder


➲ Master version flow execution
➲ naming conventions flows
➲ product-dependent FORTRAN
➲ third-party software ➲ coding standards
➲ User version ➲ library summary
directory structure ➲ subroutines
➲ development files FrameMaker
➲ expanded ➲ autosave files
disk I/O (FORTRAN) ➲ backup files
disk iteration examples ➲ creating new file in
disk_iter.c ➲ editing a file in
disk_iter.menu ➲ lock status
domain mapping (FORTRAN) ➲ recover files
double buffer tools ➲ starting
➲ examples ➲ working with files in
function, of ProMAX
E
ealloc
G
ens_define.f geophysical routines (FORTRAN)
ens_define.inc global include file examples
ens_define.menu global parameters
ensemble definition programs global parameters, overview
ensemble tools global variables, overview
➲ examples global.inc
environmental variable gmake
error routines GNU make
➲ C subroutines
➲ FORTRAN subroutines H
EXAMPLE.menu (Lisp)
exec subroutine header entries
Executive headers, overview
➲ execution routine heap
➲ functions helpfiles
➲ initialization routine ➲ common error messages
➲ tools ➲ customizing the User Interface
expanded directory structure ➲ example
➲ FrameMaker-formatted
➲ hypertext
F ➲ interactive display
features, ProMAX System ➲ organization
files ➲ parameters
➲ changing, inline tool ➲ references
➲ changing, overview ➲ theory section
➲ changing, stand-alone or IPC tool ➲ usage section

Other Docs Search Page Known Problems


Index687 Developer’s Programming Guide

hypertext make system


Makeadvance
I ➲ User setup
Makeexec
include files ➲ steps
➲ examples Makefile
index values ➲ conventions
➲ trace headers ➲ directory
init subroutine ➲ header files
➲ functions ➲ options
inline tools, files to change ➲ rules
input tools ➲ techniques
➲ examples ➲ template instantiation
➲ overview ➲ terms
interp_db.c ➲ variable prefixes
interp_db.menu ➲ variables
interp_sb.c Makefile_poststack
interp_sb.menu Makefile_prestack
interpolation routines (C) man pages
inter-process communication math functions (C)
➲ trace headers matrix functions (C)
IPC memory management
➲ menu code ➲ _mem
IPC C code ➲ alloc
IPC FORTRAN code ➲ C
IPC tools ➲ C subroutines
➲ C subroutines ➲ deque
➲ examples ➲ ealloc
➲ files to change ➲ FORTRAN
ISPACEz ➲ FORTRAN subroutines
iteration tools ➲ heap
➲ linked lists
L ➲ multi-dimensional arrays
➲ overview
libraries ➲ priority queues
library summary ➲ promax
➲ C ➲ queues
➲ FORTRAN ➲ reallocation
lines ➲ routine names
linked lists ➲ RSPACEz and ISPACEz
linking C and Fortran ➲ stack
Lisp menus
➲ example ➲ adding
➲ creating
M ➲ files
machine-dependent directories multi-dimensional arrays

Other Docs Search Page Known Problems


Index688 Developer’s Programming Guide

mute/kill (FORTRAN subroutines) poststack.f


prefixes, Makefile variable
N prest_interp.c
pre-stack interpolation programs
non-portable scripts prestack.f
prestack.menu
O prestk_interp.f
prestk_interp.inc
OPF, ordered parameter files prestk_interp.menu
➲ examples priority queues
➲ for inter-tool communication Processes file
➲ overview processing pipeline
overview of ProMAX system promax memory management routines
PVM (C)
P
packet files (C) Q
packet files (FORTRAN) queues
panel tools
➲ examples
panel_test.f R
panel_test.inc reallocation, memory
panel_test.menu recompilation
panelTest.c re-entrancy
parameter input (C) regular expression
parameter input (FORTRAN) resource reporting (FORTRAN)
parameter interpolation (C) RSPACEz
parameter interpolation (FORTRAN)
parameter list (C)
parameter list (FORTRAN)
S
parameter tables sc_amp.f
➲ Delaunay triangles sc_amp.inc
➲ extrapolation sc_amp.menu
➲ interpolation scripts
➲ overview ➲ non-portable
➲ rules ➲ portable
➲ structure SEG vector routines (FORTRAN)
➲ subroutine categories Seg-Y disk (FORTRAN)
➲ x values semblance.f
parameter tables (C) semblance.inc
parameter tables (FORTRAN) semblance.menu
parms structure setup
➲ in re-entrancy ➲ Solaris
plotting (C) ➲ System Administrator
portable code, rules for ➲ User
portable scripts signal processing (C)
poststack.c signal processing (FORTRAN)

Other Docs Search Page Known Problems


Index689 Developer’s Programming Guide

simple processes, example ➲ complex, options


simple tool ➲ double buffer
simple tools ➲ double buffer examples
➲ examples ➲ ensemble
simple.c ➲ ensemble, examples
simple.menu ➲ executive
sine_wave.f ➲ files to change
sine_wave.inc ➲ input
sine_wave.menu ➲ input, examples
sineWave.c ➲ IPC
single buffer tools ➲ IPC, examples
➲ examples ➲ iteration
Socket Tools ➲ panel
socket tools-see IPC tools ➲ panel, examples
Solaris setup ➲ simple
sorting/searching (C) ➲ simple, examples
stack ➲ single buffer
stand-alone tools ➲ single buffer, examples
➲ examples ➲ stand-alone
➲ files to change ➲ stand-alone, examples
➲ overview ➲ types
standard orders trace executive (FORTRAN)
➲ list Trace Headers
statics (FORTRAN) trace headers
string decoding (FORTRAN) ➲ alphabetical list
summing (FORTRAN) ➲ C subroutines
Super Executive ➲ FORTRAN subroutines
system ➲ geometry-related
➲ architecture ➲ index values
➲ converting to new ➲ input-related
➲ customizing ➲ mute-related
➲ overview ➲ special applications-related
System Administrator setup ➲ special geometry-related
system overview, illustration ➲ standard
➲ statics-related
T ➲ system-related
➲ usage
tables obsolete (FORTRAN) trace I/O (FORTRAN)
third-party software trace interpolation examples
toggling products, .promax trace muting (C)
tool anatomy transform.c
tools transform.f
➲ adding transform.inc
➲ communication between transform.menu
➲ complex
➲ complex, examples

Other Docs Search Page Known Problems


Index690 Developer’s Programming Guide

U
UNIX interface (C)
UNIX interface (FORTRAN)
User Interface
User setup
utopdir

V
variables, Makefile
vector routines (C)
vel_io.f
velocity (C)

Other Docs Search Page Known Problems

Potrebbero piacerti anche