Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
JintaoLee-Roger committed Aug 6, 2021
0 parents commit cfc16eb
Show file tree
Hide file tree
Showing 12 changed files with 1,288 additions and 0 deletions.
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
*.out
*.exe
*.cppout
*.cout

.vscode/*
*.json

temp/*

*.segy
*.dat
*.sgy
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# segyConvert

A tool with C++ to read 3D seismic data in SEG-Y format
and convert 3D seismic data in binary format to SEG-Y format.

About SEGY-Y format: [SEG-Y rev 1](https://seg.org/Portals/0/SEG/News%20and%20Resources/Technical%20Standards/seg_y_rev1.pdf), [SEG-Y rev 2](https://seg.org/Portals/0/SEG/News%20and%20Resources/Technical%20Standards/seg_y_rev2_0-mar2017.pdf) and [A comparison of all version](https://wiki.seg.org/images/4/42/SEG-Y_bytestream_all_revisions.pdf).

Some code references Google's respository: [segy-stack](https://github.com/google/segy-stack).


## Usage

### Compile

```shell
# readSegy
g++ -o printTextHeader segy.cpp printTextHeader.cpp
g++ -o scan scan.cpp segy.cpp
g++ -o convertToDat convertToDat.cpp segy.cpp

# addSegy
g++ -o convrtToSegy addSegy.cpp convrtToSegy.cpp
```

The three files are also avaliable in [**Releases**](https://github.com/JintaoLee-Roger/segyConvert/releases)

### Run

The usage of `printTextHeader`, `scan` and `convertToDat` see [**readSegy**](https://github.com/JintaoLee-Roger/segyConvert/readSegy/README.md)

The usage of `convertToSegy` see [**addSegy**](https://github.com/JintaoLee-Roger/segyConvert/addSegy/README.md)


### TODO List

- [x] 4-byte IBM floating-point to 4-byte IEEE floating-point
- [ ] 4-byte IEEE floating-point to 4-byte IBM floating-point
63 changes: 63 additions & 0 deletions addSegy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# addSegy

A tool with C++ to convert 3D seismic binary data to SEG-Y format.

About SEGY-Y format: [SEG-Y rev 1](https://seg.org/Portals/0/SEG/News%20and%20Resources/Technical%20Standards/seg_y_rev1.pdf), [SEG-Y rev 2](https://seg.org/Portals/0/SEG/News%20and%20Resources/Technical%20Standards/seg_y_rev2_0-mar2017.pdf) and [A comparison of all version](https://wiki.seg.org/images/4/42/SEG-Y_bytestream_all_revisions.pdf).

## Usage

### Compile

```shell
g++ -o convrtToSegy addSegy.cpp convrtToSegy.cpp
```

The three files are also avaliable in [**Releases**](https://github.com/JintaoLee-Roger/segyConvert/releases)

### Run

Convert a binary file to a segy format file.
```shell
# get help
./convertToSegy
# Usage: convertToSegy infile n1 n2 n3 [outfile dt sxline sinline]
# param:
# infile: binary file path, e.g. mybin.dat
# n1: ns, i.e. number of samples per data trace
# n2: crossline number, i.e. number of traces per inline
# n3: inline number, i.e. number of traces per crossline
# outfile (optional): output file name, e.g. mytest, default: OUT_AddSegy
# dt (optional): Sample interval, default: 4000 microsecond
# sxline (optional): The first crossline number, default: 1
# sinline (optional): The first inline number, default: 1

# 4 parameters
./convertToSegy yourfile.dat 100 1835 540

# 5 parameters
./convertToSegy yourfile.dat 100 1835 540 outfile

# 6 parameters
./convertToSegy yourfile.dat 100 1835 540 outfile 4000

# 8 parameters
./convertToSegy yourfile.dat 100 1835 540 outfile 4000 20 50
```

### API
Some API
```c++
AddSegy(const std::string infile,
const int ns, const int nxline, const int ninline);

void setSampleInterval(int t); // default 4000 microsecond
void setLoc(int iloc, int xloc); // default 5, 17
void setStart(int is, int xs); // default 1, 1
void setOutName(const std::string outfile);
void convert();
```
### TODO List
- [x] stored in 4-byte IEEE floating-point format
- [ ] stored in 4-byte IBM floating-point format
224 changes: 224 additions & 0 deletions addSegy/addSegy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
/*
* Copyright (c) 2021 Jintao Li. All rights reserved.
* University of Science and Technology of China (USTC),
* Computational and Interpretation Group (CIG).
*
* @author: Jintao Li
* @version: v0.1
* @date: 2021-08-06
*
* @file: addSegy.cpp
* @brief: definition of SegyFile class
*/

