Skip to content

Commit

Permalink
Add SEG-Y Revision 2.1 to supported formats (#232)
Browse files Browse the repository at this point in the history
* Add support for SEG-Y Rev2.1 specification

* Add support for SEG-Y Rev2.1 specification

---------

Co-authored-by: Altay Sansal <altay.sansal@tgs.com>
  • Loading branch information
tasansal and Altay Sansal authored Nov 20, 2024
1 parent 965311e commit 4a431ad
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 10 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,10 @@ are still in progress and not all validation logic is implemented yet:

- ✅ Rev 0 (1975)
- ✅ Rev 1 (2002)
- ✅ Rev 2 (2017)
- 🔲 Rev 2.1 (2023)
- ✅ Rev 2 (2017)\*\*
- ✅ Rev 2.1 (2023)\*\*

\*\* The XML stanzas and extended trace headers are not currently supported.

### Custom SEG-Y Standards

Expand Down
2 changes: 2 additions & 0 deletions src/segy/standards/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
from segy.standards.spec import REV0
from segy.standards.spec import REV1
from segy.standards.spec import REV2
from segy.standards.spec import REV21

register_segy_standard(version_or_name=0.0, spec=REV0)
register_segy_standard(version_or_name=1.0, spec=REV1)
register_segy_standard(version_or_name=2.0, spec=REV2)
register_segy_standard(version_or_name=2.1, spec=REV21)


__all__ = ["get_segy_standard", "SegyStandard"]
10 changes: 8 additions & 2 deletions src/segy/standards/fields/binary.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,16 @@ class Rev2(SegStandardEnum):
BYTE_ORDER = (97, "int32")
SEGY_REVISION_MAJOR = (301, "uint8")
SEGY_REVISION_MINOR = (302, "uint8")
MAX_EXTENDED_TRACE_HEADERS = (307, "int16")
SURVEY_TYPE = (309, "int16")
MAX_EXTENDED_TRACE_HEADERS = (307, "int32")
TIME_BASIS_CODE = (311, "int16")
NUM_TRACES = (313, "uint64")
BYTE_OFFSET_FIRST_TRACE = (321, "uint64")
NUM_DATA_TRAILER_STANZAS = (329, "int32")


class Rev21(SegStandardEnum):
"""Definition of SEG-Y Rev2 binary headers."""

MAX_EXTENDED_TRACE_HEADERS = (307, "int16")
SURVEY_TYPE = (309, "int16")
# fmt:on
30 changes: 25 additions & 5 deletions src/segy/standards/spec.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""SEG-Y Revision 0 Specification."""


from segy.schema.base import Endianness
from segy.schema.format import ScalarType
from segy.schema.format import TextHeaderEncoding
Expand All @@ -15,16 +14,25 @@
from segy.standards.fields import trace

BIN_HDR_FIELDS_REV0 = [field.model for field in binary.Rev0]
TRC_HDR_FIELDS_REV0 = [field.model for field in trace.Rev0]

BIN_HDR_FIELDS_REV1 = BIN_HDR_FIELDS_REV0 + [field.model for field in binary.Rev1]
BIN_HDR_FIELDS_REV2 = BIN_HDR_FIELDS_REV1 + [field.model for field in binary.Rev2]
TRC_HDR_FIELDS_REV1 = TRC_HDR_FIELDS_REV0 + [field.model for field in trace.Rev1]

# Rev2 removes segy_revision and splits it into major/minor revision fields
BIN_HDR_FIELDS_REV2 = BIN_HDR_FIELDS_REV1 + [field.model for field in binary.Rev2]
BIN_HDR_FIELDS_REV2.remove(binary.Rev1.SEGY_REVISION.model)
BIN_HDR_FIELDS_REV2 = sorted(BIN_HDR_FIELDS_REV2, key=lambda f: f.byte)

TRC_HDR_FIELDS_REV0 = [field.model for field in trace.Rev0]
TRC_HDR_FIELDS_REV1 = TRC_HDR_FIELDS_REV0 + [field.model for field in trace.Rev1]
TRC_HDR_FIELDS_REV2 = TRC_HDR_FIELDS_REV1 + [field.model for field in trace.Rev2]

# Rev2.1 splits maximum extended trace headers into two 16-bit.
# First reduces it from 32-bit to 16-bit
# Second gets new "survey type" field
BIN_HDR_FIELDS_REV21 = BIN_HDR_FIELDS_REV2 + [field.model for field in binary.Rev21]
BIN_HDR_FIELDS_REV21.remove(binary.Rev2.MAX_EXTENDED_TRACE_HEADERS.model)
BIN_HDR_FIELDS_REV21 = sorted(BIN_HDR_FIELDS_REV21, key=lambda f: f.byte)
TRC_HDR_FIELDS_REV21 = TRC_HDR_FIELDS_REV2 # no change


text_header_ebcdic = TextHeaderSpec(
rows=40,
Expand Down Expand Up @@ -68,3 +76,15 @@
header=HeaderSpec(fields=TRC_HDR_FIELDS_REV2, item_size=240),
),
)

REV21 = SegySpec(
segy_standard=SegyStandard.REV21,
endianness=Endianness.BIG,
text_header=text_header_ebcdic,
binary_header=HeaderSpec(fields=BIN_HDR_FIELDS_REV21, item_size=400, offset=3200),
ext_text_header=ext_text_header_ebcdic_3200,
trace=TraceSpec(
data=TraceDataSpec(format=ScalarType.IBM32),
header=HeaderSpec(fields=TRC_HDR_FIELDS_REV21, item_size=240),
),
)
3 changes: 2 additions & 1 deletion tests/test_segy_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ class TestSegyFile:
"""Test the usage of SegyFile class."""

@pytest.mark.parametrize(
"standard", [SegyStandard.REV0, SegyStandard.REV1, SegyStandard.REV2]
"standard",
[SegyStandard.REV0, SegyStandard.REV1, SegyStandard.REV2, SegyStandard.REV21],
)
@pytest.mark.parametrize("endianness", [Endianness.BIG, Endianness.LITTLE])
@pytest.mark.parametrize("sample_format", [ScalarType.IBM32, ScalarType.FLOAT32])
Expand Down

0 comments on commit 4a431ad

Please sign in to comment.