LoopStructural 1.6.18__tar.gz → 1.6.20__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.18 → loopstructural-1.6.20}/LoopStructural/__init__.py +11 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_p1interpolator.py +3 -2
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_p2interpolator.py +2 -1
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/core/geological_model.py +96 -61
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/core/stratigraphic_column.py +30 -4
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/_base_geological_feature.py +2 -1
- loopstructural-1.6.20/LoopStructural/modelling/features/_feature_converters.py +36 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/_geological_feature.py +1 -1
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/_structural_frame.py +2 -6
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/builders/_folded_feature_builder.py +22 -4
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/builders/_geological_feature_builder.py +3 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/builders/_structural_frame_builder.py +33 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/input/process_data.py +2 -0
- loopstructural-1.6.20/LoopStructural/version.py +1 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural.egg-info/PKG-INFO +1 -1
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural.egg-info/SOURCES.txt +1 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/PKG-INFO +1 -1
- loopstructural-1.6.18/LoopStructural/version.py +0 -1
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LICENSE +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/__init__.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/_base.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/_example_models.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/claudius.csv +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/claudiusbb.txt +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/duplex.csv +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/duplexbb.txt +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/fault_trace/fault_trace.cpg +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/fault_trace/fault_trace.dbf +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/fault_trace/fault_trace.prj +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/fault_trace/fault_trace.shp +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/fault_trace/fault_trace.shx +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/geological_map_data/bbox.csv +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/geological_map_data/contacts.csv +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/geological_map_data/fault_displacement.csv +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/geological_map_data/fault_edges.txt +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/geological_map_data/fault_locations.csv +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/geological_map_data/fault_orientations.csv +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/geological_map_data/stratigraphic_order.csv +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/geological_map_data/stratigraphic_orientations.csv +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/geological_map_data/stratigraphic_thickness.csv +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/intrusion.csv +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/intrusionbb.txt +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/onefoldbb.txt +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/onefolddata.csv +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/refolded_bb.txt +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/refolded_fold.csv +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datasets/data/tabular_intrusion.csv +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datatypes/__init__.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datatypes/_bounding_box.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datatypes/_point.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datatypes/_structured_grid.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/datatypes/_surface.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/export/exporters.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/export/file_formats.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/export/geoh5.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/export/gocad.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/export/omf_wrapper.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/__init__.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_api.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_builders.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_constant_norm.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_cython/__init__.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_discrete_fold_interpolator.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_discrete_interpolator.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_finite_difference_interpolator.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_geological_interpolator.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_interpolator_builder.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_interpolator_factory.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_interpolatortype.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_operator.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_surfe_wrapper.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/supports/_2d_base_unstructured.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/supports/_2d_p1_unstructured.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/supports/_2d_p2_unstructured.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/supports/_2d_structured_grid.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/supports/_2d_structured_tetra.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/supports/_3d_base_structured.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/supports/_3d_p2_tetra.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/supports/_3d_structured_grid.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/supports/_3d_structured_tetra.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/supports/_3d_unstructured_tetra.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/supports/__init__.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/supports/_aabb.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/supports/_base_support.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/supports/_face_table.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/supports/_support_factory.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/__init__.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/core/__init__.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/core/fault_topology.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/__init__.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/_analytical_feature.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/_cross_product_geological_feature.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/_lambda_geological_feature.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/_projected_vector_feature.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/_region.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/_unconformity_feature.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/builders/__init__.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/builders/_base_builder.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/builders/_fault_builder.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/fault/__init__.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/fault/_fault_function.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/fault/_fault_function_feature.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/fault/_fault_segment.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/fold/__init__.py +1 -1
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/fold/_fold.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/fold/_fold_rotation_angle_feature.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/fold/_foldframe.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/fold/_svariogram.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/fold/fold_function/__init__.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/fold/fold_function/_base_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/fold/fold_function/_fourier_series_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/fold/fold_function/_lambda_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/features/fold/fold_function/_trigo_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/input/__init__.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/input/fault_network.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/input/map2loop_processor.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/input/project_file.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/intrusions/__init__.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/intrusions/geom_conceptual_models.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/intrusions/geometric_scaling_functions.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/intrusions/intrusion_builder.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/intrusions/intrusion_feature.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/intrusions/intrusion_frame_builder.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/intrusions/intrusion_support_functions.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/__init__.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/_surface.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/_transformation.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/colours.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/config.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/dtm_creator.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/exceptions.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/features.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/helper.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/json_encoder.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/linalg.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/logging.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/maths.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/observer.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/regions.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/typing.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/utils/utils.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/visualisation/__init__.py +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural.egg-info/dependency_links.txt +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural.egg-info/requires.txt +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural.egg-info/top_level.txt +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/README.md +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/pyproject.toml +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/setup.cfg +0 -0
- {loopstructural-1.6.18 → loopstructural-1.6.20}/setup.py +0 -0
|
@@ -7,6 +7,9 @@ LoopStructural
|
|
|
7
7
|
import logging
|
|
8
8
|
from logging.config import dictConfig
|
|
9
9
|
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
|
|
12
|
+
|
|
10
13
|
__all__ = ["GeologicalModel"]
|
|
11
14
|
import tempfile
|
|
12
15
|
from pathlib import Path
|
|
@@ -18,6 +21,14 @@ formatter = logging.Formatter("%(levelname)s: %(asctime)s: %(filename)s:%(lineno
|
|
|
18
21
|
ch.setFormatter(formatter)
|
|
19
22
|
ch.setLevel(logging.WARNING)
|
|
20
23
|
loggers = {}
|
|
24
|
+
@dataclass
|
|
25
|
+
class LoopStructuralConfig:
|
|
26
|
+
"""
|
|
27
|
+
Configuration for LoopStructural
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
nelements: int = 10_000
|
|
31
|
+
|
|
21
32
|
from .modelling.core.geological_model import GeologicalModel
|
|
22
33
|
from .modelling.core.stratigraphic_column import StratigraphicColumn
|
|
23
34
|
from .modelling.core.fault_topology import FaultTopology
|
{loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_p1interpolator.py
RENAMED
|
@@ -6,8 +6,9 @@ import logging
|
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
|
|
9
|
-
from ._discrete_interpolator import DiscreteInterpolator
|
|
10
9
|
|
|
10
|
+
from ._discrete_interpolator import DiscreteInterpolator
|
|
11
|
+
from . import InterpolatorType
|
|
11
12
|
logger = logging.getLogger(__name__)
|
|
12
13
|
|
|
13
14
|
|
|
@@ -37,7 +38,7 @@ class P1Interpolator(DiscreteInterpolator):
|
|
|
37
38
|
"tpw": 1.0,
|
|
38
39
|
"ipw": 1.0,
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
+
self.type = InterpolatorType.PIECEWISE_LINEAR
|
|
41
42
|
def add_gradient_constraints(self, w=1.0):
|
|
42
43
|
pass
|
|
43
44
|
|
{loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/interpolators/_p2interpolator.py
RENAMED
|
@@ -8,6 +8,7 @@ from typing import Optional, Callable
|
|
|
8
8
|
import numpy as np
|
|
9
9
|
|
|
10
10
|
from ..interpolators import DiscreteInterpolator
|
|
11
|
+
from . import InterpolatorType
|
|
11
12
|
|
|
12
13
|
logger = logging.getLogger(__name__)
|
|
13
14
|
|
|
@@ -41,7 +42,7 @@ class P2Interpolator(DiscreteInterpolator):
|
|
|
41
42
|
"tpw": 1.0,
|
|
42
43
|
"ipw": 1.0,
|
|
43
44
|
}
|
|
44
|
-
|
|
45
|
+
self.type = InterpolatorType.PIECEWISE_QUADRATIC
|
|
45
46
|
def setup_interpolator(self, **kwargs):
|
|
46
47
|
"""
|
|
47
48
|
Searches through kwargs for any interpolation weights and updates
|
{loopstructural-1.6.18 → loopstructural-1.6.20}/LoopStructural/modelling/core/geological_model.py
RENAMED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Main entry point for creating a geological model
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from LoopStructural import LoopStructuralConfig
|
|
5
6
|
from ...utils import getLogger
|
|
6
7
|
|
|
7
8
|
import numpy as np
|
|
@@ -20,6 +21,7 @@ from ...modelling.features import (
|
|
|
20
21
|
UnconformityFeature,
|
|
21
22
|
StructuralFrame,
|
|
22
23
|
GeologicalFeature,
|
|
24
|
+
BaseFeature,
|
|
23
25
|
FeatureType,
|
|
24
26
|
)
|
|
25
27
|
from ...modelling.features.fold import (
|
|
@@ -330,7 +332,21 @@ class GeologicalModel:
|
|
|
330
332
|
name of the feature to return
|
|
331
333
|
"""
|
|
332
334
|
return self.get_feature_by_name(feature_name)
|
|
335
|
+
def __setitem__(self, feature_name, feature):
|
|
336
|
+
"""Set a feature in the model using feature_name_index
|
|
333
337
|
|
|
338
|
+
Parameters
|
|
339
|
+
----------
|
|
340
|
+
feature_name : string
|
|
341
|
+
name of the feature to set
|
|
342
|
+
feature : GeologicalFeature
|
|
343
|
+
the geological feature to set
|
|
344
|
+
"""
|
|
345
|
+
if not issubclass(type(feature), BaseFeature):
|
|
346
|
+
raise TypeError("feature must be a GeologicalFeature")
|
|
347
|
+
if feature.name != feature_name:
|
|
348
|
+
raise ValueError("feature name does not match key")
|
|
349
|
+
self._add_feature(feature)
|
|
334
350
|
def __contains__(self, feature_name):
|
|
335
351
|
return feature_name in self.feature_name_index
|
|
336
352
|
|
|
@@ -426,7 +442,7 @@ class GeologicalModel:
|
|
|
426
442
|
except pickle.PicklingError:
|
|
427
443
|
logger.error("Error saving file")
|
|
428
444
|
|
|
429
|
-
def _add_feature(self, feature):
|
|
445
|
+
def _add_feature(self, feature, index: Optional[int] = None):
|
|
430
446
|
"""
|
|
431
447
|
Add a feature to the model stack
|
|
432
448
|
|
|
@@ -443,9 +459,18 @@ class GeologicalModel:
|
|
|
443
459
|
)
|
|
444
460
|
self.features[self.feature_name_index[feature.name]] = feature
|
|
445
461
|
else:
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
462
|
+
if index is not None:
|
|
463
|
+
if index < 0 or index > len(self.features):
|
|
464
|
+
raise IndexError(f"Index {index} out of bounds for features list")
|
|
465
|
+
self.features.insert(index, feature)
|
|
466
|
+
self.feature_name_index[feature.name] = index
|
|
467
|
+
logger.info(f"Adding {feature.name} to model at location {index}")
|
|
468
|
+
for index, feature in enumerate(self.features):
|
|
469
|
+
self.feature_name_index[feature.name] = index
|
|
470
|
+
else:
|
|
471
|
+
self.features.append(feature)
|
|
472
|
+
self.feature_name_index[feature.name] = len(self.features) - 1
|
|
473
|
+
logger.info(f"Adding {feature.name} to model at location {len(self.features)}")
|
|
449
474
|
self._add_domain_fault_above(feature)
|
|
450
475
|
if feature.type == FeatureType.INTERPOLATED:
|
|
451
476
|
self._add_unconformity_above(feature)
|
|
@@ -553,7 +578,7 @@ class GeologicalModel:
|
|
|
553
578
|
}
|
|
554
579
|
|
|
555
580
|
"""
|
|
556
|
-
self.stratigraphic_column.clear()
|
|
581
|
+
self.stratigraphic_column.clear(basement=False)
|
|
557
582
|
# if the colour for a unit hasn't been specified we can just sample from
|
|
558
583
|
# a colour map e.g. tab20
|
|
559
584
|
logger.info("Adding stratigraphic column to model")
|
|
@@ -561,6 +586,9 @@ class GeologicalModel:
|
|
|
561
586
|
"set_stratigraphic_column is deprecated, use model.stratigraphic_column.add_units instead"
|
|
562
587
|
)
|
|
563
588
|
for i, g in enumerate(stratigraphic_column.keys()):
|
|
589
|
+
if g == 'faults':
|
|
590
|
+
logger.info('Not adding faults to stratigraphic column')
|
|
591
|
+
continue
|
|
564
592
|
for u in stratigraphic_column[g].keys():
|
|
565
593
|
thickness = 0
|
|
566
594
|
if "min" in stratigraphic_column[g][u] and "max" in stratigraphic_column[g][u]:
|
|
@@ -582,15 +610,16 @@ class GeologicalModel:
|
|
|
582
610
|
self.stratigraphic_column.add_unconformity(
|
|
583
611
|
name=''.join([g, 'unconformity']),
|
|
584
612
|
)
|
|
585
|
-
self.stratigraphic_column.group_mapping[f'Group_{i
|
|
613
|
+
self.stratigraphic_column.group_mapping[f'Group_{i}'] = g
|
|
586
614
|
|
|
587
615
|
def create_and_add_foliation(
|
|
588
616
|
self,
|
|
589
617
|
series_surface_name: str,
|
|
590
618
|
*,
|
|
591
|
-
|
|
619
|
+
index: Optional[int] = None,
|
|
620
|
+
data: Optional[pd.DataFrame] = None,
|
|
592
621
|
interpolatortype: str = "FDI",
|
|
593
|
-
nelements: int =
|
|
622
|
+
nelements: int = LoopStructuralConfig.nelements,
|
|
594
623
|
tol=None,
|
|
595
624
|
faults=None,
|
|
596
625
|
**kwargs,
|
|
@@ -643,13 +672,13 @@ class GeologicalModel:
|
|
|
643
672
|
**kwargs,
|
|
644
673
|
)
|
|
645
674
|
# add data
|
|
646
|
-
if
|
|
647
|
-
|
|
675
|
+
if data is None:
|
|
676
|
+
data = self.data.loc[self.data["feature_name"] == series_surface_name]
|
|
648
677
|
|
|
649
|
-
if
|
|
678
|
+
if data.shape[0] == 0:
|
|
650
679
|
logger.warning("No data for {series_surface_data}, skipping")
|
|
651
680
|
return
|
|
652
|
-
series_builder.add_data_from_data_frame(self.prepare_data(
|
|
681
|
+
series_builder.add_data_from_data_frame(self.prepare_data(data))
|
|
653
682
|
self._add_faults(series_builder, features=faults)
|
|
654
683
|
|
|
655
684
|
# build feature
|
|
@@ -660,16 +689,17 @@ class GeologicalModel:
|
|
|
660
689
|
# could just pass a regular grid of points - mask by any above unconformities??
|
|
661
690
|
|
|
662
691
|
series_feature.type = FeatureType.INTERPOLATED
|
|
663
|
-
self._add_feature(series_feature)
|
|
692
|
+
self._add_feature(series_feature,index=index)
|
|
664
693
|
return series_feature
|
|
665
694
|
|
|
666
695
|
def create_and_add_fold_frame(
|
|
667
696
|
self,
|
|
668
697
|
fold_frame_name: str,
|
|
669
698
|
*,
|
|
670
|
-
|
|
699
|
+
index: Optional[int] = None,
|
|
700
|
+
data=None,
|
|
671
701
|
interpolatortype="FDI",
|
|
672
|
-
nelements=
|
|
702
|
+
nelements=LoopStructuralConfig.nelements,
|
|
673
703
|
tol=None,
|
|
674
704
|
buffer=0.1,
|
|
675
705
|
**kwargs,
|
|
@@ -717,12 +747,12 @@ class GeologicalModel:
|
|
|
717
747
|
**kwargs,
|
|
718
748
|
)
|
|
719
749
|
# add data
|
|
720
|
-
if
|
|
721
|
-
|
|
722
|
-
if
|
|
750
|
+
if data is None:
|
|
751
|
+
data = self.data.loc[self.data["feature_name"] == fold_frame_name]
|
|
752
|
+
if data.shape[0] == 0:
|
|
723
753
|
logger.warning(f"No data for {fold_frame_name}, skipping")
|
|
724
754
|
return
|
|
725
|
-
fold_frame_builder.add_data_from_data_frame(self.prepare_data(
|
|
755
|
+
fold_frame_builder.add_data_from_data_frame(self.prepare_data(data))
|
|
726
756
|
self._add_faults(fold_frame_builder[0])
|
|
727
757
|
self._add_faults(fold_frame_builder[1])
|
|
728
758
|
self._add_faults(fold_frame_builder[2])
|
|
@@ -732,7 +762,7 @@ class GeologicalModel:
|
|
|
732
762
|
|
|
733
763
|
fold_frame.type = FeatureType.STRUCTURALFRAME
|
|
734
764
|
fold_frame.builder = fold_frame_builder
|
|
735
|
-
self._add_feature(fold_frame)
|
|
765
|
+
self._add_feature(fold_frame,index=index)
|
|
736
766
|
|
|
737
767
|
return fold_frame
|
|
738
768
|
|
|
@@ -740,9 +770,10 @@ class GeologicalModel:
|
|
|
740
770
|
self,
|
|
741
771
|
foliation_name,
|
|
742
772
|
*,
|
|
743
|
-
|
|
773
|
+
index: Optional[int] = None,
|
|
774
|
+
data=None,
|
|
744
775
|
interpolatortype="DFI",
|
|
745
|
-
nelements=
|
|
776
|
+
nelements=LoopStructuralConfig.nelements,
|
|
746
777
|
buffer=0.1,
|
|
747
778
|
fold_frame=None,
|
|
748
779
|
svario=True,
|
|
@@ -786,7 +817,7 @@ class GeologicalModel:
|
|
|
786
817
|
fold_frame = self.features[-1]
|
|
787
818
|
assert isinstance(fold_frame, FoldFrame), "Please specify a FoldFrame"
|
|
788
819
|
|
|
789
|
-
fold = FoldEvent(fold_frame, name=f"Fold_{
|
|
820
|
+
fold = FoldEvent(fold_frame, name=f"Fold_{foliation_name}", invert_norm=invert_fold_norm)
|
|
790
821
|
|
|
791
822
|
if interpolatortype != "DFI":
|
|
792
823
|
logger.warning("Folded foliation only supports DFI interpolator, changing to DFI")
|
|
@@ -801,12 +832,12 @@ class GeologicalModel:
|
|
|
801
832
|
model=self,
|
|
802
833
|
**kwargs,
|
|
803
834
|
)
|
|
804
|
-
if
|
|
805
|
-
|
|
806
|
-
if
|
|
835
|
+
if data is None:
|
|
836
|
+
data = self.data.loc[self.data["feature_name"] == foliation_name]
|
|
837
|
+
if data.shape[0] == 0:
|
|
807
838
|
logger.warning(f"No data for {foliation_name}, skipping")
|
|
808
839
|
return
|
|
809
|
-
series_builder.add_data_from_data_frame(self.prepare_data(
|
|
840
|
+
series_builder.add_data_from_data_frame(self.prepare_data(data))
|
|
810
841
|
|
|
811
842
|
self._add_faults(series_builder)
|
|
812
843
|
# series_builder.add_data_to_interpolator(True)
|
|
@@ -817,19 +848,20 @@ class GeologicalModel:
|
|
|
817
848
|
# series_feature = series_builder.build(**kwargs)
|
|
818
849
|
series_feature = series_builder.feature
|
|
819
850
|
series_builder.update_build_arguments(kwargs)
|
|
820
|
-
series_feature.type = FeatureType.
|
|
851
|
+
series_feature.type = FeatureType.FOLDED
|
|
821
852
|
series_feature.fold = fold
|
|
822
853
|
|
|
823
|
-
self._add_feature(series_feature)
|
|
854
|
+
self._add_feature(series_feature,index)
|
|
824
855
|
return series_feature
|
|
825
856
|
|
|
826
857
|
def create_and_add_folded_fold_frame(
|
|
827
858
|
self,
|
|
828
859
|
fold_frame_name: str,
|
|
829
860
|
*,
|
|
830
|
-
|
|
861
|
+
index: Optional[int] = None,
|
|
862
|
+
data: Optional[pd.DataFrame] = None,
|
|
831
863
|
interpolatortype="FDI",
|
|
832
|
-
nelements=
|
|
864
|
+
nelements=LoopStructuralConfig.nelements,
|
|
833
865
|
fold_frame=None,
|
|
834
866
|
tol=None,
|
|
835
867
|
**kwargs,
|
|
@@ -882,7 +914,7 @@ class GeologicalModel:
|
|
|
882
914
|
logger.info("Using last feature as fold frame")
|
|
883
915
|
fold_frame = self.features[-1]
|
|
884
916
|
assert isinstance(fold_frame, FoldFrame), "Please specify a FoldFrame"
|
|
885
|
-
fold = FoldEvent(fold_frame, name=f"Fold_{
|
|
917
|
+
fold = FoldEvent(fold_frame, name=f"Fold_{fold_frame_name}")
|
|
886
918
|
|
|
887
919
|
interpolatortypes = [
|
|
888
920
|
"DFI",
|
|
@@ -899,9 +931,9 @@ class GeologicalModel:
|
|
|
899
931
|
model=self,
|
|
900
932
|
**kwargs,
|
|
901
933
|
)
|
|
902
|
-
if
|
|
903
|
-
|
|
904
|
-
fold_frame_builder.add_data_from_data_frame(self.prepare_data(
|
|
934
|
+
if data is None:
|
|
935
|
+
data = self.data[self.data["feature_name"] == fold_frame_name]
|
|
936
|
+
fold_frame_builder.add_data_from_data_frame(self.prepare_data(data))
|
|
905
937
|
|
|
906
938
|
for i in range(3):
|
|
907
939
|
self._add_faults(fold_frame_builder[i])
|
|
@@ -915,7 +947,7 @@ class GeologicalModel:
|
|
|
915
947
|
|
|
916
948
|
folded_fold_frame.type = FeatureType.STRUCTURALFRAME
|
|
917
949
|
|
|
918
|
-
self._add_feature(folded_fold_frame)
|
|
950
|
+
self._add_feature(folded_fold_frame,index=index)
|
|
919
951
|
|
|
920
952
|
return folded_fold_frame
|
|
921
953
|
|
|
@@ -978,14 +1010,14 @@ class GeologicalModel:
|
|
|
978
1010
|
|
|
979
1011
|
interpolatortype = kwargs.get("interpolatortype", "PLI")
|
|
980
1012
|
# buffer = kwargs.get("buffer", 0.1)
|
|
981
|
-
nelements = kwargs.get("nelements",
|
|
1013
|
+
nelements = kwargs.get("nelements", LoopStructuralConfig.nelements)
|
|
982
1014
|
|
|
983
1015
|
weights = [gxxgz, gxxgy, gyxgz]
|
|
984
1016
|
|
|
985
1017
|
intrusion_frame_builder = IntrusionFrameBuilder(
|
|
986
1018
|
interpolatortype=interpolatortype,
|
|
987
1019
|
bounding_box=self.bounding_box.with_buffer(kwargs.get("buffer", 0.1)),
|
|
988
|
-
nelements=kwargs.get("nelements",
|
|
1020
|
+
nelements=kwargs.get("nelements", LoopStructuralConfig.nelements),
|
|
989
1021
|
name=intrusion_frame_name,
|
|
990
1022
|
model=self,
|
|
991
1023
|
**kwargs,
|
|
@@ -1128,7 +1160,7 @@ class GeologicalModel:
|
|
|
1128
1160
|
feature.add_region(f)
|
|
1129
1161
|
break
|
|
1130
1162
|
|
|
1131
|
-
def add_unconformity(self, feature: GeologicalFeature, value: float) -> UnconformityFeature:
|
|
1163
|
+
def add_unconformity(self, feature: GeologicalFeature, value: float, index: Optional[int] = None) -> UnconformityFeature:
|
|
1132
1164
|
"""
|
|
1133
1165
|
Use an existing feature to add an unconformity to the model.
|
|
1134
1166
|
|
|
@@ -1165,10 +1197,10 @@ class GeologicalModel:
|
|
|
1165
1197
|
else:
|
|
1166
1198
|
f.add_region(uc_feature)
|
|
1167
1199
|
# now add the unconformity to the feature list
|
|
1168
|
-
self._add_feature(uc_feature)
|
|
1200
|
+
self._add_feature(uc_feature,index=index)
|
|
1169
1201
|
return uc_feature
|
|
1170
1202
|
|
|
1171
|
-
def add_onlap_unconformity(self, feature: GeologicalFeature, value: float) -> GeologicalFeature:
|
|
1203
|
+
def add_onlap_unconformity(self, feature: GeologicalFeature, value: float, index: Optional[int] = None) -> GeologicalFeature:
|
|
1172
1204
|
"""
|
|
1173
1205
|
Use an existing feature to add an unconformity to the model.
|
|
1174
1206
|
|
|
@@ -1196,12 +1228,18 @@ class GeologicalModel:
|
|
|
1196
1228
|
continue
|
|
1197
1229
|
if f != feature:
|
|
1198
1230
|
f.add_region(uc_feature)
|
|
1199
|
-
self._add_feature(uc_feature.inverse())
|
|
1231
|
+
self._add_feature(uc_feature.inverse(),index=index)
|
|
1200
1232
|
|
|
1201
1233
|
return uc_feature
|
|
1202
1234
|
|
|
1203
1235
|
def create_and_add_domain_fault(
|
|
1204
|
-
self,
|
|
1236
|
+
self,
|
|
1237
|
+
fault_surface_data,
|
|
1238
|
+
*,
|
|
1239
|
+
nelements=LoopStructuralConfig.nelements,
|
|
1240
|
+
interpolatortype="FDI",
|
|
1241
|
+
index: Optional[int] = None,
|
|
1242
|
+
**kwargs,
|
|
1205
1243
|
):
|
|
1206
1244
|
"""
|
|
1207
1245
|
Parameters
|
|
@@ -1242,7 +1280,7 @@ class GeologicalModel:
|
|
|
1242
1280
|
domain_fault = domain_fault_feature_builder.feature
|
|
1243
1281
|
domain_fault_feature_builder.update_build_arguments(kwargs)
|
|
1244
1282
|
domain_fault.type = FeatureType.DOMAINFAULT
|
|
1245
|
-
self._add_feature(domain_fault)
|
|
1283
|
+
self._add_feature(domain_fault, index=index)
|
|
1246
1284
|
self._add_domain_fault_below(domain_fault)
|
|
1247
1285
|
|
|
1248
1286
|
domain_fault_uc = UnconformityFeature(domain_fault, 0)
|
|
@@ -1255,7 +1293,8 @@ class GeologicalModel:
|
|
|
1255
1293
|
fault_name: str,
|
|
1256
1294
|
displacement: float,
|
|
1257
1295
|
*,
|
|
1258
|
-
|
|
1296
|
+
index: Optional[int] = None,
|
|
1297
|
+
data: Optional[pd.DataFrame] = None,
|
|
1259
1298
|
interpolatortype="FDI",
|
|
1260
1299
|
tol=None,
|
|
1261
1300
|
fault_slip_vector=None,
|
|
@@ -1344,14 +1383,14 @@ class GeologicalModel:
|
|
|
1344
1383
|
fault_frame_builder = FaultBuilder(
|
|
1345
1384
|
interpolatortype,
|
|
1346
1385
|
bounding_box=self.bounding_box,
|
|
1347
|
-
nelements=kwargs.pop("nelements",
|
|
1386
|
+
nelements=kwargs.pop("nelements", LoopStructuralConfig.nelements),
|
|
1348
1387
|
name=fault_name,
|
|
1349
1388
|
model=self,
|
|
1350
1389
|
**kwargs,
|
|
1351
1390
|
)
|
|
1352
|
-
if
|
|
1353
|
-
|
|
1354
|
-
if
|
|
1391
|
+
if data is None:
|
|
1392
|
+
data = self.data.loc[self.data["feature_name"] == fault_name]
|
|
1393
|
+
if data.shape[0] == 0:
|
|
1355
1394
|
logger.warning(f"No data for {fault_name}, skipping")
|
|
1356
1395
|
return
|
|
1357
1396
|
|
|
@@ -1367,7 +1406,7 @@ class GeologicalModel:
|
|
|
1367
1406
|
if intermediate_axis:
|
|
1368
1407
|
intermediate_axis = intermediate_axis
|
|
1369
1408
|
fault_frame_builder.create_data_from_geometry(
|
|
1370
|
-
fault_frame_data=self.prepare_data(
|
|
1409
|
+
fault_frame_data=self.prepare_data(data),
|
|
1371
1410
|
fault_center=fault_center,
|
|
1372
1411
|
fault_normal_vector=fault_normal_vector,
|
|
1373
1412
|
fault_slip_vector=fault_slip_vector,
|
|
@@ -1399,7 +1438,7 @@ class GeologicalModel:
|
|
|
1399
1438
|
break
|
|
1400
1439
|
if displacement == 0:
|
|
1401
1440
|
fault.type = FeatureType.INACTIVEFAULT
|
|
1402
|
-
self._add_feature(fault)
|
|
1441
|
+
self._add_feature(fault,index=index)
|
|
1403
1442
|
|
|
1404
1443
|
return fault
|
|
1405
1444
|
|
|
@@ -1515,7 +1554,7 @@ class GeologicalModel:
|
|
|
1515
1554
|
if self.stratigraphic_column is None:
|
|
1516
1555
|
logger.warning("No stratigraphic column defined")
|
|
1517
1556
|
return strat_id
|
|
1518
|
-
|
|
1557
|
+
|
|
1519
1558
|
s_id = 0
|
|
1520
1559
|
for g in reversed(self.stratigraphic_column.get_groups()):
|
|
1521
1560
|
feature_id = self.feature_name_index.get(g.name, -1)
|
|
@@ -1526,7 +1565,7 @@ class GeologicalModel:
|
|
|
1526
1565
|
s_id += 1
|
|
1527
1566
|
if feature_id == -1:
|
|
1528
1567
|
logger.error(f"Model does not contain {g.name}")
|
|
1529
|
-
|
|
1568
|
+
|
|
1530
1569
|
return strat_id
|
|
1531
1570
|
|
|
1532
1571
|
def evaluate_model_gradient(self, points: np.ndarray, *, scale: bool = True) -> np.ndarray:
|
|
@@ -1548,16 +1587,13 @@ class GeologicalModel:
|
|
|
1548
1587
|
if scale:
|
|
1549
1588
|
xyz = self.scale(xyz, inplace=False)
|
|
1550
1589
|
grad = np.zeros(xyz.shape)
|
|
1551
|
-
for
|
|
1552
|
-
|
|
1553
|
-
continue
|
|
1554
|
-
feature_id = self.feature_name_index.get(group, -1)
|
|
1590
|
+
for g in reversed(self.stratigraphic_column.get_groups()):
|
|
1591
|
+
feature_id = self.feature_name_index.get(g.name, -1)
|
|
1555
1592
|
if feature_id >= 0:
|
|
1556
|
-
|
|
1557
|
-
gradt = feature.evaluate_gradient(xyz)
|
|
1593
|
+
gradt = self.features[feature_id].evaluate_gradient(xyz)
|
|
1558
1594
|
grad[~np.isnan(gradt).any(axis=1)] = gradt[~np.isnan(gradt).any(axis=1)]
|
|
1559
1595
|
if feature_id == -1:
|
|
1560
|
-
logger.error(f"Model does not contain {
|
|
1596
|
+
logger.error(f"Model does not contain {g.name}")
|
|
1561
1597
|
|
|
1562
1598
|
return grad
|
|
1563
1599
|
|
|
@@ -1728,7 +1764,6 @@ class GeologicalModel:
|
|
|
1728
1764
|
list of unique stratigraphic ids, featurename, unit name and min and max scalar values
|
|
1729
1765
|
"""
|
|
1730
1766
|
return self.stratigraphic_column.get_stratigraphic_ids()
|
|
1731
|
-
|
|
1732
1767
|
|
|
1733
1768
|
def get_fault_surfaces(self, faults: List[str] = []):
|
|
1734
1769
|
surfaces = []
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import enum
|
|
2
2
|
from typing import Dict, Optional, List, Tuple
|
|
3
3
|
import numpy as np
|
|
4
|
-
from LoopStructural.utils import rng, getLogger, Observable
|
|
4
|
+
from LoopStructural.utils import rng, getLogger, Observable, random_colour
|
|
5
5
|
logger = getLogger(__name__)
|
|
6
6
|
logger.info("Imported LoopStructural Stratigraphic Column module")
|
|
7
7
|
class UnconformityType(enum.Enum):
|
|
@@ -57,7 +57,7 @@ class StratigraphicUnit(StratigraphicColumnElement, Observable['StratigraphicUni
|
|
|
57
57
|
self._thickness = thickness
|
|
58
58
|
self.data = data
|
|
59
59
|
self.element_type = StratigraphicColumnElementType.UNIT
|
|
60
|
-
self.
|
|
60
|
+
self.id = id
|
|
61
61
|
self.min_value = None # Minimum scalar field value for the unit
|
|
62
62
|
self.max_value = None # Maximum scalar field value for the unit
|
|
63
63
|
@property
|
|
@@ -99,7 +99,7 @@ class StratigraphicUnit(StratigraphicColumnElement, Observable['StratigraphicUni
|
|
|
99
99
|
colour = self.colour
|
|
100
100
|
if isinstance(colour, np.ndarray):
|
|
101
101
|
colour = colour.astype(float).tolist()
|
|
102
|
-
return {"name": self.name, "colour": colour, "thickness": self.thickness, 'uuid': self.uuid}
|
|
102
|
+
return {"name": self.name, "colour": colour, "thickness": self.thickness, 'uuid': self.uuid, 'id': self.id}
|
|
103
103
|
|
|
104
104
|
@classmethod
|
|
105
105
|
def from_dict(cls, data):
|
|
@@ -112,7 +112,7 @@ class StratigraphicUnit(StratigraphicColumnElement, Observable['StratigraphicUni
|
|
|
112
112
|
colour = data.get("colour")
|
|
113
113
|
thickness = data.get("thickness", None)
|
|
114
114
|
uuid = data.get("uuid", None)
|
|
115
|
-
return cls(uuid=uuid, name=name, colour=colour, thickness=thickness)
|
|
115
|
+
return cls(uuid=uuid, name=name, colour=colour, thickness=thickness, id=data.get("id", None))
|
|
116
116
|
|
|
117
117
|
def __str__(self):
|
|
118
118
|
"""
|
|
@@ -575,3 +575,29 @@ class StratigraphicColumn(Observable['StratigraphicColumn']):
|
|
|
575
575
|
ax.axis("off")
|
|
576
576
|
|
|
577
577
|
return fig
|
|
578
|
+
|
|
579
|
+
def cmap(self):
|
|
580
|
+
try:
|
|
581
|
+
import matplotlib.colors as colors
|
|
582
|
+
|
|
583
|
+
colours = []
|
|
584
|
+
boundaries = []
|
|
585
|
+
data = []
|
|
586
|
+
for group in self.get_groups():
|
|
587
|
+
for u in group.units:
|
|
588
|
+
colour = u.colour
|
|
589
|
+
if not isinstance(colour, str):
|
|
590
|
+
try:
|
|
591
|
+
u.colour = colors.to_hex(colour)
|
|
592
|
+
except ValueError:
|
|
593
|
+
logger.warning(f"Cannot convert colour {colour} to hex, using default")
|
|
594
|
+
u.colour = random_colour()
|
|
595
|
+
data.append((u.id, u.colour))
|
|
596
|
+
colours.append(u.colour)
|
|
597
|
+
boundaries.append(u.id)
|
|
598
|
+
# print(u,v)
|
|
599
|
+
cmap = colors.ListedColormap(colours)
|
|
600
|
+
except ImportError:
|
|
601
|
+
logger.warning("Cannot use predefined colours as I can't import matplotlib")
|
|
602
|
+
cmap = "tab20"
|
|
603
|
+
return cmap
|
|
@@ -271,7 +271,7 @@ class BaseFeature(metaclass=ABCMeta):
|
|
|
271
271
|
|
|
272
272
|
def surfaces(
|
|
273
273
|
self,
|
|
274
|
-
value: Union[float, int, List[Union[float, int]]],
|
|
274
|
+
value: Optional[Union[float, int, List[Union[float, int]]]] = None,
|
|
275
275
|
bounding_box=None,
|
|
276
276
|
name: Optional[Union[List[str], str]] = None,
|
|
277
277
|
colours: Optional[Union[str, np.ndarray]] = None,
|
|
@@ -293,6 +293,7 @@ class BaseFeature(metaclass=ABCMeta):
|
|
|
293
293
|
raise ValueError("Must specify bounding box")
|
|
294
294
|
bounding_box = self.model.bounding_box
|
|
295
295
|
regions = self.regions
|
|
296
|
+
|
|
296
297
|
try:
|
|
297
298
|
self.regions = [
|
|
298
299
|
r for r in self.regions if r.name != self.name and r.parent.name != self.name
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from LoopStructural.modelling.features.fold import FoldEvent
|
|
2
|
+
from LoopStructural.modelling.features.builders import FoldedFeatureBuilder, StructuralFrameBuilder
|
|
3
|
+
def add_fold_to_feature(feature, fold_frame,**kwargs):
|
|
4
|
+
fold = FoldEvent(fold_frame, name=f"Fold_{feature.name}", invert_norm=kwargs.get('invert_fold_norm', False))
|
|
5
|
+
|
|
6
|
+
builder = FoldedFeatureBuilder.from_feature_builder(
|
|
7
|
+
feature.builder,
|
|
8
|
+
fold,
|
|
9
|
+
**kwargs
|
|
10
|
+
)
|
|
11
|
+
feature = builder.feature
|
|
12
|
+
feature.fold = fold
|
|
13
|
+
return feature
|
|
14
|
+
|
|
15
|
+
def convert_feature_to_structural_frame(feature, **kwargs):
|
|
16
|
+
"""
|
|
17
|
+
Convert a geological feature to a structural frame by adding the feature to the frame
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
feature : GeologicalFeature
|
|
22
|
+
the geological feature to convert
|
|
23
|
+
|
|
24
|
+
Returns
|
|
25
|
+
-------
|
|
26
|
+
StructuralFrame
|
|
27
|
+
the updated structural frame with the feature added
|
|
28
|
+
"""
|
|
29
|
+
builder = feature.builder
|
|
30
|
+
|
|
31
|
+
new_builder = StructuralFrameBuilder.from_feature_builder(
|
|
32
|
+
builder,
|
|
33
|
+
**kwargs
|
|
34
|
+
)
|
|
35
|
+
return new_builder.frame
|
|
36
|
+
|
|
@@ -134,7 +134,7 @@ class StructuralFrame(BaseFeature):
|
|
|
134
134
|
v[:, 0] = self.features[0].evaluate_value(pos, ignore_regions=ignore_regions)
|
|
135
135
|
v[:, 1] = self.features[1].evaluate_value(pos, ignore_regions=ignore_regions)
|
|
136
136
|
v[:, 2] = self.features[2].evaluate_value(pos, ignore_regions=ignore_regions)
|
|
137
|
-
return v
|
|
137
|
+
return v[:,0]
|
|
138
138
|
|
|
139
139
|
def evaluate_gradient(self, pos, i=None, ignore_regions=False):
|
|
140
140
|
"""
|
|
@@ -152,11 +152,7 @@ class StructuralFrame(BaseFeature):
|
|
|
152
152
|
"""
|
|
153
153
|
if i is not None:
|
|
154
154
|
return self.features[i].support.evaluate_gradient(pos, ignore_regions=ignore_regions)
|
|
155
|
-
return (
|
|
156
|
-
self.features[0].support.evaluate_gradient(pos, ignore_regions=ignore_regions),
|
|
157
|
-
self.features[1].support.evaluate_gradient(pos, ignore_regions=ignore_regions),
|
|
158
|
-
self.features[2].support.evaluate_gradient(pos, ignore_regions=ignore_regions),
|
|
159
|
-
)
|
|
155
|
+
return self.features[0].support.evaluate_gradient(pos, ignore_regions=ignore_regions)
|
|
160
156
|
|
|
161
157
|
def get_data(self, value_map: Optional[dict] = None) -> List[Union[ValuePoints, VectorPoints]]:
|
|
162
158
|
"""Return the data associated with the features in the
|