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.
Files changed (119) hide show
  1. Miniconda/envs/loop/Lib/site-packages/LoopStructural/__init__.py +12 -7
  2. Miniconda/envs/loop/Lib/site-packages/LoopStructural/__pycache__/__init__.cpython-36.pyc +0 -0
  3. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__pycache__/__init__.cpython-36.pyc +0 -0
  4. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__pycache__/_base.cpython-36.pyc +0 -0
  5. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__init__.py +3 -0
  6. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/__init__.cpython-36.pyc +0 -0
  7. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/base_structured_3d_support.cpython-36.pyc +0 -0
  8. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/discrete_fold_interpolator.cpython-36.pyc +0 -0
  9. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/discrete_interpolator.cpython-36.pyc +0 -0
  10. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/finite_difference_interpolator.cpython-36.pyc +0 -0
  11. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/geological_interpolator.cpython-36.pyc +0 -0
  12. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/operator.cpython-36.pyc +0 -0
  13. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/piecewiselinear_interpolator.cpython-36.pyc +0 -0
  14. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/structured_grid.cpython-36.pyc +0 -0
  15. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/structured_tetra.cpython-36.pyc +0 -0
  16. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/surfe_wrapper.cpython-36.pyc +0 -0
  17. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/base_structured_3d_support.py +101 -0
  18. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/__pycache__/__init__.cpython-36.pyc +0 -0
  19. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/dsi_helper.c +4137 -2716
  20. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/dsi_helper.cp36-win_amd64.pyd +0 -0
  21. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/discrete_fold_interpolator.py +56 -22
  22. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/discrete_interpolator.py +61 -28
  23. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/finite_difference_interpolator.py +71 -11
  24. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/geological_interpolator.py +22 -3
  25. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/operator.py +16 -1
  26. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/piecewiselinear_interpolator.py +150 -11
  27. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_grid.py +31 -69
  28. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_tetra.py +89 -45
  29. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/surfe_wrapper.py +7 -8
  30. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/__pycache__/__init__.cpython-36.pyc +0 -0
  31. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/__init__.cpython-36.pyc +0 -0
  32. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/geological_model.cpython-36.pyc +0 -0
  33. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/geological_model_graph.cpython-36.pyc +0 -0
  34. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/stratigraphic_column.cpython-36.pyc +0 -0
  35. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/geological_model.py +515 -197
  36. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/geological_model_graph.py +881 -0
  37. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/stratigraphic_column.py +5 -0
  38. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__init__.py +1 -0
  39. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/__init__.cpython-36.pyc +0 -0
  40. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_builder.cpython-36.pyc +0 -0
  41. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_function.cpython-36.pyc +0 -0
  42. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_function_feature.cpython-36.pyc +0 -0
  43. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_segment.cpython-36.pyc +0 -0
  44. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_builder.py +127 -0
  45. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_function.py +2 -1
  46. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_function_feature.py +2 -1
  47. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_segment.py +30 -3
  48. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__init__.py +1 -0
  49. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/__init__.cpython-36.pyc +0 -0
  50. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/cross_product_geological_feature.cpython-36.pyc +0 -0
  51. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/geological_feature.cpython-36.pyc +0 -0
  52. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/geological_feature_builder.cpython-36.pyc +0 -0
  53. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/lambda_geological_feature.cpython-36.pyc +0 -0
  54. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/region_feature.cpython-36.pyc +0 -0
  55. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/structural_frame.cpython-36.pyc +0 -0
  56. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/structural_frame_builder.cpython-36.pyc +0 -0
  57. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/unconformity_feature.cpython-36.pyc +0 -0
  58. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/cross_product_geological_feature.py +18 -5
  59. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/geological_feature.py +22 -49
  60. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/geological_feature_builder.py +171 -47
  61. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/lambda_geological_feature.py +31 -0
  62. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/region_feature.py +3 -0
  63. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/structural_frame.py +28 -11
  64. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/structural_frame_builder.py +32 -22
  65. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/unconformity_feature.py +6 -1
  66. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/__init__.cpython-36.pyc +0 -0
  67. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold.cpython-36.pyc +0 -0
  68. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold_rotation_angle.cpython-36.pyc +0 -0
  69. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold_rotation_angle_feature.cpython-36.pyc +0 -0
  70. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/foldframe.cpython-36.pyc +0 -0
  71. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/svariogram.cpython-36.pyc +0 -0
  72. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold.py +13 -5
  73. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold_rotation_angle.py +5 -4
  74. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold_rotation_angle_feature.py +2 -1
  75. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/foldframe.py +7 -5
  76. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/svariogram.py +2 -1
  77. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__init__.py +5 -1
  78. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/__init__.cpython-36.pyc +0 -0
  79. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/bounding_box.cpython-36.pyc +0 -0
  80. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/exceptions.cpython-36.pyc +0 -0
  81. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/helper.cpython-36.pyc +0 -0
  82. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/logging.cpython-36.pyc +0 -0
  83. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/map2loop.cpython-36.pyc +0 -0
  84. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/regions.cpython-36.pyc +0 -0
  85. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/utils.cpython-36.pyc +0 -0
  86. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/bounding_box.py +21 -0
  87. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/exceptions.py +2 -1
  88. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/helper.py +10 -2
  89. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/logging.py +60 -0
  90. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/map2loop.py +128 -37
  91. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/regions.py +11 -0
  92. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/utils.py +40 -47
  93. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/__init__.cpython-36.pyc +0 -0
  94. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/map_viewer.cpython-36.pyc +0 -0
  95. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/model_plotter.cpython-36.pyc +0 -0
  96. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/model_visualisation.cpython-36.pyc +0 -0
  97. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/rotation_angle_plotter.cpython-36.pyc +0 -0
  98. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/sphinx_scraper.cpython-36.pyc +0 -0
  99. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/stratigraphic_column.cpython-36.pyc +0 -0
  100. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/map_viewer.py +236 -36
  101. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/model_plotter.py +2 -1
  102. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/model_visualisation.py +427 -79
  103. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/rotation_angle_plotter.py +29 -12
  104. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/stratigraphic_column.py +60 -0
  105. 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
  106. 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
  107. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.71.dev0-py3.6.egg-info/requires.txt +8 -0
  108. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/__init__.cpython-36.pyc +0 -0
  109. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.3-py3.6.egg-info/requires.txt +0 -3
  110. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_faults.cpython-36.pyc +0 -0
  111. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_fold.cpython-36.pyc +0 -0
  112. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_interpolator.cpython-36.pyc +0 -0
  113. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_refolded.cpython-36.pyc +0 -0
  114. Miniconda/envs/loop/Lib/site-packages/tests/test_faults.py +0 -17
  115. Miniconda/envs/loop/Lib/site-packages/tests/test_fold.py +0 -57
  116. Miniconda/envs/loop/Lib/site-packages/tests/test_interpolator.py +0 -88
  117. Miniconda/envs/loop/Lib/site-packages/tests/test_refolded.py +0 -22
  118. /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
  119. /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
