2. CMP面元一致性检查与坏道剔除

为什么先做面元一致性检查

速度谱拾取以 CMP 道集为输入,而叠加前必须保证每个 CMP 面元内的道集是“完整且不重复”的。若某面元缺道,速度谱能量聚焦会变弱;若同一物理位置的道被重复计入(重复道头、重复偏移距),叠加时该位置权重被放大,形成假能量团。因此本案例的任务是:基于道头 CDP 与偏移距,统计每个 CMP 面元内的道数分布,定位缺失/重复道,输出坏道清单,供后续叠加前剔除。

检查对象与判定口径

先明确三个判定口径,避免后续统计口径混乱:

  • 面元键:以道头 CDP 号作为 CMP 面元标识(本例假设 CDP 已按面元编号,1 个 CDP = 1 个面元)。
  • 面元内道数:同一 CDP 下所有道的计数 n_trace。
  • 重复道判定:同一 CDP 内出现相同偏移距 offset 的道,视为重复(偏移距相同意味着近似同一炮检距位置,叠加权重重复)。

缺失判定需要参照“期望道数”。实际资料中期望道数常由观测系统决定,本例采用两种可操作口径:一是全测线面元道数的众数作为期望值 n_expect;二是若已知最大偏移距与偏移距步长,可用 n_expect = round(offset_max / offset_step) + 1 估算。下面用众数口径演示。

统计与定位的实现

下面是一段可直接运行的 Python 示例(仅依赖标准库),输入为从 SEGY 道头导出的记录列表,每条记录含 cdp 与 offset。代码完成:按 CDP 分组计数、求众数期望道数、标记缺道面元、标记重复偏移距道,并输出坏道清单。

from collections import Counter, defaultdict

# 示例:从道头导出的记录(cdp, offset, trace_no)
# 真实场景由 SEGY 读取后填充,此处为教学示例数据
records = [
    (101, 100, 1), (101, 200, 2), (101, 300, 3), (101, 400, 4),
    (102, 100, 5), (102, 200, 6), (102, 300, 7),          # 缺 400 偏移距
    (103, 100, 8), (103, 200, 9), (103, 200, 10), (103, 300, 11), (103, 400, 12),  # 200 重复
    (104, 100, 13), (104, 200, 14), (104, 300, 15), (104, 400, 16),
]

by_cdp = defaultdict(list)
for cdp, off, tr in records:
    by_cdp[cdp].append((off, tr))

# 1) 每个面元道数
counts = {cdp: len(v) for cdp, v in by_cdp.items()}
print("面元道数:", counts)

# 2) 期望道数:取众数
n_expect = Counter(counts.values()).most_common(1)[0][0]
print("期望道数 n_expect =", n_expect)

# 3) 缺道面元
missing = [cdp for cdp, n in counts.items() if n < n_expect]
print("缺道面元:", missing)

# 4) 重复偏移距道(同 CDP 同 offset 的第 2 条及以后)
bad_traces = []
for cdp, items in by_cdp.items():
    seen = {}
    for off, tr in items:
        if off in seen:
            bad_traces.append((cdp, off, tr, "重复偏移距"))
        else:
            seen[off] = tr
    if len(items) < n_expect:
        for off, tr in items:
            bad_traces.append((cdp, off, tr, "面元缺道"))

print("坏道清单:")
for row in bad_traces:
    print(row)

示例数据下预期输出:n_expect = 4;缺道面元为 [102];坏道清单包含 CDP 102 的 3 条道(面元缺道)与 CDP 103 中 trace_no=10 的道(重复偏移距)。这些结果属于由给定输入直接推出的示例结论,不是实测数据。

若资料存在 CDP 编号跳号(如 101、102、104),说明整个面元缺失,应把跳号区间也纳入缺道清单,而不是只统计已出现的 CDP。可用 range(min_cdp, max_cdp+1) 与已出现 CDP 集合做差集定位。

面元道数分布与坏道定位关系

下图把“道头输入 → 按 CDP 分组 → 道数分布 → 缺道/重复判定 → 坏道清单”的判定关系画成一张结构图,重点表现两种异常的分支与最终清单的对应关系。

道头记录 CDP offset trace_no 按 CDP 分组 n_trace = 道数 offset 集合 道数分布 众数 → n_expect 101:4 102:3 103:5 104:4 缺道判定 n_trace < n_expect → CDP 102 重复判定 同 CDP 同 offset → CDP 103 trace 10 坏道清单 cdp, offset, trace_no + 原因 判定口径:面元键 = CDP;期望道数取众数;重复 = 同 CDP 同 offset

坏道清单的字段与使用方式

清单要能直接驱动后续剔除,字段至少包含:cdp、offset、trace_no、reason(缺道/重复偏移距/面元跳号)。剔除时按 trace_no 精确删除,避免误删同偏移距的正常道。下表为示例数据生成的清单片段:

cdpoffsettrace_noreason
1021005面元缺道
1022006面元缺道
1023007面元缺道
10320010重复偏移距
缺道面元有两种处理策略:一是整面元剔除(保守,避免速度谱能量不足),二是保留并标记为低置信面元。选择取决于缺道比例:若缺道面元占比很小,整面元剔除更安全;若占比大,应回到观测系统或道头检查,而不是简单删除大量数据。

结果验证

剔除后应重新统计一次面元道数分布,确认:① 所有保留面元的 n_trace 等于 n_expect;② 每个面元内 offset 无重复;③ 坏道清单中的 trace_no 已不在保留集合中。三项同时满足,才可进入速度谱拾取环节。