LoopStructural 1.0.3__zip → 1.0.71.dev0__zip
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.
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/__init__.py +12 -7
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__pycache__/_base.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__init__.py +3 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/base_structured_3d_support.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/discrete_fold_interpolator.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/discrete_interpolator.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/finite_difference_interpolator.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/geological_interpolator.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/operator.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/piecewiselinear_interpolator.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/structured_grid.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/structured_tetra.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/surfe_wrapper.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/base_structured_3d_support.py +101 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/dsi_helper.c +4137 -2716
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/dsi_helper.cp36-win_amd64.pyd +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/discrete_fold_interpolator.py +56 -22
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/discrete_interpolator.py +61 -28
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/finite_difference_interpolator.py +71 -11
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/geological_interpolator.py +22 -3
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/operator.py +16 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/piecewiselinear_interpolator.py +150 -11
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_grid.py +31 -69
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_tetra.py +89 -45
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/surfe_wrapper.py +7 -8
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/geological_model.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/geological_model_graph.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/stratigraphic_column.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/geological_model.py +515 -197
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/geological_model_graph.py +881 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/stratigraphic_column.py +5 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__init__.py +1 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_builder.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_function.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_function_feature.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_segment.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_builder.py +127 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_function.py +2 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_function_feature.py +2 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_segment.py +30 -3
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__init__.py +1 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/cross_product_geological_feature.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/geological_feature.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/geological_feature_builder.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/lambda_geological_feature.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/region_feature.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/structural_frame.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/structural_frame_builder.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/unconformity_feature.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/cross_product_geological_feature.py +18 -5
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/geological_feature.py +22 -49
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/geological_feature_builder.py +171 -47
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/lambda_geological_feature.py +31 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/region_feature.py +3 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/structural_frame.py +28 -11
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/structural_frame_builder.py +32 -22
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/unconformity_feature.py +6 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold_rotation_angle.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold_rotation_angle_feature.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/foldframe.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/svariogram.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold.py +13 -5
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold_rotation_angle.py +5 -4
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold_rotation_angle_feature.py +2 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/foldframe.py +7 -5
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/svariogram.py +2 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__init__.py +5 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/bounding_box.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/exceptions.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/helper.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/logging.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/map2loop.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/regions.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/utils.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/bounding_box.py +21 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/exceptions.py +2 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/helper.py +10 -2
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/logging.py +60 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/map2loop.py +128 -37
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/regions.py +11 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/utils.py +40 -47
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/map_viewer.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/model_plotter.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/model_visualisation.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/rotation_angle_plotter.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/sphinx_scraper.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/stratigraphic_column.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/map_viewer.py +236 -36
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/model_plotter.py +2 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/model_visualisation.py +427 -79
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/rotation_angle_plotter.py +29 -12
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/stratigraphic_column.py +60 -0
- Miniconda/envs/loop/Lib/site-packages/{LoopStructural-1.0.3-py3.6.egg-info → LoopStructural-1.0.71.dev0-py3.6.egg-info}/PKG-INFO +1 -1
- Miniconda/envs/loop/Lib/site-packages/{LoopStructural-1.0.3-py3.6.egg-info → LoopStructural-1.0.71.dev0-py3.6.egg-info}/SOURCES.txt +10 -5
- Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.71.dev0-py3.6.egg-info/requires.txt +8 -0
- Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.3-py3.6.egg-info/requires.txt +0 -3
- Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_faults.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_fold.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_interpolator.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_refolded.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/tests/test_faults.py +0 -17
- Miniconda/envs/loop/Lib/site-packages/tests/test_fold.py +0 -57
- Miniconda/envs/loop/Lib/site-packages/tests/test_interpolator.py +0 -88
- Miniconda/envs/loop/Lib/site-packages/tests/test_refolded.py +0 -22
- /Miniconda/envs/loop/Lib/site-packages/{LoopStructural-1.0.3-py3.6.egg-info → LoopStructural-1.0.71.dev0-py3.6.egg-info}/dependency_links.txt +0 -0
- /Miniconda/envs/loop/Lib/site-packages/{LoopStructural-1.0.3-py3.6.egg-info → LoopStructural-1.0.71.dev0-py3.6.egg-info}/top_level.txt +0 -0
|
@@ -4,15 +4,19 @@ A wrapper for lavavu
|
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
import logging
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
from LoopStructural.utils import getLogger
|
|
8
|
+
logger = getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
import lavavu
|
|
12
|
+
from lavavu.vutils import is_notebook
|
|
13
|
+
except ImportError:
|
|
14
|
+
logger.error("Please install lavavu: pip install lavavu")
|
|
9
15
|
import numpy as np
|
|
10
|
-
from
|
|
11
|
-
from
|
|
12
|
-
|
|
16
|
+
from skimage.measure import marching_cubes
|
|
17
|
+
from LoopStructural.modelling.features import GeologicalFeature
|
|
13
18
|
from LoopStructural.utils.helper import create_surface, get_vectors, create_box
|
|
14
19
|
|
|
15
|
-
logger = logging.getLogger(__name__)
|
|
16
20
|
# adapted/copied from pyvista for sphinx scraper
|
|
17
21
|
_OPEN_VIEWERS = {}
|
|
18
22
|
|
|
@@ -40,12 +44,13 @@ class LavaVuModelViewer:
|
|
|
40
44
|
----------
|
|
41
45
|
**kwargs : lavavu viewer kwargs
|
|
42
46
|
|
|
43
|
-
|
|
44
|
-
----------
|
|
45
|
-
lv Lavavu.Viewer object
|
|
47
|
+
|
|
46
48
|
objects : dictionary of objects that have been plotted
|
|
47
49
|
"""
|
|
48
50
|
# copied from pyvista
|
|
51
|
+
if lavavu is None:
|
|
52
|
+
logger.error("Lavavu isn't installed: pip install lavavu")
|
|
53
|
+
return
|
|
49
54
|
self._id_name = "{}-{}".format(str(hex(id(self))), len(_OPEN_VIEWERS))
|
|
50
55
|
_OPEN_VIEWERS[self._id_name] = self
|
|
51
56
|
#
|
|
@@ -63,11 +68,55 @@ class LavaVuModelViewer:
|
|
|
63
68
|
logger.error("Plot area has not been defined.")
|
|
64
69
|
self.bounding_box = np.array(self.bounding_box)
|
|
65
70
|
self.nsteps = np.array(self.nsteps)
|
|
66
|
-
self.
|
|
71
|
+
self._model = model
|
|
67
72
|
# prerotate to a nice view
|
|
68
73
|
# self.lv.rotate([-57.657936096191406, -13.939384460449219, -6.758780479431152])
|
|
69
74
|
def close(self):
|
|
70
75
|
pass
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def model(self):
|
|
79
|
+
return self._model
|
|
80
|
+
|
|
81
|
+
@model.setter
|
|
82
|
+
def model(self, model):
|
|
83
|
+
if model is not None:
|
|
84
|
+
self.bounding_box = np.array(model.bounding_box)
|
|
85
|
+
self.nsteps = np.array(model.nsteps)
|
|
86
|
+
self._model = model
|
|
87
|
+
self._nelements = self.nsteps[0]*self.nsteps[1]*self.nsteps[2]
|
|
88
|
+
logger.debug("Using bounding box from model")
|
|
89
|
+
@property
|
|
90
|
+
def nelements(self):
|
|
91
|
+
"""The number of elements to use for evaluating the isosurface
|
|
92
|
+
|
|
93
|
+
Returns
|
|
94
|
+
-------
|
|
95
|
+
nelements : int
|
|
96
|
+
number of elements to use for isosurfacing
|
|
97
|
+
"""
|
|
98
|
+
return self._nelements
|
|
99
|
+
|
|
100
|
+
@nelements.setter
|
|
101
|
+
def nelements(self, nelements : int):
|
|
102
|
+
"""Setter for nelements, automatically caculates the number of equally sized elements
|
|
103
|
+
to isosurface. Better than specifying step distance manually
|
|
104
|
+
|
|
105
|
+
Parameters
|
|
106
|
+
----------
|
|
107
|
+
nelements : int
|
|
108
|
+
[description]
|
|
109
|
+
"""
|
|
110
|
+
box_vol = (self.bounding_box[1, 0]-self.bounding_box[0, 0]) * (self.bounding_box[1, 1]-self.bounding_box[0, 1]) * (self.bounding_box[1, 2]-self.bounding_box[0, 2])
|
|
111
|
+
ele_vol = box_vol / nelements
|
|
112
|
+
# calculate the step vector of a regular cube
|
|
113
|
+
step_vector = np.zeros(3)
|
|
114
|
+
step_vector[:] = ele_vol ** (1. / 3.)
|
|
115
|
+
# step_vector /= np.array([1,1,2])
|
|
116
|
+
# number of steps is the length of the box / step vector
|
|
117
|
+
nsteps = np.ceil((self.bounding_box[1, :] - self.bounding_box[0, :]) / step_vector).astype(int)
|
|
118
|
+
self.nsteps = nsteps
|
|
119
|
+
logger.info("Using grid with dimensions {} {} {}".format(nsteps[0],nsteps[1],nsteps[2]))
|
|
71
120
|
|
|
72
121
|
def deep_clean(self):
|
|
73
122
|
"""[summary]
|
|
@@ -77,8 +126,8 @@ class LavaVuModelViewer:
|
|
|
77
126
|
self.lv.clear()
|
|
78
127
|
self.lv.cleardata()
|
|
79
128
|
pass
|
|
80
|
-
|
|
81
|
-
def add_section(self, geological_feature=None, axis='x', value=None,
|
|
129
|
+
|
|
130
|
+
def add_section(self, geological_feature=None, axis='x', value=None, **kwargs):
|
|
82
131
|
"""
|
|
83
132
|
|
|
84
133
|
Plot a section/map thru the model and paint with a geological feature
|
|
@@ -98,29 +147,26 @@ class LavaVuModelViewer:
|
|
|
98
147
|
-------
|
|
99
148
|
|
|
100
149
|
"""
|
|
101
|
-
|
|
102
150
|
if axis == 'x':
|
|
103
151
|
tri, yy, zz = create_surface(self.bounding_box[:, [1, 2]], self.nsteps[[1, 2]])
|
|
104
152
|
xx = np.zeros(zz.shape)
|
|
105
153
|
if value is None:
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
xx[:] = value
|
|
154
|
+
value = np.nanmean(self.bounding_box[:, 0])
|
|
155
|
+
xx[:] = value
|
|
109
156
|
if axis == 'y':
|
|
110
157
|
tri, xx, zz = create_surface(self.bounding_box[:, [0, 2]], self.nsteps[[0, 2]])
|
|
111
158
|
yy = np.zeros(xx.shape)
|
|
112
159
|
if value is None:
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
yy[:] = value
|
|
160
|
+
value = np.nanmean(self.bounding_box[:, 1])
|
|
161
|
+
yy[:] = value
|
|
116
162
|
if axis == 'z':
|
|
117
163
|
tri, xx, yy = create_surface(self.bounding_box[:, 0:2], self.nsteps[0:2])
|
|
118
164
|
zz = np.zeros(xx.shape)
|
|
119
165
|
if value is None:
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
name =
|
|
166
|
+
value = np.nanmean(self.bounding_box[:, 2])
|
|
167
|
+
zz[:] = value
|
|
168
|
+
name = kwargs.get('name', geological_feature.name)
|
|
169
|
+
name = '{}_section_at_{}_of_{}'.format(axis,value,name)
|
|
124
170
|
colour = kwargs.get('colour', 'red')
|
|
125
171
|
|
|
126
172
|
# create an array to evaluate the feature on for the section
|
|
@@ -130,12 +176,13 @@ class LavaVuModelViewer:
|
|
|
130
176
|
points[:, 2] = zz
|
|
131
177
|
|
|
132
178
|
surf = self.lv.triangles(name)
|
|
133
|
-
surf.vertices(points)
|
|
179
|
+
surf.vertices(self.model.rescale(points,inplace=False))
|
|
134
180
|
surf.indices(tri)
|
|
135
181
|
logger.info("Adding %s section at %f" % (axis, value))
|
|
136
182
|
if geological_feature is None:
|
|
137
183
|
surf.colours(colour)
|
|
138
|
-
|
|
184
|
+
|
|
185
|
+
if geological_feature is not None and type(geological_feature) == GeologicalFeature:
|
|
139
186
|
if 'norm' in kwargs:
|
|
140
187
|
surf.values(np.linalg.norm(
|
|
141
188
|
geological_feature.evaluate_gradient(points), axis=1),
|
|
@@ -150,10 +197,19 @@ class LavaVuModelViewer:
|
|
|
150
197
|
logger.info("Colouring section with %s min: %f, max: %f" % (
|
|
151
198
|
geological_feature.name, geological_feature.min(), geological_feature.max()))
|
|
152
199
|
surf.colourmap(cmap, range=[geological_feature.min(), geological_feature.max()])
|
|
200
|
+
if geological_feature == 'model' and self.model is not None:
|
|
201
|
+
name = kwargs.get('name','model_section')
|
|
202
|
+
surf.values(self.model.evaluate_model(points,scale=True),
|
|
203
|
+
name)
|
|
204
|
+
surf["colourby"] = name
|
|
205
|
+
cmap = lavavu.cubehelix(100)
|
|
206
|
+
if 'cmap' in kwargs:
|
|
207
|
+
cmap = kwargs['cmap']
|
|
208
|
+
|
|
153
209
|
|
|
154
210
|
def add_isosurface(self, geological_feature, value = None, isovalue=None,
|
|
155
211
|
paint_with=None, slices=None, colour='red', nslices=None,
|
|
156
|
-
cmap=None, filename=None,
|
|
212
|
+
cmap=None, filename=None, names=None, colours=None,**kwargs):
|
|
157
213
|
""" Plot the surface of a geological feature
|
|
158
214
|
|
|
159
215
|
[extended_summary]
|
|
@@ -177,14 +233,19 @@ class LavaVuModelViewer:
|
|
|
177
233
|
cmap : [type], optional
|
|
178
234
|
[description], by default None
|
|
179
235
|
filename: string, optional
|
|
180
|
-
filename for exporting
|
|
236
|
+
filename for exporting
|
|
237
|
+
names: list, optional
|
|
238
|
+
list of names same length as slices
|
|
239
|
+
colours: list, optional
|
|
240
|
+
list of colours same length as slices
|
|
181
241
|
|
|
182
242
|
Returns
|
|
183
243
|
-------
|
|
184
244
|
[type]
|
|
185
245
|
[description]
|
|
186
246
|
"""
|
|
187
|
-
|
|
247
|
+
if geological_feature is None:
|
|
248
|
+
logger.error("Cannot add isosurface GeologicalFeature does not exist")
|
|
188
249
|
# update the feature to make sure its current
|
|
189
250
|
if 'update' in kwargs:
|
|
190
251
|
geological_feature.update()
|
|
@@ -230,7 +291,7 @@ class LavaVuModelViewer:
|
|
|
230
291
|
if region is not None:
|
|
231
292
|
val[~region(np.array([xx.flatten(), yy.flatten(), zz.flatten()]).T)] = np.nan
|
|
232
293
|
step_vector = np.array([x[1] - x[0], y[1] - y[0], z[1] - z[0]])
|
|
233
|
-
for isovalue in slices_:
|
|
294
|
+
for i, isovalue in enumerate(slices_):
|
|
234
295
|
logger.info("Creating isosurface of %s at %f" % (geological_feature.name, isovalue))
|
|
235
296
|
|
|
236
297
|
if isovalue > np.nanmax(val) or isovalue < np.nanmin(val):
|
|
@@ -242,23 +303,41 @@ class LavaVuModelViewer:
|
|
|
242
303
|
isovalue,
|
|
243
304
|
spacing=step_vector)
|
|
244
305
|
verts += np.array([self.bounding_box[0, 0], self.bounding_box[0, 1], self.bounding_box[1, 2]])
|
|
245
|
-
|
|
246
|
-
|
|
306
|
+
self.model.rescale(verts)
|
|
307
|
+
|
|
308
|
+
except (ValueError, RuntimeError) as e:
|
|
309
|
+
print(e)
|
|
310
|
+
logger.warning("Cannot isosurface {} at {}, skipping".format(geological_feature.name,isovalue))
|
|
247
311
|
continue
|
|
248
|
-
|
|
249
312
|
|
|
313
|
+
|
|
250
314
|
name = geological_feature.name
|
|
251
315
|
name = kwargs.get('name', name)
|
|
252
316
|
name += '_iso_%f' % isovalue
|
|
317
|
+
if names is not None and len(names) == len(slices_):
|
|
318
|
+
name = names[i]
|
|
319
|
+
if name in self.lv.objects:
|
|
320
|
+
ii = 0
|
|
321
|
+
newname = name+"_{}".format(ii)
|
|
322
|
+
while newname in self.lv.objects:
|
|
323
|
+
ii+=1
|
|
324
|
+
newname = name+"_{}".format(ii)
|
|
325
|
+
name = newname
|
|
326
|
+
|
|
327
|
+
if colours is not None and len(colours) == len(slices_):
|
|
328
|
+
colour=colours[i]
|
|
253
329
|
if filename is not None:
|
|
330
|
+
svalues = None
|
|
331
|
+
# svalues[:] = np.nan
|
|
254
332
|
try:
|
|
255
333
|
import meshio
|
|
334
|
+
meshio.write_points_cells(filename.format(name),
|
|
335
|
+
verts,
|
|
336
|
+
[("triangle", faces)]
|
|
337
|
+
)
|
|
256
338
|
except ImportError:
|
|
257
339
|
logger.error("Could not save surfaces, meshio is not installed")
|
|
258
|
-
|
|
259
|
-
self.model.rescale(verts),
|
|
260
|
-
[("triangle", faces)]
|
|
261
|
-
)
|
|
340
|
+
|
|
262
341
|
surf = self.lv.triangles(name)
|
|
263
342
|
surf.vertices(verts)
|
|
264
343
|
surf.indices(faces)
|
|
@@ -268,7 +347,7 @@ class LavaVuModelViewer:
|
|
|
268
347
|
# add a property to the surface nodes for visualisation
|
|
269
348
|
# calculate the mode value, just to get the most common value
|
|
270
349
|
surfaceval = np.zeros(verts.shape[0])
|
|
271
|
-
surfaceval[:] = painter.evaluate_value(verts)
|
|
350
|
+
surfaceval[:] = painter.evaluate_value(self.model.scale(verts))
|
|
272
351
|
if painter.name is geological_feature.name:
|
|
273
352
|
logger.info("Setting surface value to %f"%isovalue)
|
|
274
353
|
surfaceval[:] = isovalue
|
|
@@ -278,43 +357,63 @@ class LavaVuModelViewer:
|
|
|
278
357
|
vmax = kwargs.get('vmax', max_property_val)
|
|
279
358
|
surf.colourmap(cmap, range=(vmin, vmax)) # nodes.shape[0]))
|
|
280
359
|
|
|
281
|
-
def add_scalar_field(self, geological_feature, **kwargs):
|
|
282
|
-
"""
|
|
360
|
+
def add_scalar_field(self, geological_feature, name=None, cmap='rainbow', vmin=None, vmax = None, **kwargs):
|
|
361
|
+
"""Add a block the size of the model area painted with the scalar field value
|
|
283
362
|
|
|
284
363
|
Parameters
|
|
285
364
|
----------
|
|
286
365
|
geological_feature : GeologicalFeature
|
|
287
366
|
the geological feature to colour the scalar field by
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
367
|
+
name : string, optional
|
|
368
|
+
Name of the object for lavavu, needs to be unique for the viewer object, by default uses feature name
|
|
369
|
+
cmap : str, optional
|
|
370
|
+
mpl colourmap reference, by default 'rainbow'
|
|
371
|
+
vmin : double, optional
|
|
372
|
+
minimum value of the colourmap, by default None
|
|
373
|
+
vmax : double, optional
|
|
374
|
+
maximum value of the colourmap, by default None
|
|
294
375
|
"""
|
|
295
|
-
|
|
376
|
+
if name == None:
|
|
377
|
+
if geological_feature is None:
|
|
378
|
+
name = 'unnamed scalar field'
|
|
379
|
+
else:
|
|
380
|
+
name = geological_feature.name + '_scalar_field'
|
|
381
|
+
|
|
296
382
|
points, tri = create_box(self.bounding_box,self.nsteps)
|
|
297
383
|
|
|
298
384
|
surf = self.lv.triangles(name)
|
|
299
|
-
surf.vertices(points)
|
|
385
|
+
surf.vertices(self.model.rescale(points))
|
|
300
386
|
surf.indices(tri)
|
|
301
|
-
val =geological_feature.evaluate_value(points)
|
|
387
|
+
val =geological_feature.evaluate_value(self.model.scale(points))
|
|
302
388
|
surf.values(val, geological_feature.name)
|
|
303
389
|
surf["colourby"] = geological_feature.name
|
|
304
|
-
cmap = kwargs.get('cmap',lavavu.cubehelix(100))
|
|
305
|
-
|
|
306
390
|
logger.info("Adding scalar field of %s to viewer. Min: %f, max: %f" % (geological_feature.name,
|
|
307
391
|
geological_feature.min(),
|
|
308
392
|
geological_feature.max()))
|
|
309
|
-
vmin
|
|
310
|
-
|
|
393
|
+
if vmin == None:
|
|
394
|
+
vmin =np.nanmin(val)
|
|
395
|
+
if vmax == None:
|
|
396
|
+
vmax = np.nanmax(val)
|
|
311
397
|
surf.colourmap(cmap, range=(vmin, vmax))
|
|
312
398
|
|
|
313
|
-
def
|
|
399
|
+
def add_box(self,bounding_box,name,colour='red'):
|
|
400
|
+
points, tri = create_box(bounding_box,self.nsteps)
|
|
401
|
+
|
|
402
|
+
surf = self.lv.triangles(name)
|
|
403
|
+
surf.vertices(self.model.rescale(points))
|
|
404
|
+
surf.indices(tri)
|
|
405
|
+
surf.colours(colour)
|
|
406
|
+
|
|
407
|
+
def add_model(self, cmap = None, **kwargs):
|
|
314
408
|
"""Add a block model painted by stratigraphic id to the viewer
|
|
315
409
|
|
|
316
410
|
Calls self.model.evaluate_model() for a cube surrounding the model.
|
|
317
411
|
|
|
412
|
+
Parameters
|
|
413
|
+
----------
|
|
414
|
+
cmap : matplotlib cmap, optional
|
|
415
|
+
colourmap name or object from mpl
|
|
416
|
+
|
|
318
417
|
Notes
|
|
319
418
|
------
|
|
320
419
|
It is sensible to increase the viewer step sizes before running this function to
|
|
@@ -324,17 +423,36 @@ class LavaVuModelViewer:
|
|
|
324
423
|
>>> viewer.nsteps = np.array([100,100,100])
|
|
325
424
|
|
|
326
425
|
"""
|
|
426
|
+
import matplotlib.colors as colors
|
|
427
|
+
from matplotlib import cm
|
|
428
|
+
|
|
327
429
|
name = kwargs.get('name', 'geological_model')
|
|
328
430
|
points, tri = create_box(self.bounding_box, self.nsteps)
|
|
329
431
|
|
|
330
432
|
surf = self.lv.triangles(name)
|
|
331
|
-
surf.vertices(points)
|
|
433
|
+
surf.vertices(self.model.rescale(points))
|
|
332
434
|
surf.indices(tri)
|
|
333
|
-
val = self.model.evaluate_model(points,
|
|
435
|
+
val = self.model.evaluate_model(points,scale=True)
|
|
334
436
|
surf.values(val, 'model')
|
|
335
437
|
surf["colourby"] = 'model'
|
|
336
|
-
cmap = kwargs.get('cmap', lavavu.cubehelix(100))
|
|
337
438
|
|
|
439
|
+
if cmap is None:
|
|
440
|
+
import matplotlib.colors as colors
|
|
441
|
+
colours = []
|
|
442
|
+
boundaries = []
|
|
443
|
+
data = []
|
|
444
|
+
for g in self.model.stratigraphic_column.keys():
|
|
445
|
+
if g == 'faults':
|
|
446
|
+
continue
|
|
447
|
+
for u, v in self.model.stratigraphic_column[g].items():
|
|
448
|
+
data.append((v['id'],v['colour']))
|
|
449
|
+
colours.append(v['colour'])
|
|
450
|
+
boundaries.append(v['id'])#print(u,v)
|
|
451
|
+
cmap = colors.ListedColormap(colours).colors
|
|
452
|
+
# else:
|
|
453
|
+
# cmap = cm.get_cmap(cmap,n_units)
|
|
454
|
+
|
|
455
|
+
|
|
338
456
|
# logger.info("Adding scalar field of %s to viewer. Min: %f, max: %f" % (geological_feature.name,
|
|
339
457
|
# geological_feature.min(),
|
|
340
458
|
# geological_feature.max()))
|
|
@@ -342,7 +460,55 @@ class LavaVuModelViewer:
|
|
|
342
460
|
vmax = kwargs.get('vmax', np.nanmax(val))
|
|
343
461
|
surf.colourmap(cmap, range=(vmin, vmax))
|
|
344
462
|
|
|
345
|
-
def
|
|
463
|
+
def add_fault_displacements(self, cmap = 'rainbow', **kwargs):
|
|
464
|
+
"""Add a block model painted by the fault displacement magnitude
|
|
465
|
+
|
|
466
|
+
Calls fault.displacementfeature.evaluate_value(points) for all faults
|
|
467
|
+
|
|
468
|
+
Parameters
|
|
469
|
+
----------
|
|
470
|
+
cmap : matplotlib cmap, optional
|
|
471
|
+
colourmap name or object from mpl
|
|
472
|
+
|
|
473
|
+
Notes
|
|
474
|
+
------
|
|
475
|
+
It is sensible to increase the viewer step sizes before running this function to
|
|
476
|
+
increase the resolution of the model as its not possible to interpolate a discrete
|
|
477
|
+
colourmap and this causes the model to look like a lego block.
|
|
478
|
+
You can update the model resolution by changing the attribute nsteps
|
|
479
|
+
>>> viewer.nsteps = np.array([100,100,100])
|
|
480
|
+
|
|
481
|
+
"""
|
|
482
|
+
|
|
483
|
+
name = kwargs.get('name', 'fault_displacements')
|
|
484
|
+
points, tri = create_box(self.bounding_box, self.nsteps)
|
|
485
|
+
|
|
486
|
+
surf = self.lv.triangles(name)
|
|
487
|
+
surf.vertices(self.model.rescale(points))
|
|
488
|
+
surf.indices(tri)
|
|
489
|
+
vals = self.model.evaluate_fault_displacements(points)
|
|
490
|
+
surf.values(vals, 'displacement')
|
|
491
|
+
surf["colourby"] = 'displacement'
|
|
492
|
+
|
|
493
|
+
vmin = kwargs.get('vmin', np.nanmin(vals))
|
|
494
|
+
vmax = kwargs.get('vmax', np.nanmax(vals))
|
|
495
|
+
surf.colourmap(cmap, range=(vmin, vmax))
|
|
496
|
+
|
|
497
|
+
def add_fault(self,fault,step=100):
|
|
498
|
+
self.add_isosurface(fault,value=0,name=fault.name)
|
|
499
|
+
self.add_vector_field(fault,locations=self.model.regular_grid()[::step])
|
|
500
|
+
|
|
501
|
+
def unfault_grid(self,feature,grid=None):
|
|
502
|
+
if grid is None:
|
|
503
|
+
grid = self.model.regular_grid()
|
|
504
|
+
# apply all faults associated with a feature to a regular grid
|
|
505
|
+
self.add_value_data(self.model.rescale(grid,inplace=False),grid[:,2],name='Regular grid before faults',pointsize=10,)
|
|
506
|
+
|
|
507
|
+
for f in feature.faults:
|
|
508
|
+
grid = f.apply_to_points(grid)
|
|
509
|
+
self.add_value_data(self.model.rescale(grid,inplace=False),grid[:,2],name='Regular grid after faults',pointsize=10,)
|
|
510
|
+
|
|
511
|
+
def add_model_surfaces(self, strati=True, faults = True, cmap=None, fault_colour='black',**kwargs):
|
|
346
512
|
"""Add surfaces for all of the interfaces in the model
|
|
347
513
|
|
|
348
514
|
|
|
@@ -357,26 +523,79 @@ class LavaVuModelViewer:
|
|
|
357
523
|
Other parameters are passed to self.add_isosurface()
|
|
358
524
|
|
|
359
525
|
"""
|
|
526
|
+
import time
|
|
360
527
|
from matplotlib import cm
|
|
528
|
+
from matplotlib import colors
|
|
529
|
+
from tqdm.auto import tqdm
|
|
530
|
+
start = time.time()
|
|
361
531
|
n_units = 0 #count how many discrete colours
|
|
362
|
-
for g in self.model.stratigraphic_column.keys():
|
|
363
|
-
for u in self.model.stratigraphic_column[g].keys():
|
|
364
|
-
n_units+=1
|
|
365
|
-
tab = cm.get_cmap(cmap,n_units)
|
|
366
|
-
ci = 0
|
|
367
|
-
|
|
368
532
|
for g in self.model.stratigraphic_column.keys():
|
|
369
533
|
if g in self.model.feature_name_index:
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
534
|
+
for u in self.model.stratigraphic_column[g].keys():
|
|
535
|
+
n_units+=1
|
|
536
|
+
n_faults = 0
|
|
537
|
+
for f in self.model.features:
|
|
538
|
+
if f.type=='fault':
|
|
539
|
+
n_faults+=1
|
|
540
|
+
|
|
541
|
+
if cmap is None:
|
|
542
|
+
colours = []
|
|
543
|
+
boundaries = []
|
|
544
|
+
data = []
|
|
545
|
+
for g in self.model.stratigraphic_column.keys():
|
|
546
|
+
if g == 'faults':
|
|
547
|
+
# skip anything saved in faults here
|
|
548
|
+
continue
|
|
549
|
+
for u, v in self.model.stratigraphic_column[g].items():
|
|
550
|
+
data.append((v['id'],v['colour']))
|
|
551
|
+
colours.append(v['colour'])
|
|
552
|
+
boundaries.append(v['id'])
|
|
553
|
+
cmap = colors.ListedColormap(colours)
|
|
554
|
+
else:
|
|
555
|
+
cmap = cm.get_cmap(cmap,n_units)
|
|
556
|
+
ci = 0
|
|
557
|
+
cmap_colours = colors.to_rgba_array(cmap.colors)
|
|
558
|
+
n_surfaces = 0
|
|
559
|
+
if strati:
|
|
560
|
+
n_surfaces+=n_units
|
|
374
561
|
if faults:
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
562
|
+
n_surfaces+=n_faults
|
|
563
|
+
with tqdm(total=n_surfaces) as pbar:
|
|
564
|
+
|
|
565
|
+
if strati:
|
|
566
|
+
for g in self.model.stratigraphic_column.keys():
|
|
567
|
+
if g in self.model.feature_name_index:
|
|
568
|
+
feature = self.model.features[self.model.feature_name_index[g]]
|
|
569
|
+
names = []
|
|
570
|
+
values = []
|
|
571
|
+
colours = []
|
|
572
|
+
for u, vals in self.model.stratigraphic_column[g].items():
|
|
573
|
+
names.append(u)
|
|
574
|
+
values.append(vals['min'])
|
|
575
|
+
colours.append(cmap_colours[ci,:])
|
|
576
|
+
ci+=1
|
|
577
|
+
pbar.set_description('Isosurfacing {}'.format(feature.name))
|
|
578
|
+
self.add_isosurface(feature, slices=values,names=names,colours=colours,**kwargs)
|
|
579
|
+
pbar.update(len(values))
|
|
580
|
+
|
|
379
581
|
|
|
582
|
+
if faults:
|
|
583
|
+
for f in self.model.features:
|
|
584
|
+
if f.type == 'fault':
|
|
585
|
+
def mask(x):
|
|
586
|
+
val = f.displacementfeature.evaluate_value(x)
|
|
587
|
+
val[np.isnan(val)] = 0
|
|
588
|
+
maskv = np.zeros(val.shape).astype(bool)
|
|
589
|
+
maskv[np.abs(val) > 0.001] = 1
|
|
590
|
+
return maskv
|
|
591
|
+
if f.name in self.model.stratigraphic_column['faults']:
|
|
592
|
+
fault_colour = self.model.stratigraphic_column['faults'][f.name].get('colour',['red'])
|
|
593
|
+
pbar.set_description('Isosurfacing {}'.format(f.name))
|
|
594
|
+
|
|
595
|
+
region = kwargs.pop('region',None)
|
|
596
|
+
self.add_isosurface(f,isovalue=0,region=mask,colour=fault_colour[0],name=f.name,**kwargs)
|
|
597
|
+
pbar.update(1)
|
|
598
|
+
print("Adding surfaces took {} seconds".format(time.time()-start))
|
|
380
599
|
def add_vector_field(self, geological_feature, **kwargs):
|
|
381
600
|
"""
|
|
382
601
|
|
|
@@ -406,7 +625,7 @@ class LavaVuModelViewer:
|
|
|
406
625
|
vector[mask, :] /= np.linalg.norm(vector[mask, :], axis=1)[:, None]
|
|
407
626
|
vectorfield = self.lv.vectors(geological_feature.name + "_grad",
|
|
408
627
|
**kwargs)
|
|
409
|
-
vectorfield.vertices(locations[mask, :])
|
|
628
|
+
vectorfield.vertices(self.model.rescale(locations[mask, :],inplace=False))
|
|
410
629
|
vectorfield.vectors(vector[mask, :])
|
|
411
630
|
return
|
|
412
631
|
|
|
@@ -429,6 +648,7 @@ class LavaVuModelViewer:
|
|
|
429
648
|
add_grad = True
|
|
430
649
|
add_value = True
|
|
431
650
|
add_tang = True
|
|
651
|
+
add_interface = True
|
|
432
652
|
if 'name' in kwargs:
|
|
433
653
|
name = kwargs['name']
|
|
434
654
|
del kwargs['name']
|
|
@@ -438,26 +658,49 @@ class LavaVuModelViewer:
|
|
|
438
658
|
add_value = kwargs['value']
|
|
439
659
|
if 'tang' in kwargs:
|
|
440
660
|
add_tang = kwargs['tang']
|
|
661
|
+
if 'interface' in kwargs:
|
|
662
|
+
add_interface = kwargs['interface']
|
|
441
663
|
grad = feature.builder.get_gradient_constraints()
|
|
442
664
|
norm = feature.builder.get_norm_constraints()
|
|
443
665
|
value = feature.builder.get_value_constraints()
|
|
444
666
|
tang = feature.builder.get_tangent_constraints()
|
|
667
|
+
interface = feature.builder.get_interface_constraints()
|
|
668
|
+
|
|
445
669
|
if grad.shape[0] > 0 and add_grad:
|
|
446
|
-
self.add_vector_data(grad[:, :3], grad[:, 3:6], name + "_grad_cp",
|
|
670
|
+
self.add_vector_data(self.model.rescale(grad[:, :3],inplace=False), grad[:, 3:6], name + "_grad_cp",
|
|
447
671
|
**kwargs)
|
|
448
672
|
|
|
449
673
|
if norm.shape[0] > 0 and add_grad:
|
|
450
|
-
self.add_vector_data(norm[:, :3], norm[:, 3:6], name + "_norm_cp",
|
|
674
|
+
self.add_vector_data(self.model.rescale(norm[:, :3],inplace=False), norm[:, 3:6], name + "_norm_cp",
|
|
451
675
|
**kwargs)
|
|
452
676
|
if value.shape[0] > 0 and add_value:
|
|
453
677
|
kwargs['range'] = [feature.min(), feature.max()]
|
|
454
|
-
self.add_value_data(value[:, :3], value[:, 3], name + "_value_cp",
|
|
678
|
+
self.add_value_data(self.model.rescale(value[:, :3],inplace=False), value[:, 3], name + "_value_cp",
|
|
455
679
|
**kwargs)
|
|
456
680
|
if tang.shape[0] > 0 and add_tang:
|
|
457
|
-
self.add_vector_data(tang[:, :3], tang[:, 3:6], name + "_tang_cp",
|
|
681
|
+
self.add_vector_data(self.model.rescale(tang[:, :3],inplace=False), tang[:, 3:6], name + "_tang_cp",
|
|
458
682
|
**kwargs)
|
|
683
|
+
if interface.shape[0] > 0 and add_interface:
|
|
684
|
+
self.add_points(self.model.rescale(interface[:,:3],inplace=False), name + "_interface_cp")
|
|
459
685
|
|
|
460
|
-
|
|
686
|
+
def add_intersection_lineation(self, feature, **kwargs):
|
|
687
|
+
name = feature.name
|
|
688
|
+
if 'name' in kwargs:
|
|
689
|
+
name = kwargs['name']
|
|
690
|
+
del kwargs['name']
|
|
691
|
+
intersection = feature.fold.foldframe.calculate_intersection_lineation(
|
|
692
|
+
feature.builder)
|
|
693
|
+
gpoints = feature.builder.interpolator.get_gradient_constraints()[:,:6]
|
|
694
|
+
npoints = feature.builder.interpolator.get_norm_constraints()[:,:6]
|
|
695
|
+
points = []
|
|
696
|
+
if gpoints.shape[0] > 0:
|
|
697
|
+
points.append(gpoints)
|
|
698
|
+
if npoints.shape[0] > 0:
|
|
699
|
+
points.append(npoints)
|
|
700
|
+
points = np.vstack(points)
|
|
701
|
+
if intersection.shape[0] > 0:
|
|
702
|
+
self.add_vector_data(self.model.rescale(points[:,:3],inplace=False), intersection, name + "_intersection")
|
|
703
|
+
|
|
461
704
|
def add_points(self, points, name, **kwargs):
|
|
462
705
|
"""
|
|
463
706
|
|
|
@@ -523,7 +766,7 @@ class LavaVuModelViewer:
|
|
|
523
766
|
if "pointsize" not in kwargs:
|
|
524
767
|
kwargs["pointsize"] = 4
|
|
525
768
|
# set the colour map to diverge unless user decides otherwise
|
|
526
|
-
cmap = kwargs.get('cmap', "
|
|
769
|
+
cmap = kwargs.get('cmap', "rainbow")
|
|
527
770
|
p = self.lv.points(name, **kwargs)
|
|
528
771
|
p.vertices(position)
|
|
529
772
|
p.values(value, "v")
|
|
@@ -533,7 +776,7 @@ class LavaVuModelViewer:
|
|
|
533
776
|
logger.info('vmin {} and vmax {}'.format(kwargs['vmin'],kwargs['vmax']))
|
|
534
777
|
p.colourmap(cmap, range=(kwargs['vmin'],kwargs['vmax']))
|
|
535
778
|
else:
|
|
536
|
-
p.colourmap(cmap)
|
|
779
|
+
p.colourmap(cmap, range=(np.nanmin(value),np.nanmax(value)))
|
|
537
780
|
|
|
538
781
|
def add_fold(self, fold, **kwargs):
|
|
539
782
|
"""
|
|
@@ -556,6 +799,7 @@ class LavaVuModelViewer:
|
|
|
556
799
|
xx, yy, zz = np.meshgrid(x, y, z, indexing='ij')
|
|
557
800
|
locations = np.array([xx.flatten(), yy.flatten(), zz.flatten()]).T
|
|
558
801
|
r2r, fold_axis, dgz = fold.get_deformed_orientation(locations)
|
|
802
|
+
locations = self.model.rescale(locations,inplace=False)
|
|
559
803
|
self.add_vector_data(locations, r2r, fold.name + '_direction', colour='red')
|
|
560
804
|
self.add_vector_data(locations, fold_axis, fold.name + '_axis', colour='black')
|
|
561
805
|
self.add_vector_data(locations, dgz, fold.name + '_norm', colour='green')
|
|
@@ -578,7 +822,26 @@ class LavaVuModelViewer:
|
|
|
578
822
|
self.lv.control.ObjectList()
|
|
579
823
|
self.lv.interactive()
|
|
580
824
|
|
|
825
|
+
def add_support_box(self,geological_feature, paint=False, **kwargs):
|
|
826
|
+
name = kwargs.get('name', geological_feature.name + '_support')
|
|
827
|
+
box = np.vstack([geological_feature.interpolator.support.origin,geological_feature.interpolator.support.maximum])
|
|
828
|
+
points, tri = create_box(box,self.nsteps)
|
|
581
829
|
|
|
830
|
+
surf = self.lv.triangles(name)
|
|
831
|
+
surf.vertices(self.model.rescale(points))
|
|
832
|
+
surf.indices(tri)
|
|
833
|
+
if paint:
|
|
834
|
+
val =geological_feature.evaluate_value(self.model.scale(points))
|
|
835
|
+
surf.values(val, geological_feature.name)
|
|
836
|
+
surf["colourby"] = geological_feature.name
|
|
837
|
+
cmap = kwargs.get('cmap',lavavu.cubehelix(100))
|
|
838
|
+
|
|
839
|
+
logger.info("Adding scalar field of %s to viewer. Min: %f, max: %f" % (geological_feature.name,
|
|
840
|
+
geological_feature.min(),
|
|
841
|
+
geological_feature.max()))
|
|
842
|
+
vmin = kwargs.get('vmin', np.nanmin(val))
|
|
843
|
+
vmax = kwargs.get('vmax', np.nanmax(val))
|
|
844
|
+
surf.colourmap(cmap, range=(vmin, vmax))
|
|
582
845
|
def set_zscale(self,zscale):
|
|
583
846
|
""" Set the vertical scale for lavavu
|
|
584
847
|
|
|
@@ -648,6 +911,16 @@ class LavaVuModelViewer:
|
|
|
648
911
|
|
|
649
912
|
"""
|
|
650
913
|
self.lv.image(name)
|
|
914
|
+
|
|
915
|
+
def image_array(self, **kwargs):
|
|
916
|
+
"""Return the current viewer image image data as a numpy array
|
|
917
|
+
|
|
918
|
+
Returns
|
|
919
|
+
-------
|
|
920
|
+
image : np.array
|
|
921
|
+
image as a numpy array
|
|
922
|
+
"""
|
|
923
|
+
return self.lv.rawimage(**kwargs).data
|
|
651
924
|
|
|
652
925
|
def rotatex(self, r):
|
|
653
926
|
"""
|
|
@@ -730,3 +1003,78 @@ class LavaVuModelViewer:
|
|
|
730
1003
|
"""
|
|
731
1004
|
self.lv.rotation(xyz)
|
|
732
1005
|
|
|
1006
|
+
@property
|
|
1007
|
+
def border(self):
|
|
1008
|
+
"""The width of the border around the model area
|
|
1009
|
+
|
|
1010
|
+
Returns
|
|
1011
|
+
-------
|
|
1012
|
+
border : double
|
|
1013
|
+
[description]
|
|
1014
|
+
"""
|
|
1015
|
+
return self.lv['border']
|
|
1016
|
+
|
|
1017
|
+
@border.setter
|
|
1018
|
+
def border(self, border):
|
|
1019
|
+
"""Setter for the border
|
|
1020
|
+
|
|
1021
|
+
Parameters
|
|
1022
|
+
----------
|
|
1023
|
+
border : double
|
|
1024
|
+
set the thickness of the border around objects
|
|
1025
|
+
"""
|
|
1026
|
+
self.lv['border'] = border
|
|
1027
|
+
|
|
1028
|
+
def clear(self):
|
|
1029
|
+
"""Remove all objects from the viewer
|
|
1030
|
+
"""
|
|
1031
|
+
self.lv.clear()
|
|
1032
|
+
|
|
1033
|
+
@property
|
|
1034
|
+
def xmin(self):
|
|
1035
|
+
return self.lv['xmin']
|
|
1036
|
+
|
|
1037
|
+
@xmin.setter
|
|
1038
|
+
def xmin(self, xmin):
|
|
1039
|
+
self.lv['xmin'] = xmin
|
|
1040
|
+
|
|
1041
|
+
@property
|
|
1042
|
+
def xmax(self):
|
|
1043
|
+
return self.lv['xmax']
|
|
1044
|
+
|
|
1045
|
+
@xmax.setter
|
|
1046
|
+
def xmax(self, xmax):
|
|
1047
|
+
self.lv['xmax'] = xmax
|
|
1048
|
+
|
|
1049
|
+
@property
|
|
1050
|
+
def ymin(self):
|
|
1051
|
+
return self.lv['ymin']
|
|
1052
|
+
|
|
1053
|
+
@ymin.setter
|
|
1054
|
+
def ymin(self, ymin):
|
|
1055
|
+
self.lv['ymin'] = ymin
|
|
1056
|
+
|
|
1057
|
+
@property
|
|
1058
|
+
def ymax(self):
|
|
1059
|
+
return self.lv['ymax']
|
|
1060
|
+
|
|
1061
|
+
@ymax.setter
|
|
1062
|
+
def ymax(self, ymax):
|
|
1063
|
+
self.lv['ymax'] = ymax
|
|
1064
|
+
|
|
1065
|
+
@property
|
|
1066
|
+
def zmin(self):
|
|
1067
|
+
return self.lv['zmax']
|
|
1068
|
+
|
|
1069
|
+
@zmin.setter
|
|
1070
|
+
def zmin(self, zmin):
|
|
1071
|
+
self.lv['zmin'] = zmin
|
|
1072
|
+
|
|
1073
|
+
@property
|
|
1074
|
+
def zmax(self):
|
|
1075
|
+
return self.lv['zmax']
|
|
1076
|
+
|
|
1077
|
+
@zmax.setter
|
|
1078
|
+
def zmax(self, zmax):
|
|
1079
|
+
self.lv['zmax'] = zmax
|
|
1080
|
+
|