@@ -7,13 +7,15 @@ import logging
7
7
  import numpy as np
8
8
  import pandas as pd
9
9
 
10
- logger = logging.getLogger(__name__)
10
+ from LoopStructural.utils import getLogger
11
+ logger = getLogger(__name__)
11
12
 
12
13
  from LoopStructural.utils.helper import xyz_names, val_name, normal_vec_names, \
13
- weight_name, gradient_vec_names, tangent_vec_names
14
+ weight_name, gradient_vec_names, tangent_vec_names, interface_name
14
15
  from LoopStructural.modelling.features import GeologicalFeature
15
16
  from LoopStructural.utils.helper import get_data_bounding_box_map as get_data_bounding_box
16
-
17
+ from LoopStructural.utils import get_data_axis_aligned_bounding_box
18
+ from LoopStructural.utils import RegionEverywhere
17
19
 
18
20
  class GeologicalFeatureInterpolator:
19
21
  """[summary]
@@ -22,22 +24,22 @@ class GeologicalFeatureInterpolator:
22
24
  """
23
25
  def __init__(self, interpolator, name='Feature', region=None, **kwargs):
24
26
  """
25
- A builder for a GeologicalFeature will link data to the interpolator
26
- and run the interpolation
27
+ Constructor for a GeologicalFeatureInterpolator
27
28
 
28
29
  Parameters
29
30
  ----------
30
- interpolator - a GeologicalInterpolator
31
+ interpolator : GeologicalInterpolator
32
+ An empty GeologicalInterpolator
31
33
  region : lambda function
32
34
  defining whether the location (xyz) should be included in the
33
35
  kwargs - name of the feature, region to interpolate the feature
34
36
  """
