test_prestack_gather_spacing.py 7.26 KB
Newer Older
Jim King's avatar
Jim King committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import os
from pathlib import Path
from typing import Tuple, Union

import pytest
import openvds

from segyimport_test_config import test_data_dir, ImportExecutor, TempVDSGuard


def construct_respace_executor(output_vds: TempVDSGuard, segy_name: str, respace_setting: Union[str, None]) -> ImportExecutor:
    ex = ImportExecutor()

    if respace_setting:
        ex.add_args(["--respace-gathers", respace_setting])

    ex.add_arg("--prestack")
    ex.add_args(["--vdsfile", output_vds.filename])

    ex.add_arg(segy_name)

    return ex


@pytest.fixture
def output_vds() -> TempVDSGuard:
    return TempVDSGuard("import_mutes_test")


@pytest.fixture
def prestack_segy() -> str:
Jim King's avatar
Jim King committed
32
33
    return os.path.join(test_data_dir, "HeadwavePlatform", "PlatformIntegration", "Teleport", "Teleport_Trim",
                        "3D_Prestack", "ST0202R08_Gather_Time.segy")
Jim King's avatar
Jim King committed
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49


@pytest.fixture
def off_executor(prestack_segy, output_vds) -> Tuple[ImportExecutor, TempVDSGuard]:
    """Setup an ImportExecutor with respacing set to Off"""
    ex = construct_respace_executor(output_vds, prestack_segy, "Off")
    return ex, output_vds


@pytest.fixture
def invalid_executor(prestack_segy, output_vds) -> Tuple[ImportExecutor, TempVDSGuard]:
    """Setup an ImportExecutor with respacing set to an invalid value"""
    ex = construct_respace_executor(output_vds, prestack_segy, "Partial")
    return ex, output_vds


50
def get_gathers_stats(vds_filename: str) -> Tuple[int, int, int, int, int, int, int]:
Jim King's avatar
Jim King committed
51
52
53
54
55
56
57
58
59
60
61
    """
    Read all the gathers in a single inline and return stats on how many gathers have dead traces in various
    regions of the gather.

    :return tuple of (
      total gathers,
      number of gathers with dead traces only at front of gather,
      number of gathers with dead traces only within the gather,
      number of gathers with dead traces only at end of gather,
      number of gathers with dead traces in multiple places,
      number of gathers with no dead traces
62
      number of consecutive duplicate offset values within a gather
Jim King's avatar
Jim King committed
63
64
      )
    """
Jim King's avatar
Jim King committed
65
    with openvds.open(vds_filename, "") as handle:
Jim King's avatar
Jim King committed
66
67
68
69
70
71
        layout = openvds.getLayout(handle)
        access_manager = openvds.getAccessManager(handle)

        trace_channel = layout.getChannelIndex("Trace")
        assert trace_channel > 0, "Trace channel not found"

72
73
74
        offset_channel = layout.getChannelIndex("Offset")
        assert offset_channel > 0, "Offset channel not found"

Jim King's avatar
Jim King committed
75
76
77
78
79
80
81
82
83
84
85
        # only read one inline; make it the middle inline
        inline_index = layout.getDimensionNumSamples(3) // 2
        dim2_size = layout.getDimensionNumSamples(2)
        dim1_size = layout.getDimensionNumSamples(1)

        # stats counters
        front_only = 0
        middle_only = 0
        end_only = 0
        mixed = 0
        no_dead = 0
86
        duplicate_offsets = 0
Jim King's avatar
Jim King committed
87
88
89

        for crossline_index in range(dim2_size):
            trace_flag_request = access_manager.requestVolumeSubset((0, 0, crossline_index, inline_index, 0, 0),
90
91
                                                                    (1, dim1_size, crossline_index + 1,
                                                                     inline_index + 1, 1, 1),
Jim King's avatar
Jim King committed
92
93
                                                                    channel=trace_channel,
                                                                    format=openvds.VolumeDataChannelDescriptor.Format.Format_U8,
Jim King's avatar
Jim King committed
94
                                                                    dimensionsND=openvds.DimensionsND.Dimensions_012)
Jim King's avatar
Jim King committed
95

