Skip to content

Commit d39b89c

Browse files
committedMar 9, 2018
An example of defining and using a custom Binary Reel Header definition.
1 parent 0554373 commit d39b89c

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed
 

‎examples/custom_header.py

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#!/usr/bin/env python3
2+
3+
"""Demonstrates how to customise a header format.
4+
5+
Standard SEG-Y requires that all header fields are two's complement (i.e. signed)
6+
integers with a width of two or four bytes. In Segpy these are represented by the
7+
types Int16 and Int32 from the field_types module. For many header fields,
8+
negative values would be nonsensical, so in the header specifications field values
9+
can be further constrained to be non-negative by the use of the NNInt16 and NNInt32
10+
types which require non-negative (NN) values. Note that these are not the same as
11+
*unsigned* two- or four-byte integers, which would have an expanded range.
12+
13+
In this module, we show how to define and use a non-standard UInt16 type which
14+
can accommodate the full unsigned 16-bit range from 0 to 65535.
15+
16+
Usage:
17+
18+
custom_header.py <in.segy>
19+
20+
"""
21+
22+
import os
23+
24+
import sys
25+
import traceback
26+
27+
from segpy.binary_reel_header import BinaryReelHeader
28+
from segpy.datatypes import SegYType
29+
from segpy.field_types import IntFieldMeta
30+
from segpy.header import field
31+
from segpy.reader import create_reader
32+
33+
34+
# Standard SEG-Y does not support 16-bit unsigned integer values in headers.
35+
# This section customises SEG-Y to support them.
36+
37+
class UInt16(int,
38+
metaclass=IntFieldMeta,
39+
min_value=0, # Use the full-range for unsigned
40+
max_value=65535, # 16-bit integers
41+
seg_y_type=SegYType.NNINT16): # The underlying NNINT16 type is actually read as an unsigned type.
42+
"""16-bit unsigned integer."""
43+
pass
44+
45+
46+
# Subclass the standard reel header to specialize one of its fields to have a type of UInt16.
47+
48+
class CustomBinaryReelHeader(BinaryReelHeader):
49+
50+
num_samples = field(
51+
UInt16, offset=3221, default=0, documentation=
52+
"""Number of samples per data trace. Mandatory for all types of data.
53+
Note: The sample interval and number of samples in the Binary File Header should be for the primary set of
54+
seismic data traces in the file."""
55+
)
56+
57+
58+
def report_segy(in_filename):
59+
with open(in_filename, 'rb') as in_file:
60+
61+
# Create a reader using the CustomBinaryReelHeader format.
62+
segy_reader = create_reader(
63+
in_file,
64+
binary_reel_header_format=CustomBinaryReelHeader)
65+
66+
print()
67+
print("Filename: ", segy_reader.filename)
68+
print("SEG Y revision: ", segy_reader.revision)
69+
print("Number of traces: ", segy_reader.num_traces())
70+
print("Data format: ",
71+
segy_reader.data_sample_format_description)
72+
print("Dimensionality: ", segy_reader.dimensionality)
73+
74+
try:
75+
print("Number of CDPs: ", segy_reader.num_cdps())
76+
except AttributeError:
77+
pass
78+
79+
try:
80+
print("Number of inlines: ", segy_reader.num_inlines())
81+
print("Number of crosslines: ", segy_reader.num_xlines())
82+
except AttributeError:
83+
pass
84+
85+
print("=== BEGIN TEXTUAL REEL HEADER ===")
86+
for line in segy_reader.textual_reel_header:
87+
print(line[3:])
88+
print("=== END TEXTUAL REEL HEADER ===")
89+
print()
90+
print("=== BEGIN EXTENDED TEXTUAL HEADER ===")
91+
print(segy_reader.extended_textual_header)
92+
print("=== END EXTENDED TEXTUAL_HEADER ===")
93+
94+
95+
def main(argv=None):
96+
if argv is None:
97+
argv = sys.argv[1:]
98+
99+
try:
100+
in_filename = argv[0]
101+
except IndexError:
102+
print(globals()['__doc__'], file=sys.stderr)
103+
return os.EX_USAGE
104+
105+
try:
106+
report_segy(in_filename)
107+
except (FileNotFoundError, IsADirectoryError) as e:
108+
print(e, file=sys.stderr)
109+
return os.EX_NOINPUT
110+
except PermissionError as e:
111+
print(e, file=sys.stderr)
112+
return os.EX_NOPERM
113+
except Exception as e:
114+
traceback.print_exception(type(e), e, e.__traceback__, file=sys.stderr)
115+
return os.EX_SOFTWARE
116+
return os.EX_OK
117+
118+
119+
if __name__ == '__main__':
120+
sys.exit(main())

0 commit comments

Comments
 (0)