35
- self.interpolator = interpolator
36
- self.name = name
37
- self.interpolator.set_property_name(self.name)
37
+ self._interpolator = interpolator
38
+ self._name = name
39
+ self._interpolator.set_property_name(self._name)
38
40
  # everywhere region is just a lambda that returns true for all locations
39
41
  if region is None:
40
- self.region = lambda pos: np.ones(pos.shape[0], dtype=bool)
42
+ self.region = RegionEverywhere()
41
43
  else:
42
44
  self.region = region
43
45
  header = xyz_names()+val_name()+gradient_vec_names()+\
@@ -45,33 +47,75 @@ class GeologicalFeatureInterpolator:
45
47
  self.data = pd.DataFrame(columns=header)
46
48
  self.faults = []
47
49
  self.data_added = False
48
- self.interpolator.set_region(region=self.region)
50
+ self._interpolator.set_region(region=self.region)
51
+ self._feature = None
52
+ self._up_to_date = False
53
+ self._build_arguments = {}
54
+ self.fold = None
55
+ self._feature = GeologicalFeature(self._name,
56
+ self._interpolator,
57
+ builder=self,
58
+ region=self.region,
59
+ faults=self.faults,
60
+ fold = self.fold
61
+ )
62
+ self._orthogonal_features = {}
63
+ @property
64
+ def feature(self):
65
+ return self._feature
66
+
67
+ @property
68
+ def build_arguments(self):
69
+ return self._build_arguments
70
+
71
+ @build_arguments.setter
72
+ def build_arguments(self, build_arguments):
73
+ # self._build_arguments = {}
74
+ for k, i in build_arguments.items():
75
+ self._build_arguments[k] = i
49
76
 
50
77
  def update(self):
51
- pass
52
-
78
+ self.build(**self.build_arguments)
79
+ @property
80
+ def name(self):
81
+ return self._name
82
+ @property
83
+ def interpolator(self):
84
+ return self._interpolator
85
+
86
+ def up_to_date(self):
87
+ #has anything changed in the builder since we built the feature? if so update
88
+ if self._up_to_date == False:
89
+ self.update()
90
+ #check if the interpolator is up to date, if not solve
91
+ if self._interpolator.up_to_date == False:
92
+ self.update()
93
+
94
+
53
95
  def add_fault(self, fault):
54
96
  """
55
97
  Add a fault to the geological feature builder
56
98
 
57
99
  Parameters
58
100
  ----------
59
- fault FaultSegment
101
+ fault : FaultSegment
60
102
  A faultsegment to add to the geological feature
61
103
 
62
104
  Returns
63
105
  -------
64
106
 
65
107
  """
108
+ self._up_to_date = False
66
109
  self.faults.append(fault)
67
110
 
68
- def add_data_from_data_frame(self, data_frame):
111
+ def add_data_from_data_frame(self, data_frame, overwrite = False):
69
112
  """
70
113
  Extract data from a pandas dataframe with columns for
71
114
 
72
115
  Parameters
73
116
  ----------
74
- data_frame - pandas data frame
117
+ data_frame : pd.DataFrame
118
+ a dataframe containing the data to be added
75
119
 
76
120
  Returns
77
121
  -------
@@ -79,18 +123,43 @@ class GeologicalFeatureInterpolator:
79
123
  """
80
124
  self.data = data_frame.copy()
81
125
 
82
- def add_orthogonal_feature(self, feature, w=1., region=None):
83
- self.interpolator.add_gradient_orthogonal_constraint(
84
- self.interpolator.support.barycentre(),
85
- feature.evaluate_gradient(self.interpolator.support.barycentre()),
86
- w=w
87
- )
126
+ def add_orthogonal_feature(self, feature, w=1., region=None,step=1,B=0):
127
+ """
128
+ Add a constraint to the interpolator so that the gradient of an exisitng feature is orthogonal
129
+ to the feature being built. E.g. dot product between gradients should be = 0
88
130
 
131
+ Parameters
132
+ ----------
133
+ feature : GeologicalFeature
134
+ feature which we want to be orthogonal to
135
+ w : double
136
+ how much to weight in least squares sense
137
+ region : unused
138
+ step : int
139
+ numpy slicing step size to see how many tetras to add
140
+
141
+ Returns
142
+ -------
143
+
144
+ Notes
145
+ -----
146
+ The constraint can be applied to a random subset of the tetrahedral elements in the mesh
147
+ in theory this shu
148
+ """
149
+ self._orthogonal_features[feature.name] = [feature,w,region,step,B]
150
+ self._up_to_date = False
151
+
152
+
89
153
  def add_data_to_interpolator(self, constrained=False, force_constrained=False, **kwargs):
