Skip to content

Commit 7016d5a

Browse files
authored
Merge pull request #142 from jcrivenaes/xsect-seis
simplified cube xsections
2 parents ad42e78 + 76f21c3 commit 7016d5a

File tree

7 files changed

+103
-21
lines changed

7 files changed

+103
-21
lines changed

src/xtgeo/cube/_cube_utils.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import numpy as np
66

7+
import xtgeo
78
import xtgeo.cxtgeo.cxtgeo as _cxtgeo
89
from xtgeo.common import XTGeoDialog
910

@@ -261,12 +262,22 @@ def get_xy_value_from_ij(self, iloc, jloc, ixline=False, zerobased=False):
261262

262263

263264
def get_randomline(
264-
self, fencespec, zmin=None, zmax=None, zincrement=None, sampling="nearest"
265+
self,
266+
fencespec,
267+
zmin=None,
268+
zmax=None,
269+
zincrement=None,
270+
hincrement=None,
271+
atleast=5,
272+
extend=2,
273+
sampling="nearest",
265274
):
266275
"""Get a random line from a fence spesification"""
267276

268-
if not isinstance(fencespec, np.ndarray):
269-
raise ValueError("Fence is not a numpy array")
277+
if isinstance(fencespec, xtgeo.Polygons):
278+
logger.info("Estimate hincrement from Polygons instance...")
279+
fencespec = _get_randomline_fence(self, fencespec, hincrement, atleast, extend)
280+
logger.info("Estimate hincrement from Polygons instance... DONE")
270281

