segyio 1.9.13__cp313-cp313-macosx_10_13_x86_64.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.
Potentially problematic release.
This version of segyio might be problematic. Click here for more details.
- segyio/__init__.py +99 -0
- segyio/_segyio.cpython-313-darwin.so +0 -0
- segyio/binfield.py +89 -0
- segyio/create.py +257 -0
- segyio/depth.py +180 -0
- segyio/field.py +546 -0
- segyio/gather.py +444 -0
- segyio/line.py +498 -0
- segyio/open.py +192 -0
- segyio/segy.py +1010 -0
- segyio/segysampleformat.py +19 -0
- segyio/su/__init__.py +2 -0
- segyio/su/file.py +118 -0
- segyio/su/words.py +284 -0
- segyio/tools.py +731 -0
- segyio/trace.py +967 -0
- segyio/tracefield.py +195 -0
- segyio/tracesortingformat.py +6 -0
- segyio/utils.py +28 -0
- segyio-1.9.13.dist-info/METADATA +79 -0
- segyio-1.9.13.dist-info/RECORD +23 -0
- segyio-1.9.13.dist-info/WHEEL +5 -0
- segyio-1.9.13.dist-info/top_level.txt +1 -0
segyio/tools.py
ADDED
|
@@ -0,0 +1,731 @@
|
|
|
1
|
+
import segyio
|
|
2
|
+
from . import TraceSortingFormat
|
|
3
|
+
from . import SegySampleFormat
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import textwrap
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def dt(f, fallback_dt=4000.0):
|
|
10
|
+
"""Delta-time
|
|
11
|
+
|
|
12
|
+
Infer a ``dt``, the sample rate, from the file. If none is found, use the
|
|
13
|
+
fallback.
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
|
|
18
|
+
f : segyio.SegyFile
|
|
19
|
+
fallback_dt : float
|
|
20
|
+
delta-time to fall back to, in microseconds
|
|
21
|
+
|
|
22
|
+
Returns
|
|
23
|
+
-------
|
|
24
|
+
dt : float
|
|
25
|
+
|
|
26
|
+
Notes
|
|
27
|
+
-----
|
|
28
|
+
|
|
29
|
+
.. versionadded:: 1.1
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
return f.xfd.getdt(fallback_dt)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def sample_indexes(segyfile, t0=0.0, dt_override=None):
|
|
36
|
+
"""
|
|
37
|
+
Creates a list of values representing the samples in a trace at depth or time.
|
|
38
|
+
The list starts at *t0* and is incremented with am*dt* for the number of samples.
|
|
39
|
+
If a *dt_override* is not provided it will try to find a *dt* in the file.
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
Parameters
|
|
43
|
+
----------
|
|
44
|
+
segyfile : segyio.SegyFile
|
|
45
|
+
t0 : float
|
|
46
|
+
initial sample, or delay-recording-time
|
|
47
|
+
dt_override : float or None
|
|
48
|
+
|
|
49
|
+
Returns
|
|
50
|
+
-------
|
|
51
|
+
samples : array_like of float
|
|
52
|
+
|
|
53
|
+
Notes
|
|
54
|
+
-----
|
|
55
|
+
|
|
56
|
+
.. versionadded:: 1.1
|
|
57
|
+
|
|
58
|
+
"""
|
|
59
|
+
if dt_override is None:
|
|
60
|
+
dt_override = dt(segyfile)
|
|
61
|
+
|
|
62
|
+
return [t0 + t * dt_override for t in range(len(segyfile.samples))]
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def create_text_header(lines):
|
|
66
|
+
"""Format textual header
|
|
67
|
+
|
|
68
|
+
Create a "correct" SEG-Y textual header. Every line will be prefixed with
|
|
69
|
+
C## and there are 40 lines. The input must be a dictionary with the line
|
|
70
|
+
number[1-40] as a key. The value for each key should be up to 76 character
|
|
71
|
+
long string.
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
|
|
76
|
+
lines : dict
|
|
77
|
+
`lines` dictionary with fields:
|
|
78
|
+
|
|
79
|
+
- ``no`` : line number (`int`)
|
|
80
|
+
- ``line`` : line (`str`)
|
|
81
|
+
|
|
82
|
+
Returns
|
|
83
|
+
-------
|
|
84
|
+
|
|
85
|
+
text : str
|
|
86
|
+
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
rows = []
|
|
90
|
+
for line_no in range(1, 41):
|
|
91
|
+
line = ""
|
|
92
|
+
if line_no in lines:
|
|
93
|
+
line = lines[line_no]
|
|
94
|
+
row = "C{0:>2} {1:76}".format(line_no, line)
|
|
95
|
+
rows.append(row)
|
|
96
|
+
|
|
97
|
+
rows = ''.join(rows)
|
|
98
|
+
return rows
|
|
99
|
+
|
|
100
|
+
def wrap(s, width=80):
|
|
101
|
+
"""
|
|
102
|
+
Formats the text input with newlines given the user specified width for
|
|
103
|
+
each line. `wrap` will attempt to decode the input as ascii, ignoring any
|
|
104
|
+
errors, which occurs with many headers in ebcdic. To consider encoding
|
|
105
|
+
errors, decode the textual header before passing it to wrap.
|
|
106
|
+
|
|
107
|
+
Parameters
|
|
108
|
+
----------
|
|
109
|
+
s : text or bytearray or str
|
|
110
|
+
width : int
|
|
111
|
+
|
|
112
|
+
Returns
|
|
113
|
+
-------
|
|
114
|
+
text : str
|
|
115
|
+
|
|
116
|
+
Notes
|
|
117
|
+
-----
|
|
118
|
+
.. versionadded:: 1.1
|
|
119
|
+
|
|
120
|
+
"""
|
|
121
|
+
try:
|
|
122
|
+
s = s.decode(errors = 'ignore')
|
|
123
|
+
except AttributeError:
|
|
124
|
+
# Already str-like enough, e.g. wrap(f.text[0].decode()), so just try
|
|
125
|
+
# to wrap-join
|
|
126
|
+
pass
|
|
127
|
+
|
|
128
|
+
return '\n'.join(textwrap.wrap(s, width=width))
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def native(data,
|
|
132
|
+
format = segyio.SegySampleFormat.IBM_FLOAT_4_BYTE,
|
|
133
|
+
copy = True):
|
|
134
|
+
"""Convert numpy array to native float
|
|
135
|
+
|
|
136
|
+
Converts a numpy array from raw segy trace data to native floats. Works for numpy ndarrays.
|
|
137
|
+
|
|
138
|
+
Parameters
|
|
139
|
+
----------
|
|
140
|
+
|
|
141
|
+
data : numpy.ndarray
|
|
142
|
+
format : int or segyio.SegySampleFormat
|
|
143
|
+
copy : bool
|
|
144
|
+
If True, convert on a copy, and leave the input array unmodified
|
|
145
|
+
|
|
146
|
+
Returns
|
|
147
|
+
-------
|
|
148
|
+
|
|
149
|
+
data : numpy.ndarray
|
|
150
|
+
|
|
151
|
+
Notes
|
|
152
|
+
-----
|
|
153
|
+
|
|
154
|
+
.. versionadded:: 1.1
|
|
155
|
+
|
|
156
|
+
Examples
|
|
157
|
+
--------
|
|
158
|
+
|
|
159
|
+
Convert mmap'd trace to native float:
|
|
160
|
+
|
|
161
|
+
>>> d = np.memmap('file.sgy', offset = 3600, dtype = np.uintc)
|
|
162
|
+
>>> samples = 1500
|
|
163
|
+
>>> trace = segyio.tools.native(d[240:240+samples])
|
|
164
|
+
|
|
165
|
+
"""
|
|
166
|
+
|
|
167
|
+
data = data.view( dtype = np.single )
|
|
168
|
+
if copy:
|
|
169
|
+
data = np.copy( data )
|
|
170
|
+
|
|
171
|
+
format = int(segyio.SegySampleFormat(format))
|
|
172
|
+
return segyio._segyio.native(data, format)
|
|
173
|
+
|
|
174
|
+
def collect(itr):
|
|
175
|
+
"""Collect traces or lines into one ndarray
|
|
176
|
+
|
|
177
|
+
Eagerly copy a series of traces, lines or depths into one numpy ndarray. If
|
|
178
|
+
collecting traces or fast-direction over a post-stacked file, reshaping the
|
|
179
|
+
resulting array is equivalent to calling ``segyio.tools.cube``.
|
|
180
|
+
|
|
181
|
+
Parameters
|
|
182
|
+
----------
|
|
183
|
+
|
|
184
|
+
itr : iterable of numpy.ndarray
|
|
185
|
+
|
|
186
|
+
Returns
|
|
187
|
+
-------
|
|
188
|
+
|
|
189
|
+
data : numpy.ndarray
|
|
190
|
+
|
|
191
|
+
Notes
|
|
192
|
+
-----
|
|
193
|
+
|
|
194
|
+
.. versionadded:: 1.1
|
|
195
|
+
|
|
196
|
+
Examples
|
|
197
|
+
--------
|
|
198
|
+
|
|
199
|
+
collect-cube identity:
|
|
200
|
+
|
|
201
|
+
>>> with segyio.open('post-stack.sgy') as f:
|
|
202
|
+
>>> x = segyio.tools.collect(f.trace[:])
|
|
203
|
+
>>> x = x.reshape((len(f.ilines), len(f.xlines), f.samples))
|
|
204
|
+
>>> numpy.all(x == segyio.tools.cube(f))
|
|
205
|
+
|
|
206
|
+
"""
|
|
207
|
+
return np.stack([np.copy(x) for x in itr])
|
|
208
|
+
|
|
209
|
+
def cube(f):
|
|
210
|
+
"""Read a full cube from a file
|
|
211
|
+
|
|
212
|
+
Takes an open segy file (created with segyio.open) or a file name.
|
|
213
|
+
|
|
214
|
+
If the file is a prestack file, the cube returned has the dimensions
|
|
215
|
+
``(fast, slow, offset, sample)``. If it is post-stack (only the one
|
|
216
|
+
offset), the dimensions are normalised to ``(fast, slow, sample)``
|
|
217
|
+
|
|
218
|
+
Parameters
|
|
219
|
+
----------
|
|
220
|
+
|
|
221
|
+
f : str or segyio.SegyFile
|
|
222
|
+
|
|
223
|
+
Returns
|
|
224
|
+
-------
|
|
225
|
+
|
|
226
|
+
cube : numpy.ndarray
|
|
227
|
+
|
|
228
|
+
Notes
|
|
229
|
+
-----
|
|
230
|
+
|
|
231
|
+
.. versionadded:: 1.1
|
|
232
|
+
|
|
233
|
+
"""
|
|
234
|
+
|
|
235
|
+
if not isinstance(f, segyio.SegyFile):
|
|
236
|
+
with segyio.open(f) as fl:
|
|
237
|
+
return cube(fl)
|
|
238
|
+
|
|
239
|
+
ilsort = f.sorting == segyio.TraceSortingFormat.INLINE_SORTING
|
|
240
|
+
fast = f.ilines if ilsort else f.xlines
|
|
241
|
+
slow = f.xlines if ilsort else f.ilines
|
|
242
|
+
fast, slow, offs = len(fast), len(slow), len(f.offsets)
|
|
243
|
+
smps = len(f.samples)
|
|
244
|
+
dims = (fast, slow, smps) if offs == 1 else (fast, slow, offs, smps)
|
|
245
|
+
return f.trace.raw[:].reshape(dims)
|
|
246
|
+
|
|
247
|
+
def rotation(f, line = 'fast'):
|
|
248
|
+
""" Find rotation of the survey
|
|
249
|
+
|
|
250
|
+
Find the clock-wise rotation and origin of `line` as ``(rot, cdpx, cdpy)``
|
|
251
|
+
|
|
252
|
+
The clock-wise rotation is defined as the angle in radians between line
|
|
253
|
+
given by the first and last trace of the first line and the axis that gives
|
|
254
|
+
increasing CDP-Y, in the direction that gives increasing CDP-X.
|
|
255
|
+
|
|
256
|
+
By default, the first line is the 'fast' direction, which is inlines if the
|
|
257
|
+
file is inline sorted, and crossline if it's crossline sorted.
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
Parameters
|
|
261
|
+
----------
|
|
262
|
+
|
|
263
|
+
f : SegyFile
|
|
264
|
+
line : { 'fast', 'slow', 'iline', 'xline' }
|
|
265
|
+
|
|
266
|
+
Returns
|
|
267
|
+
-------
|
|
268
|
+
|
|
269
|
+
rotation : float
|
|
270
|
+
cdpx : int
|
|
271
|
+
cdpy : int
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
Notes
|
|
275
|
+
-----
|
|
276
|
+
|
|
277
|
+
.. versionadded:: 1.2
|
|
278
|
+
|
|
279
|
+
"""
|
|
280
|
+
|
|
281
|
+
if f.unstructured:
|
|
282
|
+
raise ValueError("Rotation requires a structured file")
|
|
283
|
+
|
|
284
|
+
lines = { 'fast': f.fast,
|
|
285
|
+
'slow': f.slow,
|
|
286
|
+
'iline': f.iline,
|
|
287
|
+
'xline': f.xline,
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if line not in lines:
|
|
291
|
+
error = "Unknown line {}".format(line)
|
|
292
|
+
solution = "Must be any of: {}".format(' '.join(lines.keys()))
|
|
293
|
+
raise ValueError('{} {}'.format(error, solution))
|
|
294
|
+
|
|
295
|
+
l = lines[line]
|
|
296
|
+
origin = f.header[0][segyio.su.cdpx, segyio.su.cdpy]
|
|
297
|
+
cdpx, cdpy = origin[segyio.su.cdpx], origin[segyio.su.cdpy]
|
|
298
|
+
|
|
299
|
+
rot = f.xfd.rotation( len(l),
|
|
300
|
+
l.stride,
|
|
301
|
+
len(f.offsets),
|
|
302
|
+
np.fromiter(l.keys(), dtype = np.intc) )
|
|
303
|
+
return rot, cdpx, cdpy
|
|
304
|
+
|
|
305
|
+
def metadata(f):
|
|
306
|
+
"""Get survey structural properties and metadata
|
|
307
|
+
|
|
308
|
+
Create a description object that, when passed to ``segyio.create()``, would
|
|
309
|
+
create a new file with the same structure, dimensions, and metadata as
|
|
310
|
+
``f``.
|
|
311
|
+
|
|
312
|
+
Takes an open segy file (created with segyio.open) or a file name.
|
|
313
|
+
|
|
314
|
+
Parameters
|
|
315
|
+
----------
|
|
316
|
+
|
|
317
|
+
f : str or segyio.SegyFile
|
|
318
|
+
|
|
319
|
+
Returns
|
|
320
|
+
-------
|
|
321
|
+
spec : segyio.spec
|
|
322
|
+
|
|
323
|
+
Notes
|
|
324
|
+
-----
|
|
325
|
+
|
|
326
|
+
.. versionadded:: 1.4
|
|
327
|
+
|
|
328
|
+
"""
|
|
329
|
+
|
|
330
|
+
if not isinstance(f, segyio.SegyFile):
|
|
331
|
+
with segyio.open(f) as fl:
|
|
332
|
+
return metadata(fl)
|
|
333
|
+
|
|
334
|
+
spec = segyio.spec()
|
|
335
|
+
|
|
336
|
+
spec.iline = f._il
|
|
337
|
+
spec.xline = f._xl
|
|
338
|
+
spec.samples = f.samples
|
|
339
|
+
spec.format = f.format
|
|
340
|
+
|
|
341
|
+
spec.ilines = f.ilines
|
|
342
|
+
spec.xlines = f.xlines
|
|
343
|
+
spec.offsets = f.offsets
|
|
344
|
+
spec.sorting = f.sorting
|
|
345
|
+
|
|
346
|
+
spec.tracecount = f.tracecount
|
|
347
|
+
|
|
348
|
+
spec.ext_headers = f.ext_headers
|
|
349
|
+
spec.endian = f.endian
|
|
350
|
+
|
|
351
|
+
return spec
|
|
352
|
+
|
|
353
|
+
def resample(f, rate = None, delay = None, micro = False,
|
|
354
|
+
trace = True,
|
|
355
|
+
binary = True):
|
|
356
|
+
"""Resample a file
|
|
357
|
+
|
|
358
|
+
Resample all data traces, and update the file handle to reflect the new
|
|
359
|
+
sample rate. No actual samples (data traces) are modified, only the header
|
|
360
|
+
fields and interpretation.
|
|
361
|
+
|
|
362
|
+
By default, the rate and the delay are in millseconds - if you need higher
|
|
363
|
+
resolution, passing micro=True interprets rate as microseconds (as it is
|
|
364
|
+
represented in the file). Delay is always milliseconds.
|
|
365
|
+
|
|
366
|
+
By default, both the global binary header and the trace headers are updated
|
|
367
|
+
to reflect this. If preserving either the trace header interval field or
|
|
368
|
+
the binary header interval field is important, pass trace=False and
|
|
369
|
+
binary=False respectively, to not have that field updated. This only apply
|
|
370
|
+
to sample rates - the recording delay is only found in trace headers and
|
|
371
|
+
will be written unconditionally, if delay is not None.
|
|
372
|
+
|
|
373
|
+
.. warning::
|
|
374
|
+
This function requires an open file handle and is **DESTRUCTIVE**. It
|
|
375
|
+
will modify the file, and if an exception is raised then partial writes
|
|
376
|
+
might have happened and the file might be corrupted.
|
|
377
|
+
|
|
378
|
+
This function assumes all traces have uniform delays and frequencies.
|
|
379
|
+
|
|
380
|
+
Parameters
|
|
381
|
+
----------
|
|
382
|
+
|
|
383
|
+
f : SegyFile
|
|
384
|
+
rate : int
|
|
385
|
+
delay : int
|
|
386
|
+
micro : bool
|
|
387
|
+
if True, interpret rate as microseconds
|
|
388
|
+
trace : bool
|
|
389
|
+
Update the trace header if True
|
|
390
|
+
binary : bool
|
|
391
|
+
Update the binary header if True
|
|
392
|
+
|
|
393
|
+
Notes
|
|
394
|
+
-----
|
|
395
|
+
|
|
396
|
+
.. versionadded:: 1.4
|
|
397
|
+
|
|
398
|
+
"""
|
|
399
|
+
|
|
400
|
+
if rate is not None:
|
|
401
|
+
if not micro: rate *= 1000
|
|
402
|
+
|
|
403
|
+
if binary: f.bin[segyio.su.hdt] = rate
|
|
404
|
+
if trace: f.header = { segyio.su.dt: rate}
|
|
405
|
+
|
|
406
|
+
if delay is not None:
|
|
407
|
+
f.header = { segyio.su.delrt: delay }
|
|
408
|
+
|
|
409
|
+
t0 = delay if delay is not None else f.samples[0]
|
|
410
|
+
rate = rate / 1000 if rate is not None else f.samples[1] - f.samples[0]
|
|
411
|
+
|
|
412
|
+
f._samples = (np.arange(len(f.samples)) * rate) + t0
|
|
413
|
+
|
|
414
|
+
return f
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def from_array(filename, data, iline=189,
|
|
418
|
+
xline=193,
|
|
419
|
+
format=SegySampleFormat.IBM_FLOAT_4_BYTE,
|
|
420
|
+
dt=4000,
|
|
421
|
+
delrt=0):
|
|
422
|
+
""" Create a new SEGY file from an n-dimentional array. Create a structured
|
|
423
|
+
SEGY file with defaulted headers from a 2-, 3- or 4-dimensional array.
|
|
424
|
+
ilines, xlines, offsets and samples are inferred from the size of the
|
|
425
|
+
array. Please refer to the documentation for functions from_array2D,
|
|
426
|
+
from_array3D and from_array4D to see how the arrays are interpreted.
|
|
427
|
+
|
|
428
|
+
Structure-defining fields in the binary header and in the traceheaders are
|
|
429
|
+
set accordingly. Such fields include, but are not limited to iline, xline
|
|
430
|
+
and offset. The file also contains a defaulted textual header.
|
|
431
|
+
|
|
432
|
+
Parameters
|
|
433
|
+
----------
|
|
434
|
+
filename : string-like
|
|
435
|
+
Path to new file
|
|
436
|
+
data : 2-,3- or 4-dimensional array-like
|
|
437
|
+
iline : int or segyio.TraceField
|
|
438
|
+
Inline number field in the trace headers. Defaults to 189 as per the
|
|
439
|
+
SEG-Y rev1 specification
|
|
440
|
+
xline : int or segyio.TraceField
|
|
441
|
+
Crossline number field in the trace headers. Defaults to 193 as per the
|
|
442
|
+
SEG-Y rev1 specification
|
|
443
|
+
format : int or segyio.SegySampleFormat
|
|
444
|
+
Sample format field in the trace header. Defaults to IBM float 4 byte
|
|
445
|
+
dt : int-like
|
|
446
|
+
sample interval
|
|
447
|
+
delrt : int-like
|
|
448
|
+
|
|
449
|
+
Notes
|
|
450
|
+
-----
|
|
451
|
+
.. versionadded:: 1.8
|
|
452
|
+
|
|
453
|
+
Examples
|
|
454
|
+
--------
|
|
455
|
+
Create a file from a 3D array, open it and read an iline:
|
|
456
|
+
|
|
457
|
+
>>> segyio.tools.from_array(path, array3d)
|
|
458
|
+
>>> segyio.open(path, mode) as f:
|
|
459
|
+
... iline = f.iline[0]
|
|
460
|
+
...
|
|
461
|
+
"""
|
|
462
|
+
|
|
463
|
+
dt = int(dt)
|
|
464
|
+
delrt = int(delrt)
|
|
465
|
+
|
|
466
|
+
data = np.asarray(data)
|
|
467
|
+
dimensions = len(data.shape)
|
|
468
|
+
|
|
469
|
+
if dimensions not in range(2, 5):
|
|
470
|
+
problem = "Expected 2, 3, or 4 dimensions, {} was given".format(dimensions)
|
|
471
|
+
raise ValueError(problem)
|
|
472
|
+
|
|
473
|
+
spec = segyio.spec()
|
|
474
|
+
spec.iline = iline
|
|
475
|
+
spec.xline = xline
|
|
476
|
+
spec.format = format
|
|
477
|
+
spec.sorting = TraceSortingFormat.INLINE_SORTING
|
|
478
|
+
|
|
479
|
+
if dimensions == 2:
|
|
480
|
+
spec.ilines = [1]
|
|
481
|
+
spec.xlines = list(range(1, np.size(data,0) + 1))
|
|
482
|
+
spec.samples = list(range(np.size(data,1)))
|
|
483
|
+
spec.tracecount = np.size(data, 1)
|
|
484
|
+
|
|
485
|
+
if dimensions == 3:
|
|
486
|
+
spec.ilines = list(range(1, np.size(data, 0) + 1))
|
|
487
|
+
spec.xlines = list(range(1, np.size(data, 1) + 1))
|
|
488
|
+
spec.samples = list(range(np.size(data, 2)))
|
|
489
|
+
|
|
490
|
+
if dimensions == 4:
|
|
491
|
+
spec.ilines = list(range(1, np.size(data, 0) + 1))
|
|
492
|
+
spec.xlines = list(range(1, np.size(data, 1) + 1))
|
|
493
|
+
spec.offsets = list(range(1, np.size(data, 2)+ 1))
|
|
494
|
+
spec.samples = list(range(np.size(data,3)))
|
|
495
|
+
|
|
496
|
+
samplecount = len(spec.samples)
|
|
497
|
+
|
|
498
|
+
with segyio.create(filename, spec) as f:
|
|
499
|
+
tr = 0
|
|
500
|
+
for ilno, il in enumerate(spec.ilines):
|
|
501
|
+
for xlno, xl in enumerate(spec.xlines):
|
|
502
|
+
for offno, off in enumerate(spec.offsets):
|
|
503
|
+
f.header[tr] = {
|
|
504
|
+
segyio.su.tracf : tr,
|
|
505
|
+
segyio.su.cdpt : tr,
|
|
506
|
+
segyio.su.offset : off,
|
|
507
|
+
segyio.su.ns : samplecount,
|
|
508
|
+
segyio.su.dt : dt,
|
|
509
|
+
segyio.su.delrt : delrt,
|
|
510
|
+
segyio.su.iline : il,
|
|
511
|
+
segyio.su.xline : xl
|
|
512
|
+
}
|
|
513
|
+
if dimensions == 2: f.trace[tr] = data[tr, :]
|
|
514
|
+
if dimensions == 3: f.trace[tr] = data[ilno, xlno, :]
|
|
515
|
+
if dimensions == 4: f.trace[tr] = data[ilno, xlno, offno, :]
|
|
516
|
+
tr += 1
|
|
517
|
+
|
|
518
|
+
f.bin.update(
|
|
519
|
+
tsort=TraceSortingFormat.INLINE_SORTING,
|
|
520
|
+
hdt=dt,
|
|
521
|
+
dto=dt
|
|
522
|
+
)
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
def from_array2D(filename, data, iline=189,
|
|
526
|
+
xline=193,
|
|
527
|
+
format=SegySampleFormat.IBM_FLOAT_4_BYTE,
|
|
528
|
+
dt=4000,
|
|
529
|
+
delrt=0):
|
|
530
|
+
""" Create a new SEGY file from a 2D array
|
|
531
|
+
Create an structured SEGY file with defaulted headers from a 2-dimensional
|
|
532
|
+
array. The file is inline-sorted and structured as a slice, i.e. it has one
|
|
533
|
+
iline and the xlinecount equals the tracecount. The tracecount and
|
|
534
|
+
samplecount are inferred from the size of the array. Structure-defining
|
|
535
|
+
fields in the binary header and in the traceheaders are set accordingly.
|
|
536
|
+
Such fields include, but are not limited to iline, xline and offset. The
|
|
537
|
+
file also contains a defaulted textual header.
|
|
538
|
+
|
|
539
|
+
The 2 dimensional array is interpreted as::
|
|
540
|
+
|
|
541
|
+
samples
|
|
542
|
+
--------------------
|
|
543
|
+
trace 0 | s0 | s1 | ... | sn |
|
|
544
|
+
--------------------
|
|
545
|
+
trace 1 | s0 | s1 | ... | sn |
|
|
546
|
+
--------------------
|
|
547
|
+
.
|
|
548
|
+
.
|
|
549
|
+
--------------------
|
|
550
|
+
trace n | s0 | s1 | ... | sn |
|
|
551
|
+
--------------------
|
|
552
|
+
|
|
553
|
+
traces = [0, len(axis(0)]
|
|
554
|
+
samples = [0, len(axis(1)]
|
|
555
|
+
|
|
556
|
+
Parameters
|
|
557
|
+
----------
|
|
558
|
+
filename : string-like
|
|
559
|
+
Path to new file
|
|
560
|
+
data : 2-dimensional array-like
|
|
561
|
+
iline : int or segyio.TraceField
|
|
562
|
+
Inline number field in the trace headers. Defaults to 189 as per the
|
|
563
|
+
SEG-Y rev1 specification
|
|
564
|
+
xline : int or segyio.TraceField
|
|
565
|
+
Crossline number field in the trace headers. Defaults to 193 as per the
|
|
566
|
+
SEG-Y rev1 specification
|
|
567
|
+
format : int or segyio.SegySampleFormat
|
|
568
|
+
Sample format field in the trace header. Defaults to IBM float 4 byte
|
|
569
|
+
dt : int-like
|
|
570
|
+
sample interval
|
|
571
|
+
delrt : int-like
|
|
572
|
+
|
|
573
|
+
Notes
|
|
574
|
+
-----
|
|
575
|
+
.. versionadded:: 1.8
|
|
576
|
+
|
|
577
|
+
Examples
|
|
578
|
+
--------
|
|
579
|
+
Create a file from a 2D array, open it and read a trace:
|
|
580
|
+
|
|
581
|
+
>>> segyio.tools.from_array2D(path, array2d)
|
|
582
|
+
>>> segyio.open(path, mode, strict=False) as f:
|
|
583
|
+
... tr = f.trace[0]
|
|
584
|
+
"""
|
|
585
|
+
|
|
586
|
+
data = np.asarray(data)
|
|
587
|
+
dimensions = len(data.shape)
|
|
588
|
+
|
|
589
|
+
if dimensions != 2:
|
|
590
|
+
problem = "Expected 2 dimensions, {} was given".format(dimensions)
|
|
591
|
+
raise ValueError(problem)
|
|
592
|
+
|
|
593
|
+
from_array(filename, data, iline=iline, xline=xline, format=format,
|
|
594
|
+
dt=dt,
|
|
595
|
+
delrt=delrt)
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
def from_array3D(filename, data, iline=189,
|
|
599
|
+
xline=193,
|
|
600
|
+
format=SegySampleFormat.IBM_FLOAT_4_BYTE,
|
|
601
|
+
dt=4000,
|
|
602
|
+
delrt=0):
|
|
603
|
+
""" Create a new SEGY file from a 3D array
|
|
604
|
+
Create an structured SEGY file with defaulted headers from a 3-dimensional
|
|
605
|
+
array. The file is inline-sorted. ilines, xlines and samples are inferred
|
|
606
|
+
from the array. Structure-defining fields in the binary header and
|
|
607
|
+
in the traceheaders are set accordingly. Such fields include, but are not
|
|
608
|
+
limited to iline, xline and offset. The file also contains a defaulted
|
|
609
|
+
textual header.
|
|
610
|
+
|
|
611
|
+
The 3-dimensional array is interpreted as::
|
|
612
|
+
|
|
613
|
+
xl0 xl1 xl2
|
|
614
|
+
-----------------
|
|
615
|
+
/ | tr0 | tr1 | tr2 | il0
|
|
616
|
+
-----------------
|
|
617
|
+
| / | tr3 | tr4 | tr5 | il1
|
|
618
|
+
-----------------
|
|
619
|
+
| / | tr6 | tr7 | tr8 | il2
|
|
620
|
+
-----------------
|
|
621
|
+
| / / / / n-samples
|
|
622
|
+
------------------
|
|
623
|
+
|
|
624
|
+
ilines = [1, len(axis(0) + 1]
|
|
625
|
+
xlines = [1, len(axis(1) + 1]
|
|
626
|
+
samples = [0, len(axis(2)]
|
|
627
|
+
|
|
628
|
+
Parameters
|
|
629
|
+
----------
|
|
630
|
+
filename : string-like
|
|
631
|
+
Path to new file
|
|
632
|
+
data : 3-dimensional array-like
|
|
633
|
+
iline : int or segyio.TraceField
|
|
634
|
+
Inline number field in the trace headers. Defaults to 189 as per the
|
|
635
|
+
SEG-Y rev1 specification
|
|
636
|
+
xline : int or segyio.TraceField
|
|
637
|
+
Crossline number field in the trace headers. Defaults to 193 as per the
|
|
638
|
+
SEG-Y rev1 specification
|
|
639
|
+
format : int or segyio.SegySampleFormat
|
|
640
|
+
Sample format field in the trace header. Defaults to IBM float 4 byte
|
|
641
|
+
dt : int-like
|
|
642
|
+
sample interval
|
|
643
|
+
delrt : int-like
|
|
644
|
+
|
|
645
|
+
Notes
|
|
646
|
+
-----
|
|
647
|
+
.. versionadded:: 1.8
|
|
648
|
+
|
|
649
|
+
Examples
|
|
650
|
+
--------
|
|
651
|
+
Create a file from a 3D array, open it and read an iline:
|
|
652
|
+
|
|
653
|
+
>>> segyio.tools.from_array3D(path, array3d)
|
|
654
|
+
>>> segyio.open(path, mode) as f:
|
|
655
|
+
... iline = f.iline[0]
|
|
656
|
+
...
|
|
657
|
+
"""
|
|
658
|
+
|
|
659
|
+
data = np.asarray(data)
|
|
660
|
+
dimensions = len(data.shape)
|
|
661
|
+
|
|
662
|
+
if dimensions != 3:
|
|
663
|
+
problem = "Expected 3 dimensions, {} was given".format(dimensions)
|
|
664
|
+
raise ValueError(problem)
|
|
665
|
+
|
|
666
|
+
from_array(filename, data, iline=iline, xline=xline, format=format,
|
|
667
|
+
dt=dt,
|
|
668
|
+
delrt=delrt)
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
def from_array4D(filename, data, iline=189,
|
|
672
|
+
xline=193,
|
|
673
|
+
format=SegySampleFormat.IBM_FLOAT_4_BYTE,
|
|
674
|
+
dt=4000,
|
|
675
|
+
delrt=0):
|
|
676
|
+
""" Create a new SEGY file from a 4D array
|
|
677
|
+
Create an structured SEGY file with defaulted headers from a 4-dimensional
|
|
678
|
+
array. The file is inline-sorted. ilines, xlines, offsets and samples are
|
|
679
|
+
inferred from the array. Structure-defining fields in the binary header and
|
|
680
|
+
in the traceheaders are set accordingly. Such fields include, but are not
|
|
681
|
+
limited to iline, xline and offset. The file also contains a defaulted
|
|
682
|
+
textual header.
|
|
683
|
+
|
|
684
|
+
The 4D array is interpreted:
|
|
685
|
+
|
|
686
|
+
ilines = [1, len(axis(0) + 1]
|
|
687
|
+
xlines = [1, len(axis(1) + 1]
|
|
688
|
+
offsets = [1, len(axis(2) + 1]
|
|
689
|
+
samples = [0, len(axis(3)]
|
|
690
|
+
|
|
691
|
+
Parameters
|
|
692
|
+
----------
|
|
693
|
+
filename : string-like
|
|
694
|
+
Path to new file
|
|
695
|
+
data : 4-dimensional array-like
|
|
696
|
+
iline : int or segyio.TraceField
|
|
697
|
+
Inline number field in the trace headers. Defaults to 189 as per the
|
|
698
|
+
SEG-Y rev1 specification
|
|
699
|
+
xline : int or segyio.TraceField
|
|
700
|
+
Crossline number field in the trace headers. Defaults to 193 as per the
|
|
701
|
+
SEG-Y rev1 specification
|
|
702
|
+
format : int or segyio.SegySampleFormat
|
|
703
|
+
Sample format field in the trace header. Defaults to IBM float 4 byte
|
|
704
|
+
dt : int-like
|
|
705
|
+
sample interval
|
|
706
|
+
delrt : int-like
|
|
707
|
+
|
|
708
|
+
Notes
|
|
709
|
+
-----
|
|
710
|
+
.. versionadded:: 1.8
|
|
711
|
+
|
|
712
|
+
Examples
|
|
713
|
+
--------
|
|
714
|
+
Create a file from a 3D array, open it and read an iline:
|
|
715
|
+
|
|
716
|
+
>>> segyio.tools.create_from_array4D(path, array4d)
|
|
717
|
+
>>> segyio.open(path, mode) as f:
|
|
718
|
+
... iline = f.iline[0]
|
|
719
|
+
...
|
|
720
|
+
"""
|
|
721
|
+
|
|
722
|
+
data = np.asarray(data)
|
|
723
|
+
dimensions = len(data.shape)
|
|
724
|
+
|
|
725
|
+
if dimensions != 4:
|
|
726
|
+
problem = "Expected 4 dimensions, {} was given".format(dimensions)
|
|
727
|
+
raise ValueError(problem)
|
|
728
|
+
|
|
729
|
+
from_array(filename, data, iline=iline, xline=xline, format=format,
|
|
730
|
+
dt=dt,
|
|
731
|
+
delrt=delrt)
|