90
154
  """
91
155
  Iterates through the list of data and applies any faults active on the
92
156
  data in the order they are added
93
157
 
158
+ Parameters
159
+ -----------
160
+ constrained : boolean
161
+ force_constrained : boolean
162
+
94
163
  Returns
95
164
  -------
96
165
 
@@ -139,38 +208,62 @@ class GeologicalFeatureInterpolator:
139
208
  logger.error("Not enough constraints for scalar field add more")
140
209
  # self.interpolator.reset()
141
210
  mask = ~np.isnan(data.loc[:,val_name()].to_numpy())
142
-
211
+ # add value constraints
143
212
  if mask.shape[0]>0:
144
213
  value_data = data.loc[mask[:,0],xyz_names()+val_name()+weight_name()].to_numpy()
145
214
  self.interpolator.set_value_constraints(value_data)
146
215
 
216
+ # add gradient constraints
147
217
  mask = np.all(~np.isnan(data.loc[:, gradient_vec_names()].to_numpy()), axis=1)
148
218
  if mask.shape[0]>0:
149
219
  gradient_data = data.loc[
150
220
  mask, xyz_names() + gradient_vec_names() + weight_name()].to_numpy()
151
221
  self.interpolator.set_gradient_constraints(gradient_data)
152
222
 
223
+ # add normal vector data
153
224
  mask = np.all(~np.isnan(data.loc[:, normal_vec_names()].to_numpy()), axis=1)
154
225
  if mask.shape[0]>0:
155
226
  normal_data = data.loc[
156
227
  mask, xyz_names() + normal_vec_names() + weight_name()].to_numpy()
157
228
  self.interpolator.set_normal_constraints(normal_data)
158
229
 
230
+ # add tangent data
159
231
  mask = np.all(~np.isnan(data.loc[:, tangent_vec_names()].to_numpy()), axis=1)
160
232
  if mask.shape[0]>0:
161
233
  tangent_data = data.loc[
162
234
  mask, xyz_names() + tangent_vec_names() + weight_name()].to_numpy()
163
235
  self.interpolator.set_tangent_constraints(tangent_data)
164
236
 
165
- self.data_added = True
237
+ # add interface constraints
238
+ mask = np.all(~np.isnan(data.loc[:, interface_name()].to_numpy()), axis=1)
239
+ if mask.shape[0] > 0:
240
+ interface_data = data.loc[
241
+ mask, xyz_names() + interface_name() + weight_name()].to_numpy()
242
+ self.interpolator.set_interface_constraints(interface_data)
166
243
 
244
+ self.data_added = True
245
+ self._up_to_date = False
246
+
247
+ def install_gradient_constraint(self):
248
+ for g in self._orthogonal_features.values():
249
+ feature,w,region,step,B = g
250
+ vector = feature.evaluate_gradient(self.interpolator.support.barycentre())
251
+ vector /= np.linalg.norm(vector,axis=1)[:,None]
252
+ element_idx = np.arange(self.interpolator.support.n_elements)
253
+ np.random.shuffle(element_idx)
254
+ self.interpolator.add_gradient_orthogonal_constraint(
255
+ self.interpolator.support.barycentre()[element_idx[::step],:],
256
+ vector[element_idx[::step],:],
257
+ w=w,
258
+ B=B
259
+ )
167
260
  def get_value_constraints(self):
168
261
  """
169
262
  Get the value constraints for this geological feature
170
263
 
171
264
  Returns
172
265
  -------
173
- numpy array
266
+ np.array((N,4),dtype=double)
174
267
  """
175
268
  header = xyz_names()+val_name()+weight_name()
176
269
  mask = ~np.isnan(self.data.loc[:,val_name()].to_numpy())
@@ -192,7 +285,7 @@ class GeologicalFeatureInterpolator:
192
285
  mask, xyz_names() + gradient_vec_names() + weight_name(
193
286
  )].to_numpy()
194
287
  else:
195
- return np.zeros(0, 7)
288
+ return np.zeros((0, 7))
196
289
 
197
290
  def get_tangent_constraints(self):
198
291
  """
