LoopStructural 1.0.9__cp39-cp39-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.cp39-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,421 @@
1
+ """
2
+ Cartesian grid for fold interpolator
3
+
4
+ """
5
+ import logging
6
+
7
+ import numpy as np
8
+
9
+ from .base_structured_3d_support import BaseStructuredSupport
10
+
11
+
12
+ from LoopStructural.utils import getLogger
13
+ logger = getLogger(__name__)
14
+
15
+ class StructuredGrid(BaseStructuredSupport):
16
+ """
17
+
18
+ """
19
+ def __init__(self,
20
+ origin=np.zeros(3),
21
+ nsteps=np.array([10, 10, 10]),
22
+ step_vector=np.ones(3),
23
+ name=None
24
+ ):
25
+ """
26
+
27
+ Parameters
28
+ ----------
29
+ origin - 3d list or numpy array
30
+ nsteps - 3d list or numpy array of ints
31
+ step_vector - 3d list or numpy array of int
32
+ """
33
+ BaseStructuredSupport.__init__(self,origin,nsteps,step_vector)
34
+ self.regions = {}
35
+ self.regions['everywhere'] = np.ones(self.n_nodes).astype(bool)
36
+ self.name = name
37
+
38
+ def barycentre(self):
39
+ return self.cell_centres(np.arange(self.n_elements))
40
+
41
+
42
+ def cell_centres(self, global_index):
43
+ """[summary]
44
+
45
+ [extended_summary]
46
+
47
+ Parameters
48
+ ----------
49
+ global_index : [type]
50
+ [description]
51
+
52
+ Returns
53
+ -------
54
+ [type]
55
+ [description]
56
+ """
57
+ ix, iy, iz = self.global_index_to_cell_index(global_index)
58
+ x = self.origin[None, 0] + self.step_vector[None, 0] * .5 + \
59
+ self.step_vector[None, 0] * ix
60
+ y = self.origin[None, 1] + self.step_vector[None, 1] * .5 + \
61
+ self.step_vector[None, 1] * iy
62
+ z = self.origin[None, 2] + self.step_vector[None, 2] * .5 + \
63
+ self.step_vector[None, 2] * iz
64
+ return np.array([x, y, z]).T
65
+
66
+ def position_to_cell_index(self, pos):
67
+ """[summary]
68
+
69
+ [extended_summary]
70
+
71
+ Parameters
72
+ ----------
73
+ pos : [type]
74
+ [description]
75
+
76
+ Returns
77
+ -------
78
+ [type]
79
+ [description]
80
+ """
81
+
82
+ pos = self.check_position(pos)
83
+
84
+ ix = pos[:, 0] - self.origin[None, 0]
85
+ iy = pos[:, 1] - self.origin[None, 1]
86
+ iz = pos[:, 2] - self.origin[None, 2]
87
+ ix = ix // self.step_vector[None, 0]
88
+ iy = iy // self.step_vector[None, 1]
89
+ iz = iz // self.step_vector[None, 2]
90
+ return ix.astype(int), iy.astype(int), iz.astype(int)
91
+
92
+ def inside(self, pos):
93
+
94
+ # check whether point is inside box
95
+ inside = np.ones(pos.shape[0]).astype(bool)
96
+ for i in range(3):
97
+ inside *= pos[:, i] > self.origin[None, i]
98
+ inside *= pos[:, i] < self.origin[None, i] + \
99
+ self.step_vector[None, i] * self.nsteps_cells[None, i]
100
+ return inside
101
+
102
+ def check_position(self, pos):
103
+ """[summary]
104
+
105
+ [extended_summary]
106
+
107
+ Parameters
108
+ ----------
109
+ pos : [type]
110
+ [description]
111
+
112
+ Returns
113
+ -------
114
+ [type]
115
+ [description]
116
+ """
117
+
118
+ if len(pos.shape) == 1:
119
+ pos = np.array([pos])
120
+ if len(pos.shape) != 2:
121
+ print("Position array needs to be a list of points or a point")
122
+ return False
123
+ return pos
124
+
125
+ def trilinear(self, x, y, z):
126
+ """
127
+ returns the trilinear interpolation for the local coordinates
128
+ Parameters
129
+ ----------
130
+ x - double, array of doubles
131
+ y - double, array of doubles
132
+ z - double, array of doubles
133
+
134
+ Returns
135
+ -------
136
+ array of interpolation coefficients
137
+
138
+ """
139
+ return np.array([(1 - x) * (1 - y) * (1 - z),
140
+ x * (1 - y) * (1 - z),
141
+ (1 - x) * y * (1 - z),
142
+ (1 - x) * (1 - y) * z,
143
+ x * (1 - y) * z,
144
+ (1 - x) * y * z,
145
+ x * y * (1 - z),
146
+ x * y * z])
147
+
148
+ def position_to_local_coordinates(self, pos):
149
+ """
150
+ Convert from global to local coordinates within a cel
151
+ Parameters
152
+ ----------
153
+ pos - array of positions inside
154
+
155
+ Returns
156
+ -------
157
+ localx, localy, localz
158
+
159
+ """
160
+ # TODO check if inside mesh
161
+
162
+ # calculate local coordinates for positions
163
+ local_x = ((pos[:, 0] - self.origin[None, 0]) % self.step_vector[
164
+ None, 0]) / self.step_vector[None, 0]
165
+ local_y = ((pos[:, 1] - self.origin[None, 1]) % self.step_vector[
166
+ None, 1]) / self.step_vector[None, 1]
167
+ local_z = ((pos[:, 2] - self.origin[None, 2]) % self.step_vector[
168
+ None, 2]) / self.step_vector[None, 2]
169
+
170
+ return local_x, local_y, local_z
171
+
172
+ def position_to_dof_coefs(self, pos):
173
+ """
174
+ global posotion to interpolation coefficients
175
+ Parameters
176
+ ----------
177
+ pos
178
+
179
+ Returns
180
+ -------
181
+
182
+ """
183
+ x_local, y_local, local_z = self.position_to_local_coordinates(pos)
184
+ weights = self.trilinear(x_local, y_local, local_z)
185
+ return weights
186
+
187
+ def global_indicies(self, indexes):
188
+ """
189
+ xi, yi, zi to global index
190
+
191
+ Parameters
192
+ ----------
193
+ indexes
194
+
195
+ Returns
196
+ -------
197
+
198
+ """
199
+ indexes = np.array(indexes).swapaxes(0, 2)
200
+ return indexes[:, :, 0] + self.nsteps[None, None, 0] * indexes[:, :,
201
+ 1] + \
202
+ self.nsteps[None, None, 0] * self.nsteps[
203
+ None, None, 1] * indexes[:, :, 2]
204
+
205
+ def neighbour_global_indexes(self, mask = None, **kwargs):
206
+ """
207
+ Get neighbour indexes
208
+
209
+ Parameters
210
+ ----------
211
+ kwargs - indexes array specifying the cells to return neighbours
212
+
213
+ Returns
214
+ -------
215
+
216
+ """
217
+ indexes = None
218
+ if "indexes" in kwargs:
219
+ indexes = kwargs['indexes']
220
+ if "indexes" not in kwargs:
221
+ ii = []
222
+ jj = []
223
+ kk = []
224
+ for i in range(1, self.nsteps[0] - 1):
225
+ for j in range(1, self.nsteps[1] - 1):
226
+ for k in range(1, self.nsteps[2] - 1):
227
+ kk.append(k)
228
+ ii.append(i)
229
+ jj.append(j)
230
+ indexes = np.array([ii, jj, kk])
231
+ # indexes = np.array(indexes).T
232
+ if indexes.ndim != 2:
233
+ print(indexes.ndim)
234
+ return
235
+ # determine which neighbours to return default is diagonals included.
236
+ if mask is None:
237
+ mask = np.array([
238
+ [-1, 0, 1, -1, 0, 1, -1, 0, 1,
239
+ -1, 0, 1, -1, 0, 1, -1, 0, 1,
240
+ -1, 0, 1, -1, 0, 1, -1, 0, 1],
241
+ [-1, -1, -1, 0, 0, 0, 1, 1, 1,
242
+ -1, -1, -1, 0, 0, 0, 1, 1, 1,
243
+ -1, -1, -1, 0, 0, 0, 1, 1, 1],
244
+ [-1, -1, -1, -1, -1, -1, -1, -1, -1,
245
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
246
+ 1, 1, 1, 1, 1, 1, 1, 1, 1]
247
+ ])
248
+ neighbours = indexes[:, None, :] + mask[:, :, None]
249
+ return(neighbours[0, :, :] + self.nsteps[0, None, None] * neighbours[1,
250
+ :, :] + \
251
+ self.nsteps[0, None, None] * self.nsteps[
252
+ 1, None, None] * neighbours[2, :, :]).astype(np.int64)
253
+
254
+ def cell_corner_indexes(self, x_cell_index, y_cell_index, z_cell_index):
255
+ """
256
+ Returns the indexes of the corners of a cell given its location xi,
257
+ yi, zi
258
+
259
+ Parameters
260
+ ----------
261
+ x_cell_index
262
+ y_cell_index
263
+ z_cell_index
264
+
265
+ Returns
266
+ -------
267
+
268
+ """
269
+ xcorner = np.array([0, 1, 0, 0, 1, 0, 1, 1])
270
+ ycorner = np.array([0, 0, 1, 0, 0, 1, 1, 1])
271
+ zcorner = np.array([0, 0, 0, 1, 1, 1, 0, 1])
272
+ xcorners = x_cell_index[:, None] + xcorner[None, :]
273
+ ycorners = y_cell_index[:, None] + ycorner[None, :]
274
+ zcorners = z_cell_index[:, None] + zcorner[None, :]
275
+ return xcorners, ycorners, zcorners
276
+
277
+ def global_index_to_cell_index(self, global_index):
278
+ """
279
+ Convert from global indexes to xi,yi,zi
280
+
281
+ Parameters
282
+ ----------
283
+ global_index
284
+
285
+ Returns
286
+ -------
287
+
288
+ """
289
+ # determine the ijk indices for the global index.
290
+ # remainder when dividing by nx = i
291
+ # remained when dividing modulus of nx by ny is j
292
+
293
+ x_index = global_index % self.nsteps_cells[0, None]
294
+ y_index = global_index // self.nsteps_cells[0, None] % \
295
+ self.nsteps_cells[1, None]
296
+ z_index = global_index // self.nsteps_cells[0, None] // \
297
+ self.nsteps_cells[1, None]
298
+ return x_index, y_index, z_index
299
+
300
+ def node_indexes_to_position(self, xindex, yindex, zindex):
301
+
302
+ x = self.origin[0] + self.step_vector[0] * xindex
303
+ y = self.origin[1] + self.step_vector[1] * yindex
304
+ z = self.origin[2] + self.step_vector[2] * zindex
305
+
306
+ return x, y, z
307
+
308
+ def position_to_cell_corners(self, pos):
309
+
310
+ inside = self.inside(pos)
311
+ ix, iy, iz = self.position_to_cell_index(pos)
312
+ cornersx, cornersy, cornersz = self.cell_corner_indexes(ix, iy, iz)
313
+ globalidx = self.global_indicies(
314
+ np.dstack([cornersx, cornersy, cornersz]).T)
315
+ # if global index is not inside the support set to -1
316
+ globalidx[~inside] = -1
317
+ return globalidx, inside
318
+
319
+ def evaluate_value(self, evaluation_points, property_array):
320
+ """
321
+ Evaluate the value of of the property at the locations.
322
+ Trilinear interpolation dot corner values
323
+
324
+ Parameters
325
+ ----------
326
+ evaluation_points np array of locations
327
+ property_name string of property name
328
+
329
+ Returns
330
+ -------
331
+
332
+ """
333
+ if property_array.shape[0] != self.n_nodes:
334
+ logger.error("Property array does not match grid")
335
+ raise BaseException
336
+ idc, inside = self.position_to_cell_corners(evaluation_points)
337
+ v = np.zeros(idc.shape)
338
+ v[:, :] = np.nan
339
+
340
+ v[inside, :] = self.position_to_dof_coefs(
341
+ evaluation_points[inside, :]).T
342
+
343
+ v[inside, :] *= property_array[idc[inside, :]]
344
+
345
+ return np.sum(v, axis=1)
346
+
347
+ def evaluate_gradient(self, evaluation_points, property_array):
348
+ if property_array.shape[0] != self.n_nodes:
349
+ logger.error("Property array does not match grid")
350
+ raise BaseException
351
+ idc, inside = self.position_to_cell_corners(evaluation_points)
352
+ T = np.zeros((idc.shape[0], 3, 8))
353
+ T[inside, :, :] = self.calcul_T(evaluation_points[inside, :])
354
+ # indices = np.array([self.position_to_cell_index(evaluation_points)])
355
+ # idc = self.global_indicies(indices.swapaxes(0,1))
356
+ # print(idc)
357
+ T[inside, 0, :] *= property_array[idc[inside, :]]
358
+ T[inside, 1, :] *= property_array[idc[inside, :]]
359
+ T[inside, 2, :] *= property_array[idc[inside, :]]
360
+ return np.array(
361
+ [np.sum(T[:, 0, :], axis=1), np.sum(T[:, 1, :], axis=1) ,
362
+ np.sum(T[:, 2, :], axis=1) ]).T
363
+
364
+ def calcul_T(self, pos):
365
+ """
366
+ Calculates the gradient matrix at location pos
367
+ :param pos: numpy array of location Nx3
368
+ :return: Nx3x4 matrix
369
+ """
370
+ # 6_ _ _ _ 8
371
+ # /| /|
372
+ # 4 /_| 5/ |
373
+ # | 2|_ _|_| 7
374
+ # | / | /
375
+ # |/_ _ _|/
376
+ # 0 1
377
+ #
378
+ # xindex, yindex, zindex = self.position_to_cell_index(pos)
379
+ # cellx, celly, cellz = self.cell_corner_indexes(xindex, yindex,zindex)
380
+ # x, y, z = self.node_indexes_to_position(cellx, celly, cellz)
381
+ T = np.zeros((pos.shape[0], 3, 8))
382
+ x, y, z = self.position_to_local_coordinates(pos)
383
+ # div = self.step_vector[0] * self.step_vector[1] * self.step_vector[2]
384
+
385
+ T[:, 0, 0] = -(1 - y) * (1 - z) # v000
386
+ T[:, 0, 1] = (1 - y) * (1 - z) # (y[:, 3] - pos[:, 1]) / div
387
+ T[:, 0, 2] = -y * (1 - z) # (pos[:, 1] - y[:, 0]) / div
388
+ T[:, 0, 3] = -(1 - y) * z # (pos[:, 1] - y[:, 1]) / div
389
+ T[:, 0, 4] = (1 - y) * z
390
+ T[:, 0, 5] = - y * z
391
+ T[:, 0, 6] = y * (1 - z)
392
+ T[:, 0, 7] = y * z
393
+
394
+ T[:, 1, 0] = - (1 - x) * (1 - z)
395
+ T[:, 1, 1] = - x * (1 - z)
396
+ T[:, 1, 2] = (1 - x) * (1 - z)
397
+ T[:, 1, 3] = -(1 - x) * z
398
+ T[:, 1, 4] = -x * z
399
+ T[:, 1, 5] = (1 - x) * z
400
+ T[:, 1, 6] = x * (1 - z)
401
+ T[:, 1, 7] = x * z
402
+
403
+ T[:, 2, 0] = -(1 - x) * (1 - y)
404
+ T[:, 2, 1] = - x * (1 - y)
405
+ T[:, 2, 2] = - (1 - x) * y
406
+ T[:, 2, 3] = (1 - x) * (1 - y)
407
+ T[:, 2, 4] = x * (1 - y)
408
+ T[:, 2, 5] = (1 - x) * y
409
+ T[:, 2, 6] = - x * y
410
+ T[:, 2, 7] = x * y
411
+ return T
412
+
413
+ def slice(self, propertyname, isovalue, region):
414
+ logger.error("function has been removed, please use the modelviewer class")
415
+ return
416
+ #
417
+ # verts, faces, normals, values = marching_cubes(
418
+ # self.properties[propertyname].reshape(self.nsteps, order='F'),
419
+ # isovalue,
420
+ # spacing=self.step_vector)
421
+ # return faces, verts + self.origin[None, :]