Programming Principles

Module coding style has changed significantly since conversion to C++ in version 4.5.  The reliance on naming conventions has reduced and remains as a legacy in some older parts of the system.  Over time, the need for naming conventions will go away; however, for backward compatibility of the code, old names will still be available in the form of macros.

Components of a Seismic Processing Module

All components of the module are accessed by the monitoring program by the name of the module, and thus the naming convention is very essential. Every module is located in the folder bearing its name. Let us assume that the module we are describing is named ourmod (the names are currently limited to 7 characters, due to the standard tab stops at 8 characters). This module will be located in the folder $SIAHOME/modules/ourmod, where SIAHOME is the environment variable pointing to home directory of the system.

The three important files in located in this directory and constituting the module for the system will be then: 

The parameter definition file is translated once during the development of the module using the program pdf, located in the directory indicated by the environment variable SIABIN. This program reformats the file into a binary form, and puts the result into the folder $SIALIB/PRM. Also, the program pdf generates a makefile, named simply m, which is used afterwards to compile all of the module's codes. The command for this compilation is:

make -f m

At present, program pdf allows the following switches:

Naming Conventions

In programming the monitoring program and modules, I to use self-explanatory names of the subroutines and global variables. This helps to reduce the chance of naming collisions during the inclusion of new modules in the system. Also, practically all public functions provided by the libraries have prefixes related to their origin. General-purpose monitor functions begin with SIA_, functions used only during the Edit phase have the prefix PDF_, mathematical functions often begin with MATH_, the functions from the special trace manipulation library—with TRACE_, etc. A full list of the functions can be found in the following sections. 

In all modules, a similar naming convention is recommended. Typically, all classes defined within a particular module should have the module's name as a prefix of the class name. If a function is designed for the use with a particular module, please also use the upper-case name of the module as a prefix. Thus, for our module ourmod, most of its work would be performed by class OURMOD, and some additional functions would be named something like OURMOD_do_something (), etc. If a global variable needs to be declared, use of a similar prefix in its name is also recommended.

Basic Classes

See the complete and up-to date SIA code libraries produced by Doxygen,

Many useful data types are defined in the header files included in the files sia_module.h and sia_module.C.h (for C++ codes), one of which we always include in the source codes of the modules. All header files useful for module design are listed in Appendix A In this section, I describe the main data structures used in most applications and critical for the understanding of the concept of the system.

class or typedef equivalent explanation
boolean
char
This format serves the purpose to emphasize Boolean values (with values TRUE is the same as OK, FALSE is the same as FAIL)
DATA_SAMPLE
float
The format of the trace data samples as they are stored in memory
COMPLEX
Class Class implementing complete set of complex arithmetic
CHARSTR
Class Class implementing various operations with arbitrary-length character strings.
byte
unsigned char
The format for all general-purpose binary data, e.g., trace headers, table data entries. The types corresponding to the main seismic data structures, which appear in the modules most often, are listed in below, along with the field declared within these structures. Note that only the principal fields are shown here
FORMAT
enum
Trace header or table entry format. It may assume values of INTEGER, REAL (the same as FLOAT), DOUBLE, LONG, POINTER, and CHARACTER
Aux_Parameter
union Auxiliary parameter included in various structures. It is never used by the monitor, and is used by the modules to store the intermediate results
HEADER
Class Contains all information about the trace header or table entry.  Trace or table entry header name.
AHEADER
Class Trace header with capabilities of using arrays and additional methods defined.
HEADER_PARAM 
Class Used with the functions implementing  free-format parameter input and retrieval. It is used to read in the values from the job file which can be interpreted as numerical constants or trace/table header entries. 
HEADERS_TABLE 
Class Table of the formats of all the headers associated with one data structure (trace ensemble sequence, or table). 
DATA_PARAMS 
Parameters of all the traces in the same ensemble sequence (see below). This is used only internally to support fixed-format traces. 
TRACE 
Class Seismic trace 
ENSEMBLE 
Class Ensemble of seismic traces.
GATHER
Class A linked sequence of trace ensembles.
TABLE
Class Used to implement lists of keywords.
USER_TABLE 
Class User-defined table. Most of the databases in the system are implemented in this format. char *name ASCII name of the table. 
enum User_Table_Type
The type of the table: UT_TABLE (free-format table) or UT_MAP (multidimensional array-type table).
SIA_SYSTEM
Class Placeholder for most system-wide parameters and methods.
SIA_MODULE
Class Base class for modules written in C++
PROJECT
Class Descriptor of a processing flow.

