官方文档托管在 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-segyiopip install segyiogit 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 . sgySmall-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 编写和维护,作为一种免费、简单、易于使用的与地震数据交互的方式,可以根据我们的需求进行定制,并作为对自由软件社区的贡献。