LoopStructural 1.0.9__cp36-cp36m-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.
Files changed (77) hide show
  1. LoopStructural/__init__.py +36 -0
  2. LoopStructural/analysis/__init__.py +2 -0
  3. LoopStructural/analysis/_fault_displacement.py +67 -0
  4. LoopStructural/analysis/_fault_intersection.py +36 -0
  5. LoopStructural/analysis/_plane_fit.py +43 -0
  6. LoopStructural/datasets/__init__.py +12 -0
  7. LoopStructural/datasets/_base.py +65 -0
  8. LoopStructural/datasets/data/claudius.csv +21049 -0
  9. LoopStructural/datasets/data/claudiusbb.txt +2 -0
  10. LoopStructural/datasets/data/duplex.csv +126 -0
  11. LoopStructural/datasets/data/duplexbb.txt +2 -0
  12. LoopStructural/datasets/data/intrusion.csv +1017 -0
  13. LoopStructural/datasets/data/intrusionbb.txt +2 -0
  14. LoopStructural/datasets/data/onefoldbb.txt +2 -0
  15. LoopStructural/datasets/data/onefolddata.csv +2226 -0
  16. LoopStructural/datasets/data/refolded_bb.txt +2 -0
  17. LoopStructural/datasets/data/refolded_fold.csv +2126 -0
  18. LoopStructural/interpolators/__init__.py +34 -0
  19. LoopStructural/interpolators/base_structured_3d_support.py +101 -0
  20. LoopStructural/interpolators/cython/__init__.py +0 -0
  21. LoopStructural/interpolators/cython/dsi_helper.c +31046 -0
  22. LoopStructural/interpolators/cython/dsi_helper.cp36-win32.pyd +0 -0
  23. LoopStructural/interpolators/discrete_fold_interpolator.py +202 -0
  24. LoopStructural/interpolators/discrete_interpolator.py +584 -0
  25. LoopStructural/interpolators/finite_difference_interpolator.py +399 -0
  26. LoopStructural/interpolators/geological_interpolator.py +197 -0
  27. LoopStructural/interpolators/operator.py +61 -0
  28. LoopStructural/interpolators/piecewiselinear_interpolator.py +437 -0
  29. LoopStructural/interpolators/structured_grid.py +421 -0
  30. LoopStructural/interpolators/structured_tetra.py +681 -0
  31. LoopStructural/interpolators/surfe_wrapper.py +118 -0
  32. LoopStructural/modelling/__init__.py +46 -0
  33. LoopStructural/modelling/core/__init__.py +0 -0
  34. LoopStructural/modelling/core/geological_model.py +1513 -0
  35. LoopStructural/modelling/core/geological_model_graph.py +880 -0
  36. LoopStructural/modelling/core/stratigraphic_column.py +5 -0
  37. LoopStructural/modelling/fault/__init__.py +4 -0
  38. LoopStructural/modelling/fault/fault_builder.py +143 -0
  39. LoopStructural/modelling/fault/fault_function.py +188 -0
  40. LoopStructural/modelling/fault/fault_function_feature.py +76 -0
  41. LoopStructural/modelling/fault/fault_segment.py +298 -0
  42. LoopStructural/modelling/features/__init__.py +8 -0
  43. LoopStructural/modelling/features/cross_product_geological_feature.py +90 -0
  44. LoopStructural/modelling/features/geological_feature.py +252 -0
  45. LoopStructural/modelling/features/geological_feature_builder.py +414 -0
  46. LoopStructural/modelling/features/lambda_geological_feature.py +36 -0
  47. LoopStructural/modelling/features/region_feature.py +34 -0
  48. LoopStructural/modelling/features/structural_frame.py +133 -0
  49. LoopStructural/modelling/features/structural_frame_builder.py +206 -0
  50. LoopStructural/modelling/features/unconformity_feature.py +74 -0
  51. LoopStructural/modelling/fold/__init__.py +8 -0
  52. LoopStructural/modelling/fold/fold.py +143 -0
  53. LoopStructural/modelling/fold/fold_rotation_angle.py +133 -0
  54. LoopStructural/modelling/fold/fold_rotation_angle_feature.py +58 -0
  55. LoopStructural/modelling/fold/foldframe.py +193 -0
  56. LoopStructural/modelling/fold/svariogram.py +180 -0
  57. LoopStructural/utils/__init__.py +18 -0
  58. LoopStructural/utils/bounding_box.py +21 -0
  59. LoopStructural/utils/exceptions.py +10 -0
  60. LoopStructural/utils/helper.py +382 -0
  61. LoopStructural/utils/logging.py +60 -0
  62. LoopStructural/utils/map2loop.py +353 -0
  63. LoopStructural/utils/regions.py +11 -0
  64. LoopStructural/utils/utils.py +69 -0
  65. LoopStructural/visualisation/__init__.py +31 -0
  66. LoopStructural/visualisation/map_viewer.py +322 -0
  67. LoopStructural/visualisation/model_plotter.py +17 -0
  68. LoopStructural/visualisation/model_visualisation.py +1113 -0
  69. LoopStructural/visualisation/rotation_angle_plotter.py +83 -0
  70. LoopStructural/visualisation/sphinx_scraper.py +34 -0
  71. LoopStructural/visualisation/stratigraphic_column.py +60 -0
  72. LoopStructural-1.0.9.dist-info/LICENSE +21 -0
  73. LoopStructural-1.0.9.dist-info/METADATA +19 -0
  74. LoopStructural-1.0.9.dist-info/RECORD +77 -0
  75. LoopStructural-1.0.9.dist-info/WHEEL +5 -0
  76. LoopStructural-1.0.9.dist-info/top_level.txt +2 -0
  77. 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,2 @@
1
+ from ._fault_displacement import displacement_missfit
2
+ from ._fault_intersection import calculate_fault_intersections
@@ -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
+