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