LoopStructural 1.0.1__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.

Potentially problematic release.


This version of LoopStructural might be problematic. Click here for more details.

Files changed (119) hide show
  1. Miniconda/envs/loop/Lib/site-packages/LoopStructural/__init__.py +33 -0
  2. Miniconda/envs/loop/Lib/site-packages/LoopStructural/__pycache__/__init__.cpython-37.pyc +0 -0
  3. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__init__.py +12 -0
  4. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__pycache__/__init__.cpython-37.pyc +0 -0
  5. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__pycache__/_base.cpython-37.pyc +0 -0
  6. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/_base.py +65 -0
  7. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/claudius.csv +21049 -0
  8. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/claudiusbb.txt +2 -0
  9. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/duplex.csv +126 -0
  10. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/duplexbb.txt +2 -0
  11. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/intrusion.csv +1017 -0
  12. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/intrusionbb.txt +2 -0
  13. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/onefoldbb.txt +2 -0
  14. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/onefolddata.csv +2226 -0
  15. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/refolded_bb.txt +2 -0
  16. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/refolded_fold.csv +2126 -0
  17. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__init__.py +31 -0
  18. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/__init__.cpython-37.pyc +0 -0
  19. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/discrete_fold_interpolator.cpython-37.pyc +0 -0
  20. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/discrete_interpolator.cpython-37.pyc +0 -0
  21. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/finite_difference_interpolator.cpython-37.pyc +0 -0
  22. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/geological_interpolator.cpython-37.pyc +0 -0
  23. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/operator.cpython-37.pyc +0 -0
  24. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/piecewiselinear_interpolator.cpython-37.pyc +0 -0
  25. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/structured_grid.cpython-37.pyc +0 -0
  26. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/structured_tetra.cpython-37.pyc +0 -0
  27. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/surfe_wrapper.cpython-37.pyc +0 -0
  28. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/__init__.py +0 -0
  29. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/__pycache__/__init__.cpython-37.pyc +0 -0
  30. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/dsi_helper.c +27805 -0
  31. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/dsi_helper.cp37-win_amd64.pyd +0 -0
  32. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/discrete_fold_interpolator.py +168 -0
  33. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/discrete_interpolator.py +551 -0
  34. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/finite_difference_interpolator.py +339 -0
  35. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/geological_interpolator.py +178 -0
  36. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/operator.py +46 -0
  37. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/piecewiselinear_interpolator.py +300 -0
  38. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_grid.py +460 -0
  39. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_tetra.py +637 -0
  40. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/surfe_wrapper.py +119 -0
  41. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/__init__.py +46 -0
  42. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/__pycache__/__init__.cpython-37.pyc +0 -0
  43. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__init__.py +0 -0
  44. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/__init__.cpython-37.pyc +0 -0
  45. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/geological_model.cpython-37.pyc +0 -0
  46. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/geological_model.py +1179 -0
  47. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__init__.py +3 -0
  48. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/__init__.cpython-37.pyc +0 -0
  49. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_function.cpython-37.pyc +0 -0
  50. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_function_feature.cpython-37.pyc +0 -0
  51. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_segment.cpython-37.pyc +0 -0
  52. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_function.py +187 -0
  53. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_function_feature.py +75 -0
  54. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_segment.py +270 -0
  55. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__init__.py +7 -0
  56. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/__init__.cpython-37.pyc +0 -0
  57. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/cross_product_geological_feature.cpython-37.pyc +0 -0
  58. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/geological_feature.cpython-37.pyc +0 -0
  59. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/geological_feature_builder.cpython-37.pyc +0 -0
  60. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/region_feature.cpython-37.pyc +0 -0
  61. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/structural_frame.cpython-37.pyc +0 -0
  62. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/structural_frame_builder.cpython-37.pyc +0 -0
  63. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/unconformity_feature.cpython-37.pyc +0 -0
  64. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/cross_product_geological_feature.py +77 -0
  65. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/geological_feature.py +276 -0
  66. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/geological_feature_builder.py +289 -0
  67. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/region_feature.py +31 -0
  68. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/structural_frame.py +116 -0
  69. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/structural_frame_builder.py +179 -0
  70. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/unconformity_feature.py +69 -0
  71. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__init__.py +8 -0
  72. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/__init__.cpython-37.pyc +0 -0
  73. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold.cpython-37.pyc +0 -0
  74. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold_rotation_angle.cpython-37.pyc +0 -0
  75. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold_rotation_angle_feature.cpython-37.pyc +0 -0
  76. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/foldframe.cpython-37.pyc +0 -0
  77. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/svariogram.cpython-37.pyc +0 -0
  78. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold.py +135 -0
  79. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold_rotation_angle.py +132 -0
  80. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold_rotation_angle_feature.py +57 -0
  81. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/foldframe.py +191 -0
  82. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/svariogram.py +179 -0
  83. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__init__.py +14 -0
  84. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/__init__.cpython-37.pyc +0 -0
  85. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/exceptions.cpython-37.pyc +0 -0
  86. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/helper.cpython-37.pyc +0 -0
  87. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/map2loop.cpython-37.pyc +0 -0
  88. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/utils.cpython-37.pyc +0 -0
  89. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/exceptions.py +9 -0
  90. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/helper.py +373 -0
  91. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/map2loop.py +229 -0
  92. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/utils.py +76 -0
  93. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__init__.py +19 -0
  94. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/__init__.cpython-37.pyc +0 -0
  95. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/map_viewer.cpython-37.pyc +0 -0
  96. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/model_plotter.cpython-37.pyc +0 -0
  97. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/model_visualisation.cpython-37.pyc +0 -0
  98. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/rotation_angle_plotter.cpython-37.pyc +0 -0
  99. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/sphinx_scraper.cpython-37.pyc +0 -0
  100. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/map_viewer.py +122 -0
  101. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/model_plotter.py +16 -0
  102. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/model_visualisation.py +704 -0
  103. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/rotation_angle_plotter.py +66 -0
  104. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/sphinx_scraper.py +34 -0
  105. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.1-py3.7.egg-info/PKG-INFO +10 -0
  106. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.1-py3.7.egg-info/SOURCES.txt +60 -0
  107. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.1-py3.7.egg-info/dependency_links.txt +1 -0
  108. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.1-py3.7.egg-info/requires.txt +3 -0
  109. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.1-py3.7.egg-info/top_level.txt +2 -0
  110. Miniconda/envs/loop/Lib/site-packages/tests/__init__.py +0 -0
  111. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/__init__.cpython-37.pyc +0 -0
  112. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_faults.cpython-37.pyc +0 -0
  113. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_fold.cpython-37.pyc +0 -0
  114. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_interpolator.cpython-37.pyc +0 -0
  115. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_refolded.cpython-37.pyc +0 -0
  116. Miniconda/envs/loop/Lib/site-packages/tests/test_faults.py +17 -0
  117. Miniconda/envs/loop/Lib/site-packages/tests/test_fold.py +57 -0
  118. Miniconda/envs/loop/Lib/site-packages/tests/test_interpolator.py +88 -0
  119. Miniconda/envs/loop/Lib/site-packages/tests/test_refolded.py +22 -0
