[segyio] 250/376: Gather mode
Jørgen Kvalsvik
jokva-guest at moszumanska.debian.org
Wed Sep 20 08:04:40 UTC 2017
This is an automated email from the git hooks/post-receive script.
jokva-guest pushed a commit to branch debian
in repository segyio.
commit b80daea4c0ed79836350bf0477db8c39029973db
Author: Jørgen Kvalsvik <jokva at statoil.com>
Date: Wed Mar 29 14:31:25 2017 +0200
Gather mode
Support for reading data from some intersection in a cube.
---
python/CMakeLists.txt | 1 +
python/segyio/_gather.py | 82 ++++++++++++++++++++++++++++++++++++++++++++++++
python/segyio/segy.py | 38 ++++++++++++++++++++++
python/test/segy.py | 45 ++++++++++++++++++++++++++
4 files changed, 166 insertions(+)
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index c797160..fd322c8 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -39,6 +39,7 @@ add_python_package(pysegyio segyio
TARGETS _segyio
SOURCES segyio/__init__.py
segyio/_header.py
+ segyio/_gather.py
segyio/_line.py
segyio/_field.py
segyio/_trace.py
diff --git a/python/segyio/_gather.py b/python/segyio/_gather.py
new file mode 100644
index 0000000..e4be93e
--- /dev/null
+++ b/python/segyio/_gather.py
@@ -0,0 +1,82 @@
+import itertools
+import numpy as np
+
+import segyio.tools as tools
+from segyio.tracesortingformat import TraceSortingFormat
+
+class Gather:
+ """ Gather mode. Internal.
+
+ Provides the implementation for f.gather, reading n offsets from the
+ intersection of two lines in a cube.
+ """
+
+ def __init__(self, trace, iline, xline, offsets, sort):
+ # cache constructed modes for performance
+ self.trace = trace
+ self.iline = iline
+ self.xline = xline
+ self.offsets = offsets
+ self.sort = sort
+
+ def _getindex(self, il, xl, offset, sorting):
+ """ Get the trace index for an (il, xl, offset) tuple
+
+ :rtype: int
+ """
+ if sorting == TraceSortingFormat.INLINE_SORTING:
+ xlind = self.xline._index(xl, None)
+ return self.iline._index(il, offset) + xlind
+ else:
+ ilind = self.iline._index(il, None)
+ return self.xline._index(xl, offset) + ilind
+
+ def __getitem__(self, index):
+ """ :rtype: iterator[numpy.ndarray]|numpy.ndarray """
+ if len(index) < 3:
+ index = (index[0], index[1], slice(None))
+
+ il, xl, off = index
+ sort = self.sort
+
+ def isslice(x): return isinstance(x, slice)
+
+ # gather[int,int,int]
+ if not any(map(isslice, [il, xl, off])):
+ return self.trace[self._getindex(il, xl, off, sort)]
+
+ offs = off if isslice(off) else slice(off, off+1, 1)
+
+ xs = list(filter(self.offsets.__contains__,
+ range(*offs.indices(self.offsets[-1]+1))))
+
+ empty = np.empty(0, dtype = np.single)
+ # gather[int,int,:]
+ if not any(map(isslice, [il, xl])):
+ if len(xs) == 0: return empty
+ return tools.collect(
+ self.trace[self._getindex(il, xl, x, sort)]
+ for x in xs)
+
+ # gather[:,:,:]
+ def gen():
+ ils, _ = self.iline._indices(il, None)
+ xls, _ = self.xline._indices(xl, None)
+
+ # gather[:, :, int]
+ # i.e. every yielded array is 1-dimensional
+ if not isslice(off):
+ for i, x in itertools.product(ils, xls):
+ yield self.trace[self._getindex(i, x, off, sort)]
+ return
+
+ if len(xs) == 0:
+ for _, _ in itertools.product(ils, xls): yield empty
+ return
+
+ for i, x in itertools.product(ils, xls):
+ yield tools.collect(
+ self.trace[self._getindex(i, x, o, sort)]
+ for o in xs)
+
+ return gen()
diff --git a/python/segyio/segy.py b/python/segyio/segy.py
index af3a28c..3e9d86d 100644
--- a/python/segyio/segy.py
+++ b/python/segyio/segy.py
@@ -18,6 +18,7 @@ import itertools
import numpy as np
from segyio._header import Header
+from segyio._gather import Gather
from segyio._line import Line
from segyio._trace import Trace
from segyio._field import Field
@@ -895,6 +896,43 @@ class SegyFile(object):
self.depth_slice[:] = value
@property
+ def gather(self):
+ """ Interact with segy in gather mode
+
+ A gather is in this context the intersection of lines in a cube, i.e.
+ all the offsets at some iline/xline intersection. The primary data type
+ is the numpy ndarray, with dimensions depending on the range of offsets
+ specified. Offsets uses the line and offset numbers (names), not
+ 0-based indices.
+
+ When using ranges over lines, a generator is returned.
+
+ Examples:
+
+ Read one offset at an intersection::
+ >>> f.gather[200, 241, 25] # returns a samples-long 1d-array
+
+ Read all offsets at an intersection::
+ >>> f.gather[200, 241, :] # returns offsets x samples ndarray
+ >>> # If no offset is specified, this is implicitly (:)
+ >>> f.gather[200, 241, :] == f.gather[200, 241]
+
+ All offsets for a set of ilines, intersecting one crossline::
+ >>> f.gather[200:300, 241, :]
+
+ Some offsets for a set of ilines, interescting one crossline::
+ >>> f.gather[200:300, 241, 10:25:5]
+
+ Some offsets for a set of ilines and xlines. This effectively yields a subcube::
+ >>> f.gather[200:300, 241:248, 1:10]
+ """
+ if self.unstructured:
+ raise ValueError(self._unstructured_errmsg)
+
+ return Gather(self.trace, self.iline, self.xline,
+ self.offsets, self.sorting)
+
+ @property
def text(self):
""" Interact with segy in text mode.
diff --git a/python/test/segy.py b/python/test/segy.py
index 20048a0..833e888 100644
--- a/python/test/segy.py
+++ b/python/test/segy.py
@@ -366,6 +366,51 @@ class TestSegy(TestCase):
self.assertEqual((offs // 2) * (ils // 2), sum(1 for _ in f.iline[::2, ::-2]))
self.assertEqual((offs // 2) * (ils // 2), sum(1 for _ in f.iline[::-2, ::2]))
+
+ def test_gather_mode(self):
+ with segyio.open(self.prestack) as f:
+ empty = np.empty(0, dtype = np.single)
+ # should raise
+ with self.assertRaises(KeyError):
+ self.assertTrue(np.array_equal(empty, f.gather[2, 3, 3]))
+
+ with self.assertRaises(KeyError):
+ self.assertTrue(np.array_equal(empty, f.gather[2, 5, 1]))
+
+ with self.assertRaises(KeyError):
+ self.assertTrue(np.array_equal(empty, f.gather[5, 2, 1]))
+
+ self.assertTrue(np.array_equal(f.trace[10], f.gather[2, 3, 1]))
+ self.assertTrue(np.array_equal(f.trace[11], f.gather[2, 3, 2]))
+
+ traces = segyio.tools.collect(f.trace[10:12])
+ gather = f.gather[2,3,:]
+ self.assertTrue(np.array_equal(traces, gather))
+ self.assertTrue(np.array_equal(traces, f.gather[2,3]))
+ self.assertTrue(np.array_equal(empty, f.gather[2,3,1:0]))
+ self.assertTrue(np.array_equal(empty, f.gather[2,3,3:4]))
+
+ for g, line in zip(f.gather[1:3, 3, 1], f.iline[1:3]):
+ self.assertEqual(10, len(g))
+ self.assertEqual((10,), g.shape)
+ self.assertTrue(np.array_equal(line[2], g))
+
+ for g, line in zip(f.gather[1:3, 3, :], f.iline[1:3]):
+ self.assertEqual(2, len(g))
+ self.assertEqual((2, 10), g.shape)
+ self.assertTrue(np.array_equal(line[2], g[0]))
+
+ for g, line in zip(f.gather[1, 1:3, 1], f.xline[1:3]):
+ self.assertEqual(10, len(g))
+ self.assertEqual((10,), g.shape)
+ self.assertTrue(np.array_equal(line[0], g))
+
+ for g, line in zip(f.gather[1, 1:3, :], f.xline[1:3]):
+ self.assertEqual(2, len(g))
+ self.assertEqual((2, 10), g.shape)
+ self.assertTrue(np.array_equal(line[0], g[0]))
+
+
def test_line_generators(self):
with segyio.open(self.filename, "r") as f:
for line in f.iline:
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/segyio.git
More information about the debian-science-commits
mailing list