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.
- loopstructural-1.6.16/LoopStructural/__init__.py +71 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_geological_interpolator.py +8 -2
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/core/geological_model.py +87 -102
- loopstructural-1.6.16/LoopStructural/modelling/core/stratigraphic_column.py +473 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/builders/_fault_builder.py +1 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fault/_fault_segment.py +1 -1
- loopstructural-1.6.16/LoopStructural/version.py +1 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural.egg-info/PKG-INFO +1 -1
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural.egg-info/SOURCES.txt +1 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/PKG-INFO +1 -1
- loopstructural-1.6.15/LoopStructural/__init__.py +0 -53
- loopstructural-1.6.15/LoopStructural/version.py +0 -1
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LICENSE +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/_base.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/_example_models.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/claudius.csv +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/claudiusbb.txt +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/duplex.csv +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/duplexbb.txt +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/fault_trace/fault_trace.cpg +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/fault_trace/fault_trace.dbf +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/fault_trace/fault_trace.prj +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/fault_trace/fault_trace.shp +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/fault_trace/fault_trace.shx +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/bbox.csv +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/contacts.csv +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/fault_displacement.csv +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/fault_edges.txt +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/fault_locations.csv +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/fault_orientations.csv +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/stratigraphic_order.csv +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/stratigraphic_orientations.csv +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/geological_map_data/stratigraphic_thickness.csv +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/intrusion.csv +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/intrusionbb.txt +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/onefoldbb.txt +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/onefolddata.csv +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/refolded_bb.txt +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/refolded_fold.csv +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datasets/data/tabular_intrusion.csv +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datatypes/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datatypes/_bounding_box.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datatypes/_point.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datatypes/_structured_grid.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/datatypes/_surface.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/export/exporters.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/export/file_formats.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/export/geoh5.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/export/gocad.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/export/omf_wrapper.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_api.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_builders.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_constant_norm.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_cython/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_discrete_fold_interpolator.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_discrete_interpolator.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_finite_difference_interpolator.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_interpolator_builder.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_interpolator_factory.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_interpolatortype.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_operator.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_p1interpolator.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_p2interpolator.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/_surfe_wrapper.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_2d_base_unstructured.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_2d_p1_unstructured.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_2d_p2_unstructured.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_2d_structured_grid.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_2d_structured_tetra.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_3d_base_structured.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_3d_p2_tetra.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_3d_structured_grid.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_3d_structured_tetra.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_3d_unstructured_tetra.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_aabb.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_base_support.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_face_table.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/interpolators/supports/_support_factory.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/core/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_analytical_feature.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_base_geological_feature.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_cross_product_geological_feature.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_geological_feature.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_lambda_geological_feature.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_projected_vector_feature.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_region.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_structural_frame.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/_unconformity_feature.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/builders/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/builders/_base_builder.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/builders/_folded_feature_builder.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/builders/_geological_feature_builder.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/builders/_structural_frame_builder.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fault/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fault/_fault_function.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fault/_fault_function_feature.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/_fold.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/_fold_rotation_angle_feature.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/_foldframe.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/_svariogram.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/fold_function/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/fold_function/_base_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/fold_function/_fourier_series_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/fold_function/_lambda_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/features/fold/fold_function/_trigo_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/input/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/input/fault_network.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/input/map2loop_processor.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/input/process_data.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/input/project_file.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/intrusions/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/intrusions/geom_conceptual_models.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/intrusions/geometric_scaling_functions.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/intrusions/intrusion_builder.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/intrusions/intrusion_feature.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/intrusions/intrusion_frame_builder.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/intrusions/intrusion_support_functions.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/_surface.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/_transformation.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/colours.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/config.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/dtm_creator.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/exceptions.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/features.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/helper.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/json_encoder.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/linalg.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/logging.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/maths.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/regions.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/typing.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/utils/utils.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/visualisation/__init__.py +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural.egg-info/dependency_links.txt +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural.egg-info/requires.txt +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural.egg-info/top_level.txt +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/README.md +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/pyproject.toml +0 -0
- {loopstructural-1.6.15 → loopstructural-1.6.16}/setup.cfg +0 -0
- {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("
|
|
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
|
{loopstructural-1.6.15 → loopstructural-1.6.16}/LoopStructural/modelling/core/geological_model.py
RENAMED
|
@@ -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 =
|
|
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
|
-
|
|
539
|
-
|
|
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
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
1740
|
-
|
|
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
|
-
|
|
1743
|
-
|
|
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
|
-
|
|
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
|