LoopStructural 1.0.9__cp39-cp39-win_amd64.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.cp39-win_amd64.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,382 @@
1
+ import logging
2
+
3
+ import numpy as np
4
+ import pandas as pd
5
+ from sklearn.decomposition import PCA
6
+
7
+ from LoopStructural.utils import getLogger
8
+ logger = getLogger(__name__)
9
+
10
+
11
+ def get_data_axis_aligned_bounding_box(xyz, buffer):
12
+ """
13
+
14
+ Parameters
15
+ ----------
16
+ xyz
17
+ buffer
18
+
19
+ Returns
20
+ -------
21
+
22
+ """
23
+ minx = np.min(xyz[:, 0])
24
+ maxx = np.max(xyz[:, 0])
25
+ miny = np.min(xyz[:, 1])
26
+ maxy = np.max(xyz[:, 1])
27
+ minz = np.min(xyz[:, 2])
28
+ maxz = np.max(xyz[:, 2])
29
+
30
+ xlen = maxx - minx
31
+ ylen = maxy - miny
32
+ zlen = maxz - minz
33
+ length = np.max([xlen, ylen, zlen])
34
+ minx -= length * buffer
35
+ maxx += length * buffer
36
+
37
+ miny -= length * buffer
38
+ maxy += length * buffer
39
+
40
+ minz -= length * buffer
41
+ maxz += length * buffer
42
+
43
+ bb = np.array([[minx, miny, minz],
44
+ [maxx, maxy, maxz]
45
+ ])
46
+
47
+ def region(xyz):
48
+ """
49
+
50
+ Parameters
51
+ ----------
52
+ xyz
53
+
54
+ Returns
55
+ -------
56
+
57
+ """
58
+ # print(xyz)
59
+ # print(bb)
60
+ b = np.ones(xyz.shape[0]).astype(bool)
61
+ b = np.logical_and(b, xyz[:, 0] > minx)
62
+ b = np.logical_and(b, xyz[:, 0] < maxx)
63
+ b = np.logical_and(b, xyz[:, 1] > miny)
64
+ b = np.logical_and(b, xyz[:, 1] < maxy)
65
+ # b = np.logical_and(b,xyz[:,2]>minz)
66
+ # b = np.logical_and(b,xyz[:,2]<maxz)
67
+ return b
68
+
69
+ return bb, region
70
+
71
+ def get_data_bounding_box_map(xyz, buffer):
72
+ """
73
+
74
+ Parameters
75
+ ----------
76
+ xyz
77
+ buffer
78
+
79
+ Returns
80
+ -------
81
+
82
+ """
83
+ # find the aligned coordinates box using pca
84
+ modelpca = PCA(n_components=3)
85
+ modelpca.fit(xyz)
86
+ # transform the data to this new coordinate then find extents
87
+ transformed_xyz = modelpca.transform(xyz)
88
+ minx = np.min(xyz[:, 0])
89
+ maxx = np.max(xyz[:, 0])
90
+ miny = np.min(xyz[:, 1])
91
+ maxy = np.max(xyz[:, 1])
92
+ minz = np.min(xyz[:, 2])
93
+ maxz = np.max(xyz[:, 2])
94
+
95
+ xlen = maxx - minx
96
+ ylen = maxy - miny
97
+ zlen = maxz - minz
98
+ length = np.max([xlen, ylen, zlen])
99
+ minx -= buffer
100
+ maxx += buffer
101
+
102
+ miny -= buffer
103
+ maxy += buffer
104
+
105
+ minz -= buffer
106
+ maxz += buffer
107
+
108
+ bb = np.array([[minx, miny, minz],
109
+ [maxx, maxy, maxz]
110
+ ])
111
+
112
+ def region(xyz):
113
+ b = np.ones(xyz.shape[0]).astype(bool)
114
+ b = np.logical_and(b, xyz[:, 0] > minx)
115
+ b = np.logical_and(b, xyz[:, 0] < maxx)
116
+ b = np.logical_and(b, xyz[:, 1] > miny)
117
+ b = np.logical_and(b, xyz[:, 1] < maxy)
118
+
119
+ return b
120
+
121
+ return bb, region
122
+ def get_data_bounding_box(xyz, buffer):
123
+ """
124
+
125
+ Parameters
126
+ ----------
127
+ xyz
128
+ buffer
129
+
130
+ Returns
131
+ -------
132
+
133
+ """
134
+ # find the aligned coordinates box using pca
135
+ modelpca = PCA(n_components=3)
136
+ modelpca.fit(xyz)
137
+ # transform the data to this new coordinate then find extents
138
+ transformed_xyz = modelpca.transform(xyz)
139
+ minx = np.min(xyz[:, 0])
140
+ maxx = np.max(xyz[:, 0])
141
+ miny = np.min(xyz[:, 1])
142
+ maxy = np.max(xyz[:, 1])
143
+ minz = np.min(xyz[:, 2])
144
+ maxz = np.max(xyz[:, 2])
145
+
146
+ xlen = maxx - minx
147
+ ylen = maxy - miny
148
+ zlen = maxz - minz
149
+ length = np.max([xlen,ylen,zlen])
150
+ minx -= length * buffer
151
+ maxx += length * buffer
152
+
153
+ miny -= length * buffer
154
+ maxy += length * buffer
155
+
156
+ minz -= length * buffer
157
+ maxz += length * buffer
158
+
159
+ bb = np.array([[minx, miny, minz],
160
+ [maxx, maxy, maxz]
161
+ ])
162
+
163
+ def region(xyz):
164
+ b = np.ones(xyz.shape[0]).astype(bool)
165
+ b = np.logical_and(b, xyz[:, 0] > minx)
166
+ b = np.logical_and(b, xyz[:, 0] < maxx)
167
+ b = np.logical_and(b, xyz[:, 1] > miny)
168
+ b = np.logical_and(b, xyz[:, 1] < maxy)
169
+ b = np.logical_and(b, xyz[:, 2] > minz)
170
+ b = np.logical_and(b, xyz[:, 2] < maxz)
171
+ return b
172
+
173
+ return bb, region
174
+
175
+
176
+ def plunge_and_plunge_dir_to_vector(plunge, plunge_dir):
177
+ plunge = np.deg2rad(plunge)
178
+ plunge_dir = np.deg2rad(plunge_dir)
179
+ vec = np.zeros(3)
180
+ vec[0] = np.sin(plunge_dir) * np.cos(plunge)
181
+ vec[1] = np.cos(plunge_dir) * np.cos(plunge)
182
+ vec[2] = -np.sin(plunge)
183
+ return vec
184
+
185
+
186
+ def create_surface(bounding_box, nstep):
187
+ x = np.linspace(bounding_box[0, 0], bounding_box[1, 0], nstep[0]) #
188
+ y = np.linspace(bounding_box[0, 1], bounding_box[1, 1], nstep[1])
189
+ xx, yy = np.meshgrid(x, y, indexing='xy')
190
+
191
+ def gi(i, j):
192
+ return i + j * nstep[0]
193
+
194
+ corners = np.array([[0, 1, 0, 1], [0, 0, 1, 1]])
195
+ i = np.arange(0, nstep[0] - 1)
196
+
197
+ j = np.arange(0, nstep[1] - 1)
198
+ ii, jj = np.meshgrid(i, j, indexing='ij')
199
+ corner_gi = gi(ii[:, :, None] + corners[None, None, 0, :, ],
200
+ jj[:, :, None] + corners[None, None, 1, :, ])
201
+ corner_gi = corner_gi.reshape((nstep[0] - 1) * (nstep[1] - 1), 4)
202
+ tri = np.vstack([corner_gi[:, :3], corner_gi[:, 1:]])
203
+ return tri, xx.flatten(), yy.flatten()
204
+
205
+ def create_box(bounding_box, nsteps):
206
+ tri, xx, yy = create_surface(bounding_box[0:2, :], nsteps[0:2])
207
+
208
+ zz = np.zeros(xx.shape)
209
+ zz[:] = bounding_box[1, 2]
210
+
211
+ tri = np.vstack([tri, tri + np.max(tri) + 1])
212
+ xx = np.hstack([xx, xx])
213
+ yy = np.hstack([yy, yy])
214
+
215
+ z = np.zeros(zz.shape)
216
+ z[:] = bounding_box[0, 2]
217
+ zz = np.hstack([zz, z])
218
+ # y faces
219
+ t, x, z = create_surface(bounding_box[:, [0, 2]], nsteps[[0, 2]])
220
+ tri = np.vstack([tri, t + np.max(tri) + 1])
221
+
222
+ y = np.zeros(x.shape)
223
+ y[:] = bounding_box[0, 1]
224
+ xx = np.hstack([xx, x])
225
+ zz = np.hstack([zz, z])
226
+ yy = np.hstack([yy, y])
227
+
228
+ tri = np.vstack([tri, t + np.max(tri) + 1])
229
+ y[:] = bounding_box[1, 1]
230
+ xx = np.hstack([xx, x])
231
+ zz = np.hstack([zz, z])
232
+ yy = np.hstack([yy, y])
233
+
234
+ # x faces
235
+ t, y, z = create_surface(bounding_box[:, [1, 2]], nsteps[[1, 2]])
236
+ tri = np.vstack([tri, t + np.max(tri) + 1])
237
+ x = np.zeros(y.shape)
238
+ x[:] = bounding_box[0, 0]
239
+ xx = np.hstack([xx, x])
240
+ zz = np.hstack([zz, z])
241
+ yy = np.hstack([yy, y])
242
+
243
+ tri = np.vstack([tri, t + np.max(tri) + 1])
244
+ x[:] = bounding_box[1, 0]
245
+ xx = np.hstack([xx, x])
246
+ zz = np.hstack([zz, z])
247
+ yy = np.hstack([yy, y])
248
+
249
+ points = np.zeros((len(xx), 3)) #
250
+ points[:, 0] = xx
251
+ points[:, 1] = yy
252
+ points[:, 2] = zz
253
+ return points, tri
254
+
255
+ def get_vectors(normal):
256
+ length = np.linalg.norm(normal,axis=1)[:,None]
257
+ normal /= length#np.linalg.norm(normal,axis=1)[:,None]
258
+ strikedip = normal_vector_to_strike_and_dip(normal)
259
+ strike_vec = get_strike_vector(strikedip[:, 0])
260
+ strike_vec /= np.linalg.norm(strike_vec,axis=0)[None,:]
261
+ dip_vec = np.cross(strike_vec, normal, axisa=0, axisb=1).T # (strikedip[:, 0], strikedip[:, 1])
262
+ dip_vec /= np.linalg.norm(dip_vec,axis=0)[None,:]
263
+ return strike_vec*length.T, dip_vec*length.T
264
+
265
+
266
+ def get_strike_vector(strike):
267
+ """
268
+
269
+ Parameters
270
+ ----------
271
+ strike
272
+
273
+ Returns
274
+ -------
275
+
276
+ """
277
+
278
+ v = np.array([np.sin(np.deg2rad(-strike)),
279
+ -np.cos(np.deg2rad(-strike)),
280
+ np.zeros(strike.shape[0])
281
+ ])
282
+
283
+ return v
284
+
285
+
286
+ def get_dip_vector(strike, dip):
287
+ v = np.array([-np.cos(np.deg2rad(-strike)) * np.cos(-np.deg2rad(dip)),
288
+ np.sin(np.deg2rad(-strike)) * np.cos(-np.deg2rad(dip)),
289
+ np.sin(-np.deg2rad(dip))
290
+ ])
291
+ return v
292
+
293
+
294
+ def rotation(axis, angle):
295
+ c = np.cos(np.deg2rad(angle))
296
+ s = np.sin((np.deg2rad(angle)))
297
+ C = 1.0 - c
298
+ x = axis[0]
299
+ y = axis[1]
300
+ z = axis[2]
301
+ xs = x * s
302
+ ys = y * s
303
+ zs = z * s
304
+ xC = x * C
305
+ yC = y * C
306
+ zC = z * C
307
+ xyC = x * yC
308
+ yzC = y * zC
309
+ zxC = z * xC
310
+ rotation_mat = np.zeros((3, 3))
311
+ rotation_mat[0][0] = x * xC + c
312
+ rotation_mat[0][1] = xyC - zs
313
+ rotation_mat[0][2] = zxC + ys
314
+
315
+ rotation_mat[1][0] = xyC + zs
316
+ rotation_mat[1][1] = y * yC + c
317
+ rotation_mat[1][2] = yzC - xs
318
+
319
+ rotation_mat[2][0] = zxC - ys
320
+ rotation_mat[2][1] = yzC + xs
321
+ rotation_mat[2][2] = z * zC + c
322
+ return rotation_mat
323
+
324
+
325
+ def strike_dip_vector(strike, dip):
326
+ vec = np.zeros((len(strike), 3))
327
+ s_r = np.deg2rad(strike)
328
+ d_r = np.deg2rad((dip))
329
+ vec[:, 0] = np.sin(d_r) * np.cos(s_r)
330
+ vec[:, 1] = -np.sin(d_r) * np.sin(s_r)
331
+ vec[:, 2] = np.cos(d_r)
332
+ vec /= np.linalg.norm(vec, axis=1)[:, None]
333
+ return vec
334
+
335
+
336
+ def normal_vector_to_strike_and_dip(normal_vector):
337
+ normal_vector /= np.linalg.norm(normal_vector, axis=1)[:, None]
338
+ dip = np.rad2deg(np.arccos(normal_vector[:, 2]))
339
+ strike = -np.rad2deg(np.arctan2(normal_vector[:, 1], normal_vector[:,
340
+ 0])) # atan2(v2[1],v2[0])*rad2deg;
341
+
342
+ return np.array([strike, dip]).T
343
+
344
+
345
+ def xyz_names():
346
+ return ['X', 'Y', 'Z']
347
+
348
+
349
+ def normal_vec_names():
350
+ return ['nx', 'ny', 'nz']
351
+
352
+
353
+ def tangent_vec_names():
354
+ return ['tx', 'ty', 'tz']
355
+
356
+
357
+ def gradient_vec_names():
358
+ return ['gx', 'gy', 'gz']
359
+
360
+
361
+ def weight_name():
362
+ return ['w']
363
+
364
+
365
+ def val_name():
366
+ return ['val']
367
+
368
+ def coord_name():
369
+ return ['coord']
370
+
371
+ def interface_name():
372
+ return ['interface']
373
+
374
+
375
+ def feature_name():
376
+ return ['feature_name']
377
+
378
+ def all_heading():
379
+ return xyz_names() + normal_vec_names() + tangent_vec_names() + \
380
+ gradient_vec_names() + weight_name() + val_name() + coord_name() + feature_name() + interface_name()
381
+ def empty_dataframe():
382
+ empty_data_frame =pd.DataFrame(columns=[all_heading()])
@@ -0,0 +1,60 @@
1
+ import logging
2
+ import LoopStructural
3
+
4
+ def get_levels():
5
+ """dict for converting to logger levels from string
6
+
7
+
8
+ Returns
9
+ -------
10
+ dict
11
+ contains all strings with corresponding logging levels.
12
+ """
13
+ return {'info':logging.INFO,'warning':logging.WARNING,'error':logging.ERROR,'debug':logging.DEBUG}
14
+
15
+ def getLogger(name):
16
+ logger = logging.getLogger(name)
17
+ logger.addHandler(LoopStructural.ch)
18
+ LoopStructural.loggers[name] = logger
19
+ return logger
20
+
21
+ def log_to_file(filename,level='info'):
22
+ """Set the logging parameters for log file
23
+
24
+
25
+ Parameters
26
+ ----------
27
+ filename : string
28
+ name of file or path to file
29
+ level : str, optional
30
+ 'info', 'warning', 'error', 'debug' mapped to logging levels, by default 'info'
31
+ """
32
+ levels = get_levels()
33
+ level = levels.get(level,logging.WARNING)
34
+ fh = logging.FileHandler(filename)
35
+ fh.setFormatter(LoopStructural.formatter)
36
+ fh.setLevel(level)
37
+ for logger in LoopStructural.loggers.values():
38
+ for hdlr in logger.handlers[:]: # remove the existing file handlers
39
+ if isinstance(hdlr,logging.FileHandler): #fixed two typos here
40
+ logger.removeHandler(hdlr)
41
+ logger.addHandler(fh)
42
+ logger.setLevel(level)
43
+
44
+
45
+ def log_to_console(level='warning'):
46
+ """Set the level of logging to the console
47
+
48
+
49
+ Parameters
50
+ ----------
51
+ level : str, optional
52
+ 'info', 'warning', 'error', 'debug' mapped to logging levels, by default 'info'
53
+ """
54
+ levels = get_levels()
55
+ level = levels.get(level,logging.WARNING)
56
+ for logger in LoopStructural.loggers.values():
57
+ for hdlr in logger.handlers:
58
+ # both stream and file are base stream, so check if not a filehandler
59
+ if not isinstance(hdlr,logging.FileHandler):
60
+ hdlr.setLevel(level)