Skip to content

Latest commit

 

History

History
369 lines (281 loc) · 12.8 KB

README_ZH.md

File metadata and controls

369 lines (281 loc) · 12.8 KB

cigsegy

English 中文

中文版的README不是最新的, 只支持到1.1.5, 详情请参考英文版

此文件最后更新版本为 1.1.5

一个读写 segy 格式地震数据的 pythonc++ 工具。可以将 segy 格式文件读到内存或者直接转为二进制文件,也可以将一个 numpy 数据存储为segy格式的文件。

特点:

  • 快,底层使用c++实现
  • 可以在python中使用,使用了pybind11将c++包装为python可调用的库
  • 可以处理规则不规则的地震数据,比如工区不是一个矩形(有缺失)或数据间隔不为1
  • 可以使用已有的segy文件的道头进行创建新的segy文件

你可以通过pip简单的安装 cigsegy

pip install cigsegy

你可以读取各种segy文件(无论是否规则)通过一个简单的函数:

d = cigsegy.fromfile('f.segy', iline=, xline=, istep=, xstep=)

你可以在创建一个新的segy文件的时候,使用一个老的segy文件的道头,相当于对老的segy文件的数据进行替换:

cigsegy.create_by_sharing_header('out.segy', 'header.segy', d, iline=, xline=, istep=, xstep=)

更多的用例见:Cases

v1.1.5 更新内容

  • 在 jupyter notebook 中禁止显示进度条
  • 允许 numpy slice, 即一个子数组传入 create_by_sharing_header 函数中,现在不需要在传入之前使用 data.clone()来使内存连续了。
  • 添加了一个 tools.read_header来获取 binary/trace 的全部道头信息。
  • 添加了一个 tools.get_metaInfo() 来获取元信息,以字典的形式存在

目录

安装

  • 使用 pip 安装:
pip install cigsegy
  • 本地安装 首先你需要安装依赖库 fmtpybind11.
# linux
sudo apt-get install python3-pybind11 libfmt-dev

# mac
brew install pybind11 fmt

你也可以手动安装依赖哭 fmtpybind11 .

# 安装 fmt
mkdir thridPart && cd thridPart/
git clone https://github.com/fmtlib/fmt.git
# 现在 fmt 被安装到 /xxx/cigsegy/thridPart/fmt


# 使用 pypi 安装 pybind11
pip install pybind11
# 现在 pybind11 被安装到 /xxx/lib/python3.8/site-packages/pybind11/

如果你仅需要python的版本,你可以运行:

pip install -U pip
pip install .

# 如果 fmt 没有被包含在系统的路径里
pip install . --install-option="--fmt_root=/xxx/fmt"

# 如果你需要的是一个 wheel 文件
# pip wheel . --build-option="--fmt_root=/xxx/fmt"

如果你还需要使用C++编写,可以在终端运行的两个可执行文件:

mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=your-install-dir
make
make install

# 如果 fmt 和 pybind11 没有在系统的搜索路径里
cmake .. -DCMAKE_INSTALL_PREFIX=your-install-dir \
  -Dpybind11_ROOT=/xxx/lib/python3.8/site-packages/pybind11/ \
  -Dfmt_ROOT=/xxx/cigsegy/thridPart/fmt/build/fmt/

# 如果你想要其他python版本的结果, 
# 添加 -DPYTHON_EXECUTABL 和 -DPYTHON_LIBRARIES 选项指定python的信息
cmake .. -DCMAKE_INSTALL_PREFIX=your-install-dir -DPYTHON_EXECUTABLE=/xxx/bin/python -DPYTHON_LIBRARIES=/xxx/lib/

用法

更多例子: Cases

import cigsegy

# 显示segy文件的前3200个字节的文本道头信息
cigsegy.textual_header('fx.segy')

# 显示一个segy文件的一些关键信息,比如shape, 数据格式等
cigsegy.metaInfo('fx.segy', iline=189, xline=193, istep=1, xstep=1)

# 如果不知道iline等信息,可以使用
cigsegy.metaInfo('fx.segy', use_guess=True)

# 将fx.segy文件读入到内存中,d 为 numpy.ndarray 格式
d = cigsegy.fromfile('fx.segy')

# 读取fx.segy文件,并指定inline/crossline的存储位置和间隔
d = cigsegy.fromfile('fx.segy', iline=189, xline=193, istep=1, xstep=1)

# 不读入到内存,而是直接将其转存到二进制文件 fx.dat 中
# 在 fx.segy 非常大,超过内存大小的时候很有用
cigsegy.tofile('fx.segy', 'fx.dat', iline=189, xline=193, istep=1, xstep=1)