@@ -209,7 +302,7 @@ class GeologicalFeatureInterpolator:
209
302
  mask, xyz_names() + tangent_vec_names() + weight_name(
210
303
  )].to_numpy()
211
304
  else:
212
- return np.zeros(0, 7)
305
+ return np.zeros((0, 7))
213
306
 
214
307
  def get_norm_constraints(self):
215
308
  """
@@ -227,8 +320,15 @@ class GeologicalFeatureInterpolator:
227
320
 
228
321
  )].to_numpy()
229
322
  else:
230
- return np.zeros(0,7)
323
+ return np.zeros((0,7))
231
324
 
325
+ def get_interface_constraints(self):
326
+ mask = np.all(~np.isnan(self.data.loc[:, interface_name()].to_numpy()), axis=1)
327
+ if mask.shape[0] > 0:
328
+ return self.data.loc[
329
+ mask, xyz_names() + interface_name() + weight_name()].to_numpy()
330
+ else:
331
+ return np.zeros((0,5))
232
332
 
233
333
  def get_data_locations(self):
234
334
  """
@@ -239,8 +339,25 @@ class GeologicalFeatureInterpolator:
239
339
 
240
340
  """
241
341
  return self.data.loc[:, xyz_names()].to_numpy()
342
+ def set_interpolation_geometry(self,origin,maximum):
343
+ """Update the interpolation support geometry to new bounding box
242
344
 
243
- def build(self, fold=None, fold_weights=None, data_region=None, **kwargs):
345
+ Parameters
346
+ ----------
347
+ origin : np.array(3)
348
+ origin vector
349
+ maximum : np.array(3)
350
+ maximum vector
351
+ """
352
+ logger.info("Setting mesh origin: {} {} {} ".format(origin[0],origin[1],origin[2]))
353
+ logger.info("Setting mesh maximum: {} {} {}".format(maximum[0],maximum[1],maximum[2]))
354
+ self.interpolator.support.origin = origin
355
+ self.interpolator.support.maximum = maximum
356
+
357
+
358
+ self._up_to_date = False
359
+
360
+ def build(self, fold=None, fold_weights={}, data_region=None, **kwargs):
244
361
  """
245
362
  Runs the interpolation and builds the geological feature
246
363
 
@@ -258,32 +375,39 @@ class GeologicalFeatureInterpolator:
258
375
 
