This document will introduce the reading and writing process of SEGY, including the conversion of two data formats: IBM and PC.
The program will call the file to complete the conversion of IBM and PC formats.
Create new header files and C++ files, as well as the main program.
1. Writing and specifications of header files
1.1 Program description, call, declaration, definition
/********************************************************************** * Copyright(C) 2018,Company All Rights Reserved (1)Copyright Statement * * @file : (2) File name * * @brief : Realize the read and write operations of earthquake data (3) Introduction to the main functions of this file * * @version : 1.0 (4) Version information * * @author : Fan XinRan (5) Create the author * * @date: Tuesday, 2022/2/8 (6) Creation time * * Others: (7) Notes, changes, etc. ************************************************************************ //Call the required C header file#include<> //C Language header file #include<> #include<> #include<> //Call the required C++ header file#include<iostream> // C++ header file #include<vector> #include<algorithm> //Calling non-standard library#include"" // Used to create multidimensional arrays#include"" // Contains segy and bhed structures to extract information collected and stored in the roll head and the trail head // Define global variables and namespaces#define PI 3.141592654 //Constant Number Definition #define EPS 0.0000001 using namespace std;
1.2 Declare functions
unsigned short exchangeLowHigh16(unsigned short Data_temp);//The 16-bit high and low-bit conversion function short accounts for 2 bytes, 2*8unsigned int exchangeLowHigh32(unsigned int Data_temp); //32-bit high and low bit conversion function 4*8float ibm2pc(unsigned int Data_temp); //IBM to PC dataunsigned int pc2ibm(float input); //PC to IBM datafloat ieee2pc(unsigned int Data_temp); //IEEE to PC void trace_ibm2pc(float *data_output, int *data_input, int nt); //The seismic channel data is converted from IBM to PC formatvoid trace_pc2ibm(float *data_input, int *data_output, int nt); //The seismic channel data is converted from PC to IBM format bool copySeismicDataIBM(const char *filenameInput, const char *filenameOutput); //Copy seismic data from Inputfile to Outputfile
1.3 Complete Code
/********************************************************************** * Copyright(C) 2018,Company All Rights Reserved * * @file: * * @brief: Realize the read and write operations of earthquake data * * @version : 1.0 * * @author : Fan XinRan * * @date: Tuesday, 2022/2/8 * * Others: ************************************************************************ //(1) Call the required C header file#include<> // C Language header file #include<> #include<> #include<> //(2) Call the required C++ header file#include<iostream> // C++ header file #include<vector> #include<algorithm> //(3) Call the required non-standard library header file#include"" // project header file #include"" #include //(4) Define global constant#define PI 3.141592654 // Constant Number Definition #define EPS 0.0000001 //(5) Declare the namespaceusing namespace std; //(6) Declare the function name, input, output and its typeunsigned short exchangeLowHigh16(unsigned short Data_temp);//The 16-bit high and low-bit conversion function short accounts for 2 bytes, 2*8unsigned int exchangeLowHigh32(unsigned int Data_temp); //32-bit high and low bit conversion function 4*8float ibm2pc(unsigned int Data_temp); //IBM to PC dataunsigned int pc2ibm(float input); //PC to IBM datafloat ieee2pc(unsigned int Data_temp); //IEEE to PC void trace_ibm2pc(float *data_output, int *data_input, int nt); //The seismic channel data is converted from IBM to PC formatvoid trace_pc2ibm(float *data_input, int *data_output, int nt); //The seismic channel data is converted from PC to IBM format bool copySeismicDataIBM(const char *filenameInput, const char *filenameOutput); //Copy seismic data from Inputfile to Outputfile
2. Writing and specifications of C++ files
2.1 Necessary Notes
/************************************************************************************************************* Function: copySeismicDataIBM (1) Function name Description: copy segy file from input data to output data (2) Briefly describe its functions Input: const char *filenameInput [in] input filename (.segy) (3) Input variables and input file type Output: const char *filenameOutput[out] output filename (.segy) (4) Output variable and output file type Return: bool true program success bool false program failed (5)Return value and description Author: Fan XinRan (6) Create the author Date: 2022/2/8 (7) Creation time Others: (8) Notes, changes, etc. ******************************************************************************************************************************************
2.2 Defining Reading and Write Functions
#include "" bool copySeismicDataIBM(const char *filenameInput, const char *filenameOutput){ //Implementation code ... }
(1) Define the structure variables and numerical variables to be used
bhed
andsegy
All are defined inThe structure in the structure contains binary volume header information and path header information, and uses member access operators(.)
Get its content;
useunsigned int
Declare integer variables, uselong long
or__int64
Declare the number of bytes of SEGY file and the number of bytes of seismic channel to prevent the amount of data from exceeding the range, and initialize the variables as much as possible.
bhed fileheader; // file headersegy traceheader; // trace headerunsigned int nt=0; // number of sampleunsigned int sizefileheader=sizeof(fileheader); // size of fileheader; unsigned int sizetraceheader=sizeof(traceheader); // size of traceheader; unsigned int ncdp = 0; // number of cdp channel numberlong long size_file = 0; //size of input file long long size_trace = 0; //size of per-trace
(2) Create a new pointer variable
In the task of reading and writing seismic channel data, input pointer, output pointer, seismic channel data pointer, head pointer and a temporary pointer variable are used, including five pointer variables.
FILE *fpinput = NULL; // input file pointer FILE *fpoutput = NULL; // output file pointer float *dataInput = NULL; // input data pointer segy *traceheaderArray = NULL; // traceheader pointer int* temp = NULL; // temp pointer
In previous missionsfread(dataInput[itrace],nt * sizeof(float),1,fpinput)
,
The entire reading and writing process is:fpinput-->Read nt data-->dataInput[itrace]-->Write nt data-->fpoutput
In this task, the data needs to be transformed, and the process becomes:fpinput-->Read nt data-->temp-->IBM/PC conversion-->dataInput[itrace]-->Write nt data-->fpoutput
。
(3) Open the input and output file pointers
fpinput = fopen(filenameInput, "rb"); //open input file pointer fpoutput = fopen(filenameOutput,"wb"); //open output file pointer //Read and write operations... //Fopen() and fclose() appear in pairs. Remember to close the file after the operation of the file is completed.fclose(fpinput); //close input file pointer fclose(fpoutput); //close output file pointer
(4) Determine the file opening situation
if(fpinput==NULL){ //If the file pointer is NULL printf("Cannot open %s file\n", filenameInput); //Print "File opening failed" return false; //End the program} if(fpoutput==NULL){ printf("Cannot open %s file\n", filenameOutput); return false; }
(5) Read/calculate volume and channel information
fread(&fileheader,sizefileheader,1,fpinput); // Read the volume header information from the input stream (fpinput) to the specified address----->fileheader nt = exchangeLowHigh16() // High and low bit conversion _fseeki64(fpinput,0,SEEK_END); // Offset the 0 lengths of this structure from the end of the file to the file pointer fpinput, that is, fpinput points to the end of the file at this time size_file = _ftelli64(fpinput); // Return to the current file location, that is, the total number of bytes of the filesize_trace = nt*sizeof(float)+sizetraceheader; // Number of bytes per channel = number of sampled points + number of header bytes ncdp = (size_file - (long long)sizefileheader)/size_trace; // Number of channels = (Total number of file bytes - Number of volume header bytes)/Number of bytes per channel _fseeki64(fpinput,sizefileheader,SEEK_SET); // Offset the sizefileheader (number of volume header) length from the beginning of the file to the pointer fpinput, that is, fpinput points to the beginning of the first path at this timefwrite(&fileheader, sizefileheader, 1, fpoutput); // Write to the header first
-
fread()
Read data from a given stream into the array pointed to by the pointer; -
fwrite(*ptr, size, nmemb,*stream)
Parameters andfread()
Same,ptr
The data in the pointed array is written to the given streamstream
middle; -
_fseeki64
Usage andfseek
Same, means a certain number of bytes offset from the specified location of the file; the former has higher compatibility; -
_ftelli64
andftell
Similarly, return the current file location of the given stream; -
exchangeLowHigh16()
Finishshorthigh and low conversion,intUse high and low bit conversionexchangeLowHigh64()
。
(6) Traverse each earthquake channel and read and write data
dataInput=alloc2float(nt,ncdp); // Allocate the memory space required for nt*ncdp (sampling points × number of channels) to store two-dimensional seismic channel data// Where alloc2float is a function in uninstallation, creating a float-type two-dimensional array//dataInput is a secondary pointer, which can be simply recorded as dataInput pointing to the beginning of each line memset(dataInput[0], 0, nt*ncdp * sizeof(float)); // Start from the beginning of the first line, assign nt*ncdp characters in the memory block to 0// dataInput points to the beginning of each line, and dataInput[0] is the starting position of the entire 2D array // Allocate ncdp continuous space with length of sizetraceheader in the dynamic memory areatraceheaderArray = (segy*)calloc(ncdp,sizetraceheader); temp = (int*)calloc(nt,sizeof(int)); //Read the data of the trail head and seismic roads one by onefor(int itrace = 0; itrace < ncdp; itrace++){ fread(&traceheaderArray[itrace],sizetraceheader,1,fpinput); // &traceheaderArray[itrace] is the address of the itrace channel, and read the header information of the channel fread(temp,nt * sizeof(float),1,fpinput); // Read the information of nt sampling points and point the result to temp // Use trace_ibm2pc to convert the data of the nt sampling points after the temp position and perform IBM-->PC conversion, and the result points to the beginning of each channel (dataInput[itrace]) trace_ibm2pc(dataInput[itrace], temp, nt); }//end for(int itrace = 0; itrace < ncdp; itrace++) //Write the data of the trailhead and earthquake roads one by onefor (int itrace = 0; itrace < ncdp; itrace++) { fwrite(&traceheaderArray[itrace], sizetraceheader, 1, fpoutput); // Write the header information // Use trace_pc2ibm to convert the data of the nt sampling points after the temp position to PC-->IBM, and the result points to the beginning of each channel (dataInput[itrace]) trace_pc2ibm(dataInput[itrace],temp,nt); fwrite(temp, nt * sizeof(int), 1, fpoutput); // Save back to fpoutput in IBM format}//end for(int itrace = 0; itrace < ncdp; itrace++) // Add notes at the end of each loop for easy search and distinction //Release the memory after the write operation is completedfree(temp); // free temp pointer free(traceheaderArray); // free traceheader pointer free2float(dataInput); // free data input pointer
-
calloc(num,size)
: Allocated in the dynamic memory storage areanum
The length issize
The continuous space of the function returns a pointer to the starting address of the allocation; if the allocation is unsuccessful, return NULL; -
malloc(size)
: Function andcalloc()
Similar, the difference ismalloc()
The memory value will not be initialized to 0, andcalloc()
The newly requested memory will be filled with 0.
2.3 Complete code
/***************************************************************************** Function: CopySeismicData Description: copy segy file from input data to output data Input: const char *filenameInput [in] input filename (.segy) Output: const char *filenameOutput[out] output filename (.segy) Return: bool true program success bool false program failed Author: Fan XinRan Date : 2022/2/8 Others: *****************************************************************************/ #include "" bool copySeismicDataIBM(const char *filenameInput, const char *filenameOutput){ segy traceheader; // trace header bhed fileheader; // file header unsigned int nt = 0; // number of sample unsigned int sizetraceheader = sizeof(traceheader); // size of traceheader; unsigned int sizefileheader = sizeof(fileheader); // size of fileheader; unsigned int ncdp = 0; // number of cdp long long size_file = 0; //size of input file long long size_trace = 0; //size of per-trace FILE *fpinput = NULL; // input file pointer FILE *fpoutput = NULL; //output file pointer float **dataInput = NULL; //input data pointer segy *traceheaderArray = NULL; // int* temp = NULL; fpinput = fopen(filenameInput, "rb"); //open input file pointer fpoutput = fopen(filenameOutput, "wb"); //open output file pointer if (fpinput == NULL) { printf("Cannot open %s file\n", filenameInput); return false; } if (fpoutput == NULL) { printf("Cannot open %s file\n", filenameOutput); return false; } fread(&fileheader, sizefileheader, 1, fpinput); nt = ; nt = exchangeLowHigh16(); _fseeki64(fpinput, 0, SEEK_END); size_file = _ftelli64(fpinput); size_trace = nt * sizeof(float) + sizetraceheader; ncdp = (size_file - (long long)sizefileheader) / size_trace; _fseeki64(fpinput, sizefileheader, SEEK_SET); dataInput = alloc2float(nt, ncdp); memset(dataInput[0], 0, nt*ncdp * sizeof(float)); traceheaderArray = (segy*)calloc(ncdp, sizetraceheader); temp = (int*)calloc(nt,sizeof(int)); fwrite(&fileheader,sizefileheader,1, fpoutput); for (int itrace = 0; itrace < ncdp; itrace++) { fread(&traceheaderArray[itrace], sizetraceheader, 1, fpinput); fread(temp, nt * sizeof(int), 1, fpinput); trace_ibm2pc(dataInput[itrace], temp, nt); }//end for(int itrace = 0; itrace < ncdp; itrace++) for (int itrace = 0; itrace < ncdp; itrace++) { fwrite(&traceheaderArray[itrace], sizetraceheader, 1, fpoutput); trace_pc2ibm(dataInput[itrace],temp,nt); fwrite(temp, nt * sizeof(int), 1, fpoutput); }//end for(int itrace = 0; itrace < ncdp; itrace++) free(temp); free(traceheaderArray); free2float(dataInput); // free data input pointer fclose(fpoutput); //close output file pointer fclose(fpinput); //close input file pointer return true; }
3 Main function and operation results
#include"" void main(){ copySeismicDataIBM("",""); }
After running the main function, the program will read it in, this is an IBM format data. Write to
, thereby completing the copying of the SEGY file.
The above is the detailed explanation of the detailed reading of C/C++ segy files. For more information about C++ segy files, please pay attention to my other related articles!