The modules can access the processing flow structures used by the seismic monitor itself. This, however, is not recommended. Instead, a number of functions is provided, which return the necessary pointers to the input and output ensemble sequences, data parameter blocks, header tables, etc. I describe the structures corresponding to the processing flow shown in Figure 1 for the purpose of illustration only. 

FILE_ACCESS 
Class The parameters of the ASCII file access used by the module. Every module may have its own log and error files; also, its write/append output mode to ASCII files may be changed using calls to the module setup. These modes affect opening of all ASCII files opened using SIA_open_file ().
MODULE 
Class Seismic processing module. A pointer to this structure is returned by the function SIA_current_module ().

Several types implement general array operations:

ARRAY<type>
Template Variable-length array of arbitrary type
ARRAY_FIXED<size,type>
Template Fixed-length array of arbitrary type
ARRAY_IO<type>
Template Variable-length array of arbitrary type with file input/output operations
STRING<TYPE>
Template Variable-length array of arbitrary type.  The type is restricted to a "simple" type without constructors.

Classes performing matrix operations:

MATRIX_GENERAL<type>
Template General matrix operations (+,-,*)
MATRIX
MATRIX_GENERAL<float>
Also includes matrix inversion and division
VECTOR
Class A ingle-column MATRIX

Seismic data formats

Six formats of seismic data samples are currently supported. These formats are distinguished by the value of the field type (see class TRACE above). Traces of different formats can be joined into one trace ensemble. These formats (values returned by the method TRACE::type()), and the corresponding data sample types are the following: 

Except COMPLEX, these types are designed mainly for a compact storage of integer or floating-point values. Memory reallocations and data conversions are performed automatically by functions TRACE::copy(); actual trace data length in bytes is returned by TRACE::data_length().

Module Data Organization

All modules are reentrant, unless special measures are taken to destroy the reentrancy. All the programmer needs to do is to include all the parameters used by the module into a single class, to crfeate an object of this class during the Edit phase, and to return the pointer to it. For example, for our module ourmod, this structure, typically declared in the header file ourmod.h would look something like the following: 

class OURMOD 
{ 
	HEADER *source, *target;    // any internal data needed by the module
  	void proc();        	// any processing methods
};

and the beginning of the Edit phase will look like this: 

#include "sia_module.C.h"
 #include "ourmod.h"
 int ourmod_editp_ ( OURMOD *O ) 
{
    *O = new OURMOD;
    (*O)->source.get ( "ENTRY" ); ...

(also see the Edit phase template). The first operator here initilizes the entire module data object and returns its pointer *O to the monitor. During the Process phase afterwards, the monitor will provide us with the pointer to this object. This pointer can be obtained from any subroutine, e.g., from the main Process phase function: 

#include "sia_module.C.h" 
#include "ourmod.h" 
bool ourmod_procp_ ( GATHER* input, GATHER*output ) 
{ 
    OURMOD *O = (OURMOD*) SIA_param_block (); ... 

If you use a global variable in your module and want to make your module reentrant, make sure you reset the value of the global variable at the beginning and at the end of the Edit and Process phase processing. The number and the sequence of calls of a particular module depends on the seismic job and on the processing situation, so surprises may occur. If you want to ensure that your module is used only once in the job, you can easily ensure this using the mechanism of messages.