Skip to content

Commit c3035db

Browse files
committed
Adjust PreStackGathers3DTime template
1 parent f220049 commit c3035db

File tree

4 files changed

+51
-48
lines changed

4 files changed

+51
-48
lines changed

src/mdio/builder/templates/seismic_prestack.py

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,17 @@ class SeismicPreStackTemplate(AbstractDatasetTemplate):
2020
def __init__(self, data_domain: SeismicDataDomain):
2121
super().__init__(data_domain=data_domain)
2222

23-
self._coord_dim_names = [
24-
"shot_line",
25-
"gun",
26-
"shot_point",
27-
"cable",
28-
"channel",
29-
] # Custom coordinates for shot gathers
30-
self._dim_names = [*self._coord_dim_names, self._data_domain]
31-
self._coord_names = [
32-
"energy_source_point_number",
33-
"source_coord_x",
34-
"source_coord_y",
35-
"group_coord_x",
36-
"group_coord_y",
37-
]
38-
self._var_chunk_shape = [1, 1, 16, 1, 32, -1]
23+
self._spatial_dim_names = ("shot_line", "gun", "shot_point", "cable", "channel")
24+
self._dim_names = (*self._spatial_dim_names, self._data_domain)
25+
self._physical_coord_names = ("source_coord_x", "source_coord_y", "group_coord_x", "group_coord_y")
26+
self._logical_coord_names = ("orig_field_record_num",)
27+
# TODO(Dmitriy Repin): Allow specifying full-dimension-extent chunk size in templates.
28+
# https://github.com/TGSAI/mdio-python/issues/720
29+
# When implemented, the following will be requesting the chunk size of the last dimension
30+
# to be equal to the size of the dimension.
31+
# self._var_chunk_shape = (1, 1, 16, 1, 32, -1)
32+
# For now, we are hardcoding the chunk size to 1024.
33+
self._var_chunk_shape = (1, 1, 16, 1, 32, 1024)
3934

4035
@property
4136
def _name(self) -> str:
@@ -55,31 +50,31 @@ def _add_coordinates(self) -> None:
5550

5651
# Add non-dimension coordinates
5752
self._builder.add_coordinate(
58-
"energy_source_point_number",
53+
"orig_field_record_num",
5954
dimensions=("shot_line", "gun", "shot_point"),
6055
data_type=ScalarType.INT32,
6156
)
6257
self._builder.add_coordinate(
6358
"source_coord_x",
6459
dimensions=("shot_line", "gun", "shot_point"),
6560
data_type=ScalarType.FLOAT64,
66-
metadata=CoordinateMetadata(units_v1=self._horizontal_coord_unit),
61+
metadata=CoordinateMetadata(units_v1=self.get_unit_by_key("source_coord_x")),
6762
)
6863
self._builder.add_coordinate(
6964
"source_coord_y",
7065
dimensions=("shot_line", "gun", "shot_point"),
7166
data_type=ScalarType.FLOAT64,
72-
metadata=CoordinateMetadata(units_v1=self._horizontal_coord_unit),
67+
metadata=CoordinateMetadata(units_v1=self.get_unit_by_key("source_coord_y")),
7368
)
7469
self._builder.add_coordinate(
7570
"group_coord_x",
7671
dimensions=("shot_line", "gun", "shot_point", "cable", "channel"),
7772
data_type=ScalarType.FLOAT64,
78-
metadata=CoordinateMetadata(units_v1=self._horizontal_coord_unit),
73+
metadata=CoordinateMetadata(units_v1=self.get_unit_by_key("group_coord_x")),
7974
)
8075
self._builder.add_coordinate(
8176
"group_coord_y",
8277
dimensions=("shot_line", "gun", "shot_point", "cable", "channel"),
8378
data_type=ScalarType.FLOAT64,
84-
metadata=CoordinateMetadata(units_v1=self._horizontal_coord_unit),
79+
metadata=CoordinateMetadata(units_v1=self.get_unit_by_key("group_coord_y")),
8580
)

