Skip to content

Commit a26fc49

Browse files
committed
add docs
1 parent 33b2967 commit a26fc49

1 file changed

Lines changed: 129 additions & 0 deletions

File tree

loopstructural/main/model_manager.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
"""Geological model manager utilities used by the LoopStructural plugin.
2+
3+
This module exposes the `GeologicalModelManager` which wraps a LoopStructural
4+
`GeologicalModel` and provides helpers to ingest GeoDataFrames, update
5+
stratigraphy and faults, evaluate features on point clouds or meshes, and
6+
export results to GeoDataFrames or VTK meshes.
7+
8+
The goal of the manager is to isolate data transformation, sampling and
9+
interaction with the LoopStructural model from the GUI code.
10+
"""
11+
112
from collections import defaultdict
213
from typing import Callable
314

@@ -162,6 +173,27 @@ def update_contact_traces(
162173
unit_name_field=None,
163174
use_z_coordinate=False,
164175
):
176+
"""Ingest basal contact traces and populate internal stratigraphy.
177+
178+
Parameters
179+
----------
180+
basal_contacts : geopandas.GeoDataFrame
181+
GeoDataFrame containing basal contact geometries and attributes.
182+
sampler : callable, optional
183+
Callable used to sample geometries to point rows (default: AllSampler()).
184+
unit_name_field : str or None
185+
Field name in `basal_contacts` giving the stratigraphic unit name. If
186+
None the function returns early.
187+
use_z_coordinate : bool
188+
If True, use Z values from geometries when available; otherwise use
189+
the manager's DEM function.
190+
191+
Notes
192+
-----
193+
This method clears existing stratigraphy and replaces contact entries
194+
keyed by unit name. It does not notify observers; callers should call
195+
`update_model` or trigger observers as required.
196+
"""
165197
self.stratigraphy.clear() # Clear existing stratigraphy
166198
unit_points = sampler(basal_contacts, self.dem_function, use_z_coordinate)
167199
if len(unit_points) == 0 or unit_points.empty:
@@ -345,6 +377,14 @@ def update_model(self):
345377
observer()
346378

347379
def features(self):
380+
"""Return the list of features currently held by the internal model.
381+
382+
Returns
383+
-------
384+
list
385+
List-like collection of feature objects contained in the wrapped
386+
LoopStructural `GeologicalModel`.
387+
"""
348388
return self.model.features
349389

350390
def add_foliation(
@@ -355,6 +395,31 @@ def add_foliation(
355395
sampler=AllSampler(),
356396
use_z_coordinate=False,
357397
):
398+
"""Create and add a foliation feature from grouped input layers.
399+
400+
Parameters
401+
----------
402+
name : str
403+
Name for the new foliation feature.
404+
data : dict
405+
Mapping of layer identifiers to dicts describing each layer. Each
406+
layer dict must include a 'type' key (one of 'Orientation',
407+
'Formline', 'Value', 'Inequality') and the fields required by that
408+
type (e.g. 'strike_field', 'dip_field', 'value_field', ...).
409+
folded_feature_name : str or None
410+
Optional name of a feature to which the foliation should be
411+
associated/converted (currently unused in this helper).
412+
sampler : callable, optional
413+
Callable used to sample provided GeoDataFrames into plain pandas
414+
rows (default: AllSampler()).
415+
use_z_coordinate : bool
416+
Whether to use Z coordinates from input geometries when present.
417+
418+
Raises
419+
------
420+
ValueError
421+
If a layer uses an unknown 'type' value.
422+
"""
358423
# for z
359424
dfs = []
360425
kwargs={}
@@ -391,7 +456,25 @@ def add_foliation(
391456
# self.model[folded_feature_name] = folded_feature
392457
for observer in self.observers:
393458
observer()
459+
394460
def add_unconformity(self, foliation_name: str, value: float, type: FeatureType = FeatureType.UNCONFORMITY):
461+
"""Add an unconformity (or onlap unconformity) to a named foliation.
462+
463+
Parameters
464+
----------
465+
foliation_name : str
466+
Name of an existing foliation feature in the model.
467+
value : float
468+
Value (level) at which the unconformity should be inserted.
469+
type : FeatureType
470+
Type of unconformity (default: FeatureType.UNCONFORMITY). Use
471+
FeatureType.ONLAPUNCONFORMITY for onlap-type behaviour.
472+
473+
Raises
474+
------
475+
ValueError
476+
If the foliation named by `foliation_name` cannot be found in the model.
477+
"""
395478
foliation = self.model.get_feature_by_name(foliation_name)
396479
if foliation is None:
397480
raise ValueError(f"Foliation '{foliation_name}' not found in the model.")
@@ -401,6 +484,24 @@ def add_unconformity(self, foliation_name: str, value: float, type: FeatureType
401484
self.model.add_onlap_unconformity(foliation, value)
402485

403486
def add_fold_to_feature(self, feature_name: str, fold_frame_name: str, fold_weights={}):
487+
"""Apply a FoldFrame to an existing feature, producing a folded feature.
488+
489+
Parameters
490+
----------
491+
feature_name : str
492+
Name of the feature to fold.
493+
fold_frame_name : str
494+
Name of an existing fold frame feature in the model to use for
495+
folding.
496+
fold_weights : dict
497+
Optional weights passed to the fold conversion; currently forwarded
498+
to the converter implementation.
499+
500+
Raises
501+
------
502+
ValueError
503+
If either the fold frame or the target feature cannot be found.
504+
"""
404505

405506
from LoopStructural.modelling.features._feature_converters import add_fold_to_feature
406507

@@ -416,6 +517,17 @@ def add_fold_to_feature(self, feature_name: str, fold_frame_name: str, fold_weig
416517
self.model[feature_name] = folded_feature
417518

418519
def convert_feature_to_structural_frame(self, feature_name: str):
520+
"""Convert an interpolated feature into a StructuralFrame.
521+
522+
This helper constructs a StructuralFrameBuilder from the existing
523+
feature's builder and replaces the feature in the model with the new
524+
frame instance.
525+
526+
Parameters
527+
----------
528+
feature_name : str
529+
Name of the feature to convert.
530+
"""
419531
from LoopStructural.modelling.features.builders import StructuralFrameBuilder
420532

421533
builder = self.model.get_feature_by_name(feature_name).builder
@@ -531,6 +643,23 @@ def export_feature_values_to_geodataframe(
531643
return gdf
532644

533645
def export_feature_values_to_vtk_mesh(self, name, mesh, scalar_type='scalar'):
646+
"""Evaluate a feature on a mesh's points and attach the values as a field.
647+
648+
Parameters
649+
----------
650+
name : str
651+
Feature name to evaluate.
652+
mesh : pyvista.PolyData or similar
653+
Mesh-like object exposing a `points` array and supporting item
654+
assignment for point data (e.g. mesh[name] = values).
655+
scalar_type : str
656+
'scalar' or 'gradient' to control what is computed and attached.
657+
658+
Returns
659+
-------
660+
mesh
661+
The same mesh instance with added/updated point data named `name`.
662+
"""
534663
pts = mesh.points
535664
values = self.evaluate_feature_on_points(name, pts, scalar_type=scalar_type)
536665
mesh[name] = values

0 commit comments

Comments
 (0)