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/depth.py ADDED
@@ -0,0 +1,180 @@
1
+ try:
2
+ from collections.abc import Sequence # noqa
3
+ except ImportError:
4
+ from collections import Sequence # noqa
5
+
6
+ import numpy as np
7
+ try: from future_builtins import zip
8
+ except ImportError: pass
9
+ from .trace import Sequence
10
+ from .utils import castarray
11
+
12
+ class Depth(Sequence):
13
+ """
14
+ The Depth implements the array interface, where every array element, the
15
+ depth, is a numpy.ndarray of a horizontal cut of the volume. As all arrays
16
+ it can be random accessed, iterated over, and read strided. Please note
17
+ that SEG-Y data is laid out trace-by-trace on disk, so accessing horizontal
18
+ cuts (fixed z-coordinates in a cartesian grid) is *very* inefficient.
19
+
20
+ This mode works even on unstructured files, because it is not reliant on
21
+ in/crosslines to be sensible. Please note that in the case of unstructured
22
+ depth slicing, the array shape == tracecount.
23
+
24
+ Notes
25
+ -----
26
+ .. versionadded:: 1.1
27
+
28
+ .. versionchanged:: 1.6
29
+ common list operations (Sequence)
30
+
31
+ .. versionchanged:: 1.7.1
32
+ enabled for unstructured files
33
+
34
+ .. warning::
35
+ Accessing the file by depth (fixed z-coordinate) is inefficient because
36
+ of poor locality and many reads. If you read more than a handful
37
+ depths, consider using a faster mode.
38
+ """
39
+
40
+ def __init__(self, segyfile):
41
+ super(Depth, self).__init__(len(segyfile.samples))
42
+ self.segyfd = segyfile.segyfd
43
+ self.dtype = segyfile.dtype
44
+
45
+ if segyfile.unstructured:
46
+ self.shape = segyfile.tracecount
47
+ self.offsets = 1
48
+ else:
49
+ self.shape = (len(segyfile.fast), len(segyfile.slow))
50
+ self.offsets = len(segyfile.offsets)
51
+
52
+ def __getitem__(self, i):
53
+ """depth[i]
54
+
55
+ ith depth, a horizontal cross-section of the file, starting at 0.
56
+ depth[i] returns a numpy.ndarray, and changes to this array will *not*
57
+ be reflected on disk.
58
+
59
+ When i is a slice, a generator of numpy.ndarray is returned.
60
+
61
+ The depth slices are returned as a fast-by-slow shaped array, i.e. an
62
+ inline sorted file with 10 inlines and 5 crosslines has the shape
63
+ (10,5). If the file is unsorted, the array shape == tracecount.
64
+
65
+ Be aware that this interface uses zero-based indices (like traces) and
66
+ *not keys* (like ilines), so you can *not* use the values file.samples
67
+ as indices.
68
+
69
+ Parameters
70
+ ----------
71
+ i : int or slice
72
+
73
+ Returns
74
+ -------
75
+ depth : numpy.ndarray of dtype or generator of numpy.ndarray of dtype
76
+
77
+ Notes
78
+ -----
79
+ .. versionadded:: 1.1
80
+
81
+ .. warning::
82
+ The segyio 1.5 and 1.6 series, and 1.7.0, would return the depth_slice in the
83
+ wrong shape for most files. Since segyio 1.7.1, the arrays have the
84
+ correct shape, i.e. fast-by-slow. The underlying data was always
85
+ fast-by-slow, so a numpy array reshape can fix programs using the
86
+ 1.5 and 1.6 series.
87
+
88
+ Behaves like [] for lists.
89
+
90
+ Examples
91
+ --------
92
+ Read a single cut (one sample per trace):
93
+
94
+ >>> x = f.depth_slice[199]
95
+
96
+ Copy every depth slice into a list:
97
+
98
+ >>> l = [numpy.copy(x) for x in depth[:]]
99
+
100
+ Every third depth:
101
+
102
+ >>> for d in depth[::3]:
103
+ ... (d * 6).mean()
104
+
105
+ Read up to 250:
106
+
107
+ >>> for d in depth[:250]:
108
+ ... d.mean()
109
+
110
+ >>> len(ilines), len(xlines)
111
+ (1, 6)
112
+ >>> f.depth_slice[0]
113
+ array([[0. , 0.01, 0.02, 0.03, 0.04, 0.05]], dtype=float32)
114
+ """
115
+
116
+ try:
117
+ i = self.wrapindex(i)
118
+ buf = np.empty(self.shape, dtype=self.dtype)
119
+ return self.segyfd.getdepth(i, buf.size, self.offsets, buf)
120
+
121
+ except TypeError:
122
+ try:
123
+ indices = i.indices(len(self))
124
+ except AttributeError:
125
+ msg = 'depth indices must be integers or slices, not {}'
126
+ raise TypeError(msg.format(type(i).__name__))
127
+
128
+ def gen():
129
+ x = np.empty(self.shape, dtype=self.dtype)
130
+ y = np.copy(x)
131
+
132
+ for j in range(*indices):
133
+ self.segyfd.getdepth(j, x.size, self.offsets, x)
134
+ x, y = y, x
135
+ yield y
136
+
137
+ return gen()
138
+
139
+ def __setitem__(self, depth, val):
140
+ """depth[i] = val
141
+
142
+ Write the ith depth, a horizontal cross-section, of the file, starting
143
+ at 0. It accepts any array_like, but `val` must be at least as big as
144
+ the underlying data slice.
145
+
146
+ If `val` is longer than the underlying trace, `val` is essentially truncated.
147
+
148
+ Parameters
149
+ ----------
150
+ i : int or slice
151
+ val : array_like
152
+
153
+ Notes
154
+ -----
155
+ .. versionadded:: 1.1
156
+
157
+ Behaves like [] for lists.
158
+
159
+ Examples
160
+ --------
161
+ Copy a depth:
162
+
163
+ >>> depth[4] = other[19]
164
+
165
+ Copy consecutive depths, and assign to a sub volume (inject a sub cube
166
+ into the larger volume):
167
+
168
+ >>> depth[10:50] = other[:]
169
+
170
+ Copy into every other depth from an iterable:
171
+
172
+ >>> depth[::2] = other
173
+ """
174
+ if isinstance(depth, slice):
175
+ for i, x in zip(range(*depth.indices(len(self))), val):
176
+ self[i] = x
177
+ return
178
+
179
+ val = castarray(val, dtype = self.dtype)
180
+ self.segyfd.putdepth(depth, val.size, self.offsets, val)