官方文件託管在 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 編寫和維護,作為一種免費、簡單、易於使用的與地震資料互動的方式,可以根據我們的需求進行定制,並作為對自由軟體社群的貢獻。