#include "addSegy.h"

#include <iostream>
#include <vector>
#include <ctime>
#include <iomanip>

AddSegy::AddSegy(const std::string infile,
const int ns, const int nxline, const int ninline){
this->in_.open(infile, std::ios::in | std::ios::binary);
if (!this->in_){
std::cout << "Open file: " << infile << " failure" << std::endl;
exit(1);
}

in_.seekg(0, std::ios::end);
uintmax_t flength = in_.tellg();
if (ns * nxline * ninline * sizeof(float) != flength){
std::cout << "Error dimension, " << ns << "*" << ninline
<< "*" << nxline << "*sizeof(float) is "
<< ns * nxline * ninline * sizeof(float)
<< ", which is not equal to the file size: " << flength << std::endl;
exit(1);
}
in_.seekg(0, std::ios::beg);

this->_key.ns = ns;
this->_key.nxline = nxline;
this->_key.ninline = ninline;
updateTextHeader();
updateBinaryHeader();
initialTraceHeader();
}

AddSegy::~AddSegy(){
in_.close();
if (out_){
out_.close();
}
}

void AddSegy::setSampleInterval(int t){
_key.dt = t;
}

void AddSegy::setLoc(int iloc, int xloc){
_key.iloc = iloc;
_key.xloc = xloc;
}

void AddSegy::setStart(int is, int xs){
_key.sinline = is;
_key.sxline = xs;
}

void AddSegy::setOutName(const std::string outfile){
_key.outName = outfile;
}

void AddSegy::convert(){
updateTextHeader();
updateBinaryHeader();
initialTraceHeader();

out_.open(_key.outName+".segy", std::ios::out | std::ios::binary);

writeTextHeader();
out_.write(&binaryheader[0], 400);

std::vector<float> trace(_key.ns, 0);
int64_t loc = 0;
for (int i = _key.sinline; i < (_key.sinline+_key.ninline); ++i){
for (int j = _key.sxline; j < (_key.sxline+_key.nxline); ++j){
updateTraceHeader(i, j, i*10, j*10);
out_.write(&traceheader[0], 240);
readTrace(trace, loc);
out_.write((char *)&trace[0], _key.ns*sizeof(float));
loc += (_key.ns*sizeof(float));
}
}
}

char AddSegy::getEBCIDFromASCII(char c){
if (kASCIItoEBCDICmap.find(c) != kASCIItoEBCDICmap.end()){
return kASCIItoEBCDICmap.at(c);
}
return ' ';
}

void AddSegy::writeTextHeader(){
char eb_textheader[3200];
for (int i = 0; i < 3200; ++i){
eb_textheader[i] = getEBCIDFromASCII(textheader[i]);
}
out_.write(&eb_textheader[0], 3200);
}

