KGS Home PagePRS Home PageOnline Pubs Page

Kansas Geological Survey, Open File Report 97-22


Source Code for the Pseudoseismic Transform

John F. Hopkins, Kansas Geological Survey

The pseudoseismic transform source code converts LAS formatted digital well logs into a SEG-Y formatted seismic file. This format change allows well log data to be manipulated in a seismic workstation environment (cf. Hopkins, Carr, and Feldman, 1996).

References

Hopkins, J. F., Timothy R. Carr and Howard Feldman, 1996, Pseudoseismic transforms of wireline logs: A seismic approach to petrophysical sequence stratigraphy: in Jory A. Pacht, Robert E. Sheriff, and Bob F. Perkins, eds., Stratigraphic Analysis Utilizing Advanced Geophysical, Wireline and Borehole Technology for Petroleum Exploration and Production, Gulf Coast Section Society of Economic Paleontologists and Mineralogists Foundation Seventeenth Annual Research Conference.

Download C source code(self-extracting ZIP file)

Source Code for the Pseudoseismic Transform

The following source code has been written in Gnu C++, and hopefully is generic enough to run on most C++ compilers.

/* mk3Dsl.c */
/* Create the seismic line file in SEG-Y format from the trace information */
/* file specified by the user. */
/* mksl.c written by Alan Feltz, Code modified 9/24/96 for 3D seismic */
/* by John Hopkins -- Rust Never Sleeps! */
#include <stdio.h>
void gen_tracehdr(FILE *, int, int, int, int, int); void gen_reelhdr( FILE *, int, int, int, int, char * );
void main( int argc, char *argv[] ) { char logfn[40], /* log file containing data */ hrec[128], /* log header record */ depthunits[10], /* depth units of log values */ *vptr; /* pointer to value bytes */
int i, j, /* loop variables */ totallogs, /* total number of logs */ totaltraces, /* total number of traces */ samples, /* number of samples */ min_elev, /* min elevation of all logs */ max_elev, /* max elevation of all logs */ linenum, /* current line number */ num_lines, /* maximum line number */ tracenum, /* trace number of next log */ tracesperline, currtrace, /* current trace to generate */ currline, ctelev, /* current trace elevation */ up_elev, /* upper elevation of the log */ low_elev, /* lower elevation of the log */ kellybushing; /* kelly bushing of the log */
float depth, /* depth of log value */ value; /* log value at depth */
FILE *tiffp, /* trace information input file pointer */ *logfp, /* log input file pointer */ *seisfp; /* seismic line output file pointer */
/* ERROR BLOCK */ if ( argc < 2 ) { fprintf( stderr, "Usage: mksl trace_info_file\n" ); exit( -1 ); }
if ( ( tiffp = fopen( argv[1], "r" ) ) == NULL ) { fprintf( stderr, "The trace header information file %s ", argv[1] ); fprintf( stderr, "could not be opened!\n", argv[1] ); exit(-1); }
if ( ( seisfp = fopen( "00Sline.sgy", "w" ) ) == NULL ) { fprintf( stderr, "The output seismic line file %s ", "00Sline.sgy" ); fprintf( stderr, "could not be opened!\n" ); exit(-1); }
/* read information header from trace information file */
fscanf( tiffp, "%*s%*[^\n]\n" ); /* skip header line */ fscanf( tiffp, "%d%*[^\n]\n", &totallogs ); fscanf( tiffp, "%d%*[^\n]\n", &min_elev ); fscanf( tiffp, "%d%*[^\n]\n", &max_elev ); fscanf( tiffp, "%d%*[^\n]\n", &num_lines); fscanf( tiffp, "%d%*[^\n]\n", &tracesperline); fscanf( tiffp, "%d%*[^\n]\n", &totaltraces ); fscanf( tiffp, "%d%*[^\n]\n", &samples ); fscanf( tiffp, "%s%*[^\n]\n", depthunits ); fscanf( tiffp, "%*s%*[^\n]\n" ); /* skip data header line */ fscanf( tiffp, "%*s%*[^\n]\n" ); /* skip data header line */ \printf("LINE HEADER INFORMATION\n"); printf("Total logs: %d\n", totallogs); printf("min. elev: %d\n",min_elev ); printf("max. elev: %d\n",max_elev); printf("num_lines: %d\n", num_lines); printf("tracesperline: %d\n", tracesperline); printf("totaltraces: %d\n", totaltraces); printf("samples: %d\n", samples); gen_reelhdr( seisfp, samples, num_lines, tracesperline, totaltraces, depthunits ); vptr = (char *) &value; currline = 1; while(currline<=num_lines) { currtrace=1; while(currtrace<=tracesperline) {
fscanf(tiffp, "%d%d%s%d%d%d", &linenum, &tracenum, logfn, &kellybushing, &up_elev, &low_elev);
if ( ( logfp = fopen( logfn, "r" ) ) == NULL ) { fprintf( stderr, "The log file %s was not found!...SKIPPED\n", logfn ); value = 0.0; /* generate blank traces if necessary */
printf("Generating Line %5d trace %5d : BLANK...", currline, currtrace);
/* generate trace header */ gen_tracehdr(seisfp, kellybushing, max_elev, samples,linenum, currtrace);
for(i = 0; i<samples; i++) /* fills in 0's for trace */ for(j = 0; j<4; j++) fputc(*(vptr+j), seisfp);
currtrace++; printf("Done\n");
continue; }
if(currtrace>tracenum) { printf(stderr, "Trace numbers are not in order...Exiting!\n"); exit(-1); }
printf("Generating line %5d trace %5d : %s...", currline, currtrace, logfn);
while(fgets(hrec, 81, logfp) != NULL) /* find log data section */ if(!strncmp(hrec, "~A", 2)) break;
/* generate trace header */ gen_tracehdr(seisfp, kellybushing, max_elev, samples,linenum, currtrace);
value = 0.0; /* pad top part of log */ for(ctelev=max_elev; ctelev>up_elev; ctelev--) for(i = 0; i<4; i++) fputc(*(vptr+i), seisfp);
while(fscanf(logfp, "%f%f", &depth, &value)!= EOF) /* log data */ if(((int)(10*depth))%10==0) { for(i = 0; i<4; i++) fputc(*(vptr+i), seisfp); ctelev--; }
value=0.0; /* pad bottom part of log */ for( ;ctelev>min_elev; ctelev--) for(i=0; i<4; i++) fputc( *(vptr+i), seisfp);
currtrace++; fclose(logfp);
printf("Done\n");
} /* while trace loop */
currline++; } /* while line number loop */
fclose( seisfp ); fclose( tiffp );
} /* main */
/* gen_reelhdr - Generate the information header and the reel header */
void gen_reelhdr( FILE *seisfp, int samples, int num_lines, int tracesperline, int totaltraces, char *depthunits ) { char rih[400]; /* the reel id header */ short *sptr; /* pointer to short */
int i, /* loop variable */ *iptr; /* pointer to integer */
for ( i = 0; i < 3200; i++ ) fputc( ' ', seisfp );
for ( i = 0; i < 400; i++ ) rih[i] = (char) 0;
iptr = (int *) rih; sptr = (short *) iptr;
iptr[0] = num_lines; iptr[1] = 0; iptr[2] = tracesperline; iptr[3] = 0; iptr[4] = totaltraces; iptr[6] = 0; iptr[8] = 1000;
iptr[10] = samples; sptr[11] = 0;
sptr[12] = 1; sptr[13] = 1; sptr[14] = 2; sptr[15] = 1;
if ( ! strcmp( depthunits, "FEET" ) ) sptr[27] = 2; else sptr[27] = 1;
for ( i = 0; i < 400; i++ ) fputc( rih[i], seisfp );
} /* gen_reelhdr */
/* gen_tracehdr - Generate trace header */
void gen_tracehdr( FILE *seisfp, int kellybushing, int max_elev, int samples, int linenum, int currtrace) { char thdr[240]; /* trace header block */
short *sptr; /* pointer to short */
int i, j, /* loop variable */ *iptr; /* pointer to integer */
for ( i = 0; i < 240; i++ ) thdr[i] = '\0';
iptr = (int *) thdr; sptr = (short *) iptr;
iptr[0] =linenum; iptr[2] = 0; iptr[3] =currtrace; iptr[6] = 0;
sptr[14] = 0; sptr[15] = 0; sptr[17] = 0;
iptr[10] = kellybushing; iptr[13] = max_elev; sptr[34] = 0; sptr[35] = 0;
iptr[20] = 0; iptr[21] = 0;
sptr[44] = 0; /* type of x,y location */
sptr[57] = samples; sptr[58] = 1000;
for ( j = 0; j < 240; j++ ) fputc( thdr[j], seisfp );
} /* gen_tracehdr */


Kansas Geological Survey, Open-File Report 96-37
Placed online April 1997
Comments to
webadmin@kgs.ku.edu
URL=http://www.kgs.ku.edu/PRS/publication/OFR97-22/ofr9722.html