/******************************** GPR_XFRM.C ********************************\ version 1.04.17.01 GPR_XFRM transforms GPR data from traces collected evenly in time to evenly-spaced, spatially-located traces. Use GPR_PROC to process the data before transforming. The conversion is performed as follows. The user specifies start and stop locations and a step size, and locations are calculated for the new traces. The user also specifies a bin size (which defaults to the step size but may be smaller or greater than the step size to accommodate dense or sparse data sets). Each bin is centered about a new trace location. A location (user- defined X, Y, and Z values) is assigned each old trace by splining, using the data from the MRK and XYZ files. All traces located within the bin are averaged to create the new trace for each bin. Empty bins are set to the mean value of the input data type (e.g., 32768 for unsigned short integers). Empty bins can be avoided by enlarging the step size or the bin size. X, Y, and Z values are calculated for each bin and saved to disk as an "XYZ" file. A "MRK" file is also saved. The following computer storage formats are recognized: GSSI SIR-10A version 3.x to 5.x, Sensors and Software pulseEKKO, and SEG-Y. If the storage format does not conform to any of the above or this program is having trouble reading the file correctly, there are options in the CMD file for the user to specify required parameters. Data are stored to disk in the same format as they were read in. An exception is made for early versions GSSI DZT files that had 512-byte headers. A current (version 5.x) 1024-byte header is written into the output file. To convert from one GPR storage format to another, use GPR_CONV.EXE. Because each industry storage format maintains information about the data in each trace header, both the trace header and trace data block are stored as a unit as one column in the program's internal storage grid. If the size of the trace header is not an even multiple of the data element (sample) size, the program will stop and report an error. This should only be a problem with user-defined storage formats. The input to this program is a "CMD" file, an ASCII text file containing keywords (or parameters) describing how to process the radar data. The CMD file specifies the data file name (and optionally the storage format). Inspect the example file GPR_XFRM.CMD for usage. NOTES: Only 1 to 4 headers are supported in DZT files. There is no graphic display of the data. To display the processed data, use programs such as GPR_DISP.EXE or FIELDVEW.EXE. ----------------------------------------------------------------------------- RULES FOR CONSTRUCTING "GPRSCONV.CMD" FILES: 1. All valid keywords and their defaults are shown below in the next section. Only one keyword can be used per line. 2. Keywords can be upper, lower, or mixed case. 3. Only lines with an equal sign and the valid (correctly spelled) keyword to the left of the equal sign will be used. All OTHERS ARE IGNORED (except for sets of numbers, see 11, 12, and 13 below). Blank lines are ignored everywhere (also see 6, 7, and 10 below). 4. Numeric values assigned to keywords must be a single number. Mathematical operations, such as 5+2, are not recognized. DO NOT insert a comma in a number. For example, use 1234 not 1,234. DO NOT place quotes on either side of a numeric entry. 5. Equal signs do not have to line up. 6. Spaces are ignored (and removed) except those within strings and sets of numbers. 7. A semicolon begins a comment, except within strings. Text and numbers after a semicolon are ignored. 8. Strings must be enclosed in double quotation marks. Examples: use_mark_file = "TRUE" use_xyz_file = "FALSE" NOTE: DO NOT enclose the file names in the input and output lists in quotes. 9. "TRUE" equals 1. "FALSE" equals 0. "INVALID_VALUE" equals 1.0E19. 10. Lines should be less than 160 characters long (characters past 159 are ignored). 11. Keywords can be given in any order, except the num_... keywords which must precede the arrays, or sets of numbers, they are describing. 12. Keywords that expect sets of data end in square brackets. 13. Sets of numbers or strings must be separated by a space or a "new line" characters (i.e. a carriage return/line feed pair, CR/LF, generated by pressing ). Example: num_input_files = 8 input_filelist[] = file1.dzt file2.dzt file3.dzt file4.dzt file5.dzt file6.dzt file7.dzt file8.dzt Example: num_input_files = 8 input_filelist[] = file1.dzt file2.dzt file3.dzt file4.dzt file5.dzt file6.dzt file7.dzt file8.dzt Example: num_input_files = 8 input_filelist[] = file1.dzt file2.dzt file3.dzt file4.dzt file5.dzt file6.dzt file7.dzt file8.dzt 14. Almost all values have defaults except for the input and output data filenames. At least one filename must be specified in each list. 15. Parameters or commands may appear more than once, but usually only the last instance is preserved (ie., earlier values are lost or written over). ----------------------------------------------------------------------------- WRITTEN BY: Jeff Lucius U.S. Geological Survey Box 25046 Denver Federal Center MS 964 Denver, CO 80225-0046 voice: 303-236-1413 fax: 303-236-1425 email: lucius@usgs.gov ----------------------------------------------------------------------------- Revision History: February 13, 1997 - Completed as an extensive revision of GPR_PROC.C. August 11, 1997 - Added support for modified DZT formats. June 8, 1999 - Fixed bug in finding first trace to use. August 4, 1999 - Fixed bug in DZT_IO.C when num_traces exceeds num_cols. Really need to check that first_trace plus num_cols is less than num_traces. April 16, 2001 - Made Y2K time/date corrections. - Changed way version done - added date to number. - Now writes an MRK file to go with XYZ file. Supported compilers: Intel 386/486 C Code Builder 1.1a To compile for 80386 executable: icc /F /xnovm /zfloatsync gpr_xfrm.c gpr_io.lib jl_util1.lib To compile for 80486 executable : icc /F /xnovm /zfloatsync /zmod486 gpr_xfrm.c gpr_io.lib jl_util1.lib /F removes the floating point emulator, reduces binary size. /xnovm specifies no virtual memory manager, disk access is too slow. /zfloatsync insures the FPU is operand-synchronized with the CPU. /zmod486 generates specific 80486 instructions, speeds up program. gpr_io.lib - Jeff Lucius's GPR I/O functions (DZT, DT1, SGY). jl_util1.lib - Jeff Lucius's utility functions. to remove assert() functions from code also add: /DNDEBUG To run: GPR_XFRM cmd_filename \****************************************************************************/ /*************************** Function dependency ****************************/ /* * con I/O - keyboard and/or text-mode screen used * disk I/O - reads from and/or writes to disk * DOS - DOS/BIOS interrupt performed * graphics - graphics modes required, direct writes to ports/video adaptor * port I/O - hardware I/O ports used * RAM - direct RAM memory access * * main (con I/O) * +-- ANSI_there (DOS) * | +-- GetDosVersion (DOS) * +-- Sound (port I/O) * +-- GetParameters (con I/O) * | | These functions are responsible for reading the user-supplied * | | parameters from the command (or parameter) file specified on the * | | command line and opening the GPR data/info files to get * | | additional information about the data sets. * | +-- PrintUsageMsg (con I/O) * | +-- InitParameters * | +-- GetCmdFileArgs (disk I/O) * | | +-- TrimStr * | +-- GetGprFileType (disk I/O) * | +-- ReadOneDztHeader (disk I/O) * | +-- InitDt1Parameters * | +-- GetSsHdFile (disk I/O) * | +-- PrintSsHdInfo (con I/O) * | +-- ReadSegyReelHdr (disk I/O) * | +-- PrintSegyReelHdr (con I/O) * | +-- TrimStr * | +-- GetOtherInfo (disk I/O) * | +-- GetXfrmRanges * | This function finds the first and last traces to read and * | calculates X, Y, Z for each trace. * +-- DisplayParameters (con I/O) * | This function displays the processing parameters to the user on * | the CRT screen. * +-- GetGprDataAsGrid (disk I/O)(con I/O) * | | This function retrieves the data from disk and stores in a grid. * | +-- GetDztChSubGrid8 (disk I/O) * | +-- GetDztChSubGrid16 (disk I/O) * | +-- GetGprSubGrid (disk I/O) * +-- TransformGprData (disk I/O)(con I/O) * | This function allocates storage and initializes the Bin Array and * | places the traces in the bin, calculating the average trace for * | each bin. Then each bin trace is resample if requested. X, Y, * | Z values are calculated for each bin. * +-- XfrmSaveMrkXyzData (disk I/O)(con I/O) * | This function saves the X Y and Z locations for each bin to * | disk in the "XYZ" format. * +-- XfrmSaveGprData (disk I/O)(con I/O) * | | This function copies the traces from the bins into the input * | | grid (converting the datatype) and calls the data save function. * | +-- XfrmSaveDztData (disk I/O)(con I/O) * | | +-- ReadOneDztHeader (disk I/O) * | | +-- SetDzt5xHeader * | | +-- SaveDztFile (disk I/O) * | +-- XfrmSaveDt1Data (disk I/O) * | | +-- GetSsHdFile (disk I/O) * | | +-- SaveSsHdFile (disk I/O) * | +-- XfrmSaveSgyData (disk I/O) * | | +-- ReadSegyReelHdr (disk I/O) * | | +-- ExtractSsInfoFromSegy * | | +-- SetSgyFileHeader * | +-- XfrmSaveUsrData (disk I/O) * +-- DeallocInfoStruct */ /******************* Includes all required header files *********************/ #include "gpr_xfrm.h" /**************************** Global variables ******************************/ int Debug = FALSE; /* if TRUE, turn debugging on */ int Batch = FALSE; /* if TRUE, supress interaction with user */ int ANSI_THERE = FALSE; /* TRUE if ANSI.SYS loaded */ /* error and message file that all functions have access to */ FILE *log_file = NULL; /* pointer to FILE struct */ /* The next array is used to read in values from an ASCII file that contains * control parameters. */ const char *GPR_XFRM_CMDS[] = { "debug","batch","dat_infilename","mrk_infilename","xyz_infilename", "file_header_bytes","trace_header_bytes","samples_per_trace","total_time","input_datatype", "dat_outfilename","channel","spatial_dir","spatial_start","spatial_stop", "spatial_step","bin_size","other_format","show_stats",NULL, } ; const char *GetParametersMsg[] = { "GetParameters(): No errors.", "GetParameters() ERROR: Insufficient command line arguments.", "GetCmdFileArgs() ERROR: Unable to open input command file.", "GetCmdFileArgs() ERROR: Output file not specified.", "GetCmdFileArgs() ERROR: Input file(s) not specified.", "GetParameters() ERROR: Problem getting information about input data file.", "GetParameters() ERROR: Invalid channel selection for DZT file.", "GetParameters() ERROR: Problem getting info from HD file.", "GetParameters() ERROR: Problem getting info from SGY file.", "GetParameters() ERROR: Problem determining user-defined parameters.", "GetParameters() ERROR: No recognizable data/info input files specified.", "GetParameters() ERROR: Invalid input data element type .", "GetParameters() ERROR: Less than two traces in file.", "GetParameters() ERROR: Less than two samples per trace.", "GetParameters() ERROR: nanoseconds per sample is <= 0.0.", "GetParameters() ERROR: trace_header_size must be a multiple of sample size.", "GetParameters() ERROR: spatial distance must be a multiple of spatial_step.", "GetParameters() ERROR: MRK and XYZ files must be specified for this GPR file.", "GetParameters() ERROR: Problem getting data from MRK file.", "GetParameters() ERROR: Problem getting data from XYZ file.", "GetParameters() ERROR: Number of tick marks not same in MRK and XYZ files.", "GetParameters() ERROR: Not able to allocate sufficient temporary storage.", "GetParameters() ERROR: Less than two samples per trace for transformed data.", "GetParameters() ERROR: New total_time or ns_per_samp <= 0.0.", "GetParameters() ERROR: Storage format not recognized. Must define in CMD file.", "GetParameters() ERROR: Problem in subroutine GetXfrmRanges().", "GetParameters() ERROR: Number of bins exceeds number of input traces.", "GetParameters() ERROR: Spatial_step direction must match start->stop direction", } ; const char *GetGprDataAsGridMsg[] = { "GetGprDataAsGrid(): No errors.", "GetGprDataAsGrid() ERROR: Attemp made to de-allocate storage before allocating.", "GetGprDataAsGrid() ERROR: Attemp made to re-allocate storage. De-allocate first.", "GetGprDataAsGrid() ERROR: Invalid input data element type .", "GetGprDataAsGrid() ERROR: No recognized data/info input files specified.", "GetGprDataAsGrid() ERROR: Not able to allocate storage for grid.", "GetGprDataAsGrid() ERROR: Problem getting data from input file.", } ; const char *GetXfrmRangesMsg[] = { "GetXfrmRanges() No error.", "GetXfrmRanges() ERROR: Number of marked traces < 2.", "GetXfrmRanges() ERROR: Marked traces outside data range.", "GetXfrmRanges() ERROR: spatial_start/_stop are the reverse of data direction.", "GetXfrmRanges() ERROR: Problem splining data topography.", "GetXfrmRanges() ERROR: Not able to allocate sufficient temporary storage.", } ; const char *TransformGprDataMsg[] = { "TransformGprData(): No errors.", "TransformGprData() ERROR: Invalid input data element type .", "TransformGprData() ERROR: Not able to allocate storage for bin array.", "TransformGprData() ERROR: At least one empty bin was found. See log file.", "TransformGprData() ERROR: Not able to allocate temporary storage.", "TransformGprData() ERROR: Problem splining data. See log file.", } ; const char *XfrmSaveMrkXyzDataMsg[] = { "XfrmSaveMrkXyzData(): No errors.", "XfrmSaveMrkXyzData() ERROR: Data/information was not saved to disk.", "XfrmSaveMrkXyzData() ERROR: Unable to open output MRK file.", } ; const char *XfrmSaveGprDataMsg[] = { "XfrmSaveGprData(): No errors.", "XfrmSaveGprData() ERROR: Invalid/unknown file storage format.", "XfrmSaveGprData() ERROR: Data/information was not saved to disk.", } ; const char *XfrmSaveDztDataMsg[] = { "XfrmSaveDztData(): No errors.", "XfrmSaveDztData() ERROR: Invalid datatype for output DZT file.", "XfrmSaveDztData() ERROR: Problem getting input file header.", "XfrmSaveDztData() ERROR: Problem saving data.", } ; const char *XfrmSaveDt1DataMsg[] = { "XfrmSaveDt1Data(): No errors.", "XfrmSaveDt1Data() ERROR: Invalid datatype for output DT1 file.", "XfrmSaveDt1Data() ERROR: Problem getting input file header.", "XfrmSaveDt1Data() ERROR: Problem saving HD file.", "XfrmSaveDt1Data() ERROR: Unable to open output DT1 file.", "XfrmSaveDt1Data() ERROR: Problem saving DT1 file.", } ; const char *XfrmSaveSgyDataMsg[] = { "XfrmSaveSgyData(): No errors.", "XfrmSaveSgyData() ERROR: Invalid datatype for output SGY file.", "XfrmSaveSgyData() ERROR: Problem getting input file header.", "XfrmSaveSgyData() ERROR: Unable to open output DT1 file.", "XfrmSaveSgyData() ERROR: Problem saving SGY file header.", "XfrmSaveSgyData() ERROR: Problem saving SGY file data.", } ; const char *XfrmSaveUsrDataMsg[] = { "XfrmSaveUsrData(): No errors.", "XfrmSaveUsrData() ERROR: Invalid datatype for output user-defined file.", "XfrmSaveUsrData() ERROR: Problem getting input file header.", "XfrmSaveUsrData() ERROR: Unable to open output GPR file.", "XfrmSaveUsrData() ERROR: Problem saving GPR file header.", "XfrmSaveUsrData() ERROR: Problem saving GPR file data.", } ; /********************************** main() **********************************/ void main (int argc,char *argv[]) { /***** Declare variables *****/ char log_filename[80]; /* following are scratch variables used by main */ int itemp; double dtemp; /* following is the information structure passed between functions */ struct XfrmParamInfoStruct ParamInfo; /* these variables found near beginning of this source */ extern int Debug,Batch,ANSI_THERE; extern FILE *log_file; extern const char *GetParametersMsg[]; extern const char *GetGprDataAsGridMsg[]; extern const char *TransformGprDataMsg[]; extern const char *XfrmSaveGprDataMsg[]; /***** Initialize variables *****/ /* Open error message file */ strcpy(log_filename,"gpr_xfrm.log"); log_file = fopen(log_filename,"a+t"); if (log_file == NULL) { strcpy(log_filename,"c:\\gpr_xfrm.log"); log_file = fopen(log_filename,"a+t"); } if (log_file) { struct dosdate_t dosdate; struct dostime_t dostime; char *month[] = { "","January","February","March","April","May","June", "July","August","September","October", "November","December" } ; _dos_getdate(&dosdate); _dos_gettime(&dostime); fprintf(log_file,"\n**************************************************************************\n"); fprintf(log_file,"Messages from program GPR_XFRM v. %s: %s %d, %d at %d:%02d:%02d\n", GPR_XFRM_VER,month[dosdate.month],dosdate.day,dosdate.year, dostime.hour,dostime.minute,dostime.second); fprintf(log_file,"Computer code written by Jeff Lucius, USGS, lucius@usgs.gov.\n"); } /* Check if ansi.sys loaded */ if (ANSI_there()) ANSI_THERE = TRUE; /* Zero-out information structure */ memset((void *)&ParamInfo,0x00,sizeof(struct XfrmParamInfoStruct)); /***** Get information used to process data *****/ if (log_file && argv[1]) fprintf(log_file,"Processing command file: %s\n",argv[1]); printf("Getting user parameters ..."); itemp = GetParameters(argc,argv,&ParamInfo); printf("\r \r"); if (itemp > 0) { printf("\n%s\n",GetParametersMsg[itemp]); DeallocInfoStruct(&ParamInfo); if (log_file) { fprintf(log_file,"%s\n",GetParametersMsg[itemp]); fprintf(log_file,"bin_size=%g step=%g min_trace_sep=%g max_trace_sep=%g\n", ParamInfo.bin_size,ParamInfo.spatial_step,ParamInfo.min_trace_sep,ParamInfo.max_trace_sep); fclose(log_file); } if (ANSI_THERE) printf("%c%c32;40m",0x1B,0x5B); printf("\nGPR_XFRM finished.\nFile %s on disk contains messages.\n",log_filename); if (ANSI_THERE) printf("%c%c37;40m",0x1B,0x5B); exit(1); } if (strcmp(ParamInfo.dat_infilename,ParamInfo.dat_outfilename) == 0 || ( ParamInfo.inf_infilename[0] && (strcmp(ParamInfo.inf_infilename,ParamInfo.inf_outfilename) == 0) ) ) { printf("\nERROR: Input filename is duplicated in output list.\n"); DeallocInfoStruct(&ParamInfo); if (ANSI_THERE) printf("%c%c32;40m",0x1B,0x5B); if (log_file) { fprintf(log_file,"ERROR: Input filename is duplicated in output list.\n"); fprintf(log_file,"bin_size=%g step=%g min_trace_sep=%g max_trace_sep=%g\n", ParamInfo.bin_size,ParamInfo.spatial_step,ParamInfo.min_trace_sep,ParamInfo.max_trace_sep); fclose(log_file); printf("File %s on disk contains messages.\n",log_filename); } puts("GPR_XFRM finished."); if (ANSI_THERE) printf("%c%c37;40m",0x1B,0x5B); exit(2); } if (log_file) { if (Batch) fprintf(log_file,"Program in Batch mode.\n"); if (Debug) fprintf(log_file,"Program in Debug mode.\n"); } /***** Display parameters and ask if user wants to continue *****/ DisplayParameters(&ParamInfo); if (!Batch) { printf("\nPress to quit or other key to continue ... "); if ((itemp = getch()) == ESC) { puts("\nProgram terminated by user."); DeallocInfoStruct(&ParamInfo); if (ANSI_THERE) printf("%c%c32;40m",0x1B,0x5B); if (log_file) { fprintf(log_file,"Program terminated by user.\n"); fclose(log_file); printf("File %s on disk contains messages.\n",log_filename); } puts("GPR_XFRM finished."); if (ANSI_THERE) printf("%c%c37;40m",0x1B,0x5B); exit(3); } else if (itemp == 0 || itemp == 0xE0 || itemp == 0xF0) getch(); printf("\r \r"); } /***** Get the data *****/ printf("Getting Data ..."); itemp = GetGprDataAsGrid(FUNC_CREATE,&ParamInfo); printf("\r \r"); if (itemp > 0) { printf("\n%s\n",GetGprDataAsGridMsg[itemp]); if (log_file) fprintf(log_file,"\n%s\n",GetGprDataAsGridMsg[itemp]); if (itemp == 5) /* data set too large for memory */ { unsigned long mem,stack,bytes,requested; mem = _memavl(); switch (ParamInfo.input_datatype) { case -1: case 1: bytes = 1; break; case -2: case 2: case 5: bytes = 2; break; case -3: case 3: case 6: case 4: bytes = 4; break; case 8: bytes = 8; break; } requested = (ParamInfo.last_trace - ParamInfo.first_trace + 1) * ParamInfo.data_samps * bytes; stack = requested/mem; printf("\nSize of GPR data file (%lu bytes) exceeds memory (%lu bytes).\n",requested,mem); printf("Try using GPR_CNDS first with skip_traces set to %lu or higher.\n",stack+2); if (log_file) fprintf(log_file,"Size of GPR data file (%lu bytes) exceeds memory (%lu bytes).\n",requested,mem); if (log_file) fprintf(log_file,"Try using GPR_CNDS first with skip_traces set %lu or higher.\n",stack+2); } DeallocInfoStruct(&ParamInfo); if (ANSI_THERE) printf("%c%c32;40m",0x1B,0x5B); if (log_file) { fprintf(log_file,"End of messages. Program terminated with an ERROR.\n"); fclose(log_file); printf("File %s on disk contains messages.\n",log_filename); } puts("\nGPR_XFRM finished."); if (ANSI_THERE) printf("%c%c37;40m",0x1B,0x5B); if (!Batch) { for (itemp=0,dtemp=2000.; itemp<10; itemp++,dtemp-=100.) Sound(dtemp,0.055); } exit(4); } /***** Transform the data *****/ printf("Transforming Data. Please wait ..."); itemp = TransformGprData(&ParamInfo); printf("\r \r"); if (itemp > 0) { printf("\n%s\n",TransformGprDataMsg[itemp]); GetGprDataAsGrid(FUNC_DESTROY,&ParamInfo); DeallocInfoStruct(&ParamInfo); if (ANSI_THERE) printf("%c%c32;40m",0x1B,0x5B); if (log_file) { fprintf(log_file,"%s\n",TransformGprDataMsg[itemp]); fprintf(log_file,"End of messages. Program terminated with an ERROR.\n"); fclose(log_file); printf("File %s on disk contains messages.\n",log_filename); } puts("\nGPR_XFRM finished."); if (ANSI_THERE) printf("%c%c37;40m",0x1B,0x5B); if (!Batch) { for (itemp=0,dtemp=2000.; itemp<10; itemp++,dtemp-=100.) Sound(dtemp,0.055); } exit(5); } /***** Save XYZ info to disk *****/ printf("Saving XYZ info to disk ..."); itemp = XfrmSaveMrkXyzData(&ParamInfo); printf("\r \r"); if (itemp > 0) { printf("\n%s\n",XfrmSaveMrkXyzDataMsg[itemp]); GetGprDataAsGrid(FUNC_DESTROY,&ParamInfo); DeallocInfoStruct(&ParamInfo); if (ANSI_THERE) printf("%c%c32;40m",0x1B,0x5B); if (log_file) { fprintf(log_file,"%s\n",XfrmSaveMrkXyzDataMsg[itemp]); fprintf(log_file,"End of messages. Program terminated with an ERROR.\n"); fclose(log_file); printf("File %s on disk contains messages.\n",log_filename); } puts("\nGPR_XFRM finished."); if (ANSI_THERE) printf("%c%c37;40m",0x1B,0x5B); if (!Batch) { for (itemp=0,dtemp=2000.; itemp<10; itemp++,dtemp-=100.) Sound(dtemp,0.055); } exit(6); } /***** Save grid to disk *****/ printf("Saving data to disk ..."); itemp = XfrmSaveGprData(&ParamInfo); printf("\r \r"); if (itemp > 0) { printf("\n%s\n",XfrmSaveGprDataMsg[itemp]); GetGprDataAsGrid(FUNC_DESTROY,&ParamInfo); DeallocInfoStruct(&ParamInfo); if (ANSI_THERE) printf("%c%c32;40m",0x1B,0x5B); if (log_file) { fprintf(log_file,"%s\n",XfrmSaveGprDataMsg[itemp]); fprintf(log_file,"End of messages. Program terminated with an ERROR.\n"); fclose(log_file); printf("File %s on disk contains messages.\n",log_filename); } puts("\nGPR_XFRM finished."); if (ANSI_THERE) printf("%c%c37;40m",0x1B,0x5B); if (!Batch) { for (itemp=0,dtemp=2000.; itemp<10; itemp++,dtemp-=100.) Sound(dtemp,0.055); } exit(6); } /***** Free storage and terminate program *****/ itemp = GetGprDataAsGrid(FUNC_DESTROY,&ParamInfo); DeallocInfoStruct(&ParamInfo); if (itemp > 0) { printf("\n%s\n",GetGprDataAsGridMsg[itemp]); if (ANSI_THERE) printf("%c%c32;40m",0x1B,0x5B); if (log_file) { fprintf(log_file,"%s\n",GetGprDataAsGridMsg[itemp]); fprintf(log_file,"End of messages. Program terminated with an ERROR.\n"); fclose(log_file); printf("File %s on disk contains messages.\n",log_filename); } puts("\nGPR_XFRM finished."); if (ANSI_THERE) printf("%c%c37;40m",0x1B,0x5B); if (!Batch) { for (itemp=0,dtemp=2000.; itemp<10; itemp++,dtemp-=100.) Sound(dtemp,0.055); } exit(7); } if (ANSI_THERE) printf("%c%c32;40m",0x1B,0x5B); if (log_file) { fprintf(log_file,"End of error messages. Program terminated normally.\n"); fprintf(log_file,"GPR_XFRM finished. Grid saved to disk in %s.\n",ParamInfo.dat_outfilename); fclose(log_file); printf("\nFile %s on disk contains messages.\n",log_filename); } printf("GPR_XFRM finished. Grid saved to disk in "); if (ANSI_THERE) printf("%c%c37;40m",0x1B,0x5B); printf("%s.\n",ParamInfo.dat_outfilename); exit(0); } /******************************* end of main() ******************************/ /****************************** GetParameters() *****************************/ /* Initialize processing parameters and get user-defined values. * Determine GPR file storage format. * Get information from the appropriate "information" files. * * Parameter list: * int argc - number of command-line arguments * char *argv[] - array of strings containing the arguments * struct XfrmParamInfoStruct *InfoPtr - address of structure * * Requires: , , , "gpr_xfrm.h". * Calls: strcpy, printf, fprintf, getch, strstr, strupr, puts, strncat, * atoi, atof, * PrintUsageMsg, GetCmdFileArgs, InitParameters. * ReadOneDztHeader, GetMrkData, GetXyzData, GetXfrmRanges, * GetSsHdFile, PrintSsHdInfo, ReadSegyReelHdr, PrintSegyReelHdr, * Returns: 0 on success, * >0 if error. * const char *GetParametersMsg[] = { "GetParameters(): No errors.", "GetParameters() ERROR: Insufficient command line arguments.", "GetCmdFileArgs() ERROR: Unable to open input command file.", "GetCmdFileArgs() ERROR: Output file not specified.", "GetCmdFileArgs() ERROR: Input file(s) not specified.", "GetParameters() ERROR: Problem getting information about input data file.", "GetParameters() ERROR: Invalid channel selection for DZT file.", "GetParameters() ERROR: Problem getting info from HD file.", "GetParameters() ERROR: Problem getting info from SGY file.", "GetParameters() ERROR: Problem determining user-defined parameters.", "GetParameters() ERROR: No recognizable data/info input files specified.", "GetParameters() ERROR: Invalid input data element type .", "GetParameters() ERROR: Less than two traces in file.", "GetParameters() ERROR: Less than two samples per trace.", "GetParameters() ERROR: nanoseconds per sample is <= 0.0.", "GetParameters() ERROR: trace_header_size must be a multiple of sample size.", "GetParameters() ERROR: spatial distance must be a multiple of spatial_step.", "GetParameters() ERROR: MRK and XYZ files must be specified for this GPR file.", "GetParameters() ERROR: Problem getting data from MRK file.", "GetParameters() ERROR: Problem getting data from XYZ file.", "GetParameters() ERROR: Number of tick marks not same in MRK and XYZ files.", "GetParameters() ERROR: Not able to allocate sufficient temporary storage.", "GetParameters() ERROR: Less than two samples per trace for transformed data.", "GetParameters() ERROR: New total_time or ns_per_samp <= 0.0.", "GetParameters() ERROR: Storage format not recognized. Must define in CMD file.", "GetParameters() ERROR: Problem in subroutine GetXfrmRanges().", "GetParameters() ERROR: Number of bins exceeds number of input traces.", "GetParameters() ERROR: Spatial_step direction must match start->stop direction", } ; * * Author: Jeff Lucius USGS Mineral Resources Program Lakewood, CO * Date: February 7, 1997 */ int GetParameters (int argc,char *argv[],struct XfrmParamInfoStruct *InfoPtr) { /***** Declare variables *****/ int req_args = 2; /* exe_name and cmd_filename */ int i,itemp; /* scratch variables and counters */ long samp_bytes; /* number of bytes in one trace sample */ double dtemp,dtemp2,dtemp3,dtemp4; /* scratch variables */ /* this group used by GetGprFileType() */ int file_hdr_bytes,num_hdrs,trace_hdr_bytes,samples_per_trace; int num_channels,input_datatype,total_time,file_type; long num_traces; extern int Debug; /* beginning of this source */ extern FILE *log_file; /* beginning of this source */ extern const char *GetGprFileTypeMsg[]; /* from gpr_io.h */ /***** Verify usage *****/ if (argc < req_args) { PrintUsageMsg(); return 1; } /***** Initialize information structure *****/ InitParameters(InfoPtr); strncpy(InfoPtr->cmd_filename,argv[1],sizeof(InfoPtr->cmd_filename)-1); /***** Get user-defined parameters from CMD file *****/ itemp = GetCmdFileArgs(InfoPtr); if (itemp > 0) return itemp; /* 2 to 4 */ /***** Determine GPR file storage format and essential info *****/ if (InfoPtr->storage_format == 0) { itemp = GetGprFileType(&file_hdr_bytes,&num_hdrs,&trace_hdr_bytes, &samples_per_trace,&num_channels,&num_traces, &input_datatype,&total_time,&file_type, InfoPtr->dat_infilename); if (itemp > 0) { printf("%s\n",GetGprFileTypeMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",GetGprFileTypeMsg[itemp]); return 5; } if (file_type == USR) { if (log_file) fprintf(log_file,"ERROR: Storage format not recognized. User must define in CMD file.\n"); return 24; } InfoPtr->storage_format = file_type; InfoPtr->file_header_bytes = file_hdr_bytes; InfoPtr->trace_header_bytes = trace_hdr_bytes; /* 0 for GSSI DZT file */ InfoPtr->total_traces = num_traces; InfoPtr->data_samps = samples_per_trace; InfoPtr->total_time = total_time; InfoPtr->ns_per_samp = (double)InfoPtr->total_time / (InfoPtr->data_samps - 1); InfoPtr->input_datatype = input_datatype; } /***** Get necessary information from info file/header *****/ if (InfoPtr->storage_format == DZT || InfoPtr->storage_format == MOD_DZT) { int channel,header_size; struct DztHdrStruct DztHdr; /* from gpr_io.h */ extern const char *ReadOneDztHeaderMsg[]; /* from gpr_io.h */ /* get first DZT header in file */ channel = 0; itemp = ReadOneDztHeader(InfoPtr->dat_infilename,&num_hdrs, &(InfoPtr->total_traces),channel, &header_size,&DztHdr); if (itemp > 0) { printf("%s\n",ReadOneDztHeaderMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",ReadOneDztHeaderMsg[itemp]); if (strstr(strupr((char *)(ReadOneDztHeaderMsg[itemp])),"WARNING") == NULL) { puts("Fatal error."); return 5; } } if (header_size < 1024) { puts("This DZT header is not consistent with version 5.x SIR-10A software."); if (log_file) fprintf(log_file,"This DZT header is not consistent with version 5.x SIR-10A software.\n"); } if (InfoPtr->channel >= num_hdrs) return 6; /* get selected header (if different than first) */ if (InfoPtr->channel > 0) { itemp = ReadOneDztHeader(InfoPtr->dat_infilename,&num_hdrs, &(InfoPtr->total_traces),InfoPtr->channel, &header_size,&DztHdr); if (itemp > 0) { printf("%s\n",ReadOneDztHeaderMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",ReadOneDztHeaderMsg[itemp]); if (strstr(strupr((char *)(ReadOneDztHeaderMsg[itemp])),"WARNING") == NULL) { puts("Fatal error."); return 5; } } } /* assign values to info structure */ InfoPtr->data_samps = DztHdr.rh_nsamp; if (DztHdr.rh_bits == 8) InfoPtr->input_datatype = -1; else if (DztHdr.rh_bits == 16) InfoPtr->input_datatype = -2; else if (DztHdr.rh_bits == 32) InfoPtr->input_datatype = -3; InfoPtr->total_time = DztHdr.rh_range; InfoPtr->ns_per_samp = DztHdr.rh_range/(DztHdr.rh_nsamp-1); InfoPtr->first_proc_samp = 2; if (Debug) { printf("total_traces = %u data_samps = %u total_time = %g\n", InfoPtr->total_traces,InfoPtr->data_samps,InfoPtr->total_time); printf("ns_per_samp = %g datatype = %d first_proc_samp = %d\n", InfoPtr->ns_per_samp,InfoPtr->input_datatype,InfoPtr->first_proc_samp); printf("num_hdrs = %d\n",num_hdrs); getch(); } /* Get tick mark trace locations and XYZ data */ if (InfoPtr->mrk_infilename[0] && InfoPtr->xyz_infilename[0]) { int num_mrk_ticks,num_xyz_ticks; extern const char *GetMrkDataMsg[]; /* in gpr_io.h */ extern const char *GetXyzDataMsg[]; /* in gpr_io.h */ /* NOTE: GetMrkData() and GetXyzData() allocate storage for ->tick_tracenum[] and ->tick_xyz[][] */ itemp = GetMrkData(InfoPtr->mrk_infilename,&num_mrk_ticks, &(InfoPtr->tick_tracenum)); if (itemp > 0) { printf("\n%s\n",GetMrkDataMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",GetMrkDataMsg[itemp]); return 18; } InfoPtr->num_ticks = num_mrk_ticks; itemp = GetXyzData(InfoPtr->xyz_infilename,&num_xyz_ticks, &(InfoPtr->tick_xyz)); if (itemp > 0 || num_xyz_ticks != num_mrk_ticks) { printf("\n%s\n",GetXyzDataMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",GetXyzDataMsg[itemp]); if (itemp > 0) return 19; else return 20; } } else return 17; } else if (InfoPtr->storage_format == DT1) { int print_it; struct SsHdrInfoStruct HdInfo; /* buffer to hold info from HD file */ extern const char *GetSsHdFileMsg[]; /* from gpr_io.h */ /* Get info from HD file */ InitDt1Parameters(&HdInfo); if (Debug) print_it = 1; else print_it = 0; itemp = GetSsHdFile(print_it,&HdInfo,InfoPtr->inf_infilename); if (itemp > 0) { printf("%s\n",GetSsHdFileMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",GetSsHdFileMsg[itemp]); return 7; } if (Debug) { PrintSsHdInfo("stdout",InfoPtr->inf_infilename,&HdInfo); if (!getch()) getch(); } InfoPtr->input_datatype = 2; InfoPtr->total_traces = HdInfo.num_traces; InfoPtr->data_samps = HdInfo.num_samples; InfoPtr->total_time = HdInfo.total_time_ns; InfoPtr->ns_per_samp = (double)HdInfo.total_time_ns/(HdInfo.num_samples-1); InfoPtr->first_proc_samp = 128/2; /* 128 header bytes / samp bytes */ if (Debug) { printf("total_traces = %u data_samps = %u total_time = %g\n", InfoPtr->total_traces,InfoPtr->data_samps,InfoPtr->total_time); printf("ns_per_samp = %g datatype = %d first_proc_samp = %d\n", InfoPtr->ns_per_samp,InfoPtr->input_datatype,InfoPtr->first_proc_samp); getch(); } if (HdInfo.step_size == 0) { if (InfoPtr->mrk_infilename[0] && InfoPtr->xyz_infilename[0]) { int num_mrk_ticks,num_xyz_ticks; extern const char *GetMrkDataMsg[]; /* in gpr_io.h */ extern const char *GetXyzDataMsg[]; /* in gpr_io.h */ /* NOTE: GetMrkData() and GetXyzData() allocate storage for ->tick_tracenum[] and ->tick_xyz[][] */ itemp = GetMrkData(InfoPtr->mrk_infilename,&num_mrk_ticks, &(InfoPtr->tick_tracenum)); if (itemp > 0) { printf("\n%s\n",GetMrkDataMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",GetMrkDataMsg[itemp]); return 18; } InfoPtr->num_ticks = num_mrk_ticks; itemp = GetXyzData(InfoPtr->xyz_infilename,&num_xyz_ticks, &(InfoPtr->tick_xyz)); if (itemp > 0 || num_xyz_ticks != num_mrk_ticks) { printf("\n%s\n",GetXyzDataMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",GetXyzDataMsg[itemp]); if (itemp > 0) return 19; else return 20; } } else { return 17; } } else { int j; if (Debug) puts("getting distance info from HD1 file"); InfoPtr->num_ticks = InfoPtr->total_traces; InfoPtr->tick_tracenum = (long *)malloc(InfoPtr->num_ticks * sizeof(long)); if (InfoPtr->tick_tracenum == NULL) { InfoPtr->num_ticks = 0; if (log_file) fprintf(log_file,"GetParameters(): malloc failed for tick_tracenum[]"); return 21; } InfoPtr->tick_xyz = (double **)malloc(InfoPtr->num_ticks * sizeof(double *)); if (InfoPtr->tick_xyz == NULL) { InfoPtr->num_ticks = 0; free(InfoPtr->tick_tracenum); InfoPtr->tick_tracenum = NULL; if (log_file) fprintf(log_file,"GetParameters(): malloc failed for tick_xyz[]"); return 21; } for (i=0; inum_ticks; i++) { InfoPtr->tick_xyz[i] = (double *)malloc(3 * sizeof(double)); if (InfoPtr->tick_xyz[i] == NULL) { for (j=0; jtick_xyz[j]); free(InfoPtr->tick_xyz); free(InfoPtr->tick_tracenum); InfoPtr->tick_xyz = NULL; InfoPtr->tick_tracenum = NULL; InfoPtr->num_ticks = 0; if (log_file) fprintf(log_file,"GetParameters(): malloc failed for tick_xyz[][]"); return 21; } } for (i=0; inum_ticks; i++) { InfoPtr->tick_tracenum[i] = i; InfoPtr->tick_xyz[i][0] = i * HdInfo.step_size; /* X */ InfoPtr->tick_xyz[i][1] = 0.0; /* Y */ InfoPtr->tick_xyz[i][2] = 0.0; /* Z */ /* elev. data can be stored in each trace header ! */ } InfoPtr->spatial_dir = X_DIR; } } else if (InfoPtr->storage_format == SGY) { char *cp,cmdstr[30]; char string[40][80]; /* should have 3200 continuous bytes */ int swap_bytes,str_num,max_records,num,found; int comment_size,record_length; /* bytes */ long num_traces; double step_size; struct SegyReelHdrStruct hdr; /* from gpr_io.h */ extern const char *ReadSegyReelHdrMsg[]; /* from gpr_io.h */ const char *SEGY_ASCII_CMDS[] = { "NUMBER OF TRACES","NUMBER OF PTS/TRC","TIMEZERO AT POINT","TOTAL TIME WINDOW","STARTING POSITION", "FINAL POSITION","STEP SIZE USED","POSITION UNITS","NOMINAL FREQUENCY","ANTENNA SEPARATION", "PULSER VOLTAGE (V)","NUMBER OF STACKS","SURVEY MODE","TRACES PER SECOND","METERS PER MARK", "NUMBER OF GAIN PTS","GAIN POINTS",NULL, } ; itemp = ReadSegyReelHdr(InfoPtr->dat_infilename,&swap_bytes, &num_traces,&hdr); if (itemp > 0) { printf("%s\n",ReadSegyReelHdrMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",ReadSegyReelHdrMsg[itemp]); return 8; } if (Debug) PrintSegyReelHdr(swap_bytes,num_traces,"stdout", InfoPtr->dat_infilename,&hdr); switch(hdr.format) { case 1: InfoPtr->input_datatype = 4; break; case 2: case 4: InfoPtr->input_datatype = 3; break; case 3: InfoPtr->input_datatype = 2; break; default: break; } InfoPtr->total_traces = num_traces; InfoPtr->data_samps = hdr.hns; InfoPtr->ns_per_samp = (hdr.hns - 1) * ((double)hdr.hdt / 1000.); /* was picosec */ /* Extract S&S info from SEG-Y reel header */ /* copy ASCII part of header and terminate strings */ comment_size = sizeof(hdr.comment); record_length = 80; /* bytes */ max_records = comment_size / record_length; /* should be 40 */ memcpy((void*)string,(void*)hdr.comment, (size_t)_MINN(comment_size,3200)); for (i=0; i 0) InfoPtr->total_traces = itemp; break; case 1: itemp = atoi(cp); if (itemp > 0) InfoPtr->data_samps = itemp; break; case 3: itemp = atoi(cp); if (itemp > 0) InfoPtr->total_time = atoi(cp); break; case 6: step_size = atof(cp); break; default: break; } } if (InfoPtr->data_samps > 1 && InfoPtr->total_time > 0.0) InfoPtr->ns_per_samp = InfoPtr->total_time / (InfoPtr->data_samps - 1); else InfoPtr->ns_per_samp = 0; if (hdr.format == 3) InfoPtr->first_proc_samp = 240/2; /* short int */ else /* 240 header bytes / samp bytes */ InfoPtr->first_proc_samp = 240/4; /* long int or float */ if (Debug) { printf("total_traces = %u data_samps = %u total_time = %g\n", InfoPtr->total_traces,InfoPtr->data_samps,InfoPtr->total_time); printf("ns_per_samp = %g datatype = %d first_proc_samp = %d\n", InfoPtr->ns_per_samp,InfoPtr->input_datatype,InfoPtr->first_proc_samp); getch(); } if (step_size == 0.0) { if (InfoPtr->mrk_infilename[0] && InfoPtr->xyz_infilename[0]) { int num_mrk_ticks,num_xyz_ticks; extern const char *GetMrkDataMsg[]; /* in gpr_io.h */ extern const char *GetXyzDataMsg[]; /* in gpr_io.h */ /* NOTE: GetMrkData() and GetXyzData() allocate storage for ->tick_tracenum[] and ->tick_xyz[][] */ itemp = GetMrkData(InfoPtr->mrk_infilename,&num_mrk_ticks, &(InfoPtr->tick_tracenum)); if (itemp > 0) { printf("\n%s\n",GetMrkDataMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",GetMrkDataMsg[itemp]); return 18; } InfoPtr->num_ticks = num_mrk_ticks; itemp = GetXyzData(InfoPtr->xyz_infilename,&num_xyz_ticks, &(InfoPtr->tick_xyz)); if (itemp > 0 || num_xyz_ticks != num_mrk_ticks) { printf("\n%s\n",GetXyzDataMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",GetXyzDataMsg[itemp]); if (itemp > 0) return 19; else return 20; } } else { return 17; } } else { int j; if (Debug) puts("getting distance info from SGY file"); InfoPtr->num_ticks = InfoPtr->total_traces; InfoPtr->tick_tracenum = (long *)malloc(InfoPtr->num_ticks * sizeof(long)); if (InfoPtr->tick_tracenum == NULL) { InfoPtr->num_ticks = 0; if (log_file) fprintf(log_file,"GetParameters(): malloc failed for tick_tracenum[]"); return 21; } InfoPtr->tick_xyz = (double **)malloc(InfoPtr->num_ticks * sizeof(double *)); if (InfoPtr->tick_xyz == NULL) { InfoPtr->num_ticks = 0; free(InfoPtr->tick_tracenum); InfoPtr->tick_tracenum = NULL; if (log_file) fprintf(log_file,"GetParameters(): malloc failed for tick_xyz[]"); return 21; } for (i=0; inum_ticks; i++) { InfoPtr->tick_xyz[i] = (double *)malloc(3 * sizeof(double)); if (InfoPtr->tick_xyz[i] == NULL) { for (j=0; jtick_xyz[j]); free(InfoPtr->tick_xyz); free(InfoPtr->tick_tracenum); InfoPtr->tick_xyz = NULL; InfoPtr->tick_tracenum = NULL; InfoPtr->num_ticks = 0; if (log_file) fprintf(log_file,"GetParameters(): malloc failed for tick_xyz[][]"); return 21; } } for (i=0; inum_ticks; i++) { InfoPtr->tick_tracenum[i] = i; InfoPtr->tick_xyz[i][0] = i * step_size; /* X */ InfoPtr->tick_xyz[i][1] = 0.0; /* Y */ InfoPtr->tick_xyz[i][2] = 0.0; /* Z */ /* elev. data can be stored in each trace header ! */ } InfoPtr->spatial_dir = X_DIR; } } else if (InfoPtr->storage_format == USR) /* USR must equal 4 */ { itemp = GetOtherInfo(InfoPtr); if (Debug) { puts("After GetOtherInfo():"); printf("total_traces = %u data_samps = %u total_time = %g\n", InfoPtr->total_traces,InfoPtr->data_samps,InfoPtr->total_time); printf("ns_per_samp = %g datatype = %d first_proc_samp = %d\n", InfoPtr->ns_per_samp,InfoPtr->input_datatype,InfoPtr->first_proc_samp); getch(); } if (itemp) return 9; if (InfoPtr->mrk_infilename[0] && InfoPtr->xyz_infilename[0]) { int num_mrk_ticks,num_xyz_ticks; extern const char *GetMrkDataMsg[]; /* in gpr_io.h */ extern const char *GetXyzDataMsg[]; /* in gpr_io.h */ /* NOTE: GetMrkData() and GetXyzData() allocate storage for ->tick_tracenum[] and ->tick_xyz[][] */ itemp = GetMrkData(InfoPtr->mrk_infilename,&num_mrk_ticks, &(InfoPtr->tick_tracenum)); if (itemp > 0) { printf("\n%s\n",GetMrkDataMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",GetMrkDataMsg[itemp]); return 18; } InfoPtr->num_ticks = num_mrk_ticks; itemp = GetXyzData(InfoPtr->xyz_infilename,&num_xyz_ticks, &(InfoPtr->tick_xyz)); if (itemp > 0 || num_xyz_ticks != num_mrk_ticks) { printf("\n%s\n",GetXyzDataMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",GetXyzDataMsg[itemp]); if (itemp > 0) return 19; else return 20; } } else { return 17; } } else /* unknown or unspecified storage format */ { return 10; } /***** Finish initializing variables and verifying valid ranges *****/ if (Debug) puts("Start of initialize and check section"); /* Check for valid ranges in required parameters */ switch (InfoPtr->input_datatype) { case 1: case -1: samp_bytes = 1; break; case 2: case -2: case -5: samp_bytes = 2; break; case 3: case -3: case 4: case -6: samp_bytes = 4; break; case 8: samp_bytes = 8; break; default: return 11; /* break; ** unreachable code */ } if (InfoPtr->total_traces < 2) return 12; if (InfoPtr->data_samps < 2) return 13; if (InfoPtr->ns_per_samp <= 0.0) return 14; /* Limit first and last traces used to valid ranges */ if (InfoPtr->first_trace < 0) InfoPtr->first_trace = 0; if (InfoPtr->last_trace < 0) InfoPtr->last_trace = InfoPtr->total_traces - 1; if (InfoPtr->last_trace <= InfoPtr->first_trace) InfoPtr->last_trace = InfoPtr->total_traces - 1; if (InfoPtr->last_trace > InfoPtr->total_traces - 1) InfoPtr->last_trace = InfoPtr->total_traces - 1; if (InfoPtr->first_trace >= InfoPtr->last_trace) InfoPtr->first_trace = 0; /* Verify coordinate ranges, determine number of input columns (traces), allocate storage for and assign trace_Xvals, trace_Yvals, and trace_Zvals, find smallest and largest spacing between traces from trace_?vals. */ itemp = GetXfrmRanges(InfoPtr); if (itemp > 0) { printf("\n%s\n",GetXfrmRangesMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",GetXfrmRangesMsg[itemp]); return 25; } /* Assign number of rows in the input data grid */ itemp = InfoPtr->trace_header_bytes/samp_bytes; /* truncation expected */ if ((itemp * samp_bytes) != InfoPtr->trace_header_bytes) return 15; InfoPtr->num_rows = (InfoPtr->trace_header_bytes/samp_bytes) + InfoPtr->data_samps; /* Calculate number of output traces (same as number of bins) */ if (InfoPtr->spatial_dir != 0 && InfoPtr->spatial_dir != 1) InfoPtr->spatial_dir = 0; dtemp = InfoPtr->spatial_stop - InfoPtr->spatial_start; dtemp2 = dtemp/InfoPtr->spatial_step; if (dtemp2 < 0.0) { if (log_file) { fprintf(log_file,"%s\n",GetParametersMsg[27]); fprintf(log_file,"\nstart=%g stop=%g step=%g\n",InfoPtr->spatial_start, InfoPtr->spatial_stop,InfoPtr->spatial_step); } return 27; } dtemp3 = dtemp2 * InfoPtr->spatial_step; dtemp4 = _ABS(dtemp3 - dtemp); if (dtemp4 > 0.0) { if (log_file) { fprintf(log_file,"%s\n",GetParametersMsg[16]); fprintf(log_file,"\nstop=%g start=%g stop-start=%g\nnum_steps=%g step=%g num_steps*step=%g diff=%g\n",InfoPtr->spatial_stop, InfoPtr->spatial_start,dtemp,dtemp2,InfoPtr->spatial_step,dtemp3); } return 16; } InfoPtr->num_bins = (int)dtemp2 + 1; if (InfoPtr->num_bins > InfoPtr->num_cols) { if (log_file) { fprintf(log_file,"num_bins = %ld\n",InfoPtr->num_bins); } return 26; } /* Check bin size */ if (InfoPtr->bin_size == 0.0) InfoPtr->bin_size = _ABS(InfoPtr->spatial_step); /* Set mean_value to appropriate value */ switch (InfoPtr->input_datatype) { case 1: case 2: case 3: case 4: case 8: /* signed data */ InfoPtr->mean_value = 0.0; break; case -1: /* unsigned characters */ InfoPtr->mean_value = 128.0; break; case -2: /* unsigned shorts or 2-byte ints */ InfoPtr->mean_value = 32768.0; break; case -3: /* unsigned longs or 4-byte ints */ InfoPtr->mean_value = 2147483648.0; break; case -5: /* unsigned shorts, only first 12 bits used */ InfoPtr->mean_value = 2048.0; break; case -6: /* unsigned longs, only first 24 bits used */ InfoPtr->mean_value = 8388608.0; break; } return 0; } /****************************** GetOtherInfo() ******************************/ /* Verify info read from command file and calculate remaining minimum * required values. * * Parameters: * struct XfrmParamInfoStruct *InfoPtr - adress of information structure * * NOTE: Storage for variables pointed to in parameters list must have been * allocated prior to calling this function. * * Requires: , "gpr_disp.h" * Calls: fopen, fclose, ftell, fseek. * Returns: 0 on success, * >0 on error. * * Author: Jeff Lucius USGS Mineral Resources Program Lakewood, CO * Date: January 31, 1996 */ int GetOtherInfo (struct XfrmParamInfoStruct *InfoPtr) { int error = 0; long samp_size; FILE *infile; /* Make sure info read correctly from command file */ if (InfoPtr->input_datatype == 0) error = 1; if (InfoPtr->data_samps == 0) error = 2; if (InfoPtr->file_header_bytes < 0) error = 3; if (InfoPtr->trace_header_bytes < 0) error = 4; if (InfoPtr->data_samps < 2) error = 6; /* Calculate number of bytes in 1 trace sample */ switch (InfoPtr->input_datatype) { case 1: case -1: samp_size = 1; break; case 2: case -2: case -5: samp_size = 2; break; case 3: case -3: case 4: case -6: samp_size = 4; break; case 8: samp_size = 8; break; default: error = 7; break; } /* Calculate the rest of minimal required info */ if (!error) { InfoPtr->ns_per_samp = InfoPtr->total_time/(InfoPtr->data_samps-1); InfoPtr->first_proc_samp = InfoPtr->trace_header_bytes/samp_size; if ((infile = fopen(InfoPtr->dat_infilename,"rb")) == NULL) { error = 8; printf("ERROR occurred attempting to open file %s\n",InfoPtr->dat_infilename); if (log_file) fprintf(log_file,"ERROR occurred attempting to open file %s\n",InfoPtr->dat_infilename); } else { /* determine number of GPR traces in file */ long start_byte,last_byte,num_bytes; fseek(infile,(long)InfoPtr->file_header_bytes,SEEK_SET); start_byte = ftell(infile); /* get current location (byte) */ fseek(infile, 0L, SEEK_END); /* go to end of file */ last_byte = ftell(infile); /* get last location (byte) */ num_bytes = last_byte - start_byte; InfoPtr->total_traces = num_bytes / ((InfoPtr->data_samps * samp_size) + InfoPtr->trace_header_bytes); fclose(infile); } } return error; } /****************************** GetXfrmRanges() *****************************/ /* Find limits for spatial_start and spatial_stop and first_trace and last_trace. * Spline to get X, Y, and Z locations for each trace. * Find smallest and largest spacing between traces from "Xvals". * * Parameter list: * struct DispParamInfoStruct *InfoPtr - address of structure * * Requires: "assertjl.h", , , , "gpr_disp.h" * Calls: assert, malloc, free, sqrt, Spline, printf. * Returns: 0 on success, * >0 on error (offset into message string array) * const char *GetXfrmRangesMsg[] = { "GetXfrmRanges() No error.", "GetXfrmRanges() ERROR: Number of marked traces < 2.", "GetXfrmRanges() ERROR: Marked traces outside data range.", "GetXfrmRanges() ERROR: spatial_start/_stop are the reverse of data direction.", "GetXfrmRanges() ERROR: Problem splining data topography.", *5* "GetXfrmRanges() ERROR: Not able to allocate sufficient temporary storage.", } ; * * Author: Jeff Lucius USGS Mineral Resources Program Golden, CO * Date: February 11, 1997 */ int GetXfrmRanges (struct XfrmParamInfoStruct *InfoPtr) { int i,itemp,error; int dat_forward; /* records whether trace locations are increasing or decreasing */ int hor_forward; /* records whether hor. dir. is increasing or decreasing */ double dtemp; double *trace_num = NULL; /* usable trace numbers */ double *y = NULL; /* "y" values pulled out of tick_xyz[][] */ double *tick_tracenum = NULL; /* copy InfoPtr array into double array */ extern const char *SplineMsg[]; extern FILE *log_file; extern int Debug; /* Check that arrays are allocated */ assert(InfoPtr->tick_tracenum && InfoPtr->tick_xyz); /* Must have at least 2 tick marks and valid data sets */ if (InfoPtr->num_ticks < 2) return 1; /* Verify range of tick marks at least partially overlaps data; last_trace is always >= first_trace; tracenum[] always increases. */ if ((InfoPtr->tick_tracenum[0] > InfoPtr->last_trace) || (InfoPtr->tick_tracenum[InfoPtr->num_ticks-1] < InfoPtr->first_trace) ) return 2; /* Limit start and stop to valid ranges and find first and last traces */ switch (InfoPtr->spatial_dir) { case X_DIR: /* X-coordinates */ /* verify requested horizontal start and stop within data range */ if (InfoPtr->tick_xyz[0][0] < InfoPtr->tick_xyz[InfoPtr->num_ticks-1][0]) InfoPtr->dat_forward = dat_forward = TRUE; else InfoPtr->dat_forward = dat_forward = FALSE; if (InfoPtr->spatial_start == INVALID_VALUE) InfoPtr->spatial_start = InfoPtr->tick_xyz[0][0]; if (InfoPtr->spatial_stop == INVALID_VALUE) InfoPtr->spatial_stop = InfoPtr->tick_xyz[InfoPtr->num_ticks-1][0]; if (InfoPtr->spatial_start < InfoPtr->spatial_stop) hor_forward = TRUE; else hor_forward = FALSE; if (dat_forward != hor_forward) return 3; /* find start and stop traces */ if (dat_forward) { if (hor_forward) { /* find first trace */ if (InfoPtr->spatial_start <= InfoPtr->tick_xyz[0][0]) { InfoPtr->first_trace = InfoPtr->tick_tracenum[0]; } else { for (i=1; inum_ticks; i++) { if (InfoPtr->spatial_start >= InfoPtr->tick_xyz[i-1][0] && InfoPtr->spatial_start < InfoPtr->tick_xyz[i][0]) InfoPtr->first_trace = InfoPtr->tick_tracenum[i-1]; } } /* find last_trace */ if (InfoPtr->spatial_stop >= InfoPtr->tick_xyz[InfoPtr->num_ticks-1][0]) { InfoPtr->last_trace = InfoPtr->tick_tracenum[InfoPtr->num_ticks-1]; } else { for (i=1; inum_ticks; i++) { if (InfoPtr->spatial_stop > InfoPtr->tick_xyz[i-1][0] && InfoPtr->spatial_stop <= InfoPtr->tick_xyz[i][0] ) InfoPtr->last_trace = InfoPtr->tick_tracenum[i]; } } } } else { if (!hor_forward) { /* find first trace */ if (InfoPtr->spatial_start >= InfoPtr->tick_xyz[0][0]) { InfoPtr->first_trace = InfoPtr->tick_tracenum[0]; } else { for (i=1; inum_ticks; i++) { if (InfoPtr->spatial_start <= InfoPtr->tick_xyz[i-1][0] && InfoPtr->spatial_start > InfoPtr->tick_xyz[i][0]) InfoPtr->first_trace = InfoPtr->tick_tracenum[i-1]; } } /* find last trace */ if (InfoPtr->spatial_stop <= InfoPtr->tick_xyz[InfoPtr->num_ticks-1][0]) { InfoPtr->last_trace = InfoPtr->tick_tracenum[InfoPtr->num_ticks-1]; } else { for (i=1; inum_ticks; i++) { if (InfoPtr->spatial_stop < InfoPtr->tick_xyz[i-1][0] && InfoPtr->spatial_stop >= InfoPtr->tick_xyz[i][0] ) InfoPtr->last_trace = InfoPtr->tick_tracenum[i]; } } } } break; case Y_DIR: /* y-coordinates */ /* verify requested horizontal start and stop within data range */ if (InfoPtr->tick_xyz[0][1] < InfoPtr->tick_xyz[InfoPtr->num_ticks-1][1]) InfoPtr->dat_forward = dat_forward = TRUE; else InfoPtr->dat_forward = dat_forward = FALSE; if (InfoPtr->spatial_start == INVALID_VALUE) InfoPtr->spatial_start = InfoPtr->tick_xyz[0][1]; if (InfoPtr->spatial_stop == INVALID_VALUE) InfoPtr->spatial_stop = InfoPtr->tick_xyz[InfoPtr->num_ticks-1][1]; if (InfoPtr->spatial_start < InfoPtr->spatial_stop) hor_forward = TRUE; else hor_forward = FALSE; if (dat_forward != hor_forward) return 3; /* find start and stop traces */ if (dat_forward) { if (hor_forward) { /* find first trace */ if (InfoPtr->spatial_start <= InfoPtr->tick_xyz[0][1]) { InfoPtr->first_trace = InfoPtr->tick_tracenum[0]; } else { for (i=1; inum_ticks; i++) { if (InfoPtr->spatial_start >= InfoPtr->tick_xyz[i-1][1] && InfoPtr->spatial_start < InfoPtr->tick_xyz[i][1]) InfoPtr->first_trace = InfoPtr->tick_tracenum[i-1]; } } /* find last_trace */ if (InfoPtr->spatial_stop >= InfoPtr->tick_xyz[InfoPtr->num_ticks-1][1]) { InfoPtr->last_trace = InfoPtr->tick_tracenum[InfoPtr->num_ticks-1]; } else { for (i=1; inum_ticks; i++) { if (InfoPtr->spatial_stop > InfoPtr->tick_xyz[i-1][1] && InfoPtr->spatial_stop <= InfoPtr->tick_xyz[i][1] ) InfoPtr->last_trace = InfoPtr->tick_tracenum[i]; } } } } else { if (!hor_forward) { /* find first trace */ if (InfoPtr->spatial_start >= InfoPtr->tick_xyz[0][1]) { InfoPtr->first_trace = InfoPtr->tick_tracenum[0]; } else { for (i=1; inum_ticks; i++) { if (InfoPtr->spatial_start <= InfoPtr->tick_xyz[i-1][1] && InfoPtr->spatial_start > InfoPtr->tick_xyz[i][1]) InfoPtr->first_trace = InfoPtr->tick_tracenum[i-1]; } } /* find last trace */ if (InfoPtr->spatial_stop <= InfoPtr->tick_xyz[InfoPtr->num_ticks-1][1]) { InfoPtr->last_trace = InfoPtr->tick_tracenum[InfoPtr->num_ticks-1]; } else { for (i=1; inum_ticks; i++) { if (InfoPtr->spatial_stop < InfoPtr->tick_xyz[i-1][1] && InfoPtr->spatial_stop >= InfoPtr->tick_xyz[i][1] ) InfoPtr->last_trace = InfoPtr->tick_tracenum[i]; } } } } break; } /* end of switch on spatial_dir block */ /* Determine number of columns */ InfoPtr->num_cols = InfoPtr->last_trace - InfoPtr->first_trace + 1; /* Allocate temporary storage and spline vectors as required */ InfoPtr->trace_Xval = (double *)malloc((size_t)InfoPtr->num_cols * sizeof(double)); InfoPtr->trace_Yval = (double *)malloc((size_t)InfoPtr->num_cols * sizeof(double)); InfoPtr->trace_Zval = (double *)malloc((size_t)InfoPtr->num_cols * sizeof(double)); trace_num = (double *)malloc((size_t)InfoPtr->num_cols * sizeof(double)); tick_tracenum = (double *)malloc((size_t)InfoPtr->num_ticks * sizeof(double)); y = (double *)malloc((size_t)InfoPtr->num_ticks * sizeof(double)); if ( trace_num == NULL || y == NULL || tick_tracenum == NULL || InfoPtr->trace_Xval == NULL || InfoPtr->trace_Yval == NULL || InfoPtr->trace_Zval == NULL ) { free(tick_tracenum); free(trace_num); free(y); free(InfoPtr->trace_Xval); free(InfoPtr->trace_Yval); free(InfoPtr->trace_Zval); InfoPtr->trace_Xval = NULL; InfoPtr->trace_Yval = NULL; InfoPtr->trace_Zval = NULL; return 5; } /* Assign values for Spline() */ for (i=0; inum_cols; i++) trace_num[i] = InfoPtr->first_trace + i; if (trace_num[InfoPtr->num_cols - 1] > InfoPtr->last_trace) trace_num[InfoPtr->num_cols - 1] = InfoPtr->last_trace; for (i=0; inum_ticks; i++) tick_tracenum[i] = InfoPtr->tick_tracenum[i]; /* Spline to get X, Y, and Z values for every trace used */ error = 0; for (i=0; inum_ticks; i++) y[i] = InfoPtr->tick_xyz[i][0]; /* X-coordinates */ itemp = Spline(InfoPtr->num_ticks,InfoPtr->num_cols, tick_tracenum,y,trace_num,InfoPtr->trace_Xval); if (itemp > 0) { printf("\ntrace_Xval (X): %s\n",SplineMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",SplineMsg[itemp]); error = 4; } for (i=0; inum_ticks; i++) y[i] = InfoPtr->tick_xyz[i][1]; /* Y-coordinates */ itemp = Spline(InfoPtr->num_ticks,InfoPtr->num_cols, tick_tracenum,y,trace_num,InfoPtr->trace_Yval); if (itemp > 0) { printf("\ntrace_Yval (Y): %s\n",SplineMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",SplineMsg[itemp]); error = 4; } for (i=0; inum_ticks; i++) y[i] = InfoPtr->tick_xyz[i][2]; /* Z-coordinates */ itemp = Spline(InfoPtr->num_ticks,InfoPtr->num_cols, tick_tracenum,y,trace_num,InfoPtr->trace_Zval); if (itemp > 0) { printf("\ntrace_Zval (Y): %s\n",SplineMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",SplineMsg[itemp]); error = 4; } /* Find min and max trace separations */ InfoPtr->min_trace_sep = 1000.0; InfoPtr->max_trace_sep = -1000.0; switch (InfoPtr->spatial_dir) { case X_DIR: for (i=1; inum_cols; i++) { dtemp = _ABS(InfoPtr->trace_Xval[i] - InfoPtr->trace_Xval[i-1]); if (dtemp < InfoPtr->min_trace_sep) InfoPtr->min_trace_sep = dtemp; if (dtemp > InfoPtr->max_trace_sep) InfoPtr->max_trace_sep = dtemp; } break; case Y_DIR: for (i=1; inum_cols; i++) { dtemp = _ABS(InfoPtr->trace_Yval[i] - InfoPtr->trace_Yval[i-1]); if (dtemp < InfoPtr->min_trace_sep) InfoPtr->min_trace_sep = dtemp; if (dtemp > InfoPtr->max_trace_sep) InfoPtr->max_trace_sep = dtemp; } break; } free(tick_tracenum); free(trace_num); free(y); return error; } /****************************** PrintUsageMsg() *****************************/ /* Prints message to user on stdout. * * Requires: . * Calls: puts. * Returns: void. * * Author: Jeff Lucius USGS Mineral Resources Program Lakewood, CO * Date: February 7, 1997; April 17, 2001; */ void PrintUsageMsg (void) { extern int ANSI_THERE; puts(""); if (ANSI_THERE) printf("%c%c32;40m",0x1B,0x5B); /* green on black */ puts("\n###############################################################################"); puts(" Usage: GPR_XFRM cmd_filename"); puts(" Computer code written by Jeff Lucius, USGS, lucius@usgs.gov."); puts(" This program transforms radar data by converting traces equally spaced in"); puts(" in time to equally spaced in location or distance."); puts(" The new file is saved to disk along with matching MRK and XYZ files."); puts(" Required command line arguments:"); puts(" cmd_filename - name of text file that follows the \"CMD\" format."); puts(" Look at \"GPR_XFRM.CMD\" and \"GPR_XFRM.TXT\" for keyword file format, valid"); puts(" keywords, and documentation."); puts(" Example call: GPR_XFRM xfile1.cmd"); printf(" Version %s - Last Revision Date: %s at %s\n",GPR_XFRM_VER,DATETIME,__TIME__); puts("###############################################################################"); if (ANSI_THERE) printf("%c%c37;40m",0x1B,0x5B); /* white on black */ } /***************************** InitParameters() *****************************/ /* Initialize all processing parameters to start-up (default) values. * * Parameter list: * struct XfrmParamInfoStruct *InfoPtr - address of structure * * Requires: "gpr_xfrm.h". * Calls: none. * Returns: void. * * Author: Jeff Lucius USGS Mineral Resources Program Lakewood, CO * Date: February 11, 1997; April 16, 2001; */ void InitParameters (struct XfrmParamInfoStruct *InfoPtr) { int i; InfoPtr->cmd_filename[0] = 0; InfoPtr->dat_infilename[0] = 0; InfoPtr->inf_infilename[0] = 0; InfoPtr->mrk_infilename[0] = 0; InfoPtr->xyz_infilename[0] = 0; InfoPtr->dat_outfilename[0] = 0; InfoPtr->inf_outfilename[0] = 0; InfoPtr->mrk_outfilename[0] = 0; InfoPtr->xyz_outfilename[0] = 0; InfoPtr->storage_format = 0; InfoPtr->input_datatype = 0; InfoPtr->file_header_bytes = 0; InfoPtr->trace_header_bytes = 0; InfoPtr->channel = 0; InfoPtr->first_proc_samp = 0; InfoPtr->data_samps = 0; InfoPtr->total_traces = 0; InfoPtr->first_trace = -1; InfoPtr->last_trace = -1; InfoPtr->total_time = 0.0; InfoPtr->ns_per_samp = 0.0; InfoPtr->num_ticks = 0; InfoPtr->tick_tracenum = NULL; InfoPtr->tick_xyz = NULL; InfoPtr->trace_Xval = NULL; InfoPtr->trace_Yval = NULL; InfoPtr->trace_Zval = NULL; InfoPtr->spatial_dir = X_DIR; InfoPtr->spatial_start = INVALID_VALUE; InfoPtr->spatial_stop = INVALID_VALUE; InfoPtr->spatial_step = 0.0; InfoPtr->show_stats = FALSE; InfoPtr->mean_value = INVALID_VALUE; for (i=0; iproc_hist); i++) InfoPtr->proc_hist[i] = 0; InfoPtr->BinArray = NULL; InfoPtr->num_bins = 0; InfoPtr->bin_size = 0.0; InfoPtr->min_trace_sep = 0.0; InfoPtr->max_trace_sep = 0.0; InfoPtr->created = FALSE; InfoPtr->grid = NULL; InfoPtr->num_cols = 0; InfoPtr->num_rows = 0; } /***************************** GetCmdFileArgs() *****************************/ /* Get processing parameters from user from the DOS command line. * Valid file commands: const char *GPR_XFRM_CMDS[] = { "debug","batch","dat_infilename","mrk_infilename","xyz_infilename", "file_header_bytes","trace_header_bytes","samples_per_trace","total_time","input_datatype", "dat_outfilename","channel","spatial_dir","spatial_start","spatial_stop", "spatial_step","bin_size","other_format","show_stats",NULL, } ; * Parameter list: * struct XfrmParamInfoStruct *InfoPtr - address of structure * * Requires: "assertjl.h", , , , "gpr_xfrm.h". * Calls: fopen, fclose, fgets, atoi, atof, strcpy, strstr, strncat, strchr, * strcmp, strlwr (non-ANSI), strupr (non-ANSI), Trimstr, strncpy, * assert. * Returns: 0 on success, * >0 on error (offsets 2, 3, and 4 into GetParametersMsg[] strings). * * Author: Jeff Lucius USGS Mineral Resources Program Lakewood, CO * Date: February 11, 1997 */ int GetCmdFileArgs (struct XfrmParamInfoStruct *InfoPtr) { char str[MAX_CMDLINELEN],*cp,*cp2,*cp3,*cp4,cmdstr[30]; int found,i,num,itemp,have_string; int dat_in_found = FALSE; int dat_out_found = FALSE; double dtemp; FILE *infile = NULL; extern int Debug; extern const char *GPR_XFRM_CMDS[]; if ((infile = fopen(InfoPtr->cmd_filename,"rt")) == NULL) { char *cptr; if ((cptr = strchr(InfoPtr->cmd_filename,'.')) == NULL) { strcat(InfoPtr->cmd_filename,"."); if ((infile = fopen(InfoPtr->cmd_filename,"rt")) == NULL) { strcat(InfoPtr->cmd_filename,"cmd"); if ((infile = fopen(InfoPtr->cmd_filename,"rt")) == NULL) return 2; } } else { *cptr = 0; strcat(InfoPtr->cmd_filename,".cmd"); if ((infile = fopen(InfoPtr->cmd_filename,"rt")) == NULL) return 2; } } have_string = FALSE; while (1) /* read till EOF or error */ { if (have_string == FALSE) /* if have not already retrieved file line */ { if (fgets(str,MAX_CMDLINELEN,infile) == NULL) break; /* out of while(1) loop */ } else { have_string = FALSE; } cmdstr[0] = 0; /* set to 0 so strncat() works right */ cp = strchr(str,'='); /* look for equal sign */ if (cp == NULL) continue; /* invalid command line so ignore */ num = (int)(cp-str); /* number of chars before equal sign */ strncat(cmdstr,str,(size_t)num); /* copy to working string */ TrimStr(cmdstr); /* remove leading and trailing blanks */ found = -1; i = 0; while (GPR_XFRM_CMDS[i]) /* requires last member to be NULL */ { if (strcmp(strlwr(cmdstr),GPR_XFRM_CMDS[i]) == 0) { found = i; /* store index into GPR_XFRM_CMDS[] */ break; } i++; } if (found == -1) continue; /* bad or missing command word */ cp++; /* step 1 past equal sign */ /* truncate string at semicolon if present outside of double quotes */ cp2 = cp3 = cp4 = NULL; /* initialize pointers */ cp2 = strchr(cp,'"'); /* see if first quote present */ if (cp2 != NULL) cp3 = strchr(cp2+1,'"'); /* see if second quote present */ cp4 = strchr(cp,';'); /* see if semicolon present */ if (cp4 != NULL) /* if present ... */ { if (cp3 != NULL) { if (cp4 < cp2 || cp4 > cp3) *cp4 = 0; /* truncate at semicolon */ } } TrimStr(cp); /* remove leading and trailing blanks */ #if 1 if (Debug) { printf("cp = %s\n",cp); getch(); } #endif switch (found) /* cases depend on same order in GPR_XFRM_CMDS[] */ { case 0: itemp = 0; cp2 = strchr(cp,'"'); /* look for first quote */ if (cp2 != NULL) { cp = cp2 + 1; /* step past quote */ cp2 = strchr(cp,'"'); /* look for second quote */ if (cp2 != NULL) { *cp2 = 0; /* truncate at second quote */ if (strstr(strupr(cp),"TRUE")) itemp = TRUE; else if (strstr(strupr(cp),"FALSE")) itemp = FALSE; } } else itemp = atoi(cp); if (itemp == 0) Debug = FALSE; else Debug = TRUE; break; case 1: itemp = 0; cp2 = strchr(cp,'"'); /* look for first quote */ if (cp2 != NULL) { cp = cp2 + 1; /* step past quote */ cp2 = strchr(cp,'"'); /* look for second quote */ if (cp2 != NULL) { *cp2 = 0; /* truncate at second quote */ if (strstr(strupr(cp),"TRUE")) itemp = TRUE; else if (strstr(strupr(cp),"FALSE")) itemp = FALSE; } } else itemp = atoi(cp); if (itemp == 0) Batch = FALSE; else Batch = TRUE; break; case 2: cp2 = strchr(cp,'"'); /* look for first quote */ if (cp2 == NULL) break; cp = cp2 + 1; /* step past quote */ cp2 = strchr(cp,'"'); /* look for second quote */ if (cp2 == NULL) break; *cp2 = 0; /* truncate at second quote */ strncpy(InfoPtr->dat_infilename,cp,sizeof(InfoPtr->dat_infilename)-1); strcat(InfoPtr->dat_infilename,"\0"); strupr(InfoPtr->dat_infilename); if (strstr(InfoPtr->dat_infilename,".DT1") != NULL) { strcpy(InfoPtr->inf_infilename,InfoPtr->dat_infilename); cp2 = strstr(InfoPtr->inf_infilename,"."); *cp2 = 0; strcat(InfoPtr->inf_infilename,".HD"); if (Debug) printf("info file = %s\n",InfoPtr->inf_infilename); } if (InfoPtr->dat_infilename[0]) dat_in_found = TRUE; if (Debug) printf("data=%s\n",InfoPtr->dat_infilename); break; case 3: cp2 = strchr(cp,'"'); /* look for first quote */ if (cp2 == NULL) break; cp = cp2 + 1; /* step past quote */ cp2 = strchr(cp,'"'); /* look for second quote */ if (cp2 == NULL) break; *cp2 = 0; /* truncate at second quote */ strncpy(InfoPtr->mrk_infilename,cp,sizeof(InfoPtr->mrk_infilename)-1); strcat(InfoPtr->mrk_infilename,"\0"); strupr(InfoPtr->mrk_infilename); if (Debug) printf("data=%s\n",InfoPtr->mrk_infilename); break; case 4: cp2 = strchr(cp,'"'); /* look for first quote */ if (cp2 == NULL) break; cp = cp2 + 1; /* step past quote */ cp2 = strchr(cp,'"'); /* look for second quote */ if (cp2 == NULL) break; *cp2 = 0; /* truncate at second quote */ strncpy(InfoPtr->xyz_infilename,cp,sizeof(InfoPtr->xyz_infilename)-1); strcat(InfoPtr->xyz_infilename,"\0"); strupr(InfoPtr->xyz_infilename); if (Debug) printf("data=%s\n",InfoPtr->xyz_infilename); break; case 5: itemp = atoi(cp); if (itemp > 0) InfoPtr->file_header_bytes = itemp; if (Debug) printf("file_header_bytes = %d\n",InfoPtr->file_header_bytes); break; case 6: itemp = atoi(cp); if (itemp > 0) InfoPtr->trace_header_bytes = itemp; if (Debug) printf("trace_header_bytes = %d\n",InfoPtr->trace_header_bytes); break; case 7: /* samples_per_trace */ itemp = atoi(cp); if (itemp >= 0) InfoPtr->data_samps = itemp; if (Debug) printf("data_samps = %d\n",InfoPtr->data_samps); break; case 8: dtemp = atof(cp); if (dtemp > 0.0) InfoPtr->total_time = dtemp; if (Debug) printf("total_time = %g\n",InfoPtr->total_time); break; case 9: itemp = atoi(cp); if (Debug) printf("itemp (input_datatype) = %d\n",itemp); switch (itemp) { case -6: case -5: case -3: case -2: case -1: case 1: case 2: case 3: case 4: case 8: InfoPtr->input_datatype = itemp; break; default: InfoPtr->input_datatype = 0; break; } if (Debug) printf("input_datatype = %d\n",InfoPtr->input_datatype); break; case 10: cp2 = strchr(cp,'"'); /* look for first quote */ if (cp2 == NULL) break; cp = cp2 + 1; /* step past quote */ cp2 = strchr(cp,'"'); /* look for second quote */ if (cp2 == NULL) break; *cp2 = 0; /* truncate at second quote */ strncpy(InfoPtr->dat_outfilename,cp,sizeof(InfoPtr->dat_outfilename)-1); strcat(InfoPtr->dat_outfilename,"\0"); strupr(InfoPtr->dat_outfilename); if (InfoPtr->dat_outfilename[0]) dat_out_found = TRUE; cp2 = strstr(InfoPtr->dat_outfilename,".DT1"); if (cp2 != NULL) { strncpy(InfoPtr->inf_outfilename,InfoPtr->dat_outfilename, (size_t)(cp2-InfoPtr->dat_outfilename)); strcat(InfoPtr->inf_outfilename,".HD\0"); } cp2 = strstr(InfoPtr->dat_outfilename,"."); if (cp2 != NULL) { strncpy(InfoPtr->xyz_outfilename,InfoPtr->dat_outfilename, (size_t)(cp2-InfoPtr->dat_outfilename)); strcat(InfoPtr->xyz_outfilename,".XYZ\0"); strncpy(InfoPtr->mrk_outfilename,InfoPtr->dat_outfilename, (size_t)(cp2-InfoPtr->dat_outfilename)); strcat(InfoPtr->mrk_outfilename,".MRK\0"); } break; case 11: itemp = atoi(cp); if (itemp >= 0) InfoPtr->channel = itemp; break; case 12: itemp = atoi(cp); if (itemp >= 0 && itemp < NUM_SPATIAL_DIR) InfoPtr->spatial_dir = itemp; break; case 13: cp2 = strchr(cp,'"'); /* look for first quote */ if (cp2 != NULL) { cp = cp2 + 1; /* step past quote */ cp2 = strchr(cp,'"'); /* look for second quote */ if (cp2 != NULL) { *cp2 = 0; /* truncate at second quote */ if (strstr(cp,"INVALID_VALUE")) InfoPtr->spatial_start = INVALID_VALUE; } } else { InfoPtr->spatial_start = atof(cp); } break; case 14: cp2 = strchr(cp,'"'); /* look for first quote */ if (cp2 != NULL) { cp = cp2 + 1; /* step past quote */ cp2 = strchr(cp,'"'); /* look for second quote */ if (cp2 != NULL) { *cp2 = 0; /* truncate at second quote */ if (strstr(cp,"INVALID_VALUE")) InfoPtr->spatial_stop = INVALID_VALUE; } } else { InfoPtr->spatial_stop = atof(cp); } break; case 15: cp2 = strchr(cp,'"'); /* look for first quote */ if (cp2 != NULL) { cp = cp2 + 1; /* step past quote */ cp2 = strchr(cp,'"'); /* look for second quote */ if (cp2 != NULL) { *cp2 = 0; /* truncate at second quote */ if (strstr(cp,"INVALID_VALUE")) InfoPtr->spatial_step = INVALID_VALUE; } } else { InfoPtr->spatial_step = atof(cp); } break; case 16: dtemp = atof(cp); if (dtemp != 0.0) InfoPtr->bin_size = dtemp; break; case 17: /* other_format */ itemp = 0; cp2 = strchr(cp,'"'); /* look for first quote */ if (cp2 != NULL) { cp = cp2 + 1; /* step past quote */ cp2 = strchr(cp,'"'); /* look for second quote */ if (cp2 != NULL) { *cp2 = 0; /* truncate at second quote */ if (strstr(strupr(cp),"TRUE")) itemp = 1; else if (strstr(strupr(cp),"FALSE")) itemp = 0; } } else { itemp = atoi(cp); } if (itemp != 0) InfoPtr->storage_format = USR; if (Debug) printf("storage_format = %d\n",InfoPtr->storage_format); break; case 18: itemp = 0; cp2 = strchr(cp,'"'); /* look for first quote */ if (cp2 != NULL) { cp = cp2 + 1; /* step past quote */ cp2 = strchr(cp,'"'); /* look for second quote */ if (cp2 != NULL) { *cp2 = 0; /* truncate at second quote */ if (strstr(strupr(cp),"TRUE")) itemp = 1; else if (strstr(strupr(cp),"FALSE")) itemp = 0; } } else { itemp = atoi(cp); } if (itemp != 0) InfoPtr->show_stats = TRUE; if (Debug) printf("show_stats = %d\n",InfoPtr->show_stats); break; default: break; } } fclose(infile); if (!dat_out_found) return 3; if (!dat_in_found) return 4; return 0; } /**************************** DisplayParameters() ***************************/ /* Display parameters to CRT. Also calculates approximate storage requirements. * * Parameter list: * struct XfrmParamInfoStruct *InfoPtr - address of structure * * Requires: , "gpr_xfrm.h". * Calls: printf, puts. * Returns: void. * * Author: Jeff Lucius USGS Mineral Resources Program Lakewood, CO * Date: February 7, 1997 */ void DisplayParameters (struct XfrmParamInfoStruct *InfoPtr) { char str[10]; long in_grid_size; struct dosdate_t dosdate; struct dostime_t dostime; char *month[] = { "","January","February","March","April","May","June", "July","August","September","October", "November","December" } ; extern int Debug,Batch,ANSI_THERE; _dos_getdate(&dosdate); _dos_gettime(&dostime); if (Debug) puts("DisplayParameters()"); /* Estimate storage rerquirements */ in_grid_size = InfoPtr->num_cols * InfoPtr->num_rows; switch (InfoPtr->input_datatype) { case 2: case -2: case -5: in_grid_size *= 2; break; case 3: case -3: case 4: case -6: in_grid_size *= 4; break; case 8: in_grid_size *= 8; break; } if (ANSI_THERE) printf("%c%c31;40m",0x1B,0x5B); /* red on black */ printf("\nGPR_XFRM version %s (run time: %02d:%02d:%02d on %s %d, %d)\n", GPR_XFRM_VER,dostime.hour,dostime.minute,dostime.second, month[dosdate.month],dosdate.day,dosdate.year); printf(" Computer code written by Jeff Lucius, USGS, lucius@usgs.gov\n"); if (ANSI_THERE) printf("%c%c37;40m",0x1B,0x5B); /* white on black */ printf("cmd_filename = %s\n",strupr(InfoPtr->cmd_filename)); printf("dat_infilename = %s",strupr(InfoPtr->dat_infilename)); if (InfoPtr->storage_format == DT1 || InfoPtr->storage_format == RD3) { printf(" inf_infilename = %s\n",strupr(InfoPtr->inf_infilename)); } else puts(""); printf("mrk_infilename = %s\n",strupr(InfoPtr->mrk_infilename)); printf("xyz_infilename = %s\n",strupr(InfoPtr->xyz_infilename)); printf("dat_outfilename = %s",strupr(InfoPtr->dat_outfilename)); if (InfoPtr->storage_format == DT1 || InfoPtr->storage_format == RD3) { printf(" inf_outfilename = %s\n",strupr(InfoPtr->inf_outfilename)); } else puts(""); switch (InfoPtr->storage_format) { case DZT: puts("data storage format is GSSI SIR-10 or SIR-2"); break; case DT1: puts("data storage format is S&S PulsEKKO"); break; case SGY: puts("data storage format is SEG-Y"); break; case SG2: puts("data storage format is SEG-2"); break; case RD3: puts("data storage format is MALA RAMAC/GPR"); break; case MOD_DZT: puts("data storage format is modified GSSI DZT"); break; case USR: puts("data storage format is USER DEFINED"); printf("file_header_bytes = %d trace_header_bytes = %d\n", InfoPtr->file_header_bytes,InfoPtr->trace_header_bytes); break; default: puts("unrecognized data storage format"); break; } switch (InfoPtr->input_datatype) { case -1: puts("data element type is 8-bit unsigned integers"); break; case 1: puts("data element type is 8-bit signed integers"); break; case -2: puts("data element type is 16-bit unsigned integers"); break; case 2: puts("data element type is 16-bit signed integers"); break; case -3: puts("data element type is 32-bit unsigned integers"); break; case 3: puts("data element type is 32-bit signed integers"); break; case -5: puts("data element type is 12-bit unsigned integers"); break; case -6: puts("data element type is 24-bit unsigned integers"); break; case 4: puts("data element type is 32-bit floating point"); break; case 8: puts("data element type is 64-bit floating point"); break; default: puts("unknown data element type"); break; } if (InfoPtr->storage_format == DZT || InfoPtr->storage_format == MOD_DZT) printf("DZT channel = %d \n",InfoPtr->channel); printf("first_trace = %ld last_trace = %ld total_traces = %ld\n", InfoPtr->first_trace,InfoPtr->last_trace,InfoPtr->total_traces); printf("data_samps = %ld first_proc_samp = %ld\n", InfoPtr->data_samps,InfoPtr->first_proc_samp); printf("ns_per_samp = %g total_time = %g (ns)\n", InfoPtr->ns_per_samp,InfoPtr->total_time); printf("num_cols = %ld num_rows = %ld est. grid size = %ld bytes (%g MB)\n", InfoPtr->num_cols,InfoPtr->num_rows,in_grid_size,(double)in_grid_size/(1024.0*1024.0)); if (ANSI_THERE) printf("%c%c36;40m",0x1B,0x5B); /* cyan on black */ puts("\nTRANSFORMING PARAMETERS:"); if (ANSI_THERE) printf("%c%c37;40m",0x1B,0x5B); /* white on black */ switch (InfoPtr->spatial_dir) { case X_DIR: printf("spatial_dir = X direction\n"); break; case Y_DIR: printf("spatial_dir = Y direction\n"); break; default: puts("invalid spatial_dir selected\n"); break; } printf("spatial_start = %g spatial_stop = %g spatial_step = %g\n", InfoPtr->spatial_start,InfoPtr->spatial_stop,InfoPtr->spatial_step); printf("bin size = %g num bins = %ld\n",InfoPtr->bin_size,InfoPtr->num_bins); printf("smallest trace separation = %g largest trace separation = %g\n", InfoPtr->min_trace_sep,InfoPtr->max_trace_sep); /* Issue messages */ if (Debug) puts("In TESTing mode."); else if (Batch) puts("In Batch processing mode."); } /*************************** GetGprDataAsGrid() *****************************/ /* Get the data/info from the appropriate files. * Allocate/De-allocate storage for grid[][]. * Verify valid parameters and ranges. * * NOTE: The "created" member of struct XfrmParamInfoStruct restricts the * application of the struct to one data set and one grid at a time. * To read multiple data sets and allocate multiple grids, either * de-allocate the first one OR declare multiple structs to hold the * information and pointers. * * Method: * 1. Declare variables * 2. De-allocate storage if command==FUNC_DESTROY and return, else * 3. Test for balanced calls * 4. Allocate storage for grid[][] * 5. Copy disk file data into grid[][] * * Parameter list: * int command - 0 to allocate storage; !0 to deallocate storage * struct XfrmParamInfoStruct *InfoPtr - address of structure * * Requires: , , , "gpr_xfrm.h". * Calls: strcpy, malloc, free, printf, puts, * GetDztChSubGrid8, GetDztChSubGrid16, GetGprSubGrid. * Returns: 0 on success, * >0 on error. * const char *GetGprDataAsGridMsg[] = { "GetGprDataAsGrid(): No errors.", "GetGprDataAsGrid() ERROR: Attemp made to de-allocate storage before allocating.", "GetGprDataAsGrid() ERROR: Attemp made to re-allocate storage. De-allocate first.", "GetGprDataAsGrid() ERROR: Invalid input data element type .", "GetGprDataAsGrid() ERROR: No recognized data/info input files specified.", "GetGprDataAsGrid() ERROR: Not able to allocate storage for grid.", "GetGprDataAsGrid() ERROR: Problem getting data from input file.", } ; NOTE: message 5 is checked by calling routine (main). * * Author: Jeff Lucius USGS Mineral Resources Program Lakewood, CO * Date: February 6, 1996 */ int GetGprDataAsGrid (int command,struct XfrmParamInfoStruct *InfoPtr) { /***** Declare variables *****/ long i,j,itemp; /* scratch variables and counters */ long ptr_size; /* size of element in first dimension of grid */ long grid_col_size; /* number of bytes in one trace */ long samp_bytes; /* number of bytes in one trace sample */ /***** Deallocate storage *****/ if (command == FUNC_DESTROY) { if (!InfoPtr->created) return 1; for (i=0; inum_cols; i++) free(InfoPtr->grid[i]); free(InfoPtr->grid); InfoPtr->grid = NULL; return 0; } /***** Test for balanced calls *****/ if (InfoPtr->created) return 2; InfoPtr->created = FALSE; /***** Allocate storage for grid[][] with same type as input data sets *****/ /* get row pointer size */ switch (InfoPtr->input_datatype) { case 1: case -1: ptr_size = sizeof(char *); samp_bytes = 1; break; case 2: case -2: case -5: ptr_size = sizeof(short *); samp_bytes = 2; break; case 3: case -3: case -6: ptr_size = sizeof(long *); samp_bytes = 4; break; case 4: ptr_size = sizeof(float *); samp_bytes = 4; break; case 8: ptr_size = sizeof(double *); samp_bytes = 8; break; default: return 3; } grid_col_size = InfoPtr->num_rows * samp_bytes; InfoPtr->grid = (void **)malloc((size_t)(InfoPtr->num_cols * ptr_size)); if (InfoPtr->grid) { for (i=0; inum_cols; i++) { InfoPtr->grid[i] = (void *)malloc((size_t)grid_col_size); if (InfoPtr->grid[i] == NULL) { for (j=0; jgrid[j]); free(InfoPtr->grid); InfoPtr->grid = NULL; return 5; } } } else { return 5; } /***** Get the data *****/ itemp = 0; switch (InfoPtr->storage_format) { case DZT: case MOD_DZT: { extern const char *GetDztChSubGrid8Msg[]; /* from gpr_io.h */ extern const char *GetDztChSubGrid16Msg[]; /* from gpr_io.h */ if (InfoPtr->input_datatype == -1) { itemp = GetDztChSubGrid8(InfoPtr->dat_infilename,InfoPtr->channel, InfoPtr->first_trace,InfoPtr->num_cols,InfoPtr->num_rows, (unsigned char **)(InfoPtr->grid)); if (itemp > 0) { printf("\n%s\n",GetDztChSubGrid8Msg[itemp]); if (log_file) fprintf(log_file,"%s\n",GetDztChSubGrid8Msg[itemp]); } } else if (InfoPtr->input_datatype == -2) { itemp = GetDztChSubGrid16(InfoPtr->dat_infilename,InfoPtr->channel, InfoPtr->first_trace,InfoPtr->num_cols,InfoPtr->num_rows, (unsigned short **)(InfoPtr->grid)); if (itemp > 0) { printf("\n%s\n",GetDztChSubGrid16Msg[itemp]); if (log_file) fprintf(log_file,"%s\n",GetDztChSubGrid16Msg[itemp]); } } else { puts("\nSorry, only 8-bit and 16-bit GSSI data supported at this time."); if (log_file) fprintf(log_file,"Sorry, only 8-bit and 16-bit GSSI data supported at this time."); itemp = 1; } break; } case DT1: case SGY: case USR: { extern const char *GetGprSubGridMsg[]; itemp = GetGprSubGrid(InfoPtr->dat_infilename,InfoPtr->input_datatype, InfoPtr->file_header_bytes,InfoPtr->trace_header_bytes, InfoPtr->first_trace,InfoPtr->data_samps, InfoPtr->num_cols,InfoPtr->num_rows,InfoPtr->grid); if (itemp > 0) { printf("\n%s\n",GetGprSubGridMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",GetGprSubGridMsg[itemp]); } break; } default: /* unrecognized format */ /* deallocate storage and return error code */ for (i=0; inum_cols; i++) free(InfoPtr->grid[i]); free(InfoPtr->grid); InfoPtr->grid = NULL; return 4; } if (itemp > 0) /* problem getting data */ { /* deallocate storage and return error code */ for (i=0; inum_cols; i++) free(InfoPtr->grid[i]); free(InfoPtr->grid); InfoPtr->grid = NULL; return 6; } else { /* flag structure and return success */ InfoPtr->created = TRUE; return 0; } } /*************************** TransformGprData() *****************************/ /* This is the driver routine for transforming the GPR data. * * NOTES: Maximum trace length = 2 exp 15 = 32768 samples (32 K). * * Parameter list: * struct XfrmParamInfoStruct *ParamInfoPtr - address of information structure * * Requires: , , , "jl_util1.h", "gpr_xfrm.h". * Calls: _ABS, malloc, free, printf, puts, getch, calloc, sqrt, Spline2. * Returns: 0 on success, or * >0 if an error has occurred. * const char *TransformGprDataMsg[] = { "TransformGprData(): No errors.", "TransformGprData() ERROR: Invalid input data element type .", "TransformGprData() ERROR: Not able to allocate storage for bin array.", "TransformGprData() ERROR: At least one empty bin was found. See log file.", "TransformGprData() ERROR: Not able to allocate temporary storage.", "TransformGprData() ERROR: Problem splining data. See log file.", } ; * * Author: Jeff Lucius USGS Mineral Resources Program Lakewood, CO * Date: February 12, 1997 */ int TransformGprData (struct XfrmParamInfoStruct *InfoPtr) { /***** Declare variables *****/ int min_hits = 10000; int max_hits = -10000; int bin_empty = FALSE; int itemp; long i,j,k,count; /* scratch variables and counters */ long sum_samp; /* offset into BinArray[].sum[] */ long start_num; /* offset into trace_?val[] */ double dtemp1; double sumx, sumxx, var, stdev, mean; double *x,*y,*xnew,*ynew; /* for Spline2() */ double c1,c2,xx,x1,x2,x3,x4; /* for linear interpolation */ double diff,diff1,diff2,diff3,diff4; /* for linear interpolation */ extern int Debug; extern FILE *log_file; extern const char *TransformGprDataMsg[]; extern const char *Spline2Msg[]; /***** Allocate/Set Bin structure *****/ /* Allocate array of bin structures */ InfoPtr->BinArray = (struct XfrmBin *)malloc(InfoPtr->num_bins * sizeof(struct XfrmBin)); if (InfoPtr->BinArray == NULL) return 25; dtemp1 = _ABS(InfoPtr->bin_size) / 2.0; for (i=0; inum_bins; i++) { /* assign/initialize bin coords based on binning direction */ switch (InfoPtr->spatial_dir) { case X_DIR: InfoPtr->BinArray[i].x = InfoPtr->spatial_start + (i * InfoPtr->spatial_step); InfoPtr->BinArray[i].y = INVALID_VALUE; /* assign width limits of bin */ if (InfoPtr->dat_forward) { InfoPtr->BinArray[i].left = InfoPtr->BinArray[i].x - dtemp1; InfoPtr->BinArray[i].right = InfoPtr->BinArray[i].x + dtemp1; } else { InfoPtr->BinArray[i].left = InfoPtr->BinArray[i].x + dtemp1; InfoPtr->BinArray[i].right = InfoPtr->BinArray[i].x - dtemp1; } break; case Y_DIR: InfoPtr->BinArray[i].y = InfoPtr->spatial_start + (i * InfoPtr->spatial_step); InfoPtr->BinArray[i].x = INVALID_VALUE; /* assign width limits of bin */ if (InfoPtr->dat_forward) { InfoPtr->BinArray[i].left = InfoPtr->BinArray[i].y - dtemp1; InfoPtr->BinArray[i].right = InfoPtr->BinArray[i].y + dtemp1; } else { InfoPtr->BinArray[i].left = InfoPtr->BinArray[i].y + dtemp1; InfoPtr->BinArray[i].right = InfoPtr->BinArray[i].y - dtemp1; } break; } InfoPtr->BinArray[i].z = INVALID_VALUE; /* initialize other members */ InfoPtr->BinArray[i].col_loc = INVALID_VALUE; /* so can check later */ InfoPtr->BinArray[i].num_items = 0; /* will count number of traces in bin */ InfoPtr->BinArray[i].item_size = InfoPtr->num_rows; /* won't change */ /* allocate storage for trace */ InfoPtr->BinArray[i].sum =(double *)malloc(InfoPtr->BinArray[i].item_size * sizeof(double)); if (InfoPtr->BinArray[i].sum == NULL) { for (j=0; jBinArray[j].sum); free(InfoPtr->BinArray); InfoPtr->BinArray = NULL; InfoPtr->num_bins = 0; return 2; } /* set sum[] values to 0.0 */ for (j=0; jBinArray[i].item_size; j++) InfoPtr->BinArray[i].sum[j] = 0.0; } /* Force endpoint bin values (in case of roundoff error) */ switch (InfoPtr->spatial_dir) { case X_DIR: InfoPtr->BinArray[0].x = InfoPtr->spatial_start; InfoPtr->BinArray[InfoPtr->num_bins-1].x = InfoPtr->spatial_stop; break; case Y_DIR: InfoPtr->BinArray[0].y = InfoPtr->spatial_start; InfoPtr->BinArray[InfoPtr->num_bins-1].y = InfoPtr->spatial_stop; break; } /* allocate temporary storage for Splining */ x = (double *)malloc(InfoPtr->num_cols * sizeof(double)); if (x == NULL) return 4; y = (double *)malloc(InfoPtr->num_cols * sizeof(double)); if (y == NULL) { free(x); return 4; } xnew = (double *)malloc(InfoPtr->num_bins * sizeof(double)); if (xnew == NULL) { free(x); free(y); return 4; } ynew = (double *)malloc(InfoPtr->num_bins * sizeof(double)); if (ynew == NULL) { free(x); free(y); free(xnew); return 4; } /* Locate each bin in column space to get independant variable for splining */ switch (InfoPtr->spatial_dir) { case X_DIR: /* first assign ->col_loc values that lie outside of original line values */ x1 = InfoPtr->trace_Xval[0]; /* 1st */ x2 = InfoPtr->trace_Xval[1]; /* 2nd */ x3 = InfoPtr->trace_Xval[InfoPtr->num_cols-2]; /* next to last */ x4 = InfoPtr->trace_Xval[InfoPtr->num_cols-1]; /* last */ diff1 = x2 - x1; diff2 = x4 - x3; c1 = 0; c2 = InfoPtr->num_cols-2; for (i=0; inum_bins; i++) { xx = InfoPtr->BinArray[i].x; if ( ((xx < x1) && InfoPtr->dat_forward) || (!InfoPtr->dat_forward && (xx > x1)) ) { diff = xx - x1; InfoPtr->BinArray[i].col_loc = c1+ diff/diff1; } else if ( ((xx > x4) && InfoPtr->dat_forward) || (!InfoPtr->dat_forward && (xx < x4)) ) { diff = xx - x3; InfoPtr->BinArray[i].col_loc = c2+ diff/diff2; } } /* next, spline to get remaining values; Spline2() allows xnew[] to lie out side of range of x[]. Values of ->col_loc already assigned should be ignored by Spline2() and can be recopied. */ for (i=0; inum_cols; i++) x[i] = InfoPtr->trace_Xval[i]; /* X coord for every trace */ for (i=0; inum_cols; i++) y[i] = i; /* trace column number */ for (i=0; inum_bins; i++) xnew[i] = InfoPtr->BinArray[i].x; /* X coord for every bin */ for (i=0; inum_bins; i++) ynew[i] = InfoPtr->BinArray[i].col_loc; /* bin in column space */ itemp = Spline2(InfoPtr->num_cols,InfoPtr->num_bins,x,y,xnew,ynew); if (itemp > 0) { if (log_file) fprintf(log_file,"1: %s\n",Spline2Msg[itemp]); printf("1: %s\n",Spline2Msg[itemp]); free(x); free(y); free(xnew); free(ynew); return 6; } for (i=0; inum_bins; i++) InfoPtr->BinArray[i].col_loc = ynew[i]; /* last, check for unassigned values */ for (i=0; inum_bins; i++) { if (InfoPtr->BinArray[i].col_loc == INVALID_VALUE) { printf("X_DIR: Empty bin.col_loc found at %d\n",i); } } break; case Y_DIR: x1 = InfoPtr->trace_Yval[0]; /* 1st */ x2 = InfoPtr->trace_Yval[1]; /* 2nd */ x3 = InfoPtr->trace_Yval[InfoPtr->num_cols-2]; /* next to last */ x4 = InfoPtr->trace_Yval[InfoPtr->num_cols-1]; /* last */ diff1 = x2 - x1; diff2 = x4 - x3; c1 = 0; c2 = InfoPtr->num_cols-2; for (i=0; inum_bins; i++) { xx = InfoPtr->BinArray[i].y; if ( ((xx < x1) && InfoPtr->dat_forward) || (!InfoPtr->dat_forward && (xx > x1)) ) { diff = xx - x1; InfoPtr->BinArray[i].col_loc = c1 + diff/diff1; } else if ( ((xx > x4) && InfoPtr->dat_forward) || (!InfoPtr->dat_forward && (xx < x4)) ) { diff = xx - x3; InfoPtr->BinArray[i].col_loc = c2 + diff/diff2; } } /* next, spline to get remaining values; Spline2() allows xnew[] to lie out side of range of x[]. Values of ->col_loc already assigned should be ignored by Spline2() and can be recopied. */ for (i=0; inum_cols; i++) x[i] = InfoPtr->trace_Yval[i]; /* Y coord for every trace */ for (i=0; inum_cols; i++) y[i] = i; /* trace column number */ for (i=0; inum_bins; i++) xnew[i] = InfoPtr->BinArray[i].y; /* Y coord for every bin */ for (i=0; inum_bins; i++) ynew[i] = InfoPtr->BinArray[i].col_loc; /* bin in column space */ itemp = Spline2(InfoPtr->num_cols,InfoPtr->num_bins,x,y,xnew,ynew); if (itemp > 0) { if (log_file) fprintf(log_file,"2: %s\n",Spline2Msg[itemp]); printf("2: %s\n",Spline2Msg[itemp]); free(x); free(y); free(xnew); free(ynew); return 6; } for (i=0; inum_bins; i++) InfoPtr->BinArray[i].col_loc = ynew[i]; /* last, check for unassigned values SHOULD ALL BE FULL!!!`1 */ for (i=0; inum_bins; i++) { if (InfoPtr->BinArray[i].col_loc == INVALID_VALUE) { printf("Y_DIR: Empty bin.col_loc found at %d: x=%g y=%g\n", i,InfoPtr->BinArray[i].x,InfoPtr->BinArray[i].y); } } break; } /* end of switch (InfoPtr->spatial_dir) block */ /* Get other 2 coordinates for each bin; this will be somewhat opposite of above procedure */ switch (InfoPtr->spatial_dir) { case X_DIR: /* spline to get coords along line overlap */ for (i=0; inum_cols; i++) x[i] = i; /* trace column number */ for (i=0; inum_cols; i++) y[i] = InfoPtr->trace_Yval[i]; /* Y coord for every trace */ for (i=0; inum_bins; i++) xnew[i] = InfoPtr->BinArray[i].col_loc; /* bin in column space */ itemp = Spline2(InfoPtr->num_cols,InfoPtr->num_bins,x,y,xnew,ynew); if (itemp > 0) { if (log_file) fprintf(log_file,"3: %s\n",Spline2Msg[itemp]); printf("3: %s\n",Spline2Msg[itemp]); free(x); free(y); free(xnew); free(ynew); return 6; } for (i=0; inum_bins; i++) InfoPtr->BinArray[i].y = ynew[i]; /* Y coord for bins */ /* extrapolate to get coords outside of original line */ x1 = 0; /* 1st */ x2 = 1; /* 2nd */ x3 = InfoPtr->num_cols-2; /* next to last */ x4 = InfoPtr->num_cols-1; /* last */ diff1 = x2 - x1; diff2 = x4 - x3; diff3 = InfoPtr->trace_Yval[(int)x2] - InfoPtr->trace_Yval[(int)x1]; diff4 = InfoPtr->trace_Yval[(int)x4] - InfoPtr->trace_Yval[(int)x3]; c1 = InfoPtr->trace_Yval[(int)x1]; c2 = InfoPtr->trace_Yval[(int)x3]; for (i=0; inum_bins; i++) { xx = InfoPtr->BinArray[i].col_loc; if (xx < x1) { diff = xx - x1; InfoPtr->BinArray[i].y = c1 + (diff/diff1)*diff3; } else if (xx > x4) { diff = xx - x3; InfoPtr->BinArray[i].y = c2 + (diff/diff2)*diff4; } } /* check for unassigned values SHOULD ALL BE FULL!!!`1 */ for (i=0; inum_bins; i++) { if (InfoPtr->BinArray[i].y == INVALID_VALUE) { printf("X_DIR: Empty bin.y found at %d\n",i); } } break; case Y_DIR: /* spline to get coords along line overlap */ for (i=0; inum_cols; i++) x[i] = i; /* trace column number */ for (i=0; inum_cols; i++) y[i] = InfoPtr->trace_Xval[i]; /* X coord for every trace */ for (i=0; inum_bins; i++) xnew[i] = InfoPtr->BinArray[i].col_loc; /* bin in column space */ itemp = Spline2(InfoPtr->num_cols,InfoPtr->num_bins,x,y,xnew,ynew); if (itemp > 0) { if (log_file) fprintf(log_file,"4: %s\n",Spline2Msg[itemp]); printf("4: %s\n",Spline2Msg[itemp]); free(x); free(y); free(xnew); free(ynew); return 6; } for (i=0; inum_bins; i++) InfoPtr->BinArray[i].x = ynew[i]; /* X coord for bins */ /* extrapolate to get coords outside of original line */ x1 = 0; /* 1st */ x2 = 1; /* 2nd */ x3 = InfoPtr->num_cols-2; /* next to last */ x4 = InfoPtr->num_cols-1; /* last */ diff1 = x2 - x1; diff2 = x4 - x3; diff3 = InfoPtr->trace_Xval[(int)x2] - InfoPtr->trace_Xval[(int)x1]; diff4 = InfoPtr->trace_Xval[(int)x4] - InfoPtr->trace_Xval[(int)x3]; c1 = InfoPtr->trace_Xval[(int)x1]; c2 = InfoPtr->trace_Xval[(int)x3]; for (i=0; inum_bins; i++) { xx = InfoPtr->BinArray[i].col_loc; if (xx < x1) { diff = xx - x1; InfoPtr->BinArray[i].x = c1+ (diff/diff1)*diff3; } else if (xx > x4) { diff = xx - x3; InfoPtr->BinArray[i].x = c2+ (diff/diff2)*diff4; } } /* check for unassigned values SHOULD ALL BE FULL!!!`1 */ for (i=0; inum_bins; i++) { if (InfoPtr->BinArray[i].x == INVALID_VALUE) { printf("Y_DIR: Empty bin.x found at %d\n",i); } } break; } /* same as above for Z coords */ /* spline to get coords along line overlap */ for (i=0; inum_cols; i++) x[i] = i; /* trace column number */ for (i=0; inum_cols; i++) y[i] = InfoPtr->trace_Zval[i]; /* Z coord for every trace */ for (i=0; inum_bins; i++) xnew[i] = InfoPtr->BinArray[i].col_loc; /* bin in column space */ itemp = Spline2(InfoPtr->num_cols,InfoPtr->num_bins,x,y,xnew,ynew); if (itemp > 0) { if (log_file) fprintf(log_file,"5: %s\n",Spline2Msg[itemp]); printf("5: %s\n",Spline2Msg[itemp]); free(x); free(y); free(xnew); free(ynew); return 6; } for (i=0; inum_bins; i++) InfoPtr->BinArray[i].z = ynew[i]; /* Z coord for bins */ /* extrapolate to get coords outside of original line */ x1 = 0; /* 1st */ x2 = 1; /* 2nd */ x3 = InfoPtr->num_cols-2; /* next to last */ x4 = InfoPtr->num_cols-1; /* last */ diff1 = x2 - x1; diff2 = x4 - x3; diff3 = InfoPtr->trace_Zval[(int)x2] - InfoPtr->trace_Zval[(int)x1]; diff4 = InfoPtr->trace_Zval[(int)x4] - InfoPtr->trace_Zval[(int)x3]; c1 = InfoPtr->trace_Zval[(int)x1]; c2 = InfoPtr->trace_Zval[(int)x3]; for (i=0; inum_bins; i++) { xx = InfoPtr->BinArray[i].col_loc; if (xx < x1) { diff = xx - x1; InfoPtr->BinArray[i].z = c1 + (diff/diff1)*diff3; } else if (xx > x4) { diff = xx - x3; InfoPtr->BinArray[i].z = c2 + (diff/diff2)*diff4; } } /* check for unassigned values SHOULD ALL BE FULL!!!`1 */ for (i=0; inum_bins; i++) { if (InfoPtr->BinArray[i].z == INVALID_VALUE) { printf("Z_DIR: Empty bin.z found at %d\n",i); } } /* Free temporary storage */ free(x); free(y); free(xnew); free(ynew); if (Debug) { puts("\nAfter initialization:"); for (i=0; inum_bins; i++) { printf("bin #%d: x=%g left=%g roght=%g num_items=%ld item_size=%ld sum[0]=%g\n", i,InfoPtr->BinArray[i].x,InfoPtr->BinArray[i].left,InfoPtr->BinArray[i].right, InfoPtr->BinArray[i].num_items,InfoPtr->BinArray[i].item_size, InfoPtr->BinArray[i].sum[0]); } getch(); } /***** Place data in bins *****/ start_num = 0; /* offset into trace_?val[] to start search each time */ count = InfoPtr->num_bins/10; if (count < 1) count = 1; /* i = current bin number j = current trace_?val and input grid trace number k = current sample in current trace in input grid sum_samp = current sample in bin sum trace */ for (i=0; inum_bins; i++) /* for each bin */ { if (!(i % count)) printf("."); for (j=start_num; jnum_cols; j++) /* search through trace_Xval[] */ { /* does trace fall within boundaries of this bin? */ if ( ( (InfoPtr->spatial_dir == X_DIR) && (InfoPtr->dat_forward) && (InfoPtr->BinArray[i].left < InfoPtr->trace_Xval[j]) && (InfoPtr->BinArray[i].right >= InfoPtr->trace_Xval[j]) ) || ( (InfoPtr->spatial_dir == X_DIR) && (!InfoPtr->dat_forward) && (InfoPtr->BinArray[i].left > InfoPtr->trace_Xval[j]) && (InfoPtr->BinArray[i].right <= InfoPtr->trace_Xval[j]) ) || ( (InfoPtr->spatial_dir == Y_DIR) && (InfoPtr->dat_forward) && (InfoPtr->BinArray[i].left < InfoPtr->trace_Yval[j]) && (InfoPtr->BinArray[i].right >= InfoPtr->trace_Yval[j]) ) || ( (InfoPtr->spatial_dir == Y_DIR) && (!InfoPtr->dat_forward) && (InfoPtr->BinArray[i].left > InfoPtr->trace_Yval[j]) && (InfoPtr->BinArray[i].right <= InfoPtr->trace_Yval[j]) ) ) { /* yes, so increment total */ InfoPtr->BinArray[i].num_items++; /* assign trace header; sum data */ sum_samp = 0; switch (InfoPtr->input_datatype) { case -1: { unsigned char **ucp = (unsigned char **)InfoPtr->grid; for (k=0; kfirst_proc_samp; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] = ucp[j][k]; for (k = InfoPtr->first_proc_samp; k < InfoPtr->num_rows, sum_sampBinArray[i].item_size; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] += ucp[j][k]; break; } case 1: { char **cp = (char **)InfoPtr->grid; for (k=0; kfirst_proc_samp; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] = cp[j][k]; for (k = InfoPtr->first_proc_samp; k < InfoPtr->num_rows, sum_sampBinArray[i].item_size; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] += cp[j][k]; break; } case -2: case -5: { unsigned short **usp = (unsigned short **)InfoPtr->grid; for (k=0; kfirst_proc_samp; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] = usp[j][k]; for (k = InfoPtr->first_proc_samp; k < InfoPtr->num_rows, sum_sampBinArray[i].item_size; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] += usp[j][k]; break; } case 2: { short **sp = (short **)InfoPtr->grid; for (k=0; kfirst_proc_samp; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] = sp[j][k]; for (k = InfoPtr->first_proc_samp; k < InfoPtr->num_rows, sum_sampBinArray[i].item_size; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] += sp[j][k]; break; } case -3: case -6: { unsigned long **ulp = (unsigned long **)InfoPtr->grid; for (k=0; kfirst_proc_samp; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] = ulp[j][k]; for (k = InfoPtr->first_proc_samp; k < InfoPtr->num_rows, sum_sampBinArray[i].item_size; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] += ulp[j][k]; break; } case 3: { long **lp = (long **)InfoPtr->grid; for (k=0; kfirst_proc_samp; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] = lp[j][k]; for (k = InfoPtr->first_proc_samp; k < InfoPtr->num_rows, sum_sampBinArray[i].item_size; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] += lp[j][k]; break; } case 4: { float **fp = (float **)InfoPtr->grid; for (k=0; kfirst_proc_samp; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] = fp[j][k]; for (k = InfoPtr->first_proc_samp; k < InfoPtr->num_rows, sum_sampBinArray[i].item_size; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] += fp[j][k]; break; } case 8: { double **dp = (double **)InfoPtr->grid; for (k=0; kfirst_proc_samp; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] = dp[j][k]; for (k = InfoPtr->first_proc_samp; k < InfoPtr->num_rows, sum_sampBinArray[i].item_size; k++, sum_samp++) InfoPtr->BinArray[i].sum[sum_samp] += dp[j][k]; break; } } /* end of switch (InfoPtr->input_datatype) block */ } /* check to see if past end of bin */ if ( ( (InfoPtr->spatial_dir == X_DIR) && InfoPtr->dat_forward && (InfoPtr->trace_Xval[j] > InfoPtr->BinArray[i].right) ) || ( (InfoPtr->spatial_dir == X_DIR) && !InfoPtr->dat_forward && (InfoPtr->trace_Xval[j] < InfoPtr->BinArray[i].right) ) || ( (InfoPtr->spatial_dir == Y_DIR) && InfoPtr->dat_forward && (InfoPtr->trace_Yval[j] > InfoPtr->BinArray[i].right) ) || ( (InfoPtr->spatial_dir == Y_DIR) && !InfoPtr->dat_forward && (InfoPtr->trace_Yval[j] < InfoPtr->BinArray[i].right) ) ) { if (InfoPtr->bin_size == InfoPtr->spatial_step) start_num = j; /* pick up where we left off */ else start_num = 0; /* go back to start */ break; /* out of for loop working through trace_Xval */ } } /* end of for (j=start_num; jnum_cols; j++) */ } /* end of for (i=0; inum_bins; i++) */ /* Calculate average trace for bin or normalize empty bin trace */ for (i=0; inum_bins; i++) /* for each bin */ { if (InfoPtr->BinArray[i].num_items > 0) { for (j=InfoPtr->first_proc_samp; jBinArray[i].item_size; j++) InfoPtr->BinArray[i].sum[j] /= InfoPtr->BinArray[i].num_items; } else { for (j=0; jBinArray[i].item_size; j++) InfoPtr->BinArray[i].sum[j] = InfoPtr->mean_value; bin_empty = TRUE; } } if (Debug) { puts("\nAfter filling bins:"); for (i=0; inum_bins; i++) { printf("bin #%d: x=%g left=%g right=%g num_items=%ld item_size=%ld sum[0]=%g\n", i,InfoPtr->BinArray[i].x,InfoPtr->BinArray[i].left,InfoPtr->BinArray[i].right, InfoPtr->BinArray[i].num_items,InfoPtr->BinArray[i].item_size, InfoPtr->BinArray[i].sum[0]); } getch(); } /* report statistics */ printf("\n\nTrace separation: minimum = %g maximum = %g\n", InfoPtr->min_trace_sep,InfoPtr->max_trace_sep); if (bin_empty) { printf("Empty bin number(s):"); if (log_file) fprintf(log_file,"Empty bin number(s):"); for (i=0; inum_bins; i++) { if (InfoPtr->BinArray[i].num_items == 0) { printf(" %ld",i); if (log_file) fprintf(log_file," %ld",i); } } if (log_file) fprintf(log_file,"To avoid empty bins, increase bin size or spatial step.\n"); puts(""); } else puts("There are no empty bins"); sumx = sumxx = 0.0; for (i=0; inum_bins; i++) { if (InfoPtr->BinArray[i].num_items < min_hits) min_hits = InfoPtr->BinArray[i].num_items; if (InfoPtr->BinArray[i].num_items > max_hits) max_hits = InfoPtr->BinArray[i].num_items; sumx += InfoPtr->BinArray[i].num_items; sumxx += InfoPtr->BinArray[i].num_items * InfoPtr->BinArray[i].num_items; } var = ((InfoPtr->num_bins*sumxx) - (sumx*sumx)) / (InfoPtr->num_bins*(InfoPtr->num_bins-1)); stdev = sqrt(var); mean = sumx/InfoPtr->num_bins; printf("Bin items: miniumum hits = %d maximum hits = %d\n",min_hits,max_hits); printf(" standard dev. = %g mean = %g\n",stdev, mean); return 0; } /************************** XfrmSaveMrkXyzData() *******************************/ /* This is functio saves the bin XYZ info to disk. * * Parameter list: * struct XfrmParamInfoStruct *ParamInfoPtr - address of structure * * Requires: , "gpr_xfrm.h". * Calls: fopen, fclose, fprintf. * Returns: 0 on success, or * >0 if error or warning (offset into an array of message strings). * const char *XfrmSaveXyzDataMsg[] = { "XfrmSaveMrkXyzData(): No errors.", "XfrmSaveMrkXyzData() ERROR: Unable to open output XYZ file.", "XfrmSaveMrkXyzData() ERROR: Unable to open output MRK file.", } ; * * Author: Jeff Lucius USGS Mineral Resources Program Lakewood, CO * Date: February 11, 1997; April 16, 2001; */ int XfrmSaveMrkXyzData (struct XfrmParamInfoStruct *InfoPtr) { int i; FILE *outfile; outfile = fopen(InfoPtr->xyz_outfilename,"wt"); if (outfile == NULL) return 1; fprintf(outfile,"%d\n",InfoPtr->num_bins); for (i=0; inum_bins; i++) fprintf(outfile,"%g %g %g\n",InfoPtr->BinArray[i].x, InfoPtr->BinArray[i].y,InfoPtr->BinArray[i].z); fclose(outfile); outfile = fopen(InfoPtr->mrk_outfilename,"wt"); if (outfile == NULL) return 2; fprintf(outfile,"%d\n",InfoPtr->num_bins); for (i=0; inum_bins; i++) fprintf(outfile,"%6d\n",i); fclose(outfile); return 0; } /************************** XfrmSaveGprData() *******************************/ /* This is the driver routine for saving the GPR data to disk. * * Parameter list: * struct XfrmParamInfoStruct *ParamInfoPtr - address of structure * * Requires: , , , , "gpr_xfrm.h". * Calls: printf, fprintf, sprintf, strcat, time, localtime, strlen, * XfrmSaveDztData, XfrmSaveDt1Data, XfrmSaveSgyData, XfrmSaveUsrData. * Returns: 0 on success, or * >0 if error or warning (offset into an array of message strings). * const char *XfrmSaveGprDataMsg[] = { "XfrmSaveGprData(): No errors.", "XfrmSaveGprData() ERROR: Invalid/unknown file storage format.", "XfrmSaveGprData() ERROR: Data/information was not saved to disk.", } ; * * Author: Jeff Lucius USGS Mineral Resources Program Lakewood, CO * Date: February 6, 1997; April 16, 2001; */ int XfrmSaveGprData (struct XfrmParamInfoStruct *InfoPtr) { struct dosdate_t dosdate; struct dostime_t dostime; char *month[] = { "","Jan","Feb","Mar","Apr","May","Jun", "Jul","Aug","Sep","Oct", "Nov","Dec" } ; char str[240]; int i,j,itemp; int file_saved = FALSE; struct tm *newtime; time_t long_time; extern FILE *log_file; /* beginning of this source */ extern const char *XfrmSaveDztDataMsg[]; /* beginning of this source */ extern const char *XfrmSaveDt1DataMsg[]; /* beginning of this source */ extern const char *XfrmSaveSgyDataMsg[]; /* beginning of this source */ extern const char *XfrmSaveUsrDataMsg[]; /* beginning of this source */ /* Fill processing history string */ _dos_getdate(&dosdate); _dos_gettime(&dostime); sprintf(InfoPtr->proc_hist,"\nGPR_XFRM v%s (USGS-JL) on %s %d, %d at %d:%02d\n", GPR_XFRM_VER,month[dosdate.month],dosdate.day,dosdate.year, dostime.hour,dostime.minute); sprintf(str,"GPR_XFRM Parameters: start=%g stop=%g step=%g bin_size=%g\n", InfoPtr->spatial_start,InfoPtr->spatial_stop, InfoPtr->spatial_step,InfoPtr->bin_size); strcat(InfoPtr->proc_hist,str); /* Copy output traces from BinArray to input grid */ for (i=0; inum_bins; i++) { for (j=0; jnum_rows; j++) { switch (InfoPtr->input_datatype) { case -1: { unsigned char **ucp = (unsigned char **)InfoPtr->grid; ucp[i][j] = InfoPtr->BinArray[i].sum[j]; break; } case 1: { char **cp = (char **)InfoPtr->grid; cp[i][j] = InfoPtr->BinArray[i].sum[j]; break; } case -2: case -5: { unsigned short **usp = (unsigned short **)InfoPtr->grid; usp[i][j] = InfoPtr->BinArray[i].sum[j]; break; } case 2: { short **sp = (short **)InfoPtr->grid; sp[i][j] = InfoPtr->BinArray[i].sum[j]; break; } case -3: case -6: { unsigned long **ulp = (unsigned long **)InfoPtr->grid; ulp[i][j] = InfoPtr->BinArray[i].sum[j]; break; } case 3: { long **lp = (long **)InfoPtr->grid; lp[i][j] = InfoPtr->BinArray[i].sum[j]; break; } case 4: { float **fp = (float **)InfoPtr->grid; fp[i][j] = InfoPtr->BinArray[i].sum[j]; break; } case 8: { double **dp = (double **)InfoPtr->grid; dp[i][j] = InfoPtr->BinArray[i].sum[j]; break; } } } } /***** NOTE: ->grid now contains the output traces *****/ switch (InfoPtr->storage_format) { case DZT: case MOD_DZT: { itemp = XfrmSaveDztData(InfoPtr); if (itemp > 0) { printf("\n%s\n",XfrmSaveDztDataMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",XfrmSaveDztDataMsg[itemp]); } else file_saved = TRUE; break; } case DT1: { itemp = XfrmSaveDt1Data(InfoPtr); if (itemp > 0) { printf("\n%s\n",XfrmSaveDt1DataMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",XfrmSaveDt1DataMsg[itemp]); } else file_saved = TRUE; break; } case SGY: { itemp = XfrmSaveSgyData(InfoPtr); if (itemp > 0) { printf("\n%s\n",XfrmSaveSgyDataMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",XfrmSaveSgyDataMsg[itemp]); } else file_saved = TRUE; break; } case USR: { itemp = XfrmSaveUsrData(InfoPtr); if (itemp > 0) { printf("\n%s\n",XfrmSaveUsrDataMsg[itemp]); if (log_file) fprintf(log_file,"%s\n",XfrmSaveUsrDataMsg[itemp]); } else file_saved = TRUE; break; } default: return 1; } if (file_saved) return 0; else return 2; } /******************************* XfrmSaveDztData() ******************************/ /* This function saves the GPR data to disk using the DZT format. * * Parameter list: * struct XfrmParamInfoStruct *ParamInfoPtr - address of structure * * Requires: , , , "gpr_xfrm.h". * Calls: SetDzt5xHeader, ReadOneDztHeader, SaveDztFile, _splitpath (non-ANSI), * strcpy, strncpy, strcat, sprintf, puts, printf, strlen. * Returns: 0 on success, or * >0 if error or warning (offset into an array of message strings). * const char *XfrmSaveDztDataMsg[] = { "XfrmSaveDztData(): No errors.", "XfrmSaveDztData() ERROR: Invalid datatype for output DZT file.", "XfrmSaveDztData() ERROR: Problem getting input file header.", "XfrmSaveDztData() ERROR: Problem saving data.", } ; * * Author: Jeff Lucius USGS Mineral Resources Program Lakewood, CO * Date: February 7, 1997 */ int XfrmSaveDztData (struct XfrmParamInfoStruct *InfoPtr) { int i,itemp; char name[12],antname[14], drive[_MAX_DRIVE], dir[_MAX_DIR], text[400]; char fname[_MAX_FNAME], fext[_MAX_EXT]; int max_proc_hist_size = 400; unsigned char proc_hist[400]; /* hopefully 400 is big enough! */ int hdr_num,num_hdrs,header_size,rh_dtype; unsigned short rh_nchan,rg_breaks,rh_nproc; float rg_values[8]; /* this limit may change in future versions */ long num_traces; struct DztHdrStruct hdr; /* struct in gpr_io.h */ struct DztHdrStruct *hdrPtrArray[1]; struct DztDateStruct create_date; extern const char *SaveDztFileMsg[]; /* in gpr_io.h, dzt_io.c */ extern FILE *log_file; /* beginning of this source */ switch (InfoPtr->input_datatype) { case -1: case -2: break; default: return 1; } /* Read input DZT header again */ itemp = ReadOneDztHeader(InfoPtr->dat_infilename,&num_hdrs, &num_traces,InfoPtr->channel,&header_size,&hdr); if (itemp > 0) { if (log_file) fprintf(log_file,"%s\n",ReadOneDztHeaderMsg[itemp]); return 2; } /* Set/copy values for output header */ if (hdr.rh_dtype == 0 && InfoPtr->input_datatype != -1) { if (InfoPtr->input_datatype == -2) rh_dtype = 0x0002; else if (InfoPtr->input_datatype == -3) rh_dtype = 0x0004; else rh_dtype = 0x0000; } rg_breaks = *(unsigned short *) ((char *)&hdr + hdr.rh_rgain); for (i=0; iproc_hist)-2) strcat(text,InfoPtr->proc_hist); rh_nproc = hdr.rh_nproc; if (rh_nproc > max_proc_hist_size-1) rh_nproc = max_proc_hist_size-1; for (i=0; idat_outfilename,drive,dir,fname,fext); strcpy(name,fname); strncpy(antname,hdr.rh_antname,sizeof(antname)-1); antname[sizeof(antname)-1] = 0; create_date = hdr.rh_create; hdr.rh_spm = 1.0 / InfoPtr->bin_size; hdr.rh_mpm = InfoPtr->bin_size; hdr.rh_sps = 0.0; /* Note: Do not send pointers from hdr through this function! SetDzt5xHeader() clears structure arrays before writing to them! Other members are OK as they are sent by value. */ SetDzt5xHeader(hdr_num,hdr.rh_nsamp,hdr.rh_bits,hdr.rh_zero,hdr.rh_sps, hdr.rh_spm,hdr.rh_mpm,hdr.rh_position,hdr.rh_range, hdr.rh_npass,rh_nchan,hdr.rh_epsr,hdr.rh_top,hdr.rh_depth, rh_dtype,antname,name,text,rg_breaks,rg_values,rh_nproc, proc_hist,&create_date,&hdr); /* Set "trace header" values */ switch (InfoPtr->input_datatype) { case -1: { unsigned char **ucp = (unsigned char **)InfoPtr->grid; for (i=0; inum_bins; i++) { ucp[i][0] = 0xFFU; ucp[i][1] = 0xE8U; } break; } case -2: { unsigned short **usp = (unsigned short **)InfoPtr->grid; for (i=0; inum_bins; i++) { usp[i][0] = 0xFFFFU; usp[i][1] = 0xE800U; } break; } case -3: { unsigned long **ulp = (unsigned long **)InfoPtr->grid; for (i=0; inum_bins; i++) { ulp[i][0] = 0xFFFFFFFFUL; ulp[i][1] = 0xE8000000UL; } break; } } /* Save to disk */ hdrPtrArray[0] = &hdr; itemp = SaveDztFile(InfoPtr->dat_outfilename,InfoPtr->num_bins, InfoPtr->num_rows,(int)hdr.rh_bits,hdr_num, hdrPtrArray,InfoPtr->grid); if (itemp > 0) { if (log_file) fprintf(log_file,"%s\n",SaveDztFileMsg[itemp]); return 3; } return 0; } /******************************* XfrmSaveDt1Data() ******************************/ /* This function saves the GPR data to disk using the DT1 format. * * Parameter list: * struct XfrmParamInfoStruct *ParamInfoPtr - address of structure * * Requires: , , "gpr_xfrm.h". * Calls: memset, fprintf, fopen, fclose, strcat, realloc, ferror, fwrite, * clearerr, GetSsHdFile, SaveSsHdFile. * Returns: 0 on success, or * >0 if error or warning (offset into an array of message strings). * const char *XfrmSaveDt1DataMsg[] = { "XfrmSaveDt1Data(): No errors.", "XfrmSaveDt1Data() ERROR: Invalid datatype for output DT1 file.", "XfrmSaveDt1Data() ERROR: Problem getting input file header.", "XfrmSaveDt1Data() ERROR: Problem saving HD file.", "XfrmSaveDt1Data() ERROR: Unable to open output DT1 file.", "XfrmSaveDt1Data() ERROR: Problem saving DT1 file.", } ; * * Author: Jeff Lucius USGS Mineral Resources Program Lakewood, CO * Date: February 6, 1997 */ int XfrmSaveDt1Data (struct XfrmParamInfoStruct *InfoPtr) { int itemp,print_it,num_gain_pts,proc_hist_size,trace_size; long trace; double traces_per_sec,meters_per_mark,gain_pts[8]; struct SsHdrInfoStruct HdInfo; /* struct in gpr_io.h */ FILE *outfile; extern const char *GetSsHdFileMsg[]; /* in gpr_io.h */ extern const char *SaveSsHdFileMsg[]; /* in gpr_io.h */ extern int Debug; /* beginning of this source */ extern FILE *log_file; /* beginning of this source */ #if defined(_INTELC32_) char *outbuffer = NULL; size_t vbufsize = 64512; /* 63 KB */ #endif switch (InfoPtr->input_datatype) { case 2: break; default: return 1; } /* Read input HD file again */ if (Debug) print_it = TRUE; else print_it = FALSE; itemp = GetSsHdFile(print_it,&HdInfo,InfoPtr->inf_infilename); if (itemp > 0) { if (log_file) fprintf(log_file,"%s\n",ReadOneDztHeaderMsg[itemp]); return 2; } /* Set/save values for output header file */ meters_per_mark = 1.0 / InfoPtr->bin_size; num_gain_pts = 0; proc_hist_size = strlen(HdInfo.proc_hist) + 1; proc_hist_size += strlen(InfoPtr->proc_hist) + 2; realloc(HdInfo.proc_hist,proc_hist_size); strcat(HdInfo.proc_hist,InfoPtr->proc_hist); traces_per_sec = 0.0; itemp = SaveSsHdFile((int)HdInfo.day,(int)HdInfo.month,(int)HdInfo.year, InfoPtr->num_bins,InfoPtr->num_rows, (long)HdInfo.time_zero_sample,(int)HdInfo.total_time_ns, (double)HdInfo.start_pos,(double)HdInfo.final_pos, (double)HdInfo.step_size,HdInfo.pos_units, (double)HdInfo.ant_freq,(double)HdInfo.ant_sep, (double)HdInfo.pulser_voltage,(int)HdInfo.num_stacks, HdInfo.survey_mode,HdInfo.proc_hist, InfoPtr->inf_outfilename,InfoPtr->dat_outfilename, HdInfo.job_number,HdInfo.title1,HdInfo.title2, traces_per_sec,meters_per_mark,num_gain_pts, gain_pts); if (itemp > 0) { if (log_file) fprintf(log_file,"%s\n",SaveSsHdFileMsg[itemp]); return 3; } /* Open Output DT1 file */ if ((outfile = fopen(InfoPtr->dat_outfilename,"wb")) == NULL) return 4; /* Speed up disk access by using large (conventional memory) buffer */ #if defined(_INTELC32_) realmalloc(outbuffer,vbufsize); if (outbuffer) setvbuf(outfile,outbuffer,_IOFBF,vbufsize); else setvbuf(outfile,NULL,_IOFBF,vbufsize); #endif /* Save data to disk */ itemp = 0; trace_size = InfoPtr->num_rows * 2; /* data bytes + header bytes */ for (trace = 0; trace < InfoPtr->num_bins; trace++) { fwrite(InfoPtr->grid[trace],(size_t)trace_size,(size_t)1,outfile); } if (ferror(outfile)) { clearerr(outfile); itemp = 6; } #if defined(_INTELC32_) realfree(outbuffer); #endif fclose(outfile); return itemp; } /******************************* XfrmSaveSgyData() ******************************/ /* This function saves the GPR data to disk using the SEG-Y format. * * Parameter list: * struct XfrmParamInfoStruct *ParamInfoPtr - address of structure * * Requires: , , "gpr_xfrm.h". * Calls: fprintf, fopen, fclose, strcat, malloc, free, ferror, fwrite, * clearerr, ReadSegyReelHdr, ExtractSsInfoFromSegy, SetSgyFileHeader. * Returns: 0 on success, or * >0 if error or warning (offset into an array of message strings). * const char *XfrmSaveSgyDataMsg[] = { "XfrmSaveSgyData(): No errors.", "XfrmSaveSgyData() ERROR: Invalid datatype for output SGY file.", "XfrmSaveSgyData() ERROR: Problem getting input file header.", "XfrmSaveSgyData() ERROR: Unable to open output DT1 file.", "XfrmSaveSgyData() ERROR: Problem saving SGY file header.", "XfrmSaveSgyData() ERROR: Problem saving SGY file data.", } ; * * Author: Jeff Lucius USGS Mineral Resources Program Lakewood, CO * Date: February 6, 1997 */ int XfrmSaveSgyData (struct XfrmParamInfoStruct *InfoPtr) { char *pos_units,*survey_mode,*proc_hist,dummy_text[1],*text; int day,month,year,num_stacks,num_gain_pts ; int itemp,swap_bytes,proc_hist_size; long trace,trace_size,num_traces,num_samples,time_zero_sample,total_time_ns; double start_pos,final_pos,step_size,ant_freq,ant_sep,pulser_voltage; double traces_per_sec,meters_per_mark,dummy_gain_pts[1],*gain_pts ; struct GprInfoStruct Info; /* struct in gpr_io.h */ struct SegyReelHdrStruct hdr; /* struct in gpr_io.h */ FILE *outfile; extern const char *GetSegyReelHdrMsg[]; /* in gpr_io.h */ extern FILE *log_file; /* beginning of this source */ #if defined(_INTELC32_) char *outbuffer = NULL; size_t vbufsize = 64512; /* 63 KB */ #endif switch (InfoPtr->input_datatype) { case 2: case 3: case 4: break; default: return 1; } /* Read input SEG-Y reel header again */ itemp = ReadSegyReelHdr(InfoPtr->dat_infilename,&swap_bytes,&num_traces, &hdr); if (itemp > 0) { if (log_file) fprintf(log_file,"%s\n",ReadSegyReelHdrMsg[itemp]); return 2; } ExtractSsInfoFromSegy(&Info,&hdr); /* Set/save values for output header file */ day = Info.time_date_created.day; month = Info.time_date_created.month; year = Info.time_date_created.year + 1980 - 1900; num_traces = InfoPtr->num_bins; num_samples = Info.in_samps_per_trace; time_zero_sample = Info.timezero_sample; total_time_ns = Info.in_time_window; start_pos = Info.starting_position; final_pos = Info.final_position; step_size = Info.position_step_size; pos_units = Info.position_units; ant_freq = Info.nominal_frequency; ant_sep = Info.antenna_separation; pulser_voltage = Info.pulser_voltage; num_stacks = Info.number_of_stacks; survey_mode = Info.survey_mode; if (Info.proc_hist == NULL) { proc_hist = InfoPtr->proc_hist; } else { proc_hist_size = strlen(Info.proc_hist) + 1; proc_hist_size += strlen(InfoPtr->proc_hist) + 2; proc_hist = (char *)malloc(proc_hist_size); if (proc_hist != NULL) strcat(proc_hist,InfoPtr->proc_hist); } text = Info.text; if (text == NULL) { dummy_text[0] = 0; text = dummy_text; } num_gain_pts = Info.num_gain_pts; gain_pts = Info.gain_pts; if (gain_pts == NULL) { dummy_gain_pts[0] = 0.0; gain_pts = dummy_gain_pts; num_gain_pts = 0; } meters_per_mark = 1.0 / InfoPtr->bin_size; traces_per_sec = 0.0; SetSgyFileHeader(day,month,year,num_traces,num_samples,time_zero_sample, (int)total_time_ns,start_pos,final_pos,step_size,pos_units, ant_freq,ant_sep,pulser_voltage,num_stacks,survey_mode, proc_hist,text,Info.job_number,Info.title1,Info.title2, InfoPtr->dat_outfilename,traces_per_sec,meters_per_mark, num_gain_pts,gain_pts,&hdr); free(proc_hist); /* Open output SGY file */ if ((outfile = fopen(InfoPtr->dat_outfilename,"wb")) == NULL) return 3; /* Speed up disk access by using large (conventional memory) buffer */ #if defined(_INTELC32_) realmalloc(outbuffer,vbufsize); if (outbuffer) setvbuf(outfile,outbuffer,_IOFBF,vbufsize); else setvbuf(outfile,NULL,_IOFBF,vbufsize); #endif /* Save reel header to disk */ if (fwrite((void *)&hdr,sizeof(struct SegyReelHdrStruct),(size_t)1,outfile) < 1) { fclose(outfile); #if defined(_INTELC32_) realfree(outbuffer); #endif return 4; } /* Save data to disk */ itemp = 0; switch (InfoPtr->input_datatype) { case 2: trace_size = 2; break; case 3: case 4: trace_size = 4; break; } trace_size *= InfoPtr->num_rows; /* data bytes + header bytes */ for (trace = 0; trace < InfoPtr->num_bins; trace++) { fwrite(InfoPtr->grid[trace],(size_t)trace_size,(size_t)1,outfile); } if (ferror(outfile)) { clearerr(outfile); itemp = 5; } #if defined(_INTELC32_) realfree(outbuffer); #endif fclose(outfile); return itemp; } /******************************* XfrmSaveUsrData() ******************************/ /* This function saves the GPR data to disk using the user-defined format. * * Parameter list: * struct XfrmParamInfoStruct *ParamInfoPtr - address of structure * * Requires: , , "gpr_xfrm.h". * Calls: fprintf, fopen, fclose, ferror, fread, fwrite, clearerr, * malloc, free. * Returns: 0 on success, or * >0 if error or warning (offset into an array of message strings). * const char *XfrmSaveUsrDataMsg[] = { "XfrmSaveUsrData(): No errors.", "XfrmSaveUsrData() ERROR: Invalid datatype for output user-defined file.", "XfrmSaveUsrData() ERROR: Problem getting input file header.", "XfrmSaveUsrData() ERROR: Unable to open output GPR file.", "XfrmSaveUsrData() ERROR: Problem saving GPR file header.", "XfrmSaveUsrData() ERROR: Problem saving GPR file data.", } ; * * Author: Jeff Lucius USGS Mineral Resources Program Lakewood, CO * Date: February 6, 1997 */ int XfrmSaveUsrData (struct XfrmParamInfoStruct *InfoPtr) { char *file_header; int itemp; long trace,trace_size; FILE *infile,*outfile; extern FILE *log_file; /* beginning of this source */ #if defined(_INTELC32_) char *outbuffer = NULL; size_t vbufsize = 64512; /* 63 KB */ #endif switch (InfoPtr->input_datatype) { case 1: case -1: case 2: case -2: case 3: case -3: case 4: case 8: case -5: case -6: break; default: return 1; } /* Read input user-defined header again */ if (InfoPtr->file_header_bytes > 0) { file_header = (char *)malloc(InfoPtr->file_header_bytes); if (file_header == NULL) { if (log_file) fprintf(log_file,"XfrmSaveUsrData() ERROR: unable to allocate temporary storage.\n"); return 2; } infile = fopen(InfoPtr->dat_infilename,"rb"); if (infile == NULL) { if (log_file) fprintf(log_file,"XfrmSaveUsrData() ERROR: unable to open input GPR file.\n"); return 2; } if (fread((void *)file_header,InfoPtr->file_header_bytes,(size_t)1,infile) < 1) { if (log_file) fprintf(log_file,"XfrmSaveUsrData() ERROR: unable to allocate temporary storage.\n"); return 2; } fclose(infile); } /* Open output GPR file */ if ((outfile = fopen(InfoPtr->dat_outfilename,"wb")) == NULL) return 3; /* Speed up disk access by using large (conventional memory) buffer */ #if defined(_INTELC32_) realmalloc(outbuffer,vbufsize); if (outbuffer) setvbuf(outfile,outbuffer,_IOFBF,vbufsize); else setvbuf(outfile,NULL,_IOFBF,vbufsize); #endif /* Save file header to disk */ if (InfoPtr->file_header_bytes > 0) { if (fwrite((void *)file_header,InfoPtr->file_header_bytes,(size_t)1,outfile) < 1) { fclose(outfile); #if defined(_INTELC32_) realfree(outbuffer); #endif return 4; } } /* Save data to disk */ itemp = 0; switch (InfoPtr->input_datatype) { case 1: case -1: trace_size = 1; break; case 2: case -2: case -5: trace_size = 2; break; case 3: case -3: case -6: case 4: trace_size = 4; break; case 8: trace_size = 8; break; } trace_size *= InfoPtr->num_rows; /* data bytes + header bytes */ for (trace = 0; trace < InfoPtr->num_bins; trace++) { fwrite(InfoPtr->grid[trace],(size_t)trace_size,(size_t)1,outfile); } if (ferror(outfile)) { clearerr(outfile); itemp = 5; } #if defined(_INTELC32_) realfree(outbuffer); #endif fclose(outfile); return itemp; } /**************************** DeallocInfoStruct() ***************************/ /* Deallocate the buffer space in the information structure. This function * will work correctly only if the num_... variables accurately reflect * the successful allocation of storage. * * Parameter list: * struct XfrmParamInfoStruct *InfoPtr - address of structure * * Requires: , "gpr_disp.h". * Calls: free. * Returns: void. * * Author: Jeff Lucius USGS Mineral Resources Program Golden, CO * Date: February 10, 1997 */ void DeallocInfoStruct (struct XfrmParamInfoStruct *InfoPtr) { int i; extern int Debug; if (InfoPtr->num_ticks > 0) { if (InfoPtr->tick_tracenum) { free(InfoPtr->tick_tracenum); InfoPtr->tick_tracenum = NULL; } if (InfoPtr->tick_xyz) { for (i=0; inum_ticks; i++) free(InfoPtr->tick_xyz[i]); free(InfoPtr->tick_xyz); InfoPtr->tick_xyz = NULL; } InfoPtr->num_ticks = 0; } if (InfoPtr->BinArray != NULL) { for (i=0; inum_bins; i++) { free(InfoPtr->BinArray[i].sum); } free(InfoPtr->BinArray); InfoPtr->BinArray = NULL; InfoPtr->num_bins = 0; } if (InfoPtr->trace_Xval != NULL) { free(InfoPtr->trace_Xval); InfoPtr->trace_Xval = NULL; } if (InfoPtr->trace_Yval != NULL) { free(InfoPtr->trace_Yval); InfoPtr->trace_Yval = NULL; } if (InfoPtr->trace_Zval != NULL) { free(InfoPtr->trace_Zval); InfoPtr->trace_Zval = NULL; } } /**************************** end of GPR_XFRM.C *****************************/