# 如果道头信息损坏,或者被人为隐藏了, 可以知道数据尺寸和格式,忽略掉道头信息
# 假设 shape: (inline, xline, dt) = (589, 762, 1001)
d = cigsegy.fromfile_ignore_header('fx.segy', 589, 762, 1001, format=5)
# 注意 format 5 意味着每个数据点为 4 字节的 IEEE 浮点数
# format 1 意味着每个数据点为 4 字节的 IBM 浮点数.

# 存储为一个二进制文件, i.e., 不读入到内存中
cigsegy.tofile_ignore_header('fx.segy', 'fx.dat', 589, 762, 1001, format=5)

# 仅仅获得数据作为一个2维数组
data = cigsegy.collect('fx.segy')
# data.shape = (ntraces, nt)

# 读取一个 2D 的 segy 数据
data = cigsegy.collect('fx2d.segy')

# 如果不知道 inline/crossline 的存储位置和间隔, 
# 可以使用 `guess` 函数去猜测
locs = cigsegy.tools.guess('fx.segy')

# 或者直接使用 `fromfile_by_guess`, `tofile_by_guess` 这两个函数
d = cigsegy.tools.fromfile_by_guess('fx.segy')
cigsegy.tools.tofile_by_guess('fx.segy', 'fx.dat')

# 通过 inline and crossline 画出工区的形状
cigsegy.tools.plot_region('fx.segy')

# 获取全部的道头信息, in dict
cigsegy.tools.read_header('fx.segy', type='bh') # binary header, print it
header = cigsegy.tools.read_header('fx.segy', type='bh', printstr=False) # in dict
header = cigsegy.tools.read_header('fx.segy', type='th', n=10, printstr=False) # 10-th trace header

# 获取元信息 in dict
meta = cigsegy.tools.get_metaInfo('fx.segy', iline=, xline=, ...)

import numpy as np
import cigsegy

# fx.segy

d = ... # np.ndarray, shape = (589, 762, 1001)

# 创建 "new_fx.segy", 使用数据 'd' 和来自于 fx.segy 的道头
cigsegy.create_by_sharing_header('new_fx.segy', 'fx.segy', d, 
            iline=189, xline=193, istep=1, xstep=1)

# new_fx.dat, shape = (589, 762, 1001), 
# 当 new_fx.dat 非常大时,直接内存映射
shape = (589, 762, 1001)
cigsegy.create_by_sharing_header('new_fx.segy', 'fx.segy', 'new_fx.dat', 
            shape, iline=189, xline=193, istep=1, xstep=1)

# sub_fx.dat, shape = (401, 535, 800), 相对于f3.segy整个数据
# 的offset是 (65, 73, 100), 你可以使用 `offset` 参数去创建一个小的segy文件,
# 但是使用大的(f3.segy)segy文件的道头
d = ...
shape = (401, 535, 800) # d.shape
cigsegy.create_by_sharing_header('new_fx.segy', 'fx.segy', d, 
            iline=189, xline=193, istep=1, xstep=1, offset=(65, 73, 100))
cigsegy.create_by_sharing_header('sub_fx.segy', 'fx.segy', 'sub_fx.dat', 
            shape, iline=189, xline=193, istep=1, xstep=1, offset=(65, 73, 100))

# 如果不知道 inline&crossline 的位置和间隔,可以使用
cigsegy.tools.create_by_sharing_header_guess('new_fx.segy', 'fx.segy', d)
cigsegy.tools.create_by_sharing_header_guess('new_fx.segy', 'fx.segy', 
            'new_fx.dat', shape)

# 简单创建, 不使用已有道头信息
cigsegy.create('new2_fx.segy', 'new_fx.dat', 589, 762, 1001, ...)
cigsegy.create('new2_fx.segy', d, 589, 762, 1001, ...)

所有的用于创建一个segy文件的函数都添加了custom_info参数用于自定义3200字节的文本道头的前12行信息, 比如:

my_info = ['This is a test examples', 
           'For detail information, you can see: ', 
           'https://github.com/JintaoLee-Roger/cigsegy',
           'Thank you for using cigsegy']
cigsegy.create_by_sharing_header('new_fx.segy', 'fx.segy', d, 
            iline=189, xline=193, istep=1, xstep=1, offset=(65, 73, 100),
            custom_info=my_info)
cigsegy.textual_header('new_fx.segy')
# C01 This is a test examples
# C02 For detail information, you can see: 
# C03 https://github.com/JintaoLee-Roger/cigsegy
# C04 Thank you for using cigsegy
# C05
# ...

class Pysegy

import cigsegy