void AddSegy::updateTextHeader(){
replaceStr(textheader, _key.outName, 80*3+10, 70);

std::stringstream s;
time_t now = time(0);
s << std::put_time(std::localtime(&now), "%Y/%m/%dT%H:%M");
replaceStr(textheader, s.str(), 80*4+36, 20);

replaceStr(textheader, std::to_string(_key.sinline), 80*6+18, 6);
replaceStr(textheader, std::to_string(_key.sinline + _key.ninline - 1), 80*6+38, 6);
replaceStr(textheader, std::to_string(_key.sxline), 80*7+18, 6);
replaceStr(textheader, std::to_string(_key.sxline + _key.nxline - 1), 80*7+38, 6);
replaceStr(textheader, std::to_string(_key.dt), 80*9+21, 6);
replaceStr(textheader, std::to_string(_key.ns), 80*10+38, 6);
if (!_key.big_endian)
replaceStr(textheader, "LITTLE_ENDIAN", 80*11+17, 50);
if (_key.dtype == 1) // 1 or 5
replaceStr(textheader, "4-byte IBM floating-point", 80*12+24, 50);

if (_key.iloc == 5){
replaceStr(textheader, "5-8", 80*23+40, 20);
}
else if (_key.iloc == 9){
replaceStr(textheader, "9-12", 80*23+40, 20);
}
else if (_key.iloc == 189){
replaceStr(textheader, "189-192", 80*23+40, 20);
}
else {
std::cout << "please don't save inline number in " << _key.iloc << std::endl;
}

if (_key.xloc == 17){
replaceStr(textheader, "17-20", 80*24+40, 20);
}
else if (_key.xloc == 21){
replaceStr(textheader, "21-24", 80*24+40, 20);
}
else if (_key.xloc == 193){
replaceStr(textheader, "193-196", 80*24+40, 20);
}
else {
std::cout << "please don't save xline number in " << _key.xloc << std::endl;
}

}

void AddSegy::updateBinaryHeader(){
replaceStr(binaryheader, (int32_t)1, 0);
replaceStr(binaryheader, (int32_t)1, 8);
replaceStr(binaryheader, (int16_t)1, 12);
replaceStr(binaryheader, (int16_t)_key.dt, 16);
replaceStr(binaryheader, (int16_t)_key.ns, 20);
replaceStr(binaryheader, (int16_t)_key.dtype, 24);
replaceStr(binaryheader, (int16_t)1, 26);
replaceStr(binaryheader, (int16_t)4, 28);
replaceStr(binaryheader, (int16_t)1, 30);
replaceStr(binaryheader, (int16_t)1, 54);
}

void AddSegy::initialTraceHeader(){
replaceStr(traceheader, (int32_t)1, 0);
replaceStr(traceheader, (int32_t)_key.sinline, 4);
replaceStr(traceheader, (int32_t)_key.sinline, 8);
replaceStr(traceheader, (int32_t)1, 12);
replaceStr(traceheader, (int32_t)_key.sxline, 16);
replaceStr(traceheader, (int32_t)_key.sxline, 20);
replaceStr(traceheader, (int32_t)1, 24);
replaceStr(traceheader, (int32_t)1, 28);
replaceStr(traceheader, (int16_t)1, 34);
replaceStr(traceheader, (int16_t)-10, 68);
replaceStr(traceheader, (int16_t)-100, 70);
replaceStr(traceheader, (int16_t)1, 88);
replaceStr(traceheader, (int16_t)_key.ns, 114);
replaceStr(traceheader, (int16_t)_key.dt, 116);
replaceStr(traceheader, (int16_t)1, 124);
replaceStr(traceheader, (int32_t)_key.sinline, 188);
replaceStr(traceheader, (int32_t)_key.sxline, 192);
}

void AddSegy::updateTraceHeader(size_t inum, size_t xnum, size_t x, size_t y){
replaceStr(traceheader, (int32_t)inum, 4);
replaceStr(traceheader, (int32_t)xnum, 8);
replaceStr(traceheader, (int32_t)inum, 16);
replaceStr(traceheader, (int32_t)xnum, 20);
replaceStr(traceheader, (int32_t)inum, 188);
replaceStr(traceheader, (int32_t)xnum, 192);
replaceStr(traceheader, (int32_t)x, 72);
replaceStr(traceheader, (int32_t)y, 76);
}

void AddSegy::replaceStr(char* t, const std::string s, size_t start, size_t len){
if (s.length() > len){
std::cout << "Warning! input number is out of range" << std::endl;
}
for (int i = 0; i < len; ++i){
t[start + i] = (i < s.length()) ? s[i] : ' ';
}
}

void AddSegy::readTrace(std::vector<float>& trace, int64_t loc){
in_.seekg(loc, std::ios::beg);
in_.read((char *)&trace[0], _key.ns * sizeof(float));

// TODO: complete ieee format to ibm format
for(auto &i : trace){
// if (1 == _key.dtype){
// i = ieee_to_ibm(i, true);
// }
// else {
i = swap_endian(i);
// }
}
}
Loading

0 comments on commit cfc16eb

Please sign in to comment.