LoopStructural 1.0.9__cp38-cp38-win32.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.
- LoopStructural/__init__.py +36 -0
- LoopStructural/analysis/__init__.py +2 -0
- LoopStructural/analysis/_fault_displacement.py +67 -0
- LoopStructural/analysis/_fault_intersection.py +36 -0
- LoopStructural/analysis/_plane_fit.py +43 -0
- LoopStructural/datasets/__init__.py +12 -0
- LoopStructural/datasets/_base.py +65 -0
- LoopStructural/datasets/data/claudius.csv +21049 -0
- LoopStructural/datasets/data/claudiusbb.txt +2 -0
- LoopStructural/datasets/data/duplex.csv +126 -0
- LoopStructural/datasets/data/duplexbb.txt +2 -0
- LoopStructural/datasets/data/intrusion.csv +1017 -0
- LoopStructural/datasets/data/intrusionbb.txt +2 -0
- LoopStructural/datasets/data/onefoldbb.txt +2 -0
- LoopStructural/datasets/data/onefolddata.csv +2226 -0
- LoopStructural/datasets/data/refolded_bb.txt +2 -0
- LoopStructural/datasets/data/refolded_fold.csv +2126 -0
- LoopStructural/interpolators/__init__.py +34 -0
- LoopStructural/interpolators/base_structured_3d_support.py +101 -0
- LoopStructural/interpolators/cython/__init__.py +0 -0
- LoopStructural/interpolators/cython/dsi_helper.c +31046 -0
- LoopStructural/interpolators/cython/dsi_helper.cp38-win32.pyd +0 -0
- LoopStructural/interpolators/discrete_fold_interpolator.py +202 -0
- LoopStructural/interpolators/discrete_interpolator.py +584 -0
- LoopStructural/interpolators/finite_difference_interpolator.py +399 -0
- LoopStructural/interpolators/geological_interpolator.py +197 -0
- LoopStructural/interpolators/operator.py +61 -0
- LoopStructural/interpolators/piecewiselinear_interpolator.py +437 -0
- LoopStructural/interpolators/structured_grid.py +421 -0
- LoopStructural/interpolators/structured_tetra.py +681 -0
- LoopStructural/interpolators/surfe_wrapper.py +118 -0
- LoopStructural/modelling/__init__.py +46 -0
- LoopStructural/modelling/core/__init__.py +0 -0
- LoopStructural/modelling/core/geological_model.py +1513 -0
- LoopStructural/modelling/core/geological_model_graph.py +880 -0
- LoopStructural/modelling/core/stratigraphic_column.py +5 -0
- LoopStructural/modelling/fault/__init__.py +4 -0
- LoopStructural/modelling/fault/fault_builder.py +143 -0
- LoopStructural/modelling/fault/fault_function.py +188 -0
- LoopStructural/modelling/fault/fault_function_feature.py +76 -0
- LoopStructural/modelling/fault/fault_segment.py +298 -0
- LoopStructural/modelling/features/__init__.py +8 -0
- LoopStructural/modelling/features/cross_product_geological_feature.py +90 -0
- LoopStructural/modelling/features/geological_feature.py +252 -0
- LoopStructural/modelling/features/geological_feature_builder.py +414 -0
- LoopStructural/modelling/features/lambda_geological_feature.py +36 -0
- LoopStructural/modelling/features/region_feature.py +34 -0
- LoopStructural/modelling/features/structural_frame.py +133 -0
- LoopStructural/modelling/features/structural_frame_builder.py +206 -0
- LoopStructural/modelling/features/unconformity_feature.py +74 -0
- LoopStructural/modelling/fold/__init__.py +8 -0
- LoopStructural/modelling/fold/fold.py +143 -0
- LoopStructural/modelling/fold/fold_rotation_angle.py +133 -0
- LoopStructural/modelling/fold/fold_rotation_angle_feature.py +58 -0
- LoopStructural/modelling/fold/foldframe.py +193 -0
- LoopStructural/modelling/fold/svariogram.py +180 -0
- LoopStructural/utils/__init__.py +18 -0
- LoopStructural/utils/bounding_box.py +21 -0
- LoopStructural/utils/exceptions.py +10 -0
- LoopStructural/utils/helper.py +382 -0
- LoopStructural/utils/logging.py +60 -0
- LoopStructural/utils/map2loop.py +353 -0
- LoopStructural/utils/regions.py +11 -0
- LoopStructural/utils/utils.py +69 -0
- LoopStructural/visualisation/__init__.py +31 -0
- LoopStructural/visualisation/map_viewer.py +322 -0
- LoopStructural/visualisation/model_plotter.py +17 -0
- LoopStructural/visualisation/model_visualisation.py +1113 -0
- LoopStructural/visualisation/rotation_angle_plotter.py +83 -0
- LoopStructural/visualisation/sphinx_scraper.py +34 -0
- LoopStructural/visualisation/stratigraphic_column.py +60 -0
- LoopStructural-1.0.9.dist-info/LICENSE +21 -0
- LoopStructural-1.0.9.dist-info/METADATA +19 -0
- LoopStructural-1.0.9.dist-info/RECORD +77 -0
- LoopStructural-1.0.9.dist-info/WHEEL +5 -0
- LoopStructural-1.0.9.dist-info/top_level.txt +2 -0
- tests/__init__.py +0 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
LoopStructural API
|
|
5
|
+
=======================
|
|
6
|
+
|
|
7
|
+
.. autosummary::
|
|
8
|
+
:toctree:
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
interpolators
|
|
12
|
+
modelling
|
|
13
|
+
visualisation
|
|
14
|
+
utils
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import logging
|
|
19
|
+
from logging.config import dictConfig
|
|
20
|
+
import tempfile
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
#set up logging
|
|
23
|
+
# temp_file = tempfile.mkdtemp()
|
|
24
|
+
# if temp_file:
|
|
25
|
+
# # temp_file = tempfile.tempdir+Path('/default-loop-structural-logfile.log')
|
|
26
|
+
# log_to_file(temp_file)
|
|
27
|
+
ch = logging.StreamHandler()
|
|
28
|
+
formatter = logging.Formatter('%(asctime)s ~ %(name)-12s ~ %(levelname)-10s ~ %(message)s')
|
|
29
|
+
ch.setFormatter(formatter)
|
|
30
|
+
ch.setLevel(logging.WARNING)
|
|
31
|
+
loggers = {}
|
|
32
|
+
__version__ = '1.0.9'
|
|
33
|
+
from .modelling.core.geological_model import GeologicalModel
|
|
34
|
+
from .utils import log_to_console, log_to_file, getLogger
|
|
35
|
+
logger = getLogger(__name__)
|
|
36
|
+
logger.info("Imported LoopStructural")
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from ._plane_fit import PlaneFitFeature
|
|
3
|
+
def displacement_missfit(d,
|
|
4
|
+
fault_slip,
|
|
5
|
+
fault_center,
|
|
6
|
+
fault_influence,
|
|
7
|
+
fault_extent,
|
|
8
|
+
fault_vertical_radius,
|
|
9
|
+
fault_normal,
|
|
10
|
+
fname,
|
|
11
|
+
model,
|
|
12
|
+
fault_params,
|
|
13
|
+
view=None):
|
|
14
|
+
## create the fault in the model
|
|
15
|
+
if view:
|
|
16
|
+
view.clear()
|
|
17
|
+
model.create_and_add_fault(fname,
|
|
18
|
+
d,
|
|
19
|
+
faultfunction='BaseFault',
|
|
20
|
+
fault_slip_vector=fault_slip,
|
|
21
|
+
fault_center=fault_center,
|
|
22
|
+
fault_extent=fault_extent,
|
|
23
|
+
fault_influence=fault_influence,
|
|
24
|
+
fault_vectical_radius=fault_vertical_radius,
|
|
25
|
+
# overprints=overprints,
|
|
26
|
+
**fault_params,
|
|
27
|
+
)
|
|
28
|
+
# run interpolator
|
|
29
|
+
model[fname].builder.update()
|
|
30
|
+
# determine which points are inside the fault volume
|
|
31
|
+
mask = model[fname].inside_volume(model.data[['X','Y','Z']].to_numpy())
|
|
32
|
+
# mask only data associated with the faulted strati
|
|
33
|
+
mask = np.logical_and(mask,model.data['feature_name']=='supergroup_0')
|
|
34
|
+
if view:
|
|
35
|
+
view.add_isosurface(model[fname],value=0)
|
|
36
|
+
data2 = model.data.copy()
|
|
37
|
+
value_data = data2.loc[mask,'val'].to_numpy()
|
|
38
|
+
# gx = model[fname][0].evaluate_value(data2.loc[np.logical_and(~np.isnan(data2['val']),mask),['X','Y','Z']].to_numpy(),inplace=False))
|
|
39
|
+
if view:
|
|
40
|
+
view.add_vector_field(model[fname],
|
|
41
|
+
locations=model.rescale(data2.loc[mask,['X','Y','Z']].to_numpy(),
|
|
42
|
+
inplace=False))
|
|
43
|
+
view.add_value_data(model.rescale(data2.loc[mask,['X','Y','Z']].to_numpy(),inplace=False),
|
|
44
|
+
data2.loc[mask,['val']].to_numpy(),name='pts_before',
|
|
45
|
+
vmin=np.nanmin(value_data),
|
|
46
|
+
vmax=np.nanmax(value_data),cmap='rainbow')
|
|
47
|
+
data2.loc[mask,['X','Y','Z']] = model[fname].apply_to_points(data2.loc[mask,['X','Y','Z']].to_numpy())
|
|
48
|
+
tmp_pts = data2.loc[mask,['X','Y','Z','val','nx','ny','nz']]
|
|
49
|
+
tmp_pts = tmp_pts.loc[~np.isnan(tmp_pts['val']),:]
|
|
50
|
+
fault_plane_feature = PlaneFitFeature(tmp_pts,'Plane_Fit_{}'.format(fname),model=model)
|
|
51
|
+
|
|
52
|
+
dv =data2.loc[np.logical_and(~np.isnan(data2['val']),mask),'val'].to_numpy()
|
|
53
|
+
if view:
|
|
54
|
+
view.add_value_data(data2.loc[np.logical_and(~np.isnan(data2['val']),mask),
|
|
55
|
+
['X','Y','Z']].to_numpy(),
|
|
56
|
+
dv,
|
|
57
|
+
vmin=np.nanmin(value_data),
|
|
58
|
+
vmax=np.nanmax(value_data),
|
|
59
|
+
cmap='rainbow')
|
|
60
|
+
view.add_isosurface(fault_plane_feature,
|
|
61
|
+
values=np.unique(dv),
|
|
62
|
+
paint_with=fault_plane_feature,
|
|
63
|
+
vmin=np.nanmin(value_data),
|
|
64
|
+
vmax=np.nanmax(value_data),
|
|
65
|
+
cmap='rainbow')
|
|
66
|
+
fv = fault_plane_feature.evaluate_value(data2.loc[np.logical_and(~np.isnan(data2['val']),mask),['X','Y','Z']].to_numpy())
|
|
67
|
+
return fv, dv, fault_plane_feature
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from skimage.measure import marching_cubes
|
|
2
|
+
import pandas as pd
|
|
3
|
+
import numpy as np
|
|
4
|
+
def calculate_fault_intersections(model):
|
|
5
|
+
fault_names = []
|
|
6
|
+
for f in model.features:
|
|
7
|
+
if f.type == 'fault':
|
|
8
|
+
fault_names.append(f.name)
|
|
9
|
+
fault_matrix = pd.DataFrame(columns=fault_names)
|
|
10
|
+
for f in fault_names:
|
|
11
|
+
fault_matrix.loc[f,:] = 0
|
|
12
|
+
|
|
13
|
+
for name in fault_names:
|
|
14
|
+
xyz=model.regular_grid(shuffle=False)
|
|
15
|
+
vals = model[name].evaluate_value(xyz)
|
|
16
|
+
model.nsteps = (50,50,25)
|
|
17
|
+
model.step_vector = (model.bounding_box[1,:]-model.bounding_box[0,:])/model.nsteps
|
|
18
|
+
verts, faces, normals, values = marching_cubes(
|
|
19
|
+
vals.reshape(model.nsteps, order='C'),
|
|
20
|
+
0,
|
|
21
|
+
spacing=model.step_vector)
|
|
22
|
+
verts = model.rescale(verts)
|
|
23
|
+
for name2 in fault_names:
|
|
24
|
+
if name2 == name:
|
|
25
|
+
continue
|
|
26
|
+
val = model[name2].evaluate_value(model.scale(verts,inplace=False))
|
|
27
|
+
|
|
28
|
+
if np.all(np.isnan(val)):
|
|
29
|
+
continue
|
|
30
|
+
if np.all(val[~np.isnan(val)] > 0):
|
|
31
|
+
continue#print('all > 0')
|
|
32
|
+
elif np.all(val[~np.isnan(val)] < 0):
|
|
33
|
+
continue
|
|
34
|
+
else:
|
|
35
|
+
fault_matrix.loc[name,name2] = 1
|
|
36
|
+
return fault_matrix
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
def plane_fit(points):
|
|
3
|
+
|
|
4
|
+
soln = []
|
|
5
|
+
# points = points.loc[~np.isnan(points['val']),['X','Y','Z','val']]
|
|
6
|
+
A=np.zeros((len(points)*4,4))
|
|
7
|
+
B=np.zeros((len(points)*4))
|
|
8
|
+
val_mask = ~np.isnan(points['val'])
|
|
9
|
+
vec_mask = ~np.isnan(points['nx'])
|
|
10
|
+
c = 0
|
|
11
|
+
xyz = points.loc[val_mask,['X','Y','Z']].to_numpy()
|
|
12
|
+
A[:len(points[val_mask]),:3] = xyz[:,:3]
|
|
13
|
+
A[:len(points[val_mask]),3]=1.
|
|
14
|
+
B[:len(points[val_mask])] = points.loc[val_mask,'val'].to_numpy()#v#np.zeros(A.shape[0])
|
|
15
|
+
c = len(points[val_mask])
|
|
16
|
+
A[c:len(points[vec_mask])+c,0] = 1
|
|
17
|
+
B[c:len(points[vec_mask])+c] = points.loc[vec_mask,'nx'].to_numpy()
|
|
18
|
+
c+=len(points[vec_mask])
|
|
19
|
+
A[c:len(points[vec_mask])+c,1] = 1
|
|
20
|
+
B[c:len(points[vec_mask])+c] = points.loc[vec_mask,'ny'].to_numpy()
|
|
21
|
+
c+=len(points[vec_mask])
|
|
22
|
+
A[c:len(points[vec_mask])+c,2] = 1
|
|
23
|
+
B[c:len(points[vec_mask])+c] = points.loc[vec_mask,'nz'].to_numpy()
|
|
24
|
+
c+=len(points[vec_mask])
|
|
25
|
+
x = np.linalg.lstsq(A[:c,:],B[:c],rcond=None)[0]
|
|
26
|
+
soln.append(x)
|
|
27
|
+
# print(B)
|
|
28
|
+
return soln
|
|
29
|
+
|
|
30
|
+
class PlaneFitFeature:
|
|
31
|
+
def __init__(self,data,name='Plane',model=None):
|
|
32
|
+
self.soln = np.array(plane_fit(data)).T
|
|
33
|
+
self.name = name
|
|
34
|
+
self.model = model
|
|
35
|
+
def evaluate_value(self,xyz):
|
|
36
|
+
if self.model:
|
|
37
|
+
xyz = self.model.rescale(xyz,inplace=False)
|
|
38
|
+
return xyz[:,0]*self.soln[None,0]+xyz[:,1]*self.soln[None,1]+xyz[:,2]*self.soln[None,2]+self.soln[None,3]
|
|
39
|
+
def min(self):
|
|
40
|
+
|
|
41
|
+
return -np.inf
|
|
42
|
+
def max(self):
|
|
43
|
+
return np.inf
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from ._base import load_claudius
|
|
2
|
+
from ._base import load_grose2017
|
|
3
|
+
from ._base import load_grose2018
|
|
4
|
+
from ._base import load_grose2019
|
|
5
|
+
from ._base import load_laurent2016
|
|
6
|
+
from ._base import load_noddy_single_fold
|
|
7
|
+
from ._base import load_intrusion
|
|
8
|
+
from ._base import normal_vector_headers
|
|
9
|
+
from ._base import strike_dip_headers
|
|
10
|
+
from ._base import value_headers
|
|
11
|
+
from ._base import load_unconformity
|
|
12
|
+
from ._base import load_duplex
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from os.path import dirname, join
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import numpy as np
|
|
4
|
+
import pandas as pd
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def load_claudius():
|
|
8
|
+
module_path = dirname(__file__)
|
|
9
|
+
data = pd.read_csv(join(module_path, Path('data/claudius.csv')))
|
|
10
|
+
bb = np.loadtxt(join(module_path, Path("data/claudiusbb.txt")))
|
|
11
|
+
return data, bb
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def load_noddy_single_fold():
|
|
15
|
+
module_path = dirname(__file__)
|
|
16
|
+
data = pd.read_csv(join(module_path, Path('data/onefolddata.csv')))
|
|
17
|
+
bb = np.loadtxt(join(module_path, Path('data/onefoldbb.txt')))
|
|
18
|
+
return data, bb
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def load_laurent2016():
|
|
22
|
+
module_path = dirname(__file__)
|
|
23
|
+
data = pd.read_csv(join(module_path, Path('data/refolded_fold.csv')))
|
|
24
|
+
bb = np.loadtxt(join(module_path, Path('data/refolded_bb.txt')))
|
|
25
|
+
return data, bb
|
|
26
|
+
|
|
27
|
+
def load_duplex():
|
|
28
|
+
module_path = dirname(__file__)
|
|
29
|
+
data = pd.read_csv(join(module_path, Path('data/duplex.csv')))
|
|
30
|
+
bb = np.loadtxt(join(module_path, Path('data/duplexbb.txt')))
|
|
31
|
+
return data, bb
|
|
32
|
+
|
|
33
|
+
def load_grose2017():
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def load_grose2018():
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def load_grose2019():
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def load_intrusion():
|
|
46
|
+
module_path = dirname(__file__)
|
|
47
|
+
data = pd.read_csv(join(module_path,Path('data/intrusion.csv')))
|
|
48
|
+
bb = np.loadtxt(join(module_path,Path('data/intrusionbb.txt')))
|
|
49
|
+
return data, bb
|
|
50
|
+
def load_unconformity():
|
|
51
|
+
module_path = dirname(__file__)
|
|
52
|
+
data = pd.read_csv(join(module_path,Path('data/unconformity.csv')))
|
|
53
|
+
bb = np.array([[0,0,0],
|
|
54
|
+
[4,6,4]]
|
|
55
|
+
)
|
|
56
|
+
return data,bb
|
|
57
|
+
def value_headers():
|
|
58
|
+
return ['X','Y','Z','val']
|
|
59
|
+
|
|
60
|
+
def strike_dip_headers():
|
|
61
|
+
return ['X','Y','Z','strike','dip']
|
|
62
|
+
|
|
63
|
+
def normal_vector_headers():
|
|
64
|
+
return ['X','Y','Z','nx','ny','nz']
|
|
65
|
+
|