@@ -0,0 +1,179 @@
1
+ """
2
+ structural frame builder
3
+ """
4
+
5
+ import logging
6
+
7
+ import numpy as np
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+ from LoopStructural.modelling.features.cross_product_geological_feature \
12
+ import \
13
+ CrossProductGeologicalFeature
14
+ from LoopStructural.modelling.features import \
15
+ GeologicalFeatureInterpolator
16
+ from LoopStructural.modelling.features import StructuralFrame
17
+
18
+
19
+ class StructuralFrameBuilder:
20
+ """[summary]
21
+
22
+ [extended_summary]
23
+ """
24
+ def __init__(self, interpolator=None, interpolators=None, **kwargs):
25
+ """
26
+ Class for building a structural frame - has functions to set up the
27
+ interpolator with
28
+ data and also orthogonality constraints. Can build a generic
29
+ structural frame or a
30
+ subclass of the structural frame if the kwarg `frame` is specified
31
+
32
+ Parameters
33
+ ----------
34
+ interpolator - a template interpolator for the frame
35
+ kwargs
36
+ """
37
+ self.support = None
38
+ self.fault_event = None
39
+ self.name = 'Undefined'
40
+ # self.region = 'everywhere'
41
+ self.builders = []
42
+ if 'name' in kwargs:
43
+ self.name = kwargs['name']
44
+ kwargs.pop('name')
45
+ self.data = [[], [], []]
46
+ # list of interpolators
47
+ # self.interpolators = []
48
+ # Create the interpolation objects by copying the template
49
+
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
57
+ # self.builders
58
+ self.builders.append(
59
+ GeologicalFeatureInterpolator(interpolators[0],
60
+ name=self.name + '_0',
61
+ **kwargs)) # ,region=self.region))
62
+ self.builders.append(
63
+ GeologicalFeatureInterpolator(interpolators[1],
64
+ name=self.name + '_1',
65
+ **kwargs)) # ,region=self.region))
66
+ self.builders.append(
67
+ GeologicalFeatureInterpolator(interpolators[2],
68
+ name=self.name + '_2',
69
+ **kwargs)) # ,region=self.region))
70
+
71
+ def __getitem__(self, item):
72
+ return self.builders[item]
73
+
74
+ def add_data_from_data_frame(self, data_frame):
75
+ """
76
+ extract the data for a fault from a data frame
77
+
78
+ Parameters
79
+ ----------
80
+ data_frame
81
+
82
+ Returns
83
+ -------
84
+
85
+ """
86
+ for i in range(3):
87
+ self.builders[i].add_data_from_data_frame(data_frame.loc[data_frame['coord'] == i,:])
88
+
89
+
90
+ def build(self, w1=1., w2=1., w3=1., frame=StructuralFrame, **kwargs):
91
+ """
92
+ Build the structural frame
93
+ Parameters
94
+ ----------
95
+ solver solver to use
96
+ frame - type of frame to build StructuralFrame or FoldFrame
97
+ w3
98
+ w2
99
+ w1
100
+ kwargs
101
+
102
+ Returns
103
+ -------
104
+
105
+ """
106
+ gxxgy = 1
107
+ gxxgz = 1
108
+ gyxgz = 1
109
+ if 'gxxgy' in kwargs:
110
+ gxxgy = kwargs['gxxgy']
111
+ if 'gxxgz' in kwargs:
112
+ gxxgz = kwargs['gxxgz']
113
+ if 'gyxgz' in kwargs:
114
+ gyxgz = kwargs['gyxgz']
115
+ # set regularisation so the the main surface (foliation, fault) is smooth
116
+ # and the fields are allowed to vary more
117
+ regularisation = kwargs.pop('regularisation', [1., 1., 1.])
118
+ # initialise features as none then where data exists build
119
+ gx_feature = None
120
+ gy_feature = None
121
+ gz_feature = None
122
+ fold = None
123
+ if len(self.builders[0].data) > 0:
124
+ logger.info("Building %s coordinate 0"%self.name)
125
+ gx_feature = self.builders[0].build(regularisation=regularisation[
126
+ 0], **kwargs)
127
+ # remove fold from kwargs
128
+
129
+ fold = kwargs.pop('fold', False)
130
+ if gx_feature is None:
131
+ logger.warning(
132
+ "Not enough constraints for structural frame coordinate 0, \n"
133
+ "Add some more and try again.")
134
+ # 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)
138
+ if 'data_region' in kwargs:
139
+ kwargs.pop('data_region')
140
+ if 'region' in kwargs:
141
+ kwargs.pop('region')
142
+ if len(self.builders[2].data) > 0:
143
+ logger.info("Building %s coordinate 2"%self.name)
144
+ # if gy_feature is not None:
145
+ # self.builders[
146
+ # 2].interpolator.add_gradient_orthogonal_constraint(
147
+ # np.arange(0, self.support.n_elements),
148
+ # gy_feature.evaluate_gradient(self.support.barycentre),
149
+ # 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)
153
+
154
+ if len(self.builders[1].data) > 0:
155
+ 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)
161
+
162
+ if gy_feature is None:
163
+ logger.warning(
164
+ "Not enough constraints for structural frame coordinate 1, \n"
165
+ "Add some more and try again.")
166
+
167
+ if len(self.builders[2].data) == 0:
168
+ if gy_feature is not None:
169
+ logger.debug(
170
+ "Creating analytical structural frame coordinate 2")
171
+ gz_feature = CrossProductGeologicalFeature(self.name + '_2',
172
+ gy_feature,
173
+ gx_feature)
174
+ if gy_feature is None or gx_feature is None:
175
+ logger.warning(
176
+ "Not enough constraints for fold frame coordinate 1, \n"
177
+ "Add some more and try again.")
178
+ # use the frame argument to build a structural frame
179
+ return frame(self.name, [gx_feature, gy_feature, gz_feature],fold=fold)
@@ -0,0 +1,69 @@
1
+ """
2
+
3
+ """
4
+ class UnconformityFeature:
5
+ """
6
+
7
+ """
8
+ def __init__(self, feature, value):
9
+ """
10
+
11
+ Parameters
12
+ ----------
13
+ feature
14
+ value
15
+ """
16
+ self.feature = feature
17
+ self.value = value
18
+ self.type = 'unconformity'
19
+ self.name = '{}_unconformity'.format(feature.name)
20
+
21
+ def add_region(self, region):
22
+ # self.feature.add_region(region)
23
+ pass
24
+ def set_model(self, model):
25
+ self.model = model
26
+
27
+ def evaluate(self,pos):
28
+ """
29
+
30
+ Parameters
31
+ ----------
32
+ pos : numpy array
33
+ locations to evaluate whether below or above unconformity
34
+
35
+ Returns
36
+ -------
37
+ boolean
38
+ true if above the unconformity, false if below
39
+ """
40
+ return self.feature.evaluate_value(pos) < self.value
41
+
42
+ def evaluate_value(self,pos):
43
+ """
44
+
45
+ Parameters
46
+ ----------
47
+ pos : numpy array
48
+ locations to evaluate the value of the base geological feature
49
+
50
+ Returns
51
+ -------
52
+
53
+ """
54
+ return self.feature.evaluate_value(pos)
55
+
56
+ def evaluate_gradient(self,pos):
57
+ """
58
+
59
+ Parameters
60
+ ----------
61
+ pos : numpy array
62
+ location to evaluate the gradient of the base geological feature
63
+
64
+ Returns
65
+ -------
66
+
67
+ """
68
+ return self.feature.evaluate_gradient(pos)
69
+
@@ -0,0 +1,8 @@
1
+ """
2
+
3
+ """
4
+ from .fold import FoldEvent
5
+ from .svariogram import SVariogram
6
+ from .fold_rotation_angle_feature import FoldRotationAngleFeature, fourier_series
7
+ from .foldframe import FoldFrame
8
+ from .fold_rotation_angle import FoldRotationAngle
@@ -0,0 +1,135 @@
1
+ import logging
2
+
3
+ import numpy as np
4
+
5
+ logger = logging.getLogger(__name__)
6
+
7
+
8
+ class FoldEvent:
9
+ """
10
+
11
+ """
12
+ def __init__(self, foldframe, fold_axis_rotation=None, fold_limb_rotation=None, fold_axis=None, name='Fold'):
13
+ """
14
+ A fold event describes the geometry of the fold using a fold frame
15
+ and two geometrical descriptors
16
+
17
+ Parameters
18
+ ----------
19
+ foldframe the fold frame object
20
+ fold_axis_rotation function for the fold axis rotation angle
21
+ fold_limb_rotation function for the fold limb rotation angle
22
+ """
23
+
24
+ self.foldframe = foldframe
25
+ self.fold_axis_rotation = fold_axis_rotation
26
+ self.fold_limb_rotation = fold_limb_rotation
27
+ self.fold_axis = fold_axis
28
+ self.name = name
29
+
30
+ def get_fold_axis_orientation(self, points):
31
+ """
32
+ gets the fold axis orientation for evaluation points
33
+
34
+ Parameters
35
+ ----------
36
+ points locations to calculate fold axis numpy array Nx3
37
+
38
+ Returns
39
+ -------
40
+
41
+ """
42
+ # evaluate fold axis from rotation angle
43
+ if self.fold_axis_rotation is not None:
44
+ logger.info("Using fold_axis_rotation function")
45
+ # get the gz direction
46
+ dgx = self.foldframe.features[0].evaluate_gradient(points)
47
+ dgy = self.foldframe.features[1].evaluate_gradient(points)
48
+ dgx /= np.linalg.norm(dgx, axis=1)[:, None]
49
+ dgy /= np.linalg.norm(dgy, axis=1)[:, None]
50
+ # get gy
51
+ gy = self.foldframe.features[1].evaluate_value(points)
52
+ R1 = self.rot_mat(-dgx, self.fold_axis_rotation(gy))
53
+ fold_axis = np.einsum('ijk,ki->kj', R1, dgy)
54
+ fold_axis /= np.linalg.norm(fold_axis, axis=1)[:, None]
55
+ return fold_axis
56
+
57
+ # use constant fold axis
58
+ if self.fold_axis is not None:
59
+ logger.info("Using constant fold axis")
60
+ return np.tile(self.fold_axis, (points.shape[0], 1))
61
+
62
+ def get_deformed_orientation(self, points):
63
+ """
64
+ Calculate the normal to the folded foliation at locations
65
+
66
+ Parameters
67
+ ----------
68
+ points - np.array
69
+ location Nx3 array of x,y,z locations to evaluate fold
70
+
71
+ Returns
72
+ -------
73
+
74
+ """
75
+ fold_axis = self.get_fold_axis_orientation(points)
76
+ gx = self.foldframe.features[0].evaluate_value(points)
77
+ dgx = self.foldframe.features[0].evaluate_gradient(points)
78
+ dgx /= np.linalg.norm(dgx, axis=1)[:, None]
79
+ dgz = np.cross(dgx,fold_axis,axisa=1,axisb=1)
80
+ # dgz = self.foldframe.features[2].evaluate_gradient(points)
81
+ dgz /= np.linalg.norm(dgz, axis=1)[:, None]
82
+
83
+ R2 = self.rot_mat(fold_axis, self.fold_limb_rotation(gx))
84
+ fold_direction = np.einsum('ijk,ki->kj', R2, dgx)
85
+ fold_direction /= np.sum(fold_direction, axis=1)[:, None]
86
+ # calculate dot product between fold_direction and axis
87
+ # if its less than 0 then inverse dgz
88
+ d = np.einsum('ij,ik->i', fold_direction, fold_axis)
89
+ dgz[d < 0] = -dgz[d < 0]
90
+ return fold_direction, fold_axis, dgz
91
+
92
+ def get_regularisation_direction(self, points):
93
+ self.foldframe.features[2].evaluate_gradient(points)
94
+
95
+ def rot_mat(self, axis, angle):
96
+ """
97
+ Create a rotation matrix for axis and angle
98
+
99
+ Parameters
100
+ ----------
101
+ axis Nx3 vector for axis
102
+ angle N array for angle in degrees
103
+
104
+ Returns 3,3,N rotation matrix
105
+ -------
106
+
107
+ """
108
+ c = np.cos(np.deg2rad(angle))
109
+ s = np.sin(np.deg2rad(angle))
110
+ C = 1.0 - c
111
+ x = axis[:, 0]
112
+ y = axis[:, 1]
113
+ z = axis[:, 2]
114
+ xs = x * s
115
+ ys = y * s
116
+ zs = z * s
117
+ xC = x * C
118
+ yC = y * C
119
+ zC = z * C
120
+ xyC = x * yC
121
+ yzC = y * zC
122
+ zxC = z * xC
123
+ rotation_mat = np.zeros((3, 3, len(angle)))
124
+ rotation_mat[0, 0, :] = x * xC + c
125
+ rotation_mat[0, 1, :] = xyC - zs
126
+ rotation_mat[0, 2, :] = zxC + ys
127
+
128
+ rotation_mat[1, 0, :] = xyC + zs
129
+ rotation_mat[1, 1, :] = y * yC + c
130
+ rotation_mat[1, 2, :] = yzC - xs
131
+
132
+ rotation_mat[2, 0, :] = zxC - ys
133
+ rotation_mat[2, 1, :] = yzC + xs
134
+ rotation_mat[2, 2, :] = z * zC + c
135
+ return rotation_mat
@@ -0,0 +1,132 @@
1
+ import logging
2
+
3
+ import numpy as np
4
+ from scipy.optimize import curve_fit
5
+
6
+ from LoopStructural.modelling.fold.fold_rotation_angle_feature import \
7
+ fourier_series
8
+ from LoopStructural.modelling.fold import SVariogram
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ class FoldRotationAngle:
14
+ """
15
+
16
+ """
17
+ def __init__(self, rotation_angle, fold_frame_coordinate, svario=False):
18
+ """
19
+
20
+ Parameters
21
+ ----------
22
+ rotation_angle
23
+ fold_frame_coordinate
24
+ svario
25
+ """
26
+ self.rotation_angle = rotation_angle
27
+ self.fold_frame_coordinate = fold_frame_coordinate
28
+ self.fold_rotation_function = None
29
+ self.svario = None
30
+ if svario:
31
+ self.svario = SVariogram(self.fold_frame_coordinate, self.rotation_angle)
32
+ self.fitted_params = None
33
+
34
+ def fit_fourier_series(self, wl = None, lags = None, nlag = None, lag = None):
35
+ """
36
+
37
+ Parameters
38
+ ----------
39
+ wl
40
+ lags
41
+ nlag
42
+ lag
43
+
44
+ Returns
45
+ -------
46
+
47
+ """
48
+ if self.svario is None:
49
+ self.svario = SVariogram(self.fold_frame_coordinate,
50
+ self.rotation_angle)
51
+
52
+ self.svario.calc_semivariogram(lags=lags, nlag=nlag, lag=lag)
53
+ if wl is None:
54
+ wl = self.svario.find_wavelengths(lags=lags, nlag=nlag, lag=lag)
55
+ # for now only consider single fold wavelength
56
+ wl = wl[0]
57
+ guess = np.zeros(4)
58
+ guess[3] = wl # np.max(limb_wl)
59
+ logger.info(
60
+ 'Guess: %f %f %f %f' % (guess[0], guess[1], guess[2], guess[3]))
61
+ # mask nans
62
+ mask = np.logical_or(~np.isnan(self.fold_frame_coordinate), ~np.isnan(self.rotation_angle))
63
+ logger.info(
64
+ "There are %i nans for the fold limb rotation angle and "
65
+ "%i observations" % (np.sum(~mask), np.sum(mask)))
66
+ if np.sum(mask) < len(guess):
67
+ logger.error(
68
+ "Not enough data points to fit Fourier series setting "
69
+ "fold rotation angle"
70
+ "to 0")
71
+ self.fold_rotation_function = lambda x: np.zeros(x.shape)
72
+ else:
73
+ try:
74
+ # try fitting using wavelength guess
75
+ popt, pcov = curve_fit(fourier_series,
76
+ self.fold_frame_coordinate[mask],
77
+ np.tan(np.deg2rad(self.rotation_angle[mask])),
78
+ guess)
79
+ except RuntimeError:
80
+ try:
81
+ # if fitting failed, try with just 0s
82
+ logger.info("Running curve fit without initial guess")
83
+ popt, pcov = curve_fit(fourier_series,
84
+ self.fold_frame_coordinate[mask],
85
+ np.tan(np.deg2rad(self.rotation_angle[mask])))
86
+ except RuntimeError:
87
+ # otherwise set the fourier series parameters to 0
88
+ popt = guess
89
+ logger.error(
90
+ "Could not fit curve to S-Plot, check the wavelength")
91
+ logger.info(
92
+ 'Fitted: %f %f %f %f' % (popt[0], popt[1], popt[2], popt[3]))
93
+ self.fold_rotation_function = lambda x: np.rad2deg(
94
+ np.arctan(
95
+ fourier_series(x, popt[0], popt[1], popt[2], popt[3])))
96
+ self.fitted_params = popt
97
+
98
+ def __call__(self, fold_frame_coordinate):
99
+ """
100
+
101
+ Parameters
102
+ ----------
103
+ fold_frame_coordinate
104
+
105
+ Returns
106
+ -------
107
+
108
+ """
109
+ return self.fold_rotation_function(fold_frame_coordinate)
110
+
111
+ def calculate_misfit(self):
112
+ """
113
+
114
+ Returns
115
+ -------
116
+
117
+ """
118
+ return np.tan(np.deg2rad(self.rotation_angle)) - np.tan(np.deg2rad(
119
+ self.__call__(self.fold_frame_coordinate)))
120
+
121
+ def set_function(self, function):
122
+ """
123
+
124
+ Parameters
125
+ ----------
126
+ function
127
+
128
+ Returns
129
+ -------
130
+
131
+ """
132
+ self. fold_rotation_function = function
@@ -0,0 +1,57 @@
1
+ import logging
2
+
3
+ import numpy as np
4
+
5
+ logger = logging.getLogger(__name__)
6
+
7
+
8
+ class FoldRotationAngleFeature:
9
+ """
10
+
11
+ """
12
+ def __init__(self, fold_frame, rotation):
13
+ """
14
+
15
+ Parameters
16
+ ----------
17
+ fold_frame
18
+ rotation
19
+ """
20
+ self.fold_frame = fold_frame
21
+ self.rotation = rotation
22
+
23
+ def evaluate_value(self, location):
24
+ """
25
+
26
+ Parameters
27
+ ----------
28
+ location
29
+
30
+ Returns
31
+ -------
32
+
33
+ """
34
+ s1 = self.fold_frame.features[0].evaluate_value(location)
35
+ r = self.rotation(s1)
36
+ return r
37
+
38
+
39
+ def fourier_series(x, c0, c1, c2, w):
40
+ """
41
+
42
+ Parameters
43
+ ----------
44
+ x
45
+ c0
46
+ c1
47
+ c2
48
+ w
49
+
50
+ Returns
51
+ -------
52
+
53
+ """
54
+ v = np.array(x.astype(float))
55
+ # v.fill(c0)
56
+ v = c0 + c1 * np.cos(2 * np.pi / w * x) + c2 * np.sin(2 * np.pi / w * x)
57
+ return np.rad2deg(np.arctan(v))