LoopStructural 1.0.4__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 +27782 -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 +171 -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 +342 -0
  35. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/geological_interpolator.py +190 -0
  36. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/operator.py +60 -0
  37. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/piecewiselinear_interpolator.py +348 -0
  38. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_grid.py +466 -0
  39. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_tetra.py +638 -0
  40. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/surfe_wrapper.py +117 -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 +1351 -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 +286 -0
  66. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/geological_feature_builder.py +329 -0
  67. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/region_feature.py +34 -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 +192 -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 +378 -0
  91. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/map2loop.py +314 -0
  92. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/utils.py +120 -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 +307 -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 +1012 -0
  103. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/rotation_angle_plotter.py +82 -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.4-py3.7.egg-info/PKG-INFO +10 -0
  106. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.4-py3.7.egg-info/SOURCES.txt +60 -0
  107. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.4-py3.7.egg-info/dependency_links.txt +1 -0
  108. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.4-py3.7.egg-info/requires.txt +8 -0
  109. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.4-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,120 @@
1
+ import logging
2
+
3
+ import numpy as np
4
+ import re
5
+
6
+ logger = logging.getLogger(__name__)
7
+
8
+
9
+ def strike_symbol(strike):
10
+ R = np.zeros((2, 2))
11
+ R[0, 0] = np.cos(np.deg2rad(-strike))
12
+ R[0, 1] = -np.sin(np.deg2rad(-strike))
13
+ R[1, 0] = np.sin(np.deg2rad(-strike))
14
+ R[1, 1] = np.cos(np.deg2rad(-strike))
15
+ R = np.zeros((2, 2))
16
+ R[0, 0] = np.cos(np.deg2rad(-strike))
17
+ R[0, 1] = -np.sin(np.deg2rad(-strike))
18
+ R[1, 0] = np.sin(np.deg2rad(-strike))
19
+ R[1, 1] = np.cos(np.deg2rad(-strike))
20
+
21
+ vec = np.array([0, 1])
22
+ rotated = R @ vec
23
+ vec2 = np.array([-0.5, 0])
24
+ r2 = R @ vec2
25
+ return rotated, r2
26
+ def get_levels():
27
+ """dict for converting to logger levels from string
28
+
29
+
30
+ Returns
31
+ -------
32
+ dict
33
+ contains all strings with corresponding logging levels.
34
+ """
35
+ return {'info':logging.INFO,'warning':logging.WARNING,'error':logging.ERROR,'debug':logging.DEBUG}
36
+
37
+ def log_to_file(filename,level='info'):
38
+ """Set the logging parameters for log file
39
+
40
+
41
+ Parameters
42
+ ----------
43
+ filename : string
44
+ name of file or path to file
45
+ level : str, optional
46
+ 'info', 'warning', 'error', 'debug' mapped to logging levels, by default 'info'
47
+ """
48
+ levels = get_levels()
49
+ level = levels.get(level,logging.WARNING)
50
+ logging.basicConfig(level=level,
51
+ format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
52
+ datefmt='%m-%d %H:%M',
53
+ filename=filename,
54
+ filemode='w')
55
+
56
+ def log_to_console(level='warning'):
57
+ """Set the level of logging to the console
58
+
59
+
60
+ Parameters
61
+ ----------
62
+ level : str, optional
63
+ 'info', 'warning', 'error', 'debug' mapped to logging levels, by default 'info'
64
+ """
65
+ levels = get_levels()
66
+ level = levels.get(level,logging.WARNING)
67
+
68
+ changed_level = False
69
+ for h in logging.getLogger().handlers:
70
+ if type(h) is logging.StreamHandler:
71
+ h.setLevel(level)
72
+ changed_level = True
73
+ if not changed_level:
74
+ console = logging.StreamHandler()
75
+ console.setLevel(level)
76
+ # add the handler to the root logger
77
+ logging.getLogger().addHandler(console)
78
+
79
+ def read_voxet(voxetname,propertyfile):
80
+ """
81
+ Read a gocad property file and the geometry information from the .vo file
82
+ voxetname - is the path to the voxet file
83
+ propertyfile is the path to the binary file
84
+ Returns
85
+ origin numpy array
86
+ voxet_extent - is the length of each axis of the voxet
87
+ N is the number of steps in the voxet
88
+ array is the property values
89
+ steps is the size of the step vector for the voxet
90
+ """
91
+ array = np.fromfile(propertyfile,dtype='float32')
92
+ array = array.astype('<f4') # little endian
93
+ with open(voxetname,'r') as file:
94
+ for l in file:
95
+ if 'AXIS_O ' in l:
96
+ origin = np.array(re.findall(r"[-+]?\d*\.?\d+|[-+]?\d+",l)).astype(float)
97
+ if 'AXIS_U ' in l:
98
+ U = float(re.findall(r'[\d\.\d]+',l)[0])
99
+ if 'AXIS_V ' in l:
100
+ V = float(re.findall(r'[\d\.\d]+',l)[1])
101
+ if 'AXIS_W ' in l:
102
+ W = float(re.findall(r'[\d\.\d]+',l)[2])
103
+ if 'AXIS_N ' in l:
104
+ N = np.array(re.findall(r'[\d\.\d]+',l)).astype(int)
105
+ voxet_extent = np.array([U,V,W])
106
+ steps = (voxet_extent ) / (N-1)
107
+ return origin, voxet_extent, N, array, steps
108
+
109
+ def write_property_to_gocad_voxet(propertyfilename, propertyvalues):
110
+ """
111
+ This function writes a numpy array into the right format for a gocad
112
+ voxet property file. This assumet there is a property already added to the .vo file,
113
+ and is just updating the file.
114
+ propertyfile - string giving the path to the file to write
115
+ propertyvalues - numpy array nz,ny,nx ordering and in float format
116
+ """
117
+ propertyvalues = propertyvalues.astype('>f4') #big endian
118
+ # array = propertyvalues.newbyteorder()
119
+ propertyvalues.tofile(propertyfilename)
120
+
@@ -0,0 +1,19 @@
1
+ """
2
+ This is the base visualistion module for loop structural
3
+
4
+ Submodules
5
+ ==========
6
+
7
+ .. autosummary::
8
+ :toctree: _autosummary
9
+
10
+ map_viewer
11
+ model_visualisation
12
+ rotation_angle_plotter
13
+
14
+ """
15
+
16
+ from .map_viewer import MapView
17
+ from .model_visualisation import LavaVuModelViewer
18
+ from .sphinx_scraper import _get_loop_visualisation_scraper
19
+ from .rotation_angle_plotter import RotationAnglePlotter
@@ -0,0 +1,307 @@
1
+ import logging
2
+
3
+ import matplotlib.pyplot as plt
4
+ import numpy as np
5
+
6
+ logger = logging.getLogger(__name__)
7
+
8
+
9
+ class MapView:
10
+ """
11
+
12
+ """
13
+ def __init__(self, model = None, bounding_box=np.zeros((2,2)), nsteps=None, ax = None, **kwargs):
14
+ """
15
+
16
+ Parameters
17
+ ----------
18
+ origin - lower left
19
+ maximum - upper right
20
+ nsteps - number of cells
21
+ kwargs
22
+ """
23
+
24
+ self.xx = None
25
+ self.yy = None
26
+
27
+ self._bounding_box = bounding_box
28
+ self._nsteps = nsteps
29
+ if self._nsteps is not None and self._bounding_box is not None:
30
+ self._update_grid()
31
+ if model is not None:
32
+ #make sure self._nsteps is 2d
33
+ self.model = model
34
+ self.ax = ax
35
+ if self.ax is None:
36
+ fig, self.ax = plt.subplots(1, figsize=(10, 10))
37
+ self.ax.set_aspect('equal', adjustable='box')
38
+
39
+ # set plot limits to model bounding box
40
+ self._xmin = self.bounding_box[0,0]
41
+ self._xmax = self.bounding_box[1,0]
42
+ self._ymin = self.bounding_box[0,1]
43
+ self._ymax = self.bounding_box[1,1]
44
+ self._update_plot_limits()
45
+ @property
46
+ def model(self):
47
+ return self._model
48
+
49
+ @model.setter
50
+ def model(self,model):
51
+ if model is not None:
52
+ bb = np.array([model.origin[:2],model.maximum[:2]])
53
+ self.bounding_box = bb#model.bounding_box
54
+ self.nsteps = model.nsteps[:2]
55
+ self._model = model
56
+ self._update_grid()
57
+
58
+ @property
59
+ def nsteps(self):
60
+ return self._nsteps
61
+
62
+ @nsteps.setter
63
+ def nsteps(self,nsteps):
64
+ if len(nsteps) != 2:
65
+ logger.error("Can't update nsteps, needs to be 2D")
66
+ return
67
+ self._nsteps = nsteps
68
+ self._update_grid()
69
+
70
+ @property
71
+ def bounding_box(self):
72
+ return self._bounding_box
73
+ @bounding_box.setter
74
+ def bounding_box(self,bounding_box):
75
+ self._bounding_box = bounding_box
76
+ self._update_grid()
77
+
78
+ @property
79
+ def xmin(self):
80
+ return self._xmin
81
+
82
+ @xmin.setter
83
+ def xmin(self,xmin):
84
+ self._xmin = xmin
85
+ self._update_plot_limits()
86
+
87
+ @property
88
+ def xmax(self):
89
+ return self._xmax
90
+
91
+ @xmax.setter
92
+ def xmax(self,xmax):
93
+ self._xmax = xmax
94
+ self._update_plot_limits()
95
+
96
+ @property
97
+ def ymin(self):
98
+ return self._ymin
99
+
100
+ @ymin.setter
101
+ def ymin(self,ymin):
102
+ self._ymin = ymin
103
+ self._update_plot_limits()
104
+
105
+ @property
106
+ def ymax(self):
107
+ return self._ymax
108
+
109
+ @ymax.setter
110
+ def ymax(self,ymax):
111
+ self._ymax = ymax
112
+ self._update_plot_limits()
113
+
114
+ def _update_plot_limits(self):
115
+ self.ax.set_xlim([self._xmin,self._xmax])
116
+ self.ax.set_ylim([self._ymin,self._ymax])
117
+
118
+
119
+ def _update_grid(self):
120
+ """Internal function to update the current grid when the bounding box
121
+ or number of steps changes
122
+ """
123
+ if self.nsteps is None or self.bounding_box is None:
124
+ return
125
+ x = np.linspace(self.bounding_box[0,0], self.bounding_box[1,0], self.nsteps[0])
126
+ y = np.linspace(self.bounding_box[0,1], self.bounding_box[1,1], self.nsteps[1])
127
+ self.xx, self.yy = np.meshgrid(x, y, indexing='ij')
128
+ self.xx = self.xx.flatten()
129
+ self.yy = self.yy.flatten()
130
+
131
+ def add_data(self, feature, val=True, grad=True, unfault=False, dip=True, **kwargs):
132
+ """
133
+ Adds the data associated to the feature to the plot
134
+ Parameters
135
+ ----------
136
+ feature : GeologicalFeature
137
+ the feature whose data you want to add
138
+ val : bool
139
+ whether to add value data
140
+ grad : bool
141
+ whether to add gradient data
142
+ unfault : bool
143
+ plot points in their restored location
144
+ dip : bool
145
+ whether to annotate the dip, default False
146
+
147
+ kwargs are passed to matplotlib functions and draw strike
148
+ Returns
149
+ -------
150
+
151
+ """
152
+ # logger.warning("Plotting restored data locations")
153
+ ori_data = []
154
+ gradient_data = feature.builder.get_gradient_constraints()
155
+ if unfault:
156
+ gradient_data = feature.interpolator.get_gradient_constraints()
157
+
158
+ if gradient_data.shape[0] > 0:
159
+ ori_data.append(gradient_data)
160
+ norm_data = feature.builder.get_norm_constraints()
161
+ if unfault:
162
+ norm_data = feature.interpolator.get_norm_constraints()
163
+
164
+ if norm_data.shape[0] > 0:
165
+ ori_data.append(norm_data)
166
+ cmap = kwargs.pop('cmap','rainbow')
167
+ # if single colour then specify kwarg, otherwise use point value
168
+ if val:
169
+ value_data = np.copy(feature.builder.get_value_constraints())
170
+ if unfault:
171
+ value_data = np.copy(feature.interpolator.get_value_constraints())
172
+
173
+ value_data[:,:3] = self.model.rescale(value_data[:,:3],inplace=False)
174
+ point_colour = kwargs.pop('point_colour',None)
175
+ if point_colour is None:
176
+ self.ax.scatter(value_data[:, 0], value_data[:, 1], c=value_data[:,3],
177
+ vmin=feature.min(), vmax=feature.max(),cmap=cmap)
178
+ if point_colour is not None:
179
+ self.ax.scatter(value_data[:, 0], value_data[:, 1], c=point_colour)
180
+ if grad:
181
+ symb_colour = kwargs.pop('symb_colour','black')
182
+ symb_scale=kwargs.pop('symb_scale',1.)
183
+ gradient_data = np.hstack(ori_data)
184
+ gradient_data[:,:3] = self.model.rescale(gradient_data[:,:3],inplace=False)
185
+ gradient_data[:, 3:5] /= np.linalg.norm(gradient_data[:, 3:5], axis=1)[:, None]
186
+ t = gradient_data[:, [4, 3]] * np.array([1, -1]).T
187
+ n = gradient_data[:, 3:5]
188
+ t *= symb_scale
189
+ n *= 0.5*symb_scale
190
+ p1 = gradient_data[:, [0, 1]] - t
191
+ p2 = gradient_data[:, [0, 1]] + t
192
+ # plt.scatter(val[:,0],val[:,1],c='black')
193
+ self.ax.plot([p1[:, 0], p2[:, 0]], [p1[:, 1], p2[:, 1]], symb_colour)
194
+ p1 = gradient_data[:, [0, 1]]
195
+ p2 = gradient_data[:, [0, 1]] + n
196
+ self.ax.plot([p1[:, 0], p2[:, 0]], [p1[:, 1], p2[:, 1]], symb_colour)
197
+ if dip:
198
+ dip_v = np.rad2deg(np.arccos(gradient_data[:,5])).astype(int)
199
+ for d, xy, v in zip(dip_v,gradient_data[:,:2],gradient_data[:,3:6]):
200
+ self.ax.annotate(d,xy,xytext=xy+v[:2]*.03,fontsize='small')
201
+
202
+ def add_scalar_field(self, feature, z=0, **kwargs):
203
+ """
204
+ Plot the scalar field value on a map
205
+
206
+ Parameters
207
+ ----------
208
+ feature : GeologicalFeature
209
+ which feature to plot on the map
210
+ z : double/np.array
211
+ height
212
+ kwargs
213
+
214
+ Returns
215
+ -------
216
+
217
+ """
218
+ zz = np.zeros(self.xx.shape)
219
+ zz[:] = z
220
+ v = feature.evaluate_value(self.model.scale(np.array([self.xx, self.yy, zz]).T,inplace=False))
221
+ return self.ax.imshow(v.reshape(self.nsteps).T,
222
+ extent=[self.bounding_box[0,0], self.bounding_box[1,0], self.bounding_box[0,1],
223
+ self.bounding_box[1,1]],
224
+ vmin=feature.min(), vmax=feature.max(),
225
+ origin='lower',
226
+ **kwargs)
227
+
228
+ def add_contour(self, feature, values, z=0, mask = None, **kwargs):
229
+ """Add an isoline of a scalar field to the map
230
+
231
+ Parameters
232
+ ----------
233
+ feature : GeologicalFeature
234
+ the feature to isosurface
235
+ values : list
236
+ list of values to contour
237
+ z : double/np.array, optional
238
+ elevation of map, by default 0
239
+ """
240
+ zz = np.zeros(self.xx.shape)
241
+ zz[:] = z
242
+ v = feature.evaluate_value(self.model.scale(np.array([self.xx, self.yy, zz]).T,inplace=False))
243
+ if mask:
244
+ maskv = mask(self.model.scale(np.array([self.xx, self.yy, zz]).T,inplace=False))
245
+ v[~maskv] = np.nan
246
+ return self.ax.contour(v.reshape(self.nsteps).T,extent=[self.bounding_box[0,0], self.bounding_box[1,0], self.bounding_box[0,1],
247
+ self.bounding_box[1,1]],origin='lower',levels=values,**kwargs
248
+ )
249
+
250
+
251
+
252
+ def add_model(self, z = 0,cmap=None):
253
+ """Plot the model onto a map
254
+
255
+ Parameters
256
+ ----------
257
+ z : int/numpy array, optional
258
+ height of the map surface (could also be a dem), by default 0
259
+ cmap : str/matplotlib colourmap, optional
260
+ specify a colour map, by default 'tab20'
261
+ """
262
+ if cmap is None:
263
+ import matplotlib.colors as colors
264
+ colours = []
265
+ boundaries = []
266
+ data = []
267
+ for g in self.model.stratigraphic_column.keys():
268
+ for u, v in self.model.stratigraphic_column[g].items():
269
+ data.append((v['id'],v['colour']))
270
+ colours.append(v['colour'])
271
+ boundaries.append(v['id'])#print(u,v)
272
+ cmap = colors.ListedColormap(colours)
273
+
274
+ zz = np.zeros_like(self.xx)
275
+ zz[:] = z#self.bounding_box[1,2]
276
+ pts = np.vstack([self.xx.flatten(),self.yy.flatten(),zz.flatten()])
277
+ if self.model is None:
278
+ logger.error("Mapview needs a model assigned to plot model on map")
279
+ return
280
+ vals = self.model.evaluate_model(pts.T,scale=True)
281
+ return self.ax.imshow(vals.reshape(self.nsteps).T,extent=[self.bounding_box[0,0], self.bounding_box[1,0], self.bounding_box[0,1],
282
+ self.bounding_box[1,1]],origin='lower',cmap=cmap)
283
+
284
+ def add_fault_displacements(self,z = 0, cmap='rainbow'):
285
+
286
+ zz = np.zeros_like(self.xx)
287
+ zz[:] = z#self.bounding_box[1,2]
288
+ pts = np.vstack([self.xx.flatten(),self.yy.flatten(),zz.flatten()])
289
+ if self.model is None:
290
+ logger.error("Mapview needs a model assigned to plot model on map")
291
+ return
292
+ vals = self.model.evaluate_fault_displacements(pts.T,scale=True)
293
+ return self.ax.imshow(vals.reshape(self.nsteps).T,extent=[self.bounding_box[0,0], self.bounding_box[1,0], self.bounding_box[0,1],
294
+ self.bounding_box[1,1]],origin='lower',cmap=cmap)
295
+
296
+ def add_faults(self,**kwargs):
297
+ for f in self.model.features:
298
+ if f.type=='fault':
299
+ # create a function to return true if displacement > 0
300
+ def mask(x):
301
+ val = f.displacementfeature.evaluate_value(x)
302
+ val[np.isnan(val)] = 0
303
+ maskv = np.zeros(val.shape).astype(bool)
304
+ maskv[np.abs(val) > 0.001] = 1
305
+ return maskv
306
+
307
+ self.add_contour(f,0,mask=mask)
@@ -0,0 +1,16 @@
1
+ # import logging
2
+ #
3
+ #
4
+ # logger = logging.getLogger(__name__)
5
+ #
6
+ # class BaseModelPlotter:
7
+ # def __init__(self, model):
8
+ # """
9
+ #
10
+ # Parameters
11
+ # ----------
12
+ # model
13
+ # """
14
+ # self.model = model
15
+ #
16
+ # def