1. SEG-Y文件结构解析

SEG-Y 是地震勘探行业最通用的交换格式,几乎所有采集系统、处理软件和解释平台都能读写它。但“能读”不等于“读对”。在实际项目中,因为字节位置错位、编码误判或字段含义理解偏差,导致道头被整体平移、坐标错乱、采样点数对不上的情况非常常见。要避免这些问题,第一步就是把 SEG-Y 的物理布局彻底看清楚:它本质上是一个严格按字节偏移组织的二进制文件,由文件卷头(File Header)、道头(Trace Header)和道数据(Trace Data)三段构成,前两段是“说明书”,第三段才是真正的地震波形。

三段式布局:先看骨架,再看内容

按照 SEG-Y 修订版(rev1/rev2)的通用约定,文件开头是 3200 字节的文本卷头,用 40 行 × 80 列的固定格式描述工区、测线、采集参数等文字信息;紧接着是 400 字节的二进制卷头,存放采样间隔、每道采样点数、数据格式码等关键数值;之后进入“道循环”——每一道由 240 字节的道头加一段道数据组成,道数据长度由采样点数与每样点字节数决定。整个文件就是“3200 + 400 + N×(240 + 道数据长度)”的重复结构。

理解这个骨架的关键在于:所有字段都靠字节偏移定位,而不是靠名字。软件读文件时,先跳到第 3217 字节读采样间隔,跳到第 3221 字节读每道采样点数,再根据数据格式码算出每个样点占几个字节,才能正确切分出第一道数据、第二道数据……一旦某个偏移读错,后面全部错位。因此检查 SEG-Y 的第一步永远是核对二进制卷头里的这几个“定盘星”字段。

SEG-Y 文件三段式字节布局 ① 文本卷头 Textual Header 字节 1–3200 | 40 行 × 80 列 | EBCDIC 或 ASCII 编码 | 工区/测线/采集参数文字说明 3200 B ② 二进制卷头 Binary Header 字节 3201–3600 | 400 B | 大端/小端整数 3217–3218 采样间隔(μs) 3221–3222 每道采样点数 3225–3226 数据格式码 ③ 道循环 Trace Loop(重复 N 次) 道头 Trace Header(240 B) 1–4 道序号 5–8 道内序号 9–12 原始野外记录号 17–18 每道采样点数 19–20 采样间隔(μs) 73–76 / 77–80 炮点/检波点坐标 道数据 Trace Data 长度 = 采样点数 × 每样点字节数 格式码 1:4 B IBM 浮点 格式码 2:4 B 整型 3:2 B 整型 格式码 5:4 B IEEE 浮点 样点按时间顺序连续存放 文件总长 = 3200 + 400 + Σ(240 + 道数据长度) | 所有字段按字节偏移定位

编码差异:EBCDIC 与 ASCII 不能混读

文本卷头是唯一“人可读”的部分,但它有两种编码可能:早期 SEG-Y 沿用大型机传统,使用 EBCDIC 编码;现代软件多写 ASCII。两者对同一字节的解释完全不同——例如字母“A”在 ASCII 中是 0x41,在 EBCDIC 中是 0xC1。如果拿 ASCII 方式去读 EBCDIC 文本,屏幕上会出现一堆乱码或奇怪符号,但文件本身并没有损坏。

实际判断方法很直接:用十六进制工具查看文件前几十个字节。若看到大量 0x40(EBCDIC 空格)和 0xC1–0xC9、0xD1–0xD9 区间的字母码,基本可判定为 EBCDIC;若看到 0x20(ASCII 空格)和 0x41–0x5A 的字母码,则为 ASCII。很多工具(如 segyread、Seismic Unix 的 segyread、Python 的 segyio)都提供编码参数,读之前必须显式指定,否则文本卷头不可用。需要强调的是:编码问题只影响 3200 字节文本卷头,二进制卷头与道头始终是二进制整数,不受 EBCDIC/ASCII 影响,这是初学者最容易混淆的一点。

关键字段的字节位置与含义

二进制卷头里有几个字段决定了整个文件的解析方式,必须逐一核对。下表列出最常用的偏移(以文件起始为第 1 字节计,采用 SEG-Y rev1 约定):

字段字节位置长度含义与常见取值
采样间隔3217–32182 B微秒,如 2000 表示 2 ms
每道采样点数3221–32222 B如 1500、3000
数据格式码3225–32262 B1=IBM浮点,2=4B整型,3=2B整型,5=IEEE浮点
道头中采样点数道头 17–182 B应与卷头一致,不一致需排查
道头中采样间隔道头 19–202 B应与卷头一致
炮点坐标道头 73–764 B需结合坐标缩放因子(71–72)解读

这里有一个非常实用的检查逻辑:卷头采样点数与道头采样点数应当一致。如果卷头写 1500、道头写 1000,那么按卷头切分道数据就会整体错位,第二道开始全部读错。同理,数据格式码若写成 5(IEEE 浮点)而实际数据是 IBM 浮点,读出来的波形幅度会完全失真。因此解析前先做“三对齐”核对:采样间隔对齐、采样点数对齐、格式码与实际字节数对齐。

一个可操作的解析示例

假设拿到一个文件,十六进制查看发现:3217–3218 为 0x07D0(2000 μs),3221–3222 为 0x05DC(1500 点),3225–3226 为 0x0005(IEEE 浮点)。则可推算:每道数据长度 = 1500 × 4 = 6000 字节,单道总长 = 240 + 6000 = 6240 字节。第一道道头起始于第 3601 字节,第一道数据起始于第 3841 字节,第二道道头起始于第 9841 字节,依此类推。用这个公式可以快速验证文件总长是否能被 6240 整除(余 3600 字节的卷头部分),若不能整除,说明存在变长道或文件截断,需要进一步排查。

检查 SEG-Y 时养成“先读卷头、再验道头、后切数据”的顺序:卷头定全局参数,道头验一致性,数据段才可信。编码只影响文本卷头,不要因为文本乱码就怀疑整个文件损坏。

把这三段布局和关键偏移记牢,后续的道头字段提取、坐标恢复、格式转换才有可靠基础。很多“数据读不出来”的问题,根源往往就在这最初几百个字节的偏移与编码判断上。