LoopStructural 1.6.15__tar.gz → 1.6.16__tar.gz

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 (147) hide show
  1. loopstructural-1.6.16/LoopStructural/__init__.py +71 -0
  2. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_geological_interpolator.py +8 -2
  3. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/core/geological_model.py +87 -102
  4. loopstructural-1.6.16/LoopStructural/modelling/core/stratigraphic_column.py +473 -0
  5. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/builders/_fault_builder.py +1 -0
  6. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fault/_fault_segment.py +1 -1
  7. loopstructural-1.6.16/LoopStructural/version.py +1 -0
  8. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural.egg-info/PKG-INFO +1 -1
  9. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural.egg-info/SOURCES.txt +1 -0
  10. {loopstructural-1.6.15 → loopstructural-1.6.16}/PKG-INFO +1 -1
  11. loopstructural-1.6.15/LoopStructural/__init__.py +0 -53
  12. loopstructural-1.6.15/LoopStructural/version.py +0 -1
  13. {loopstructural-1.6.15 → loopstructural-1.6.16}/LICENSE +0 -0
  14. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/__init__.py +0 -0
  15. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/_base.py +0 -0
  16. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/_example_models.py +0 -0
  17. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/claudius.csv +0 -0
  18. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/claudiusbb.txt +0 -0
  19. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/duplex.csv +0 -0
  20. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/duplexbb.txt +0 -0
  21. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/fault_trace/fault_trace.cpg +0 -0
  22. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/fault_trace/fault_trace.dbf +0 -0
  23. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/fault_trace/fault_trace.prj +0 -0
  24. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/fault_trace/fault_trace.shp +0 -0
  25. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/fault_trace/fault_trace.shx +0 -0
  26. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/bbox.csv +0 -0
  27. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/contacts.csv +0 -0
  28. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/fault_displacement.csv +0 -0
  29. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/fault_edges.txt +0 -0
  30. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/fault_locations.csv +0 -0
  31. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/fault_orientations.csv +0 -0
  32. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/stratigraphic_order.csv +0 -0
  33. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/stratigraphic_orientations.csv +0 -0
  34. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/stratigraphic_thickness.csv +0 -0
  35. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/intrusion.csv +0 -0
  36. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/intrusionbb.txt +0 -0
  37. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/onefoldbb.txt +0 -0
  38. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/onefolddata.csv +0 -0
  39. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/refolded_bb.txt +0 -0
  40. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/refolded_fold.csv +0 -0
  41. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/tabular_intrusion.csv +0 -0
  42. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datatypes/__init__.py +0 -0
  43. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datatypes/_bounding_box.py +0 -0
  44. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datatypes/_point.py +0 -0
  45. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datatypes/_structured_grid.py +0 -0
  46. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datatypes/_surface.py +0 -0
  47. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/export/exporters.py +0 -0
  48. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/export/file_formats.py +0 -0
  49. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/export/geoh5.py +0 -0
  50. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/export/gocad.py +0 -0
  51. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/export/omf_wrapper.py +0 -0
  52. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/__init__.py +0 -0
  53. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_api.py +0 -0
  54. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_builders.py +0 -0
  55. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_constant_norm.py +0 -0
  56. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_cython/__init__.py +0 -0
  57. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_discrete_fold_interpolator.py +0 -0
  58. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_discrete_interpolator.py +0 -0
  59. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_finite_difference_interpolator.py +0 -0
  60. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_interpolator_builder.py +0 -0
  61. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_interpolator_factory.py +0 -0
  62. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_interpolatortype.py +0 -0
  63. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_operator.py +0 -0
  64. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_p1interpolator.py +0 -0
  65. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_p2interpolator.py +0 -0
  66. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_surfe_wrapper.py +0 -0
  67. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_2d_base_unstructured.py +0 -0
  68. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_2d_p1_unstructured.py +0 -0
  69. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_2d_p2_unstructured.py +0 -0
  70. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_2d_structured_grid.py +0 -0
  71. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_2d_structured_tetra.py +0 -0
  72. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_3d_base_structured.py +0 -0
  73. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_3d_p2_tetra.py +0 -0
  74. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_3d_structured_grid.py +0 -0
  75. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_3d_structured_tetra.py +0 -0
  76. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_3d_unstructured_tetra.py +0 -0
  77. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/__init__.py +0 -0
  78. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_aabb.py +0 -0
  79. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_base_support.py +0 -0
  80. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_face_table.py +0 -0
  81. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_support_factory.py +0 -0
  82. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/__init__.py +0 -0
  83. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/core/__init__.py +0 -0
  84. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/__init__.py +0 -0
  85. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_analytical_feature.py +0 -0
  86. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_base_geological_feature.py +0 -0
  87. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_cross_product_geological_feature.py +0 -0
  88. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_geological_feature.py +0 -0
  89. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_lambda_geological_feature.py +0 -0
  90. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_projected_vector_feature.py +0 -0
  91. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_region.py +0 -0
  92. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_structural_frame.py +0 -0
  93. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_unconformity_feature.py +0 -0
  94. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/builders/__init__.py +0 -0
  95. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/builders/_base_builder.py +0 -0
  96. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/builders/_folded_feature_builder.py +0 -0
  97. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/builders/_geological_feature_builder.py +0 -0
  98. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/builders/_structural_frame_builder.py +0 -0
  99. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fault/__init__.py +0 -0
  100. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fault/_fault_function.py +0 -0
  101. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fault/_fault_function_feature.py +0 -0
  102. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/__init__.py +0 -0
  103. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/_fold.py +0 -0
  104. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/_fold_rotation_angle_feature.py +0 -0
  105. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/_foldframe.py +0 -0
  106. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/_svariogram.py +0 -0
  107. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/fold_function/__init__.py +0 -0
  108. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/fold_function/_base_fold_rotation_angle.py +0 -0
  109. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/fold_function/_fourier_series_fold_rotation_angle.py +0 -0
  110. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/fold_function/_lambda_fold_rotation_angle.py +0 -0
  111. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/fold_function/_trigo_fold_rotation_angle.py +0 -0
  112. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/input/__init__.py +0 -0
  113. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/input/fault_network.py +0 -0
  114. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/input/map2loop_processor.py +0 -0
  115. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/input/process_data.py +0 -0
  116. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/input/project_file.py +0 -0
  117. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/intrusions/__init__.py +0 -0
  118. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/intrusions/geom_conceptual_models.py +0 -0
  119. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/intrusions/geometric_scaling_functions.py +0 -0
  120. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/intrusions/intrusion_builder.py +0 -0
  121. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/intrusions/intrusion_feature.py +0 -0
  122. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/intrusions/intrusion_frame_builder.py +0 -0
  123. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/intrusions/intrusion_support_functions.py +0 -0
  124. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/__init__.py +0 -0
  125. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/_surface.py +0 -0
  126. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/_transformation.py +0 -0
  127. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/colours.py +0 -0
  128. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/config.py +0 -0
  129. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/dtm_creator.py +0 -0
  130. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/exceptions.py +0 -0
  131. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/features.py +0 -0
  132. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/helper.py +0 -0
  133. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/json_encoder.py +0 -0
  134. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/linalg.py +0 -0
  135. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/logging.py +0 -0
  136. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/maths.py +0 -0
  137. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/regions.py +0 -0
  138. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/typing.py +0 -0
  139. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/utils.py +0 -0
  140. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/visualisation/__init__.py +0 -0
  141. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural.egg-info/dependency_links.txt +0 -0
  142. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural.egg-info/requires.txt +0 -0
  143. {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural.egg-info/top_level.txt +0 -0
  144. {loopstructural-1.6.15 → loopstructural-1.6.16}/README.md +0 -0
  145. {loopstructural-1.6.15 → loopstructural-1.6.16}/pyproject.toml +0 -0
  146. {loopstructural-1.6.15 → loopstructural-1.6.16}/setup.cfg +0 -0
  147. {loopstructural-1.6.15 → loopstructural-1.6.16}/setup.py +0 -0
@@ -0,0 +1,71 @@
1
+ """
2
+ LoopStructural
3
+ ==============
4
+
5
+ """
6
+
7
+ import logging
8
+ from logging.config import dictConfig
9
+
10
+ __all__ = ["GeologicalModel"]
11
+ import tempfile
12
+ from pathlib import Path
13
+ from .version import __version__
14
+
15
+ experimental = False
16
+ ch = logging.StreamHandler()
17
+ formatter = logging.Formatter("%(levelname)s: %(asctime)s: %(filename)s:%(lineno)d -- %(message)s")
18
+ ch.setFormatter(formatter)
19
+ ch.setLevel(logging.WARNING)
20
+ loggers = {}
21
+ from .modelling.core.geological_model import GeologicalModel
22
+ from .modelling.core.stratigraphic_column import StratigraphicColumn
23
+ from .interpolators._api import LoopInterpolator
24
+ from .interpolators import InterpolatorBuilder
25
+ from .datatypes import BoundingBox
26
+ from .utils import log_to_console, log_to_file, getLogger, rng, get_levels
27
+
28
+ logger = getLogger(__name__)
29
+ logger.info("Imported LoopStructural")
30
+
31
+
32
+ def setLogging(level="info", handler=None):
33
+ """
34
+ Set the logging parameters for log file or custom handler
35
+
36
+ Parameters
37
+ ----------
38
+ level : str
39
+ 'info', 'warning', 'error', 'debug'
40
+ handler : logging.Handler, optional
41
+ A logging handler to use instead of the default StreamHandler
42
+ """
43
+ import LoopStructural
44
+
45
+ levels = get_levels()
46
+ level_value = levels.get(level, logging.WARNING)
47
+
48
+ # Create default handler if none provided
49
+ if handler is None:
50
+ handler = logging.StreamHandler()
51
+
52
+ formatter = logging.Formatter(
53
+ "%(levelname)s: %(asctime)s: %(filename)s:%(lineno)d -- %(message)s"
54
+ )
55
+ handler.setFormatter(formatter)
56
+ handler.setLevel(level_value)
57
+
58
+ # Replace handlers in all known loggers
59
+ for name in LoopStructural.loggers:
60
+ logger = logging.getLogger(name)
61
+ logger.handlers = []
62
+ logger.addHandler(handler)
63
+ logger.setLevel(level_value)
64
+
65
+ # Also apply to main module logger
66
+ main_logger = logging.getLogger(__name__)
67
+ main_logger.handlers = []
68
+ main_logger.addHandler(handler)
69
+ main_logger.setLevel(level_value)
70
+
71
+ main_logger.info(f"Set logging to {level}")
@@ -154,16 +154,22 @@ class GeologicalInterpolator(metaclass=ABCMeta):
154
154
  ----------
155
155
  points : np.ndarray
156
156
  array containing the value constraints usually 7-8 columns.
157
- X,Y,Z,nx,ny,nz,weight
157
+ X,Y,Z,nx,ny,nz,(weight, default : 1 for each row)
158
158
 
159
159
  Returns
160
160
  -------
161
161
 
162
+ Notes
163
+ -------
164
+ If no weights are provided, w = 1 is assigned to each normal constraint.
165
+
162
166
  """
163
167
  if points.shape[1] == self.dimensions * 2:
164
168
  points = np.hstack([points, np.ones((points.shape[0], 1))])
169
+ logger.warning(f"No weight provided for normal constraints, all weights are set to 1")
170
+ raise Warning
165
171
  if points.shape[1] < self.dimensions * 2 + 1:
166
- raise ValueError("Nonrmal constraints must at least have X,Y,Z,nx,ny,nz")
172
+ raise ValueError("Normal constraints must at least have X,Y,Z,nx,ny,nz")
167
173
  self.n_n = points.shape[0]
168
174
  self.data["normal"] = points
169
175
  self.up_to_date = False
@@ -37,7 +37,7 @@ from ...datatypes import BoundingBox
37
37
  from ...modelling.intrusions import IntrusionBuilder
38
38
 
39
39
  from ...modelling.intrusions import IntrusionFrameBuilder
40
-
40
+ from .stratigraphic_column import StratigraphicColumn
41
41
 
42
42
  logger = getLogger(__name__)
43
43
 
@@ -61,14 +61,11 @@ class GeologicalModel:
61
61
  the origin of the model box
62
62
  parameters : dict
63
63
  a dictionary tracking the parameters used to build the model
64
-
64
+
65
65
 
66
66
  """
67
67
 
68
- def __init__(
69
- self,
70
- *args
71
- ):
68
+ def __init__(self, *args):
72
69
  """
73
70
  Parameters
74
71
  ----------
@@ -78,7 +75,7 @@ class GeologicalModel:
78
75
  the origin of the model
79
76
  maximum : np.array(3,dtype=doubles)
80
77
  the maximum of the model
81
-
78
+
82
79
  Examples
83
80
  --------
84
81
  Demo data
@@ -126,7 +123,8 @@ class GeologicalModel:
126
123
  self.feature_name_index = {}
127
124
  self._data = pd.DataFrame() # None
128
125
 
129
- self.stratigraphic_column = None
126
+ self.stratigraphic_column = StratigraphicColumn()
127
+
130
128
 
131
129
  self.tol = 1e-10 * np.max(self.bounding_box.maximum - self.bounding_box.origin)
132
130
  self._dtm = None
@@ -148,29 +146,6 @@ class GeologicalModel:
148
146
  # json["features"] = [f.to_json() for f in self.features]
149
147
  return json
150
148
 
151
- # @classmethod
152
- # def from_json(cls,json):
153
- # """
154
- # Create a geological model from a json string
155
-
156
- # Parameters
157
- # ----------
158
- # json : str
159
- # json string of the geological model
160
-
161
- # Returns
162
- # -------
163
- # model : GeologicalModel
164
- # a geological model
165
- # """
166
- # model = cls(json["model"]["origin"],json["model"]["maximum"],data=None)
167
- # model.stratigraphic_column = json["model"]["stratigraphic_column"]
168
- # model.nsteps = json["model"]["nsteps"]
169
- # model.data = pd.read_json(json["model"]["data"])
170
- # model.features = []
171
- # for feature in json["features"]:
172
- # model.features.append(GeologicalFeature.from_json(feature,model))
173
- # return model
174
149
  def __str__(self):
175
150
  return f"GeologicalModel with {len(self.features)} features"
176
151
 
@@ -181,6 +156,38 @@ class GeologicalModel:
181
156
  data = data.copy()
182
157
  data[['X', 'Y', 'Z']] = self.bounding_box.project(data[['X', 'Y', 'Z']].to_numpy())
183
158
 
159
+ if "type" in data:
160
+ logger.warning("'type' is deprecated replace with 'feature_name' \n")
161
+ data.rename(columns={"type": "feature_name"}, inplace=True)
162
+ if "feature_name" not in data:
163
+ logger.error("Data does not contain 'feature_name' column")
164
+ raise BaseException("Cannot load data")
165
+ for h in all_heading():
166
+ if h not in data:
167
+ data[h] = np.nan
168
+ if h == "w":
169
+ data[h] = 1.0
170
+ if h == "coord":
171
+ data[h] = 0
172
+ if h == "polarity":
173
+ data[h] = 1.0
174
+ # LS wants polarity as -1 or 1, change 0 to -1
175
+ data.loc[data["polarity"] == 0, "polarity"] = -1.0
176
+ data.loc[np.isnan(data["w"]), "w"] = 1.0
177
+ if "strike" in data and "dip" in data:
178
+ logger.info("Converting strike and dip to vectors")
179
+ mask = np.all(~np.isnan(data.loc[:, ["strike", "dip"]]), axis=1)
180
+ data.loc[mask, gradient_vec_names()] = (
181
+ strikedip2vector(data.loc[mask, "strike"], data.loc[mask, "dip"])
182
+ * data.loc[mask, "polarity"].to_numpy()[:, None]
183
+ )
184
+ data.drop(["strike", "dip"], axis=1, inplace=True)
185
+ data[['X', 'Y', 'Z', 'val', 'nx', 'ny', 'nz', 'gx', 'gy', 'gz', 'tx', 'ty', 'tz']] = data[
186
+ ['X', 'Y', 'Z', 'val', 'nx', 'ny', 'nz', 'gx', 'gy', 'gz', 'tx', 'ty', 'tz']
187
+ ].astype(float)
188
+ return data
189
+
190
+
184
191
  if "type" in data:
185
192
  logger.warning("'type' is deprecated replace with 'feature_name' \n")
186
193
  data.rename(columns={"type": "feature_name"}, inplace=True)
@@ -402,12 +409,6 @@ class GeologicalModel:
402
409
  """
403
410
  return [f.name for f in self.faults]
404
411
 
405
- def check_inialisation(self):
406
- if self.data is None:
407
- logger.error("Data not associated with GeologicalModel. Run set_data")
408
- return False
409
- if self.data.shape[0] > 0:
410
- return True
411
412
 
412
413
  def to_file(self, file):
413
414
  """Save a model to a pickle file requires dill
@@ -506,7 +507,6 @@ class GeologicalModel:
506
507
  # self._data[['X','Y','Z']] = self.bounding_box.project(self._data[['X','Y','Z']].to_numpy())
507
508
 
508
509
 
509
-
510
510
  def set_model_data(self, data):
511
511
  logger.warning("deprecated method. Model data can now be set using the data attribute")
512
512
  self.data = data.copy()
@@ -532,28 +532,34 @@ class GeologicalModel:
532
532
  }