271282
if not len(fencespec.shape) == 2:
272283
raise ValueError("Fence is not a 2D numpy")
@@ -325,6 +336,20 @@ def get_randomline(
325336
return (hcoords[0], hcoords[-1], zmin, zmax, arr)
326337

327338

339+
def _get_randomline_fence(self, fencespec, hincrement, atleast, extend):
340+
"""Compute a resampled fence from a Polygons instance"""
341+
342+
if hincrement is None:
343+
avgdxdy = 0.5 * (self.xinc + self.yinc)
344+
distance = 0.5 * avgdxdy
345+
346+
logger.info("Getting fence from a Polygons instance...")
347+
return fencespec.get_fence(
348+
distance=distance, atleast=atleast, extend=extend, asnumpy=True
349+
)
350+
logger.info("Getting fence from a Polygons instance... DONE")
351+
352+
328353
# copy (update) values from SWIG carray to numpy, 3D array, Fortran order
329354
# to be DEPRECATED
330355
def update_values(cube):

src/xtgeo/cube/cube1.py

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,15 @@
88

99
import numpy as np
1010

11+
import xtgeo
1112
from xtgeo.common import XTGeoDialog
1213
from xtgeo.common import XTGDescription
13-
from xtgeo.common import constants
1414

1515
from xtgeo.cube import _cube_import
1616
from xtgeo.cube import _cube_export
1717
from xtgeo.cube import _cube_utils
1818
from xtgeo.cube import _cube_roxapi
1919

20-
UNDEF = constants.UNDEF
21-
UNDEF_LIMIT = constants.UNDEF_LIMIT
2220

2321
xtg = XTGeoDialog()
2422
logger = xtg.functionlogger(__name__)
@@ -95,9 +93,6 @@ class Cube(object): # pylint: disable=too-many-public-methods
9593
def __init__(self, *args, **kwargs):
9694
"""Initiate a Cube instance."""
9795

98-
clsname = "{}.{}".format(type(self).__module__, type(self).__name__)
99-
logger.info(clsname)
100-
10196
self._filesrc = None
10297
self._segyfile = None
10398
self._ilines = None
@@ -117,8 +112,6 @@ def __init__(self, *args, **kwargs):
117112
self._xlines = np.array(range(1, 3 + 1), dtype=np.int32)
118113
self._rotation = 0.0
119114
self._traceidcodes = np.ones((5, 3), dtype=np.int32)
120-
self._undef = UNDEF
121-
self._undef_limit = UNDEF_LIMIT
122115

123116
if len(args) >= 1:
124117
fformat = kwargs.get("fformat", "guess")
@@ -565,7 +558,15 @@ def get_xy_value_from_ij(self, iloc, jloc, ixline=False, zerobased=False):
565558
# =========================================================================
566559

567560
def get_randomline(
568-
self, fencespec, zmin=None, zmax=None, zincrement=None, sampling="nearest"
561+
self,
562+
fencespec,
563+
zmin=None,
564+
zmax=None,
565+
zincrement=None,
566+
hincrement=None,
567+
atleast=5,
568+
extend=2,
569+
sampling="nearest",
569570
):
570571
"""Get a randomline from a fence spesification.
571572
@@ -576,13 +577,24 @@ def get_randomline(
576577
577578
The input fencespec is a 2D numpy where each row is X, Y, Z, HLEN,
578579
where X, Y are UTM coordinates, Z is depth/time, and HLEN is a
579-
length along the fence.
580+
length along the fence, or a Polygons instance with HLEN present.
581+
582+
It is important that the HLEN array has a constant increment and ideally
583+
a sampling that is less than the Cube resolution.
580584
581585
Args:
582-
fencespec (np): 2D numpy with X, Y, Z, HLEN as rows.
586+
fencespec (~np.ndarray or :class:`~xtgeo.xyz.polygons.Polygons`):
587+
2D numpy with X, Y, Z, HLEN as rows or a xtgeo Polygons() object.
583588
zmin (float): Minimum Z (default is Cube Z minima/origin)
584589
zmax (float): Maximum Z (default is Cube Z maximum)
585-
zincrement (float): Sampling, default is Cube ZINC/2
590+
zincrement (float): Sampling vertically, default is Cube ZINC/2
591+
hincrement (float or bool): Resampling horizontally. This applies only
592+
if the fencespec is a Polygons() instance. If None (default),
593+
the distance will be deduced automatically.
594+
atleast (int): Minimum number of horizontal samples (only if
595+
fencespec is a Polygons instance)
596+
extend (int): Extend with extend*hincrement in both ends (only if
597+
fencespec is a Polygons instance)
586598
sampling (str): Algorithm, 'nearest' or 'trilinear' (first is
587599
faster, second is more precise for continuous fields)
588600
@@ -592,16 +604,25 @@ def get_randomline(
592604
Raises:
593605
ValueError: Input fence is not according to spec.
594606
595-
"""
607+
.. versionadded:: 2.1.0 support for Polygons() as fencespec, and keywords
608+
hincrement, atleast and sampling
596609
610+
"""
611+
if not isinstance(fencespec, (np.ndarray, xtgeo.Polygons)):
612+
raise ValueError("fencespec must be a numpy or a Polygons() object")
613+
logger.info("Getting randomline...")
597614
res = _cube_utils.get_randomline(
598615
self,
599616
fencespec,
600617
zmin=zmin,
601618
zmax=zmax,
602619
zincrement=zincrement,
620+
hincrement=hincrement,
621+
atleast=atleast,
622+
extend=extend,
603623
sampling=sampling,
604624
)
625+
logger.info("Getting randomline... DONE")
605626
return res
606627

607628
# =========================================================================

src/xtgeo/cxtgeo/clib/src/pol_refine.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ int pol_refine (
6969

7070
if (n>1) {
7171
len=usedist/n;
72-
72+
xtg_speak(s, 2, "LEN is %d", len);
7373
for (ii=1;ii<n; ii++) {
7474

7575
frac = (len/usedist)*ii;

src/xtgeo/cxtgeo/clib/src/pol_resampling.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ int pol_resampling(
112112
thlenx = calloc(naddr, sizeof(double));
113113

114114
/* ========================================================================
115-
* Part one, look at current input, re-estimate smapling distance, and
115+
* Part one, look at current input, re-estimate sampling distance, and
116116
* find extend angles using certain criteria
117117
* ========================================================================
118118
*/

src/xtgeo/xyz/_xyz_oper.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def get_fence(self, distance=20, atleast=5, extend=2, name=None, asnumpy=True):
137137
The atleast parameter will win over the distance, meaning that if total length
138138
horizontally is 50, and distance is set to 20, the actual length will be 50/5=10
139139
140-
"""
140+
"""
141141

142142
if len(self._df) < 2:
143143
xtg.warn("Well does not enough points in interval, outside range?")
@@ -150,11 +150,13 @@ def get_fence(self, distance=20, atleast=5, extend=2, name=None, asnumpy=True):
150150

151151
nbuf = 1000000
152152

153+
logger.info("%s %s %s %s %s ", distance, atleast, extend, name, asnumpy)
153154
npxarr = np.zeros(nbuf, dtype=np.float64)
154155
npyarr = np.zeros(nbuf, dtype=np.float64)
155156
npzarr = np.zeros(nbuf, dtype=np.float64)
156157
npharr = np.zeros(nbuf, dtype=np.float64)
157158

159+
logger.info("Calling C routine...")
158160
# C function:
159161
ier, npxarr, npyarr, npzarr, npharr, nlen = _cxtgeo.pol_resampling(
160162
self._df[self.xname].values,
@@ -169,6 +171,7 @@ def get_fence(self, distance=20, atleast=5, extend=2, name=None, asnumpy=True):
169171
0,
170172
XTGDEBUG
171173
)
174+
logger.info("Calling C routine... DONE")
172175

173176
if ier != 0:
174177
raise RuntimeError("Nonzero code from_cxtgeo.pol_resampling")

src/xtgeo/xyz/polygons.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,18 +463,19 @@ def get_fence(self, distance=20, atleast=5, extend=2, name=None, asnumpy=True):
463463
extend (int): Number of samples to extend at each end
464464
name (str): Name of polygon (if asnumpy=False)
465465
asnumpy (bool): Return a [:, 5] numpy array with
466-
columns X, Y, Z, H, dH
466+
columns X.., Y.., Z.., HLEN, dH
467467
468468
Returns:
469469
A numpy array (if asnumpy=True) or a new Polygons() object
470470
471471
.. versionadded:: 2.1.0
472472
"""
473-
473+
logger.info("Getting fence within a Polygons instance...")
474474
return _xyz_oper.get_fence(
475475
self, distance=distance, atleast=atleast, extend=extend,
476476
name=name, asnumpy=asnumpy
477477
)
478+
logger.info("Getting fence within a Polygons instance... DONE")
478479

479480
# =========================================================================
480481
# Operations restricted to inside/outside polygons

tests/test_cube/test_cube.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
import os
33
from os.path import join
44

5+
import numpy as np
6+
import pandas as pd
57
import pytest
68

9+
import xtgeo
710
from xtgeo.cube import Cube
811
from xtgeo.common import XTGeoDialog
912

@@ -311,3 +314,32 @@ def test_cube_swapaxes():
311314
tsetup.assert_almostequal(diff.mean(), 0.0, 0.000001)
312315
tsetup.assert_almostequal(diff.std(), 0.0, 0.000001)
313316
assert incube.ilines.size == incube.ncol
317+
318+
319+
def test_cube_randomline():
320+
"""Import a cube, and compute a randomline given a simple Polygon"""
321+
322+
# import matplotlib.pyplot as plt
323+
324+
incube = Cube(SFILE4)
325+
326+
# make a polyline with two points
327+
dfr = pd.DataFrame(
328+
np.array([[778133, 6737650, 2000, 1], [776880, 6738820, 2000, 1]]),
329+
columns=["X_UTME", "Y_UTMN", "Z_TVDSS", "POLY_ID"],
330+
)
331+
poly = xtgeo.Polygons()
332+
poly.dataframe = dfr
333+
334+
logger.info("Generate random line...")
335+
hmin, hmax, vmin, vmax, random = incube.get_randomline(poly)
336+
337+
tsetup.assert_almostequal(hmin, -15.655932861802714, 0.001)
338+
tsetup.assert_almostequal(random.mean(), -11.8755, 0.001)
339+
340+
# plt.figure()
341+
# plt.imshow(random, cmap='seismic', interpolation='sinc',
342+
# extent=(hmin, hmax, vmax, vmin))
343+
# plt.axis('tight')
344+
# plt.colorbar()
345+
# plt.show()

0 commit comments

Comments
 (0)