segyio 2.0.0a1__cp312-cp312-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- segyio/__init__.py +101 -0
- segyio/_segyio.cp310-win_amd64.pyd +0 -0
- segyio/_segyio.cp311-win_amd64.pyd +0 -0
- segyio/_segyio.cp312-win_amd64.pyd +0 -0
- segyio/binfield.py +153 -0
- segyio/create.py +314 -0
- segyio/depth.py +180 -0
- segyio/field.py +657 -0
- segyio/gather.py +444 -0
- segyio/line.py +498 -0
- segyio/open.py +306 -0
- segyio/segy.py +1182 -0
- segyio/segyio.cpp +3281 -0
- segyio/segysampleformat.py +19 -0
- segyio/su/__init__.py +2 -0
- segyio/su/file.py +120 -0
- segyio/su/words.py +286 -0
- segyio/tools.py +731 -0
- segyio/trace.py +1624 -0
- segyio/tracefield.py +204 -0
- segyio/tracesortingformat.py +6 -0
- segyio/utils.py +199 -0
- segyio-2.0.0a1.dist-info/METADATA +67 -0
- segyio-2.0.0a1.dist-info/RECORD +25 -0
- segyio-2.0.0a1.dist-info/WHEEL +5 -0
segyio/__init__.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""segyio
|
|
2
|
+
|
|
3
|
+
Welcome to segyio. For help, examples and reference, type ``help(function)`` in
|
|
4
|
+
your favourite python interpreter, or ``pydoc function`` in the unix console.
|
|
5
|
+
|
|
6
|
+
The segyio library attempts to be easy to use efficently for prototyping and
|
|
7
|
+
interaction with possibly large segy files. File reading and writing is
|
|
8
|
+
streaming, with large file support out of the box and without hassle. For a
|
|
9
|
+
quick start on reading files, type ``help(segyio.open)``.
|
|
10
|
+
|
|
11
|
+
An open segy file is interacted with in modes. For a reference with examples,
|
|
12
|
+
please type ``help(segyio.segy)``, look at the online documentation at
|
|
13
|
+
segyio.readthedocs.io, or run ``help()`` on the object returned by
|
|
14
|
+
``segyio.open``.. For documentation on individual modes, please
|
|
15
|
+
refer to the individual modes with ``help(f.[mode])``, where ``f`` is an open
|
|
16
|
+
file handle.
|
|
17
|
+
|
|
18
|
+
The available modes are:
|
|
19
|
+
* text, for textual headers including extended headers
|
|
20
|
+
* bin, for the binary header
|
|
21
|
+
* header, for the trace headers
|
|
22
|
+
* trace, for trace data
|
|
23
|
+
* iline, for inline biased operations
|
|
24
|
+
* xline, for crossline biased operations
|
|
25
|
+
* depth_slice, for depth biased operations
|
|
26
|
+
* gather, for gather/intersaction biased operations
|
|
27
|
+
|
|
28
|
+
The primary data type is the numpy.ndarray. All examples use ``np`` for the
|
|
29
|
+
numpy namespace. That means that any function that returns a trace, a set of
|
|
30
|
+
samples or even full lines, returns a numpy.ndarray. This enables quick and
|
|
31
|
+
easy mathematical operations on the data you care about.
|
|
32
|
+
|
|
33
|
+
Segyio is designed to blend into regular python code, so python concepts that
|
|
34
|
+
map to segy operations are written to behave similarly. That means that
|
|
35
|
+
sequences of data support list lookup, slicing (``f.trace[0:10:2]``), ``for x
|
|
36
|
+
in`` etc. Please refer to the individual modes' documentation for a more
|
|
37
|
+
extensive set of examples.
|
|
38
|
+
|
|
39
|
+
For all slicing operations that segyio provides the underlying buffer is
|
|
40
|
+
reused, so if you want to keep the data between iterations it is necessary to
|
|
41
|
+
manually copy the data, e.g. ``numpy.copy()``. Please refer to the examples.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class Enum(object):
|
|
46
|
+
def __init__(self, enum_value):
|
|
47
|
+
super(Enum, self).__init__()
|
|
48
|
+
self._value = int(enum_value)
|
|
49
|
+
|
|
50
|
+
def __int__(self):
|
|
51
|
+
return int(self._value)
|
|
52
|
+
|
|
53
|
+
def __str__(self):
|
|
54
|
+
for k, v in self.__class__.__dict__.items():
|
|
55
|
+
if isinstance(v, int) and self._value == v:
|
|
56
|
+
return k
|
|
57
|
+
return "Unknown Enum"
|
|
58
|
+
|
|
59
|
+
def __repr__(self):
|
|
60
|
+
return str(self)
|
|
61
|
+
|
|
62
|
+
def __hash__(self):
|
|
63
|
+
return hash(self._value)
|
|
64
|
+
|
|
65
|
+
def __eq__(self, other):
|
|
66
|
+
if other is None:
|
|
67
|
+
return False
|
|
68
|
+
try:
|
|
69
|
+
o = int(other)
|
|
70
|
+
except ValueError:
|
|
71
|
+
return super(Enum, self).__eq__(other)
|
|
72
|
+
else:
|
|
73
|
+
return self._value == o
|
|
74
|
+
|
|
75
|
+
def __ne__(self, other):
|
|
76
|
+
return not self == other
|
|
77
|
+
|
|
78
|
+
@classmethod
|
|
79
|
+
def enums(cls):
|
|
80
|
+
result = []
|
|
81
|
+
for k, v in cls.__dict__.items():
|
|
82
|
+
if isinstance(v, int) and not str.startswith(k, "_"):
|
|
83
|
+
result.append(cls(v))
|
|
84
|
+
|
|
85
|
+
return sorted(result, key=int)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
from .binfield import BinField
|
|
89
|
+
from .segysampleformat import SegySampleFormat
|
|
90
|
+
from .tracesortingformat import TraceSortingFormat
|
|
91
|
+
from .tracefield import TraceField
|
|
92
|
+
from . import su
|
|
93
|
+
from .open import open, open_with, open_from_memory
|
|
94
|
+
from .create import create, create_with
|
|
95
|
+
from .segy import SegyFile, spec
|
|
96
|
+
from .tools import dt, sample_indexes, create_text_header, native
|
|
97
|
+
from .tools import collect, cube
|
|
98
|
+
|
|
99
|
+
__copyright__ = 'Copyright 2016, Statoil ASA'
|
|
100
|
+
__license__ = 'GNU Lesser General Public License version 3'
|
|
101
|
+
__status__ = 'Production'
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
segyio/binfield.py
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
from . import Enum
|
|
3
|
+
|
|
4
|
+
class TracesWrapper:
|
|
5
|
+
def __get__(self, instance, owner):
|
|
6
|
+
warnings.warn(
|
|
7
|
+
"Traces is deprecated and will be removed in a future version."
|
|
8
|
+
"Please use EnsembleTraces instead.",
|
|
9
|
+
DeprecationWarning,
|
|
10
|
+
stacklevel=2
|
|
11
|
+
)
|
|
12
|
+
return 3213
|
|
13
|
+
|
|
14
|
+
class AuxTracesWrapper:
|
|
15
|
+
def __get__(self, instance, owner):
|
|
16
|
+
warnings.warn(
|
|
17
|
+
"AuxTraces is deprecated and will be removed in a future version."
|
|
18
|
+
"Please use AuxEnsembleTraces instead.",
|
|
19
|
+
DeprecationWarning,
|
|
20
|
+
stacklevel=2
|
|
21
|
+
)
|
|
22
|
+
return 3215
|
|
23
|
+
|
|
24
|
+
class ExtTracesWrapper:
|
|
25
|
+
def __get__(self, instance, owner):
|
|
26
|
+
warnings.warn(
|
|
27
|
+
"ExtTraces is deprecated and will be removed in a future version."
|
|
28
|
+
"Please use ExtEnsembleTraces instead.",
|
|
29
|
+
DeprecationWarning,
|
|
30
|
+
stacklevel=2
|
|
31
|
+
)
|
|
32
|
+
return 3261
|
|
33
|
+
|
|
34
|
+
class ExtAuxTracesWrapper:
|
|
35
|
+
def __get__(self, instance, owner):
|
|
36
|
+
warnings.warn(
|
|
37
|
+
"ExtAuxTraces is deprecated and will be removed in a future version."
|
|
38
|
+
"Please use ExtAuxEnsembleTraces instead.",
|
|
39
|
+
DeprecationWarning,
|
|
40
|
+
stacklevel=2
|
|
41
|
+
)
|
|
42
|
+
return 3265
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class BinField(Enum):
|
|
46
|
+
"""Trace header field enumerator
|
|
47
|
+
|
|
48
|
+
See also
|
|
49
|
+
-------
|
|
50
|
+
segyio.su : Seismic unix aliases for header fields
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
JobID = 3201
|
|
54
|
+
LineNumber = 3205
|
|
55
|
+
ReelNumber = 3209
|
|
56
|
+
Traces = TracesWrapper() # Deprecated, use EnsembleTraces
|
|
57
|
+
EnsembleTraces = 3213
|
|
58
|
+
AuxTraces = AuxTracesWrapper() # Deprecated, use AuxEnsembleTraces
|
|
59
|
+
AuxEnsembleTraces = 3215
|
|
60
|
+
Interval = 3217
|
|
61
|
+
IntervalOriginal = 3219
|
|
62
|
+
Samples = 3221
|
|
63
|
+
SamplesOriginal = 3223
|
|
64
|
+
Format = 3225
|
|
65
|
+
EnsembleFold = 3227
|
|
66
|
+
SortingCode = 3229
|
|
67
|
+
VerticalSum = 3231
|
|
68
|
+
SweepFrequencyStart = 3233
|
|
69
|
+
SweepFrequencyEnd = 3235
|
|
70
|
+
SweepLength = 3237
|
|
71
|
+
Sweep = 3239
|
|
72
|
+
SweepChannel = 3241
|
|
73
|
+
SweepTaperStart = 3243
|
|
74
|
+
SweepTaperEnd = 3245
|
|
75
|
+
Taper = 3247
|
|
76
|
+
CorrelatedTraces = 3249
|
|
77
|
+
BinaryGainRecovery = 3251
|
|
78
|
+
AmplitudeRecovery = 3253
|
|
79
|
+
MeasurementSystem = 3255
|
|
80
|
+
ImpulseSignalPolarity = 3257
|
|
81
|
+
VibratoryPolarity = 3259
|
|
82
|
+
ExtTraces = ExtTracesWrapper() # Deprecated, use ExtEnsembleTraces
|
|
83
|
+
ExtEnsembleTraces = 3261
|
|
84
|
+
ExtAuxTraces = ExtAuxTracesWrapper() # Deprecated, use ExtAuxEnsembleTraces
|
|
85
|
+
ExtAuxEnsembleTraces = 3265
|
|
86
|
+
ExtSamples = 3269
|
|
87
|
+
ExtInterval = 3273
|
|
88
|
+
ExtIntervalOriginal = 3281
|
|
89
|
+
ExtSamplesOriginal = 3289
|
|
90
|
+
ExtEnsembleFold = 3293
|
|
91
|
+
IntConstant = 3297
|
|
92
|
+
Unassigned1 = 3301
|
|
93
|
+
SEGYRevision = 3501
|
|
94
|
+
SEGYRevisionMinor = 3502
|
|
95
|
+
TraceFlag = 3503
|
|
96
|
+
ExtendedHeaders = 3505
|
|
97
|
+
MaxAdditionalTraceHeaders = 3507
|
|
98
|
+
SurveyType = 3509
|
|
99
|
+
TimeBasisCode = 3511
|
|
100
|
+
NrTracesInStream = 3513
|
|
101
|
+
FirstTraceOffset = 3521
|
|
102
|
+
NrTrailerRecords = 3529
|
|
103
|
+
Unassigned2 = 3533
|
|
104
|
+
|
|
105
|
+
keys = {
|
|
106
|
+
'JobID' : 3201,
|
|
107
|
+
'LineNumber' : 3205,
|
|
108
|
+
'ReelNumber' : 3209,
|
|
109
|
+
'EnsembleTraces' : 3213,
|
|
110
|
+
'AuxEnsembleTraces' : 3215,
|
|
111
|
+
'Interval' : 3217,
|
|
112
|
+
'IntervalOriginal' : 3219,
|
|
113
|
+
'Samples' : 3221,
|
|
114
|
+
'SamplesOriginal' : 3223,
|
|
115
|
+
'Format' : 3225,
|
|
116
|
+
'EnsembleFold' : 3227,
|
|
117
|
+
'SortingCode' : 3229,
|
|
118
|
+
'VerticalSum' : 3231,
|
|
119
|
+
'SweepFrequencyStart' : 3233,
|
|
120
|
+
'SweepFrequencyEnd' : 3235,
|
|
121
|
+
'SweepLength' : 3237,
|
|
122
|
+
'Sweep' : 3239,
|
|
123
|
+
'SweepChannel' : 3241,
|
|
124
|
+
'SweepTaperStart' : 3243,
|
|
125
|
+
'SweepTaperEnd' : 3245,
|
|
126
|
+
'Taper' : 3247,
|
|
127
|
+
'CorrelatedTraces' : 3249,
|
|
128
|
+
'BinaryGainRecovery' : 3251,
|
|
129
|
+
'AmplitudeRecovery' : 3253,
|
|
130
|
+
'MeasurementSystem' : 3255,
|
|
131
|
+
'ImpulseSignalPolarity' : 3257,
|
|
132
|
+
'VibratoryPolarity' : 3259,
|
|
133
|
+
'ExtEnsembleTraces' : 3261,
|
|
134
|
+
'ExtAuxEnsembleTraces' : 3265,
|
|
135
|
+
'ExtSamples' : 3269,
|
|
136
|
+
'ExtInterval' : 3273,
|
|
137
|
+
'ExtIntervalOriginal' : 3281,
|
|
138
|
+
'ExtSamplesOriginal' : 3289,
|
|
139
|
+
'ExtEnsembleFold' : 3293,
|
|
140
|
+
'IntConstant' : 3297,
|
|
141
|
+
'Unassigned1' : 3301,
|
|
142
|
+
'SEGYRevision' : 3501,
|
|
143
|
+
'SEGYRevisionMinor' : 3502,
|
|
144
|
+
'TraceFlag' : 3503,
|
|
145
|
+
'ExtendedHeaders' : 3505,
|
|
146
|
+
'MaxAdditionalTraceHeaders' : 3507,
|
|
147
|
+
'SurveyType' : 3509,
|
|
148
|
+
'TimeBasisCode' : 3511,
|
|
149
|
+
'NrTracesInStream' : 3513,
|
|
150
|
+
'FirstTraceOffset' : 3521,
|
|
151
|
+
'NrTrailerRecords' : 3529,
|
|
152
|
+
'Unassigned2' : 3533,
|
|
153
|
+
}
|
segyio/create.py
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import numpy
|
|
3
|
+
import segyio
|
|
4
|
+
|
|
5
|
+
from . import TraceSortingFormat
|
|
6
|
+
from .utils import (
|
|
7
|
+
FileDatasourceDescriptor,
|
|
8
|
+
StreamDatasourceDescriptor,
|
|
9
|
+
to_c_endianness,
|
|
10
|
+
to_c_encoding
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
def default_text_header(iline, xline, offset):
|
|
14
|
+
lines = {
|
|
15
|
+
1: "DATE %s" % datetime.date.today().isoformat(),
|
|
16
|
+
2: "AN INCREASE IN AMPLITUDE EQUALS AN INCREASE IN ACOUSTIC IMPEDANCE",
|
|
17
|
+
3: "Written by libsegyio (python)",
|
|
18
|
+
11: "TRACE HEADER POSITION:",
|
|
19
|
+
12: " INLINE BYTES %03d-%03d | OFFSET BYTES %03d-%03d" % (iline, iline + 4, int(offset), int(offset) + 4),
|
|
20
|
+
13: " CROSSLINE BYTES %03d-%03d |" % (xline, xline + 4),
|
|
21
|
+
15: "END EBCDIC HEADER",
|
|
22
|
+
}
|
|
23
|
+
rows = segyio.create_text_header(lines)
|
|
24
|
+
rows = bytearray(rows, 'ascii') # mutable array of bytes
|
|
25
|
+
rows[-1] = 128 # \x80 -- Unsure if this is really required...
|
|
26
|
+
return bytes(rows) # immutable array of bytes that is compatible with strings
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def structured(spec):
|
|
30
|
+
if not hasattr(spec, 'ilines' ): return False
|
|
31
|
+
if not hasattr(spec, 'xlines' ): return False
|
|
32
|
+
if not hasattr(spec, 'offsets'): return False
|
|
33
|
+
|
|
34
|
+
if spec.ilines is None: return False
|
|
35
|
+
if spec.xlines is None: return False
|
|
36
|
+
if spec.offsets is None: return False
|
|
37
|
+
|
|
38
|
+
if not list(spec.ilines): return False
|
|
39
|
+
if not list(spec.xlines): return False
|
|
40
|
+
if not list(spec.offsets): return False
|
|
41
|
+
|
|
42
|
+
return True
|
|
43
|
+
|
|
44
|
+
def create(filename, spec, layout_xml = None):
|
|
45
|
+
"""Create a new segy file.
|
|
46
|
+
|
|
47
|
+
Create a new segy file with the geometry and properties given by `spec`.
|
|
48
|
+
This enables creating SEGY files from your data. The created file supports
|
|
49
|
+
all segyio modes, but has an emphasis on writing. The spec must be
|
|
50
|
+
complete, otherwise an exception will be raised. A default, empty spec can
|
|
51
|
+
be created with ``segyio.spec()``.
|
|
52
|
+
|
|
53
|
+
Very little data is written to the file, so just calling create is not
|
|
54
|
+
sufficient to re-read the file with segyio. Rather, every trace header and
|
|
55
|
+
trace must be written to the file to be considered complete.
|
|
56
|
+
|
|
57
|
+
Create should be used together with python's ``with`` statement. This ensure
|
|
58
|
+
the data is written. Please refer to the examples.
|
|
59
|
+
|
|
60
|
+
The ``segyio.spec()`` function will default sorting, offsets and everything
|
|
61
|
+
in the mandatory group, except format and samples, and requires the caller
|
|
62
|
+
to fill in *all* the fields in either of the exclusive groups.
|
|
63
|
+
|
|
64
|
+
If any field is missing from the first exclusive group, and the tracecount
|
|
65
|
+
is set, the resulting file will be considered unstructured. If the
|
|
66
|
+
tracecount is set, and all fields of the first exclusive group are
|
|
67
|
+
specified, the file is considered structured and the tracecount is inferred
|
|
68
|
+
from the xlines/ilines/offsets. The offsets are defaulted to ``[1]`` by
|
|
69
|
+
``segyio.spec()``.
|
|
70
|
+
|
|
71
|
+
Parameters
|
|
72
|
+
----------
|
|
73
|
+
filename : str
|
|
74
|
+
Path to file to create
|
|
75
|
+
spec : segyio.spec
|
|
76
|
+
Structure of the segy file
|
|
77
|
+
layout_xml: bytearray
|
|
78
|
+
SEG-Y revision 2.1 D8 xml layout. Note that this layout is used only
|
|
79
|
+
during file creation and is not stored in the file.
|
|
80
|
+
|
|
81
|
+
Returns
|
|
82
|
+
-------
|
|
83
|
+
file : segyio.SegyFile
|
|
84
|
+
An open segyio file handle, similar to that returned by `segyio.open`
|
|
85
|
+
|
|
86
|
+
See also
|
|
87
|
+
--------
|
|
88
|
+
segyio.spec : template for the `spec` argument
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
Notes
|
|
92
|
+
-----
|
|
93
|
+
|
|
94
|
+
.. versionadded:: 1.1
|
|
95
|
+
|
|
96
|
+
.. versionchanged:: 1.4
|
|
97
|
+
Support for creating unstructured files
|
|
98
|
+
|
|
99
|
+
.. versionchanged:: 1.8
|
|
100
|
+
Support for creating lsb files
|
|
101
|
+
|
|
102
|
+
.. versionchanged:: 2.0
|
|
103
|
+
Support for SEG-Y revision 2.1
|
|
104
|
+
|
|
105
|
+
The ``spec`` is any object that has the following attributes
|
|
106
|
+
|
|
107
|
+
Mandatory::
|
|
108
|
+
|
|
109
|
+
iline : int or segyio.BinField
|
|
110
|
+
xline : int or segyio.BinField
|
|
111
|
+
samples : array of int
|
|
112
|
+
format : { 1, 5 }
|
|
113
|
+
1 = IBM float, 5 = IEEE float
|
|
114
|
+
|
|
115
|
+
Exclusive::
|
|
116
|
+
|
|
117
|
+
ilines : array_like of int
|
|
118
|
+
xlines : array_like of int
|
|
119
|
+
offsets : array_like of int
|
|
120
|
+
sorting : int or segyio.TraceSortingFormat
|
|
121
|
+
|
|
122
|
+
OR
|
|
123
|
+
|
|
124
|
+
tracecount : int
|
|
125
|
+
|
|
126
|
+
Optional::
|
|
127
|
+
|
|
128
|
+
ext_headers : int
|
|
129
|
+
endian : str { 'big', 'msb', 'little', 'lsb' }
|
|
130
|
+
defaults to 'big'
|
|
131
|
+
encoding : {'ebcdic', 'ascii'}
|
|
132
|
+
defaults to 'ebcdic'.
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
Examples
|
|
136
|
+
--------
|
|
137
|
+
|
|
138
|
+
Create a file:
|
|
139
|
+
|
|
140
|
+
>>> spec = segyio.spec()
|
|
141
|
+
>>> spec.ilines = [1, 2, 3, 4]
|
|
142
|
+
>>> spec.xlines = [11, 12, 13]
|
|
143
|
+
>>> spec.samples = list(range(50))
|
|
144
|
+
>>> spec.sorting = 2
|
|
145
|
+
>>> spec.format = 1
|
|
146
|
+
>>> with segyio.create(path, spec) as f:
|
|
147
|
+
... ## fill the file with data
|
|
148
|
+
... pass
|
|
149
|
+
...
|
|
150
|
+
|
|
151
|
+
Copy a file, but shorten all traces by 50 samples:
|
|
152
|
+
|
|
153
|
+
>>> with segyio.open(srcpath) as src:
|
|
154
|
+
... spec = segyio.spec()
|
|
155
|
+
... spec.sorting = src.sorting
|
|
156
|
+
... spec.format = src.format
|
|
157
|
+
... spec.samples = src.samples[:len(src.samples) - 50]
|
|
158
|
+
... spec.ilines = src.ilines
|
|
159
|
+
... spec.xline = src.xlines
|
|
160
|
+
... with segyio.create(dstpath, spec) as dst:
|
|
161
|
+
... dst.text[0] = src.text[0]
|
|
162
|
+
... dst.bin = src.bin
|
|
163
|
+
... # this is writing a sparse file, which might be slow on some
|
|
164
|
+
... # systems
|
|
165
|
+
... dst.header = src.header
|
|
166
|
+
... dst.trace = src.trace
|
|
167
|
+
|
|
168
|
+
Copy a file, but shift samples time by 50:
|
|
169
|
+
|
|
170
|
+
>>> with segyio.open(srcpath) as src:
|
|
171
|
+
... delrt = 50
|
|
172
|
+
... spec = segyio.spec()
|
|
173
|
+
... spec.samples = src.samples + delrt
|
|
174
|
+
... spec.ilines = src.ilines
|
|
175
|
+
... spec.xline = src.xlines
|
|
176
|
+
... with segyio.create(dstpath, spec) as dst:
|
|
177
|
+
... dst.text[0] = src.text[0]
|
|
178
|
+
... dst.bin = src.bin
|
|
179
|
+
... dst.header = src.header
|
|
180
|
+
... dst.header = { TraceField.DelayRecordingTime: delrt }
|
|
181
|
+
... dst.trace = src.trace
|
|
182
|
+
|
|
183
|
+
Copy a file, but shorten all traces by 50 samples (since v1.4):
|
|
184
|
+
|
|
185
|
+
>>> with segyio.open(srcpath) as src:
|
|
186
|
+
... spec = segyio.tools.metadata(src)
|
|
187
|
+
... spec.samples = spec.samples[:len(spec.samples) - 50]
|
|
188
|
+
... with segyio.create(dstpath, spec) as dst:
|
|
189
|
+
... dst.text[0] = src.text[0]
|
|
190
|
+
... dst.bin = src.bin
|
|
191
|
+
... dst.header = src.header
|
|
192
|
+
... dst.trace = src.trace
|
|
193
|
+
"""
|
|
194
|
+
return _create(FileDatasourceDescriptor(filename, "w+"), spec, layout_xml)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def create_with(stream, spec, minimize_requests_number=True, layout_xml = None):
|
|
198
|
+
"""
|
|
199
|
+
Creates a segy file on stream.
|
|
200
|
+
|
|
201
|
+
Function behaves the same as `segyio.create`, but outputs data to a
|
|
202
|
+
finite stream instead of a file. Stream's close() will be called when
|
|
203
|
+
SegyFile is closed.
|
|
204
|
+
|
|
205
|
+
Note that `segyio.create_with` can be very slow. `segyio.create` is
|
|
206
|
+
generally a preferred option when speed matters.
|
|
207
|
+
|
|
208
|
+
Parameters
|
|
209
|
+
----------
|
|
210
|
+
|
|
211
|
+
stream : file-like object
|
|
212
|
+
Data destination. It is up to the user to assure stream is opened in w+b mode.
|
|
213
|
+
spec : segyio.spec
|
|
214
|
+
Structure of the segy file
|
|
215
|
+
minimize_requests_number : bool
|
|
216
|
+
Configuration for some internal algorithms. True to minimize number of
|
|
217
|
+
requests to the stream at the cost of higher memory usage. False to
|
|
218
|
+
minimize memory usage at the cost of more requests to the stream.
|
|
219
|
+
layout_xml: bytearray
|
|
220
|
+
SEG-Y revision 2.1 D8 xml layout. Note that this layout is used only
|
|
221
|
+
during file creation and is not stored in the file.
|
|
222
|
+
"""
|
|
223
|
+
return _create(
|
|
224
|
+
StreamDatasourceDescriptor(
|
|
225
|
+
stream,
|
|
226
|
+
minimize_requests_number
|
|
227
|
+
),
|
|
228
|
+
spec,
|
|
229
|
+
layout_xml
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def _create(datasource_descriptor, spec, layout_xml):
|
|
234
|
+
if not structured(spec):
|
|
235
|
+
tracecount = spec.tracecount
|
|
236
|
+
else:
|
|
237
|
+
tracecount = len(spec.ilines) * len(spec.xlines) * len(spec.offsets)
|
|
238
|
+
|
|
239
|
+
ext_headers = spec.ext_headers if hasattr(spec, 'ext_headers') else 0
|
|
240
|
+
samples = numpy.asarray(spec.samples)
|
|
241
|
+
|
|
242
|
+
traceheader_count = spec.traceheader_count if hasattr(spec, 'traceheader_count') else 1
|
|
243
|
+
|
|
244
|
+
endian = spec.endian if hasattr(spec, 'endian') else 'big'
|
|
245
|
+
if endian is None:
|
|
246
|
+
endian = 'big'
|
|
247
|
+
|
|
248
|
+
encoding = spec.encoding if hasattr(spec, 'encoding') else 'ebcdic'
|
|
249
|
+
if encoding is None:
|
|
250
|
+
encoding = 'ebcdic'
|
|
251
|
+
|
|
252
|
+
fd = datasource_descriptor.make_segyfile_descriptor()
|
|
253
|
+
fd.segymake(
|
|
254
|
+
samples = len(samples),
|
|
255
|
+
tracecount = tracecount,
|
|
256
|
+
endianness=to_c_endianness(endian),
|
|
257
|
+
encoding=to_c_encoding(encoding),
|
|
258
|
+
format = int(spec.format),
|
|
259
|
+
ext_headers = int(ext_headers),
|
|
260
|
+
traceheader_count = traceheader_count,
|
|
261
|
+
layout_xml = layout_xml
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
# note: even if iline/xline are overridden, file is already created with
|
|
265
|
+
# standard iline/xline position, so those can mismatch
|
|
266
|
+
|
|
267
|
+
f = segyio.SegyFile(fd,
|
|
268
|
+
datasource_descriptor,
|
|
269
|
+
endian = endian,
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
f._samples = samples
|
|
273
|
+
|
|
274
|
+
if structured(spec):
|
|
275
|
+
sorting = spec.sorting if hasattr(spec, 'sorting') else None
|
|
276
|
+
if sorting is None:
|
|
277
|
+
sorting = TraceSortingFormat.INLINE_SORTING
|
|
278
|
+
f.interpret(spec.ilines, spec.xlines, spec.offsets, sorting)
|
|
279
|
+
|
|
280
|
+
f.text[0] = default_text_header(f._il, f._xl, segyio.TraceField.offset)
|
|
281
|
+
|
|
282
|
+
if len(samples) == 1:
|
|
283
|
+
interval = int(samples[0] * 1000)
|
|
284
|
+
else:
|
|
285
|
+
interval = int((samples[1] - samples[0]) * 1000)
|
|
286
|
+
|
|
287
|
+
binary_header = {}
|
|
288
|
+
binary_header.update(
|
|
289
|
+
ntrpr = 1,
|
|
290
|
+
hdt = interval,
|
|
291
|
+
dto = interval,
|
|
292
|
+
format = int(spec.format),
|
|
293
|
+
fold = 1,
|
|
294
|
+
tsort = 4,
|
|
295
|
+
exth = ext_headers,
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
if len(samples) > 2**16 - 1:
|
|
299
|
+
# when using the ext-samples field, also set rev2, even though it's a
|
|
300
|
+
# soft lie and files aren't really compliant
|
|
301
|
+
binary_header.update(
|
|
302
|
+
exthns = len(samples),
|
|
303
|
+
extnso = len(samples),
|
|
304
|
+
rev = 2
|
|
305
|
+
)
|
|
306
|
+
else:
|
|
307
|
+
binary_header.update(
|
|
308
|
+
hns = len(samples),
|
|
309
|
+
nso = len(samples),
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
f.bin.update(**binary_header)
|
|
313
|
+
|
|
314
|
+
return f
|