533
533
 
534
534
  """
535
+ self.stratigraphic_column.clear()
535
536
  # if the colour for a unit hasn't been specified we can just sample from
536
537
  # a colour map e.g. tab20
537
538
  logger.info("Adding stratigraphic column to model")
538
- random_colour = True
539
- n_units = 0
539
+ DeprecationWarning(
540
+ "set_stratigraphic_column is deprecated, use model.stratigraphic_column.add_units instead"
541
+ )
540
542
  for g in stratigraphic_column.keys():
541
543
  for u in stratigraphic_column[g].keys():
542
- if "colour" in stratigraphic_column[g][u]:
543
- random_colour = False
544
- break
545
- n_units += 1
546
- if random_colour:
547
- import matplotlib.cm as cm
548
-
549
- cmap = cm.get_cmap(cmap, n_units)
550
- cmap_colours = cmap.colors
551
- ci = 0
552
- for g in stratigraphic_column.keys():
553
- for u in stratigraphic_column[g].keys():
554
- stratigraphic_column[g][u]["colour"] = cmap_colours[ci, :]
555
- ci += 1
556
- self.stratigraphic_column = stratigraphic_column
544
+ thickness = 0
545
+ if "min" in stratigraphic_column[g][u] and "max" in stratigraphic_column[g][u]:
546
+ min_val = stratigraphic_column[g][u]["min"]
547
+ max_val = stratigraphic_column[g][u].get("max", None)
548
+ thickness = max_val - min_val if max_val is not None else None
549
+ logger.warning(
550
+ f"""
551
+ model.stratigraphic_column.add_unit({u},
552
+ colour={stratigraphic_column[g][u].get("colour", None)},
553
+ thickness={thickness})"""
554
+ )
555
+ self.stratigraphic_column.add_unit(
556
+ u,
557
+ colour=stratigraphic_column[g][u].get("colour", None),
558
+ thickness=thickness,
559
+ )
560
+ self.stratigraphic_column.add_unconformity(
561
+ name=''.join([g, 'unconformity']),
562
+ )
557
563
 
558
564
  def create_and_add_foliation(
559
565
  self,
@@ -600,9 +606,7 @@ class GeologicalModel:
600
606
  An interpolator will be chosen by calling :meth:`LoopStructural.GeologicalModel.get_interpolator`
601
607
 
602
608
  """