259
376
  """
260
377
 
378
+
379
+ self.add_data_to_interpolator(**kwargs)
261
380
  if data_region is not None:
262
- xyz = self.get_data_locations()
263
- bb, region = get_data_bounding_box(xyz, data_region)
381
+ xyz = self.interpolator.get_data_locations()
382
+ bb, region = get_data_bounding_box(xyz, data_region)
383
+ # if self.model.reuse_supports == False:
384
+ if np.any(np.min(bb[0,:])< self.interpolator.support.origin):
385
+ neworigin = np.min([self.interpolator.support.origin,bb[0,:]],axis=0)
386
+ logger.info("Changing origin of support for {} from {} {} {} to {} {} {}"\
387
+ .format(self.name,self.interpolator.support.origin[0],\
388
+ self.interpolator.support.origin[1],self.interpolator.support.origin[2],\
389
+ neworigin[0],neworigin[1],neworigin[2]))
390
+ self.interpolator.support.origin = neworigin
391
+ if np.any(np.max(bb[0,:])< self.interpolator.support.maximum):
392
+ newmax = np.max([self.interpolator.support.maximum,bb[0,:]],axis=0)
393
+ logger.info("Changing origin of support for {} from {} {} {} to {} {} {}"\
394
+ .format(self.name,self.interpolator.support.maximum[0],
395
+ self.interpolator.support.maximum[1],self.interpolator.support.maximum[2],\
396
+ newmax[0],newmax[1],newmax[2]))
397
+
398
+ self.interpolator.support.maximum = newmax
264
399
  self.interpolator.set_region(region=region)
265
- if not self.data_added:
266
- self.add_data_to_interpolator(**kwargs)
267
-
268
400
  # moving this to init because it needs to be done before constraints
269
401
  # are added?
270
402
  if fold is not None:
271
403
  logger.info("Adding fold to %s" % self.name)
272
404
  self.interpolator.fold = fold
273
405
  # if we have fold weights use those, otherwise just use default
274
- if fold_weights is None:
275
- self.interpolator.add_fold_constraints()
276
- else:
277
- self.interpolator.add_fold_constraints(fold_weights)
406
+ self.interpolator.add_fold_constraints(**fold_weights)
278
407
  if 'cgw' not in kwargs:
279
- kwargs['cgw'] = 0.
280
-
408
+ # try adding very small cg
409
+ kwargs['cgw'] = 0.0
281
410
  self.interpolator.setup_interpolator(**kwargs)
282
411
  self.interpolator.solve_system(**kwargs)
283
- return GeologicalFeature(self.name,
284
- self.interpolator,
285
- builder=self, data=self.data,
286
- region=self.region,
287
- faults=self.faults,
288
- fold = fold
289
- )
412
+ self._up_to_date = True
413
+ return self._feature
@@ -0,0 +1,31 @@
1
+ """
2
+ Geological features
3
+ """
4
+ import logging
5
+
6
+ import numpy as np
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ class LambdaGeologicalFeature:
12
+ def __init__(self,function = None,name = 'unnamed_lambda', gradient_function = None):
13
+ self.function = function
14
+ self.name = name
15
+ self.gradient_function = gradient_function
16
+ def evaluate_value(self, xyz):
17
+ v = np.zeros((xyz.shape[0]))
18
+ if self.function is None:
19
+ v[:] = np.nan
20
+ else:
21
+ v[:] = self.function(xyz)
22
+ return v
23
+ def evaluate_gradient(self,xyz):
24
+ v = np.zeros((xyz.shape[0],3))
25
+ if self.gradient_function is None:
26
+ v[:,:] = np.nan
27
+ else:
28
+ v[:,:] = self.gradient_function(xyz)
29
+ return v
30
+
31
+
@@ -29,3 +29,6 @@ class RegionFeature:
29
29
 
30
30
  def name(self):
31
31
  return self.name
32
+
33
+ # class VectorFeature:
34
+ # def __init__(self, function)
@@ -2,8 +2,9 @@
2
2
  Structural frames
3
3
  """
4
4
  import logging
5
-
6
- logger = logging.getLogger(__name__)
5
+ import numpy as np
6
+ from LoopStructural.utils import getLogger
7
+ logger = getLogger(__name__)
7
8
 
8
9
 
9
10
  class StructuralFrame:
@@ -14,8 +15,7 @@ class StructuralFrame:
14
15
  def __init__(self, name, features, fold=None):
15
16
  """
16
17
  Structural frame is a curvilinear coordinate system defined by
17
- structural
18
- observations associated with a fault or fold.
18
+ structural observations associated with a fault or fold.
19
19
 
20
20
  Parameters
21
21
  ----------
@@ -26,6 +26,7 @@ class StructuralFrame:
26
26
  self.features = features
27
27
  self.data = None
28
28
  self.fold = fold
29
+
29
30
  def __getitem__(self, item):
30
31
  """
31
32
 
@@ -39,6 +40,21 @@ class StructuralFrame:
39
40
  """
40
41
  return self.features[item]
41
42
 
43
+ def set_model(self, model):
44
+ """Link the model that created the frame to the frame
45
+ and the features that make up the frame
46
+
47
+ Parameters
48
+ ----------
49
+ model : GeologicalModel
50
+ the geological model that created the fold frame
51
+ """
52
+ self.model = model
53
+ for f in self.features:
54
+ if f is None:
55
+ continue
56
+ f.set_model(model)
57
+
42
58
  def add_region(self, region):
43
59
  for i in range(3):
44
60
  self.features[i].add_region(region)
@@ -71,7 +87,7 @@ class StructuralFrame:
71
87
  """
72
88
  self.data = data
73
89
 
74
- def evaluate_value(self, evaluation_points, i=None):
90
+ def evaluate_value(self, evaluation_points):
75
91
  """
76
92
  Evaluate the value of the structural frame for the points.
77
93
  Can optionally only evaluate one coordinate
@@ -85,12 +101,13 @@ class StructuralFrame:
85
101
  -------
86
102
 
87
103
  """
