OBN Data Import¶
This guide covers the ObnReceiverGathers3D template for importing Ocean Bottom Node (OBN) seismic data into MDIO.
Template Overview¶
The ObnReceiverGathers3D template organizes data with the following dimensions:
Dimension |
Description |
|---|---|
|
Sensor component (e.g., 1=X, 2=Y, 3=Z, 4=Hydrophone) |
|
Ocean bottom node receiver ID |
|
Shot line identifier |
|
Gun identifier for multi-gun sources |
|
Calculated dense index for shots (see Required Grid Overrides) |
|
Vertical sample axis |
Coordinates¶
Logical coordinates:
shot_point(original values),orig_field_record_numPhysical coordinates:
group_coord_x,group_coord_y,source_coord_x,source_coord_y
Note
The shot_index dimension is calculated (0 to N-1) from shot_point values during ingestion. Original shot_point values are preserved as a coordinate indexed by (shot_line, gun, shot_index).
Required Grid Overrides¶
CalculateShotIndex (Required)¶
The CalculateShotIndex grid override is required for the ObnReceiverGathers3D template. It calculates the shot_index dimension from shot_point values. Without this override, the import will fail with an error:
Required computed fields [‘shot_index’] for template ObnReceiverGathers3D not found after grid overrides.
This override handles multi-gun acquisition where shot points are interleaved across guns, calculating a dense shot_index from sparse shot_point values:
Before (interleaved shot_point):
Gun 1: 1, 3, 5, 7, ...
Gun 2: 2, 4, 6, 8, ...
After (dense shot_index):
Gun 1: 0, 1, 2, 3, ...
Gun 2: 0, 1, 2, 3, ...
For ObnReceiverGathers3D, the override uses shot_line as the line field and requires shot_line, gun, and shot_point headers.
Special Behaviors¶
Component Synthesis¶
When the SEG-Y spec does not include a component field, MDIO automatically synthesizes it with value 1 for all traces. This allows single-component data (e.g., hydrophone-only) to use the same template without modification.
Note
A warning is logged when component is synthesized:
SEG-Y headers do not contain ‘component’ field required by template ‘ObnReceiverGathers3D’. Synthesizing ‘component’ dimension with constant value 1 for all traces.
Usage¶
Basic Import¶
1from segy.schema import HeaderField
2from segy.standards import get_segy_standard
3
4from mdio import segy_to_mdio
5from mdio.builder.template_registry import get_template
6
7# Define SEG-Y header mapping
8obn_headers = [
9 HeaderField(name="orig_field_record_num", byte=9, format="int32"),
10 HeaderField(name="receiver", byte=13, format="int32"),
11 HeaderField(name="shot_point", byte=17, format="int32"),
12 HeaderField(name="shot_line", byte=133, format="int16"),
13 HeaderField(name="gun", byte=171, format="int16"),
14 HeaderField(name="component", byte=189, format="int16"),
15 HeaderField(name="coordinate_scalar", byte=71, format="int16"),
16 HeaderField(name="source_coord_x", byte=73, format="int32"),
17 HeaderField(name="source_coord_y", byte=77, format="int32"),
18 HeaderField(name="group_coord_x", byte=81, format="int32"),
19 HeaderField(name="group_coord_y", byte=85, format="int32"),
20]
21
22obn_spec = get_segy_standard(1.0).customize(trace_header_fields=obn_headers)
23
24segy_to_mdio(
25 input_path="obn_data.sgy",
26 output_path="obn_data.mdio",
27 segy_spec=obn_spec,
28 mdio_template=get_template("ObnReceiverGathers3D"),
29 grid_overrides={"CalculateShotIndex": True},
30 overwrite=True,
31)
Single-Component Data¶
For data without a component header field, simply omit it from the spec:
1# Same as above, but without the component field
2obn_headers = [
3 HeaderField(name="orig_field_record_num", byte=9, format="int32"),
4 HeaderField(name="receiver", byte=13, format="int32"),
5 HeaderField(name="shot_point", byte=17, format="int32"),
6 HeaderField(name="shot_line", byte=133, format="int16"),
7 HeaderField(name="gun", byte=171, format="int16"),
8 # component omitted - will be synthesized
9 HeaderField(name="coordinate_scalar", byte=71, format="int16"),
10 HeaderField(name="source_coord_x", byte=73, format="int32"),
11 HeaderField(name="source_coord_y", byte=77, format="int32"),
12 HeaderField(name="group_coord_x", byte=81, format="int32"),
13 HeaderField(name="group_coord_y", byte=85, format="int32"),
14]
Exploring the Data¶
1from mdio import open_mdio
2
3ds = open_mdio("obn_data.mdio")
4
5# View dimensions
6print(ds.sizes)
7# {'component': 4, 'receiver': 100, 'shot_line': 10, 'gun': 2, 'shot_index': 500, 'time': 2001}
8
9# Access original shot_point values (preserved as coordinate)
10print(ds["shot_point"].dims) # ('shot_line', 'gun', 'shot_index')
11
12# Select a receiver gather
13receiver_gather = ds.sel(receiver=150, component=4)
14receiver_gather["amplitude"].plot()
Required Header Fields¶
Field |
Required |
Notes |
|---|---|---|
|
Yes |
|
|
Yes |
|
|
Yes |
|
|
Yes |
|
|
No |
Synthesized with value 1 if missing |
|
Yes |
|
|
Yes |
|
|
Yes |
|
|
Yes |
|
|
Yes |
|
|
Yes |
See Also¶
Grid Overrides - All available grid overrides