tests/integration/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
def get_segy_mock_4d_spec() -> SegySpec:
2323
"""Create a mock 4D SEG-Y specification."""
2424
trace_header_fields = [
25-
HeaderField(name="field_rec_no", byte=9, format="int32"),
25+
HeaderField(name="orig_field_record_num", byte=9, format="int32"),
2626
HeaderField(name="channel", byte=13, format="int32"),
2727
HeaderField(name="shot_point", byte=17, format="int32"),
2828
HeaderField(name="offset", byte=37, format="int32"),
@@ -118,7 +118,7 @@ def create_segy_mock_4d( # noqa: PLR0913
118118
channel, gun, shot_line = 0, 0, 0
119119

120120
# Assign dimension coordinate fields with calculated mock data
121-
header_fields = ["field_rec_no", "channel", "shot_point", "offset", "shot_line", "cable", "gun"]
121+
header_fields = ["orig_field_record_num", "channel", "shot_point", "offset", "shot_line", "cable", "gun"]
122122
headers[header_fields][trc_idx] = (shot, channel, shot, offset, shot_line, cable, gun)
123123

124124
# Assign coordinate fields with mock data

tests/integration/test_import_streamer_grid_overrides.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
# TODO(Altay): Finish implementing these grid overrides.
3232
# https://github.com/TGSAI/mdio-python/issues/612
3333
@pytest.mark.skip(reason="NonBinned and HasDuplicates haven't been properly implemented yet.")
34-
@pytest.mark.parametrize("grid_override", [{"NonBinned": True}, {"HasDuplicates": True}])
34+
@pytest.mark.parametrize(
35+
"grid_override", [{"NonBinned": True}, {"HasDuplicates": True}], ids=["NonBinned", "HasDuplicates"]
36+
)
3537
@pytest.mark.parametrize("chan_header_type", [StreamerShotGeometryType.C])
3638
class TestImport4DNonReg: # pragma: no cover - tests is skipped
3739
"""Test for 4D segy import with grid overrides."""
@@ -78,7 +80,7 @@ def test_import_4d_segy( # noqa: PLR0913
7880
xrt.assert_duckarray_equal(ds["time"], times_expected)
7981

8082

81-
@pytest.mark.parametrize("grid_override", [{"AutoChannelWrap": True}, None])
83+
@pytest.mark.parametrize("grid_override", [{"AutoChannelWrap": True}, None], ids=["AutoChannelWrap", "None"])
8284
@pytest.mark.parametrize("chan_header_type", [StreamerShotGeometryType.A, StreamerShotGeometryType.B])
8385
class TestImport4D:
8486
"""Test for 4D segy import with grid overrides."""
@@ -156,10 +158,9 @@ def test_import_4d_segy( # noqa: PLR0913
156158
assert "This grid is very sparse and most likely user error with indexing." in str(execinfo.value)
157159

158160

159-
# TODO(Altay): Finish implementing these grid overrides.
160-
# https://github.com/TGSAI/mdio-python/issues/612
161-
@pytest.mark.skip(reason="AutoShotWrap requires a template that is not implemented yet.")
162-
@pytest.mark.parametrize("grid_override", [{"AutoChannelWrap": True}, {"AutoShotWrap": True}, None])
161+
@pytest.mark.parametrize(
162+
"grid_override", [{"AutoChannelWrap": True, "AutoShotWrap": True}, None], ids=["Channel&ShotWrap", "None"]
163+
)
163164
@pytest.mark.parametrize("chan_header_type", [StreamerShotGeometryType.A, StreamerShotGeometryType.B])
164165
class TestImport6D: # pragma: no cover - tests is skipped
165166
"""Test for 6D segy import with grid overrides."""
@@ -177,7 +178,7 @@ def test_import_6d_segy( # noqa: PLR0913
177178

178179
segy_to_mdio(
179180
segy_spec=segy_spec,
180-
mdio_template=TemplateRegistry().get("XYZ"), # Placeholder for the template
181+
mdio_template=TemplateRegistry().get("PreStackGathers3DTime"), # Placeholder for the template
181182
input_path=segy_path,
182183
output_path=zarr_tmp,
183184
overwrite=True,

tests/unit/v1/templates/test_seismic_prestack.py

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111
from mdio.builder.schemas.v1.dataset import Dataset
1212
from mdio.builder.schemas.v1.units import LengthUnitEnum
1313
from mdio.builder.schemas.v1.units import LengthUnitModel
14+
from mdio.builder.schemas.v1.units import TimeUnitEnum
15+
from mdio.builder.schemas.v1.units import TimeUnitModel
1416
from mdio.builder.templates.seismic_prestack import SeismicPreStackTemplate
1517

1618
UNITS_METER = LengthUnitModel(length=LengthUnitEnum.METER)
19+
UNITS_SECOND = TimeUnitModel(time=TimeUnitEnum.SECOND)
1720

1821

1922
def _validate_coordinates_headers_trace_mask(dataset: Dataset, headers: StructuredType, domain: str) -> None:
@@ -27,15 +30,15 @@ def _validate_coordinates_headers_trace_mask(dataset: Dataset, headers: Structur
2730
dataset,
2831
name="headers",
2932
dims=[("shot_line", 1), ("gun", 3), ("shot_point", 256), ("cable", 512), ("channel", 24)],
30-
coords=["energy_source_point_number", "source_coord_x", "source_coord_y", "group_coord_x", "group_coord_y"],
33+
coords=["orig_field_record_num", "source_coord_x", "source_coord_y", "group_coord_x", "group_coord_y"],
3134
dtype=headers,
3235
)
3336

3437
validate_variable(
3538
dataset,
3639
name="trace_mask",
3740
dims=[("shot_line", 1), ("gun", 3), ("shot_point", 256), ("cable", 512), ("channel", 24)],
38-
coords=["energy_source_point_number", "source_coord_x", "source_coord_y", "group_coord_x", "group_coord_y"],
41+
coords=["orig_field_record_num", "source_coord_x", "source_coord_y", "group_coord_x", "group_coord_y"],
3942
dtype=ScalarType.BOOL,
4043
)
4144

@@ -97,9 +100,9 @@ def _validate_coordinates_headers_trace_mask(dataset: Dataset, headers: Structur
97100
# Verify non-dimension coordinate variables
98101
validate_variable(
99102
dataset,
100-
name="energy_source_point_number",
103+
name="orig_field_record_num",
101104
dims=[("shot_line", 1), ("gun", 3), ("shot_point", 256)],
102-
coords=["energy_source_point_number"],
105+
coords=["orig_field_record_num"],
103106
dtype=ScalarType.INT32,
104107
)
105108

@@ -148,39 +151,43 @@ def test_configuration(self) -> None:
148151
t = SeismicPreStackTemplate(data_domain="time")
149152

150153
# Template attributes for prestack shot
151-
assert t._data_domain == "time"
152-
assert t._coord_dim_names == ["shot_line", "gun", "shot_point", "cable", "channel"]
153-
assert t._dim_names == ["shot_line", "gun", "shot_point", "cable", "channel", "time"]
154-
assert t._coord_names == [
155-
"energy_source_point_number",
154+
assert t.name == "PreStackGathers3DTime"
155+
assert t.default_variable_name == "amplitude"
156+
assert t.trace_domain == "time"
157+
assert t.spatial_dimension_names == ("shot_line", "gun", "shot_point", "cable", "channel")
158+
assert t.dimension_names == ("shot_line", "gun", "shot_point", "cable", "channel", "time")
159+
assert t.physical_coordinate_names == ("source_coord_x", "source_coord_y", "group_coord_x", "group_coord_y")
160+
assert t.logical_coordinate_names == ("orig_field_record_num",)
161+
assert t.coordinate_names == (
156162
"source_coord_x",
157163
"source_coord_y",
158164
"group_coord_x",
159165
"group_coord_y",
160-
]
161-
assert t._var_chunk_shape == [1, 1, 16, 1, 32, -1]
166+
"orig_field_record_num",
167+
)
168+
assert t.full_chunk_size == (1, 1, 16, 1, 32, -1)
162169

163170
# Variables instantiated when build_dataset() is called
164171
assert t._builder is None
165172
assert t._dim_sizes == ()
166-
assert t._horizontal_coord_unit is None
173+
assert t._units == {}
167174

168175
# Verify prestack shot attributes
169176
attrs = t._load_dataset_attributes()
170177
assert attrs == {"surveyDimensionality": "3D", "ensembleType": "shot_point", "processingStage": "pre-stack"}
178+
assert t.default_variable_name == "amplitude"
171179

172180
assert t.name == "PreStackGathers3DTime"
173181

174182
def test_build_dataset(self, structured_headers: StructuredType) -> None:
175183
"""Unit tests for SeismicPreStackTemplate build in time domain."""
176184
t = SeismicPreStackTemplate(data_domain="time")
185+
t.add_units({"source_coord_x": UNITS_METER, "source_coord_y": UNITS_METER}) # spatial domain units
186+
t.add_units({"group_coord_x": UNITS_METER, "group_coord_y": UNITS_METER}) # spatial domain units
187+
t.add_units({"time": UNITS_SECOND}) # data domain units
177188

178-
assert t.name == "PreStackGathers3DTime"
179189
dataset = t.build_dataset(
180-
"North Sea 3D Shot Time",
181-
sizes=(1, 3, 256, 512, 24, 2048),
182-
horizontal_coord_unit=UNITS_METER,
183-
header_dtype=structured_headers,
190+
"North Sea 3D Shot Time", sizes=(1, 3, 256, 512, 24, 2048), header_dtype=structured_headers
184191
)
185192

186193
assert dataset.metadata.name == "North Sea 3D Shot Time"
@@ -195,7 +202,7 @@ def test_build_dataset(self, structured_headers: StructuredType) -> None:
195202
dataset,
196203
name="amplitude",
197204
dims=[("shot_line", 1), ("gun", 3), ("shot_point", 256), ("cable", 512), ("channel", 24), ("time", 2048)],
198-
coords=["energy_source_point_number", "source_coord_x", "source_coord_y", "group_coord_x", "group_coord_y"],
205+
coords=["orig_field_record_num", "source_coord_x", "source_coord_y", "group_coord_x", "group_coord_y"],
199206
dtype=ScalarType.FLOAT32,
200207
)
201208
assert isinstance(seismic.compressor, Blosc)

0 commit comments

Comments
 (0)