# read
segy = cigsegy.Pysegy('fx.segy')
print(segy.textual_header())
segy.setInlineLocation(5)
segy.setCrosslineLocation(5)
d = segy.read()
d2 = segy.read(1, 5, 2, 10, 3, 9)
...
# 更多细节可以参考 cigsegy.pyi

# create
segy = cigsegy.Pysegy('fx.dat', 589, 762, 1001)
segy.set...
segy.create('new_fx.segy', d)
# m更多细节可以参考 cigsegy.pyi

用到的第三方依赖

  • src/include/mio.hpp is from mandreyel/mio: Cross-platform C++11 header-only library for memory mapped file IO

  • src/include/progressbar.hpp is from gipert/progressbar: A very simple progress bar for C++ loops

  • tools/cxxopts.hpp is from jarro2783/cxxopts: Lightweight C++ command line option parser

  • pybind/pybind11: Seamless operability between C++11 and Python

  • fmtlib/fmt: A modern formatting library

两个在终端运行的可执行文件

两个使用c++编写的位于 your-install-dir/bin/ 的可执行文件: SEGYRead and SEGYCreate.

SEGYRead

./SEGYRead
# ./SEGYRead - a tool for segy file reading to binary file
# Usage:
#   ./SEGYRead [OPTION...] positional parameters

#   -o, --out arg               out binary file name
#   -f, --fills arg             the number to fill the miss trace, can be any 
#                               float or nan, or NAN
#   -z, --inline-loc arg        inline field in trace header, default is 189
#   -c, --crossline-loc arg     crossline field in trace header, default is 
#                               193
#       --istep arg             inline step
#       --xstep arg             crossline step
#       --xloc arg              X field in trace header, default is 73
#       --yloc arg              Y field in trace header, default is 77
#   -p, --print_textual_header  print 3200 bytes textual header
#   -m, --meta_info             print meta info
#       --ignore-header         reading segy by ignoring header and specify 
#                               shape
#   -d, --dimensions arg        the dimensions (x, y, z) or (nt, ncrossline, 
#                               ninline), use as '-d 128,128,256' (Required)

# Examples:
#   ./SEGYRead -p f3.segy             : show textual header
#   ./SEGYRead -m f3.segy             : show meta information
#   ./SEGYRead -o f3.dat f3.segy      : convert
#   ./SEGYRead -i f3.segy -o f3.dat   : convert
#   ./SEGYRead -o f3.dat -z 5 f3.segy : convert by specify inline field
#   ./SEGYRead -o f3.dat -z 5 --istep 2 f3.segy : convert by specify inline field and step
#   ./SEGYRead -o f3.dat -f nan f3.segy : convert and fill with nan
#   ./SEGYRead -o f3.dat --ignore-header -d 236,789,890 f3.segy : ignore header and specify shape

SEGYCreate

./SEGYCreate
# ./SEGYCreate - a tool for creating a segy file from a binary file
# Usage:
#   ./SEGYCreate [OPTION...] positional parameters

#   -o, --out arg            out segy file name (Required)
#   -d, --dimensions arg     the dimensions (x, y, z) or (nt, ncrossline, 
#                            ninline), use as '-d 128,128,256' (Required)
#   -z, --inline-loc arg     set inline field in trace header, default is 189
#   -c, --crossline-loc arg  set crossline field in trace header, default is 
#                            193
#       --dt arg             set sample interval, default is 4000
#   -f, --data_format arg    data format code, 4 bytes (1 for IBM, 5 for 
#                            IEEE) floating point, defualt is 5
#       --dx arg             set X interval
#       --dy arg             set Y interval
#       --min-inline arg     set start inline number
#       --min-crossline arg  set start crossline number
#       --start-time arg     set start time for each trace
#   -s, --share              create a segy file using a exist segy file 
#                            header
#       --header             the shared header segy file
#       --istep arg          inline step for the header segy file
#       --xstep arg          crossline step for the header segy file

# Examples:
#   ./SEGYCreate -i test.dat -o test.segy -d 128,128,256 : convert
#   ./SEGYCreate -o test.segy -d 128,128,256 test.dat : convert
#   ./SEGYCreate -o test.segy -d 128,128,256 -f 5 test.dat : specify data format
#   ./SEGYCreate -o test.segy -d 128,128,256 --dt 2000 test.dat : specify time interval
#   ./SEGYCreate -s -i test.dat -o test.segy --header header.segy -d 128,128,256 -z 189 -c 193 : using sharing header segy file

局限性

  • 只测试过叠后数据

致谢

感谢 jiarunyangustcshenghanlin 提供的bug和需求,并且帮助进行了多个数据的测试。