官方文档托管在 readthedocs 上。
Segyio 是一个小型 LGPL 许可的 C 库,可轻松与 SEG-Y 和 Seismic Unix 格式的地震数据进行交互,并具有 Python 和 Matlab 的语言绑定。 Segyio 试图为地震应用创建一个易于使用、可嵌入、面向社区的库。根据需要添加功能;非常欢迎各种建议和贡献。
要了解最新的开发和功能,请参阅变更日志。要编写面向未来的代码,请参阅计划的重大更改。
当 segyio 构建并安装后,您就可以开始编程了!查看教程、示例、示例程序和示例笔记本。有关示例和小食谱的技术参考,请阅读文档。 API 文档也可以通过 pydoc 获得 - 启动您最喜欢的 Python 解释器并输入help(segyio)
,它应该与 IDLE、pycharm 和其他 Python 工具很好地集成。
import segyio
import numpy as np
with segyio . open ( 'file.sgy' ) as f :
for trace in f . trace :
filtered = trace [ np . where ( trace < 1e-2 )]
请参阅示例了解更多信息。
segyio 的副本可作为预构建的二进制文件和源代码使用:
apt install python3-segyio
pip install segyio
git clone https://github.com/statoil/segyio
要构建 segyio,您需要:
要构建文档,您还需要 sphinx
要构建并安装 segyio,请在控制台中执行以下操作:
git clone https://github.com/equinor/segyio
mkdir segyio/build
cd segyio/build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON
make
make install
必须以 root make install
进行系统安装;如果您想安装在主目录中,请添加-DCMAKE_INSTALL_PREFIX=~/
或其他适当的目录,或者make DESTDIR=~/ install
。请确保您的环境选择非标准安装位置(PYTHONPATH、LD_LIBRARY_PATH 和 PATH)。
如果您安装了多个 Python,或者想要使用某种替代解释器,您可以通过传递-DPYTHON_EXECUTABLE=/opt/python/binary
以及安装前缀和构建类型来帮助 cmake 找到正确的解释器。
要构建 matlab 绑定,请使用选项-DBUILD_MEX=ON
调用 CMake。在某些环境中,Matlab 二进制文件位于非标准位置,在这种情况下,您需要通过传递-DMATLAB_ROOT=/path/to/matlab
来帮助 CMake 找到 matlab 二进制文件。
建议在调试模式下构建以获得更多警告并将调试符号嵌入到对象中。在CMAKE_BUILD_TYPE
中用Debug
代替Release
就足够了。
测试位于 language/tests 目录中,强烈建议通过添加测试来演示添加的新功能的正确性和契约。所有测试都可以通过调用ctest
来运行。请随意使用已经编写的测试作为指南。
构建 segyio 后,您可以使用ctest
运行测试,从构建目录执行。
请注意,要运行 Python 示例,您需要让您的环境知道在哪里可以找到 Python 库。它可以作为用户安装,或者将 segyio/build/python 库添加到 pythonpath 中。
本教程中的所有代码都假设导入了 segyio,并且 numpy 可以作为 np.
import segyio
import numpy as np
本教程假设您熟悉 Python 和 numpy。如需更新,请查看 python 教程和 numpy 快速入门
打开文件进行读取是通过segyio.open
函数完成的,并且通常与上下文管理器一起使用。使用with
语句,即使出现异常,文件也会正确关闭。默认情况下,文件以只读方式打开。
with segyio . open ( filename ) as f :
...
Open 接受多个选项(要获得更全面的参考,请使用help(segyio.open)
检查 open 函数的文档字符串。最重要的选项是第二个(可选)位置参数。要打开文件进行写入,请执行segyio.open(filename, 'r+')
,来自 C fopen
函数。
文件可以以非结构化模式打开,可以通过传递segyio.open
可选参数strict=False
,在这种情况下,不建立结构(内联数字、跨线数字等)不是错误,并且ignore_geometry=True
,在这种情况下 segyio甚至不会尝试设置这些内部属性。
segy 文件对象有几个描述此结构的公共属性:
f.ilines
推断内联数f.xlines
推断的交叉线数f.offsets
推断的偏移量数f.samples
推断的样本偏移(频率和记录时间延迟)f.unstructured
如果非结构化则为 True,如果结构化则为 Falsef.ext_headers
扩展文本标题的数量如果文件以非结构化方式打开,则所有行属性将为None
。
在 segyio 中,数据是通过所谓的模式检索和写入的。模式是抽象数组或寻址方案,并改变名称和索引的含义。所有模式都是文件句柄对象上的属性,支持len
函数,并且读取和写入通过f.mode[]
完成。写入是通过赋值完成的。受 numpy 启发,模式支持数组切片。可以使用以下模式:
trace
跟踪模式提供文件中布局的跟踪的原始寻址。这与header
一起是可用于非结构化文件的唯一模式。跟踪被枚举为0..len(f.trace)
。
读取一条轨迹会生成一个 numpy ndarray
,读取多个轨迹会生成一个ndarray
生成器。使用生成器语义并重用相同的对象,因此如果稍后想要缓存或寻址跟踪数据,则必须显式复制。
> >> f . trace [ 10 ]
> >> f . trace [ - 2 ]
> >> f . trace [ 15 : 45 ]
> >> f . trace [: 45 : 3 ]
header
通过类似于trace
寻址行为,访问项目会产生标头对象而不是 numpy ndarray
。标头是类似字典的对象,其中键是整数、地震 unix 样式键(在 segyio.su 模块中)和 segyio 枚举 (segyio.TraceField)。
标头值可以通过分配一个类似于字典的值来更新,并且分配右侧不存在的键不会被修改。
> >> f . header [ 5 ] = { segyio . su . tracl : 10 }
> >> f . header [ 5 ]. items ()
> >> f . header [ 5 ][ 25 , 37 ] # read multiple values at once
iline
, xline
如果文件是非结构化的,这些模式将引发错误。他们将[]
的参数视为相应行的键。行数始终在增加,但可以具有任意的、不均匀的间距。有效名称可以在ilines
和xlines
属性中找到。
与迹线一样,获取一行会生成一个ndarray
,而一段行会生成一个ndarray
生成器。当使用带有步骤的切片时,如果某些中间项与步骤不匹配,则可能会跳过一些中间项,即在包含行[1,2,3,4,5]
的文件上执行f.line[1:10:3]
相当于查找1, 4, 7
并找到[1,4]
。
使用 4D 堆栈前文件时,会隐式读取第一个偏移量。要访问不同的偏移量或偏移量范围,请使用逗号分隔的索引或范围,例如: f.iline[120, 4]
。
fast
, slow
这些是iline
和xline
的别名,由跟踪的布局方式决定。对于内联排序的文件, fast
会产生iline
。
depth_slice
深度切片是在一定深度处的水平、文件宽度的切割。生成的值是ndarray
和数组生成器。
gather
gather
是内联线和横向线的交集,是调查的垂直列,除非指定单个偏移量,否则返回偏移量 x 样本ndarray
。如果存在范围,它返回此类ndarray
的生成器。
text
text
模式是文本标题的数组,其中text[0]
是标准规定的文本标题, 1..n
是可选的扩展标题。
文本标头以文件中的 3200 字节类似字节 blob 形式返回。 segyio.tools.wrap
函数可以创建该字符串的面向行的版本。
bin
具有类似字典接口的文件范围二进制标头的值。行为类似于header
模式,但没有索引。
> >> for line in f . iline [: 2430 ]:
... print ( np . average ( line ))
> >> for line in f . xline [ 2 : 10 ]:
... print ( line )
> >> for line in f . fast [:: 2 ]:
... print ( np . min ( line ))
> >> for factor , offset in enumerate ( f . iline [ 10 , :]):
... offset *= factor
print ( offset )
> >> f . gather [ 200 , 241 , :]. shape
> >> text = f . text [ 0 ]
> >> type( text )
< type 'bytes' >
> >> f . trace [ 10 ] = np . zeros ( len ( f . samples ))
更多示例和食谱可以在文档字符串help(segyio)
和示例部分中找到。
Segyio 并不一定试图成为 SEG-Y 交互的最终目标;相反,我们的目标是降低与 SEG-Y 文件交互以进行嵌入、新应用程序或独立程序的障碍。
此外,目的不是支持完整的标准或所有外来的(但符合标准)格式的文件。做出了一些假设,例如:
目前,segio 支持:
segyio 中的写入功能主要是为了修改或改编文件。从头开始创建的文件不一定是符合规范的 SEG-Y 文件,因为我们只需编写 segyio 需要的标头字段来理解几何形状。仍然强烈建议按照规范维护和编写 SEG-Y 文件,但 segyio并不强制这样做。
Segyio可以处理很多类似SEG-Y的文件,即segyio处理不严格符合SEG-Y标准的文件。 Segyio 也不区分修订版,而是尝试使用文件中可用的信息。有关实际标准的参考,请参阅 SEG 的出版物:
我们欢迎各种形式的贡献;请参阅 CONTRIBUTING.md。
xarray
集成Alan Richardson 编写了一个很棒的小工具,用于将 xarray 与 segy 文件结合使用,他在本笔记本中演示了该工具
小型 SEG-Y 格式的文件包含在存储库中用于测试目的。这些数据是无意义的,并且是可预测的,并且可以通过使用 segyio 来重现。测试文件位于 test-data 目录中。要重现数据文件,请构建 segyio 并运行测试程序make-file.py
、 make-ps-file.py
和make-rotated-copies.py
,如下所示:
python examples / make - file . py small . sgy 50 1 6 20 25
python examples / make - ps - file . py small - ps . sgy 10 1 5 1 4 1 3
python examples / make - rotated - copies . py small . sgy
Small-lsb.sgy 文件是通过运行 Flip-endianness 程序创建的。该程序包含在 segyio 源代码树中,但不是软件包的一部分,也不用于分发和安装,仅用于复制测试文件。
地震unix文件small.su和small-lsb.su是通过以下命令创建的:
segyread tape=small.sgy ns=50 remap=tracr,cdp byte=189l,193l conv=1 format=1
> small-lsb.su
suswapbytes < small.su > small-lsb.su
如果您有带有免费许可证的小数据文件,请随时将其提交到该项目!
导入有用的库:
import segyio
import numpy as np
from shutil import copyfile
打开 segy 文件并检查它:
filename = 'name_of_your_file.sgy'
with segyio . open ( filename ) as segyfile :
# Memory map file for faster reading (especially if file is big...)
segyfile . mmap ()
# Print binary header info
print ( segyfile . bin )
print ( segyfile . bin [ segyio . BinField . Traces ])
# Read headerword inline for trace 10
print ( segyfile . header [ 10 ][ segyio . TraceField . INLINE_3D ])
# Print inline and crossline axis
print ( segyfile . xlines )
print ( segyfile . ilines )
读取 segy 文件中包含的堆栈后数据立方体:
# Read data along first xline
data = segyfile . xline [ segyfile . xlines [ 1 ]]
# Read data along last iline
data = segyfile . iline [ segyfile . ilines [ - 1 ]]
# Read data along 100th time slice
data = segyfile . depth_slice [ 100 ]
# Read data cube
data = segyio . tools . cube ( filename )
读取segy文件中包含的叠前数据立方体:
filename = 'name_of_your_prestack_file.sgy'
with segyio . open ( filename ) as segyfile :
# Print offsets
print ( segyfile . offset )
# Read data along first iline and offset 100: data [nxl x nt]
data = segyfile . iline [ 0 , 100 ]
# Read data along first iline and all offsets gath: data [noff x nxl x nt]
data = np . asarray ([ np . copy ( x ) for x in segyfile . iline [ 0 : 1 , :]])
# Read data along first 5 ilines and all offsets gath: data [noff nil x nxl x nt]
data = np . asarray ([ np . copy ( x ) for x in segyfile . iline [ 0 : 5 , :]])
# Read data along first xline and all offsets gath: data [noff x nil x nt]
data = np . asarray ([ np . copy ( x ) for x in segyfile . xline [ 0 : 1 , :]])
阅读并理解相当“非结构化”的数据(例如,在共同炮集中排序的数据):
filename = 'name_of_your_prestack_file.sgy'
with segyio . open ( filename , ignore_geometry = True ) as segyfile :
segyfile . mmap ()
# Extract header word for all traces
sourceX = segyfile . attributes ( segyio . TraceField . SourceX )[:]
# Scatter plot sources and receivers color-coded on their number
plt . figure ()
sourceY = segyfile . attributes ( segyio . TraceField . SourceY )[:]
nsum = segyfile . attributes ( segyio . TraceField . NSummedTraces )[:]
plt . scatter ( sourceX , sourceY , c = nsum , edgecolor = 'none' )
groupX = segyfile . attributes ( segyio . TraceField . GroupX )[:]
groupY = segyfile . attributes ( segyio . TraceField . GroupY )[:]
nstack = segyfile . attributes ( segyio . TraceField . NStackedTraces )[:]
plt . scatter ( groupX , groupY , c = nstack , edgecolor = 'none' )
使用另一个文件的相同标头写入 segy 文件,但将数据乘以 *2
input_file = 'name_of_your_input_file.sgy'
output_file = 'name_of_your_output_file.sgy'
copyfile ( input_file , output_file )
with segyio . open ( output_file , "r+" ) as src :
# multiply data by 2
for i in src . ilines :
src . iline [ i ] = 2 * src . iline [ i ]
从 sctrach 制作 segy 文件
filename='name_of_your_file.sgy'
% Inspect segy
Segy_struct=SegySpec(filename,189,193,1);
% Read headerword inline for each trace
Segy.get_header(filename,'Inline3D')
%Read data along first xline
data= Segy.readCrossLine(Segy_struct,Segy_struct.crossline_indexes(1));
%Read cube
data=Segy.get_cube(Segy_struct);
%Write segy, use same header but multiply data by *2
input_file='input_file.sgy';
output_file='output_file.sgy';
copyfile(input_file,output_file)
data = Segy.get_traces(input_file);
data1 = 2*data;
Segy.put_traces(output_file, data1);
很多时候,人们会因为 segyio 的性能而遇到问题,特别是在创建新文件时。罪魁祸首通常是这段代码:
with segyio.create('new.sgy', spec) as dst:
dst.header = headers
代码本身完全没问题,但在新创建文件时,它在某些系统上有微妙的行为:它对稀疏文件执行许多分散的写入。这可能快也可能慢,很大程度上取决于文件系统。
重写循环以连续写入文件:
with segyio.create('new.sgy', spec) as dst:
for i in range(spec.tracecount):
dst.header[i] = headers[i]
dst.trace[i] = traces[i]
如果文件是另一个文件的修改副本,而不更改跟踪长度,则首先在不使用 segyio 的情况下复制文件,然后使用 segyio 就地修改副本通常会更快(也更容易!):
shutil.copyfile(srcfile, dstfile)
with segyio.open(dstfile) as f:
f.header = headers
当加载程序找不到核心 segyio 库时,会出现此错误。如果您已显式设置安装前缀(使用-DCMAKE_INSTALL_PREFIX
),则必须使用ld.conf.d
文件或LD_LIBRARY_PATH
变量将加载程序配置为也查找此前缀。
如果您尚未设置CMAKE_INSTALL_PREFIX
,则 cmake 将默认安装到您的加载程序通常知道的/usr/local
。在基于 Debian 的系统上,库通常安装到/usr/local/lib
,加载程序可能不知道。请参阅问题#239。
sudo ldconfig
通常可以解决问题)-DCMAKE_INSTALL_LIBDIR=lib64
当 segyio 尝试在严格模式下打开文件(假设文件是常规的排序 3D 卷)时,会引发此异常。如果文件只是任意顺序的跟踪集合,则此操作将会失败。
检查当前文件的 segyio.open iline
和xline
输入参数是否正确。 Segyio 也支持只是跟踪集合的文件,但必须告诉您这样做是可以的。将strict = False
或ignore_geometry = True
传递给segyio.open
以分别允许或强制非结构化模式。请注意, f.iline
和类似功能现已禁用,并且会引发错误。
Segyio 最初由 Equinor ASA 编写和维护,作为一种免费、简单、易于使用的与地震数据交互的方式,可以根据我们的需求进行定制,并作为对自由软件社区的贡献。