603
- if not self.check_inialisation():
604
- logger.warning(f"{series_surface_data} not added, model not initialised")
605
- return
609
+
606
610
  # if tol is not specified use the model default
607
611
  if tol is None:
608
612
  tol = self.tol
@@ -638,7 +642,7 @@ class GeologicalModel:
638
642
 
639
643
  def create_and_add_fold_frame(
640
644
  self,
641
- fold_frame_name:str,
645
+ fold_frame_name: str,
642
646
  *,
643
647
  fold_frame_data=None,
644
648
  interpolatortype="FDI",
@@ -667,15 +671,14 @@ class GeologicalModel:
667
671
  :class:`LoopStructural.modelling.features.builders.StructuralFrameBuilder`
668
672
  and :meth:`LoopStructural.modelling.features.builders.StructuralFrameBuilder.setup`
669
673
  and the interpolator, such as `domain` or `tol`
670
-
674
+
671
675
 
672
676
  Returns
673
677
  -------
674
678
  fold_frame : FoldFrame
675
679
  the created fold frame
676
680
  """
677
- if not self.check_inialisation():
678
- return False
681
+
679
682
  if tol is None:
680
683
  tol = self.tol
681
684
 
@@ -751,8 +754,7 @@ class GeologicalModel:
751
754
  :class:`LoopStructural.modelling.features.builders.FoldedFeatureBuilder`
752
755
 
753
756
  """
754
- if not self.check_inialisation():
755
- return False
757
+
756
758
  if tol is None:
757
759
  tol = self.tol
758
760
 
@@ -781,11 +783,8 @@ class GeologicalModel:
781
783
  if foliation_data.shape[0] == 0:
782
784
  logger.warning(f"No data for {foliation_name}, skipping")
783
785
  return
784
- series_builder.add_data_from_data_frame(
785
- self.prepare_data(
786
- foliation_data
787
- )
788
- )
786
+ series_builder.add_data_from_data_frame(self.prepare_data(foliation_data))
787
+
789
788
  self._add_faults(series_builder)
790
789
  # series_builder.add_data_to_interpolator(True)
791
790
  # build feature
@@ -852,8 +851,7 @@ class GeologicalModel:
852
851
  see :class:`LoopStructural.modelling.features.fold.FoldEvent`,
853
852
  :class:`LoopStructural.modelling.features.builders.FoldedFeatureBuilder`
854
853
  """
855
- if not self.check_inialisation():
856
- return False
854
+
857
855
  if tol is None:
858
856
  tol = self.tol
859
857
 
@@ -1180,7 +1178,7 @@ class GeologicalModel:
1180
1178
  return uc_feature
1181
1179
 
1182
1180
  def create_and_add_domain_fault(
1183
- self, fault_surface_data,*, nelements=10000, interpolatortype="FDI", **kwargs
1181
+ self, fault_surface_data, *, nelements=10000, interpolatortype="FDI", **kwargs
1184
1182
  ):
1185
1183
  """
1186
1184
  Parameters
@@ -1234,7 +1232,7 @@ class GeologicalModel:
1234
1232
  fault_name: str,
1235
1233
  displacement: float,
1236
1234
  *,
1237
- fault_data:Optional[pd.DataFrame] = None,
1235
+ fault_data: Optional[pd.DataFrame] = None,
1238
1236
  interpolatortype="FDI",
1239
1237
  tol=None,
1240
1238
  fault_slip_vector=None,
@@ -1319,7 +1317,7 @@ class GeologicalModel:
1319
1317
  if "data_region" in kwargs:
1320
1318
  kwargs.pop("data_region")
1321
1319
  logger.error("kwarg data_region currently not supported, disabling")
1322
- displacement_scaled = displacement
1320
+ displacement_scaled = displacement
1323
1321
  fault_frame_builder = FaultBuilder(
1324
1322
  interpolatortype,
1325
1323
  bounding_box=self.bounding_box,
@@ -1340,11 +1338,11 @@ class GeologicalModel:
1340
1338
  if fault_center is not None and ~np.isnan(fault_center).any():
1341
1339
  fault_center = self.scale(fault_center, inplace=False)
1342
1340
  if minor_axis:
1343
- minor_axis = minor_axis
1341
+ minor_axis = minor_axis
1344
1342
  if major_axis:
1345
- major_axis = major_axis
1343
+ major_axis = major_axis
1346
1344
  if intermediate_axis:
1347
- intermediate_axis = intermediate_axis
1345
+ intermediate_axis = intermediate_axis
1348
1346
  fault_frame_builder.create_data_from_geometry(
1349
1347
  fault_frame_data=self.prepare_data(fault_data),
1350
1348
  fault_center=fault_center,
@@ -1400,7 +1398,8 @@ class GeologicalModel:
1400
1398
 
1401
1399
  """
1402
1400
 
1403
- return self.bounding_box.reproject(points,inplace=inplace)
1401
+ return self.bounding_box.reproject(points, inplace=inplace)
1402
+
1404
1403
 
1405
1404
  # TODO move scale to bounding box/transformer
1406
1405
  def scale(self, points: np.ndarray, *, inplace: bool = False) -> np.ndarray:
@@ -1418,7 +1417,8 @@ class GeologicalModel:
1418
1417
  points : np.a::rray((N,3),dtype=double)
1419
1418
 
1420
1419
  """
1421
- return self.bounding_box.project(np.array(points).astype(float),inplace=inplace)
1420
+ return self.bounding_box.project(np.array(points).astype(float), inplace=inplace)
1421
+
1422
1422
 
1423
1423
  def regular_grid(self, *, nsteps=None, shuffle=True, rescale=False, order="C"):
1424
1424
  """
@@ -1567,7 +1567,7 @@ class GeologicalModel:
1567
1567
  if f.type == FeatureType.FAULT:
1568
1568
  disp = f.displacementfeature.evaluate_value(points)
1569
1569
  vals[~np.isnan(disp)] += disp[~np.isnan(disp)]
1570
- return vals # convert from restoration magnutude to displacement
1570
+ return vals # convert from restoration magnutude to displacement
1571
1571
 
1572
1572
  def get_feature_by_name(self, feature_name) -> GeologicalFeature:
1573
1573
  """Returns a feature from the mode given a name
@@ -1736,30 +1736,15 @@ class GeologicalModel:
1736
1736
  units = []
1737
1737
  if self.stratigraphic_column is None:
1738
1738
  return []
1739
- for group in self.stratigraphic_column.keys():
1740
- if group == "faults":
1739
+ units = self.stratigraphic_column.get_isovalues()
1740
+ for name, u in units.items():
1741
+ if u['group'] not in self:
1742
+ logger.warning(f"Group {u['group']} not found in model")
1741
1743
  continue
1742
- for series in self.stratigraphic_column[group].values():
1743
- series['feature_name'] = group
1744
- units.append(series)
1745
- unit_table = pd.DataFrame(units)
1746
- for u in unit_table['feature_name'].unique():
1747
-
1748
- values = unit_table.loc[unit_table['feature_name'] == u, 'min' if bottoms else 'max']
1749
- if 'name' not in unit_table.columns:
1750
- unit_table['name'] = unit_table['feature_name']
1751
-
1752
- names = unit_table[unit_table['feature_name'] == u]['name']
1753
- values = values.loc[~np.logical_or(values == np.inf, values == -np.inf)]
1744
+ feature = self.get_feature_by_name(u['group'])
1745
+
1754
1746
  surfaces.extend(
1755
- self.get_feature_by_name(u).surfaces(
1756
- values.to_list(),
1757
- self.bounding_box,
1758
- name=names.loc[values.index].to_list(),
1759
- colours=unit_table.loc[unit_table['feature_name'] == u, 'colour'].tolist()[
1760
- 1:
1761
- ], # we don't isosurface basement, no value
1762
- )
1747
+ feature.surfaces([u['value']], self.bounding_box, name=name, colours=[u['colour']])
1763
1748
  )
1764
1749
 
1765
1750
  return surfaces