88
- if i is not None:
89
- self.features[i].support.evaluate_value(evaluation_points)
90
- return (self.features[0].support.evaluate_value(evaluation_points),
91
- self.features[1].support.evaluate_value(evaluation_points),
92
- self.features[2].support.evaluate_value(evaluation_points))
93
-
104
+ v = np.zeros(evaluation_points.shape) #create new 3d array of correct length
105
+ v[:] = np.nan
106
+ v[:,0] = self.features[0].evaluate_value(evaluation_points)
107
+ v[:,1] = self.features[1].evaluate_value(evaluation_points)
108
+ v[:,2] = self.features[2].evaluate_value(evaluation_points)
109
+ return v
110
+
94
111
  def evaluate_gradient(self, evaluation_points, i=None):
95
112
  """
96
113
  Evaluate the gradient of the structural frame.
@@ -6,7 +6,8 @@ import logging
6
6
 
7
7
  import numpy as np
8
8
 
9
- logger = logging.getLogger(__name__)
9
+ from LoopStructural.utils import getLogger
10
+ logger = getLogger(__name__)
10
11
 
11
12
  from LoopStructural.modelling.features.cross_product_geological_feature \
12
13
  import \
@@ -46,14 +47,14 @@ class StructuralFrameBuilder:
46
47
  # list of interpolators
47
48
  # self.interpolators = []
48
49
  # Create the interpolation objects by copying the template
49
-
50
50
  if interpolators is None:
51
- interpolators = []
52
- interpolators.append(interpolator)
53
- interpolators.append(interpolator.copy())
54
- interpolators.append(interpolator.copy())
55
- if interpolators is None and interpolator is None:
56
- raise BaseException
51
+ if interpolator is not None:
52
+ interpolators = []
53
+ interpolators.append(interpolator)
54
+ interpolators.append(interpolator.copy())
55
+ interpolators.append(interpolator.copy())
56
+ else:
57
+ raise BaseException("Missing interpolator")
57
58
  # self.builders
58
59
  self.builders.append(
59
60
  GeologicalFeatureInterpolator(interpolators[0],
@@ -106,12 +107,14 @@ class StructuralFrameBuilder:
106
107
  gxxgy = 1
107
108
  gxxgz = 1
108
109
  gyxgz = 1
110
+ step = kwargs.get('step', 10)
109
111
  if 'gxxgy' in kwargs:
110
112
  gxxgy = kwargs['gxxgy']
111
113
  if 'gxxgz' in kwargs:
112
114
  gxxgz = kwargs['gxxgz']
113
115
  if 'gyxgz' in kwargs:
114
116
  gyxgz = kwargs['gyxgz']
117
+
115
118
  # set regularisation so the the main surface (foliation, fault) is smooth
116
119
  # and the fields are allowed to vary more
117
120
  regularisation = kwargs.pop('regularisation', [1., 1., 1.])
@@ -122,19 +125,21 @@ class StructuralFrameBuilder:
122
125
  fold = None
123
126
  if len(self.builders[0].data) > 0:
124
127
  logger.info("Building %s coordinate 0"%self.name)
125
- gx_feature = self.builders[0].build(regularisation=regularisation[
126
- 0], **kwargs)
128
+ gx_feature = self.builders[0].feature
129
+ kwargs['regularisation']=regularisation[0]
130
+ self.builders[0].build_arguments = kwargs
131
+
127
132
  # remove fold from kwargs
128
133
 
129
- fold = kwargs.pop('fold', False)
134
+ fold = kwargs.pop('fold', None)
130
135
  if gx_feature is None:
131
136
  logger.warning(
132
137
  "Not enough constraints for structural frame coordinate 0, \n"
133
138
  "Add some more and try again.")
134
139
  # make sure that all of the coordinates are using the same region
135
- if gx_feature.get_interpolator().region_function is not None:
136
- self.builders[1].interpolator.set_region(gx_feature.get_interpolator().region_function)
137
- self.builders[2].interpolator.set_region(gx_feature.get_interpolator().region_function)
140
+ if gx_feature is not None and gx_feature.interpolator.region_function is not None:
141
+ self.builders[1].interpolator.set_region(gx_feature.interpolator.region_function)
142
+ self.builders[2].interpolator.set_region(gx_feature.interpolator.region_function)
138
143
  if 'data_region' in kwargs:
139
144
  kwargs.pop('data_region')
140
145
  if 'region' in kwargs:
@@ -147,17 +152,22 @@ class StructuralFrameBuilder:
147
152
  # np.arange(0, self.support.n_elements),
148
153
  # gy_feature.evaluate_gradient(self.support.barycentre),
149
154
  # w=gyxgz)
150
- if gx_feature is not None:
151
- self.builders[2].add_orthogonal_feature(gx_feature, gxxgz)
152
- gz_feature = self.builders[2].build(regularisation=regularisation[2], **kwargs)
155
+ if gx_feature is not None and gxxgz>0:
156
+ self.builders[2].add_orthogonal_feature(gx_feature, gxxgz,step=step)
157
+ gz_feature = self.builders[2].feature
158
+ kwargs['regularisation'] = regularisation[2]
159
+ self.builders[2].build_arguments = kwargs
153
160
 
154
161
  if len(self.builders[1].data) > 0:
155
162
  logger.info("Building %s coordinate 1"%self.name)
156
- if gx_feature is not None:
157
- self.builders[1].add_orthogonal_feature(gx_feature, gxxgy)
158
- if gz_feature is not None:
159
- self.builders[1].add_orthogonal_feature(gz_feature, gyxgz)
160
- gy_feature = self.builders[1].build(regularisation=regularisation[1], **kwargs)
163
+ if gx_feature is not None and gxxgy>0:
164
+ self.builders[1].add_orthogonal_feature(gx_feature, gxxgy,step=step)
165
+ if gz_feature is not None and gyxgz>0:
166
+ self.builders[1].add_orthogonal_feature(gz_feature, gyxgz,step=step)
167
+ gy_feature = self.builders[1].feature
168
+ kwargs['regularisation'] = regularisation[1]
169
+ self.builders[1].build_arguments = kwargs
170
+
161
171
 
162
172
  if gy_feature is None:
163
173
  logger.warning(
@@ -17,7 +17,7 @@ class UnconformityFeature:
17
17
  self.value = value
18
18
  self.type = 'unconformity'
19
19
  self.name = '{}_unconformity'.format(feature.name)
20
-
20
+ self.builder = self.feature.builder
21
21
  def add_region(self, region):
22
22
  # self.feature.add_region(region)
23
23
  pass
@@ -67,3 +67,8 @@ class UnconformityFeature:
67
67
  """