96
97
98
99
100
101
102
            offset_request = access_manager.requestVolumeSubset((0, 0, crossline_index, inline_index, 0, 0),
                                                                (1, dim1_size, crossline_index + 1, inline_index + 1, 1,
                                                                 1),
                                                                channel=offset_channel,
                                                                format=openvds.VolumeDataChannelDescriptor.Format.Format_U8,
                                                                dimensionsND=openvds.DimensionsND.Dimensions_012)

Jim King's avatar
Jim King committed
103
            assert dim1_size == trace_flag_request.data.shape[0]
104
            assert dim1_size == offset_request.data.shape[0]
Jim King's avatar
Jim King committed
105

106
            # analyze trace flag and offset data to figure out which stats counters to bump
Jim King's avatar
Jim King committed
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

            dead_trace_ranges = []
            i = 0
            while i < dim1_size:
                if trace_flag_request.data[i] == 0:
                    start = i
                    i += 1
                    while i < dim1_size and trace_flag_request.data[i] == 0:
                        i += 1
                    end = i - 1
                    dead_trace_ranges.append((start, end))
                else:
                    i += 1

            if len(dead_trace_ranges) == 0:
                no_dead += 1
            elif len(dead_trace_ranges) == 1:
                # either front, middle, end
                start, stop = dead_trace_ranges[0]
                if start == 0:
                    front_only += 1
128
                elif stop == trace_flag_request.data.shape[0] - 1:
Jim King's avatar
Jim King committed
129
130
131
132
133
134
                    end_only += 1
                else:
                    middle_only += 1
            else:
                mixed += 1

135
136
137
138
139
140
            # Find any traces with duplicate offset values within the gather
            for i in range(1, offset_request.data.shape[0]):
                if offset_request.data[i] == offset_request.data[i - 1]:
                    duplicate_offsets += 1

        return dim2_size, front_only, middle_only, end_only, mixed, no_dead, duplicate_offsets
Jim King's avatar
Jim King committed
141
142


Jim King's avatar
Jim King committed
143
144
145
146
147
148
def test_gather_spacing_invalid_arg(invalid_executor):
    ex, output_vds = invalid_executor

    result = ex.run()

    assert result != 0, ex.output()
Jim King's avatar
Jim King committed
149
    assert "unknown --respace-gathers option" in ex.output().lower()
Jim King's avatar
Jim King committed
150
151


152
153
154
155
156
157
158
@pytest.mark.parametrize("respace_option", [None, "Auto", "On"])
def test_gather_spacing_with_on_variations(prestack_segy, output_vds, respace_option):
    """
    Parameterized test for the different ways to execute the importer that all result in having gather
    respacing turned On.
    """
    ex = construct_respace_executor(output_vds, prestack_segy, respace_option)
Jim King's avatar
Jim King committed
159
160
161
162
163
164

    result = ex.run()

    assert result == 0, ex.output()
    assert Path(output_vds.filename).exists()

165
166
    total, leading_only, middle_only, trailing_only, mixed, no_dead, duplicate_offsets =\
        get_gathers_stats(output_vds.filename)
Jim King's avatar
Jim King committed
167

Jim King's avatar
Jim King committed
168
    assert total == 71
169
170
    assert middle_only == 23
    assert mixed == 0
Jim King's avatar
Jim King committed
171
    assert trailing_only == 0
172
173
    assert leading_only == 0
    assert no_dead == 48
Jim King's avatar
Jim King committed
174

175
176
    # There traces with duplicate offsets in this data, and the importer must preserve all those traces
    assert duplicate_offsets == 40
Jim King's avatar
Jim King committed
177
178
179
180
181
182
183
184
185
186


def test_gather_spacing_off(off_executor):
    ex, output_vds = off_executor

    result = ex.run()

    assert result == 0, ex.output()
    assert Path(output_vds.filename).exists()

187
188
    total, leading_only, middle_only, trailing_only, mixed, no_dead, duplicate_offsets =\
        get_gathers_stats(output_vds.filename)
Jim King's avatar
Jim King committed
189

Jim King's avatar
Jim King committed
190
    assert total == 71
Jim King's avatar
Jim King committed
191
192
    assert middle_only == 0
    assert mixed == 0
193
    assert trailing_only == 23
Jim King's avatar
Jim King committed
194
    assert leading_only == 0
195
196
197
198
    assert no_dead == 48

    # There traces with duplicate offsets in this data, and the importer must preserve all those traces
    assert duplicate_offsets == 40