68
68
  return self.feature.evaluate_gradient(pos)
69
69
 
70
+ def min(self):
71
+ return self.feature.min()
72
+
73
+ def max(self):
74
+ return self.feature.max()
@@ -2,7 +2,8 @@ import logging
2
2
 
3
3
  import numpy as np
4
4
 
5
- logger = logging.getLogger(__name__)
5
+ from LoopStructural.utils import getLogger
6
+ logger = getLogger(__name__)
6
7
 
7
8
 
8
9
  class FoldEvent:
@@ -26,7 +27,7 @@ class FoldEvent:
26
27
  self.fold_limb_rotation = fold_limb_rotation
27
28
  self.fold_axis = fold_axis
28
29
  self.name = name
29
-
30
+
30
31
  def get_fold_axis_orientation(self, points):
31
32
  """
32
33
  gets the fold axis orientation for evaluation points
@@ -61,7 +62,7 @@ class FoldEvent:
61
62
 
62
63
  def get_deformed_orientation(self, points):
63
64
  """
64
- Calculate the normal to the folded foliation at locations
65
+ Calculate the direction vectors of the fold
65
66
 
66
67
  Parameters
67
68
  ----------
@@ -70,6 +71,13 @@ class FoldEvent:
70
71
 
71
72
  Returns
72
73
  -------
74
+ fold_direction : np.array
75
+ a vector parallel to the fold
76
+ fold axis : np.array
77
+ the fold axis
78
+ dgz : np.array
79
+ the X direction of the finite strain ellipsoid, perpendicular to both
80
+ fold axis and fold direction
73
81
 
74
82
  """
75
83
  fold_axis = self.get_fold_axis_orientation(points)
@@ -89,8 +97,8 @@ class FoldEvent:
89
97
  dgz[d < 0] = -dgz[d < 0]
90
98
  return fold_direction, fold_axis, dgz
91
99
 
92
- def get_regularisation_direction(self, points):
93
- self.foldframe.features[2].evaluate_gradient(points)
100
+ # def get_regularisation_direction(self, points):
101
+ # self.foldframe.features[2].evaluate_gradient(points)
94
102
 
95
103
  def rot_mat(self, axis, angle):
96
104
  """