Skip to content

Commit 364ce9a

Browse files
authored
fix: refactoring fold profiles to allow for easy user modification of fold geometry
* fix: refactoring fold rotation angle and svariogram * adding trigo and fourier series fold profile classes also added a base class to inheret fold profile from * adding some type hints to svariogram * get the data from the builder not the interpolator this means the interpolation isn't required before we can calculate fold profiles * adding observed update for when fold profile parameters change. This flags the interpolator/builder as not up to date triggering a reinterpolation * updating folded feature builder to use the new fold profile classes * set interpolator as not up to date when builder is not up to date * adding lambda fold profile, for proving a custom function * getter/factory for building fold profile object * linting * removing old rotation angle * removing unused/commentred code * fixing import errors * fold rotation plotter uses the svario * catch exception when fold paramters are not able to be updated * add getters for fold axis/limb profiles for builder
1 parent ea1de24 commit 364ce9a

14 files changed

+778
-299
lines changed

LoopStructural/modelling/features/builders/_base_builder.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ def __init__(self, model, name: str = "Feature"):
2929
self._build_arguments = {}
3030
self.faults = []
3131

32+
def set_not_up_to_date(self, caller):
33+
logger.info(
34+
f"Setting {self.name} to not up to date from an instance of {caller.__class__.__name__}"
35+
)
36+
self._up_to_date = False
37+
3238
@property
3339
def model(self):
3440
return self._model

LoopStructural/modelling/features/builders/_folded_feature_builder.py

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from ....modelling.features.builders import GeologicalFeatureBuilder
2-
from ....modelling.features.fold import FoldRotationAngle
2+
from ....modelling.features.fold.fold_function import FoldRotationType, get_fold_rotation_profile
33
import numpy as np
44

55
from ....utils import getLogger, InterpolatorError
@@ -19,6 +19,8 @@ def __init__(
1919
name="Feature",
2020
region=None,
2121
svario=True,
22+
axis_profile_type=FoldRotationType.FOURIER_SERIES,
23+
limb_profile_type=FoldRotationType.FOURIER_SERIES,
2224
**kwargs,
2325
):
2426
"""Builder for creating a geological feature using fold constraints
@@ -36,6 +38,7 @@ def __init__(
3638
region : _type_, optional
3739
_description_, by default None
3840
"""
41+
# create the feature builder, this intialises the interpolator
3942
GeologicalFeatureBuilder.__init__(
4043
self,
4144
interpolatortype=interpolatortype,
@@ -45,11 +48,27 @@ def __init__(
4548
region=region,
4649
**kwargs,
4750
)
51+
# link the interpolator to the fold object
4852
self.interpolator.fold = fold
4953
self.fold = fold
5054
self.fold_weights = fold_weights
5155
self.kwargs = kwargs
5256
self.svario = svario
57+
self.axis_profile_type = axis_profile_type
58+
self.limb_profile_type = limb_profile_type
59+
60+
@property
61+
def fold_axis_rotation(self):
62+
if self.fold.fold_axis_rotation is None:
63+
self.set_fold_axis()
64+
return self.fold.fold_axis_rotation
65+
66+
@property
67+
def fold_limb_rotation(self):
68+
_axis = self.fold.fold_axis # get axis to make sure its initialised
69+
if self.fold.fold_limb_rotation is None:
70+
self.set_fold_limb_rotation()
71+
return self.fold.fold_limb_rotation
5372

5473
def set_fold_axis(self):
5574
"""calculates the fold axis/ fold axis rotation and adds this to the fold"""
@@ -67,31 +86,41 @@ def set_fold_axis(self):
6786
if not self.fold.foldframe[1].is_valid():
6887
raise InterpolatorError("Fold frame direction coordinate is not valid")
6988
far, fad = self.fold.foldframe.calculate_fold_axis_rotation(self)
70-
fold_axis_rotation = FoldRotationAngle(far, fad, svario=self.svario)
71-
a_wl = kwargs.get("axis_wl", None)
89+
fold_axis_rotation = get_fold_rotation_profile(self.axis_profile_type, far, fad)
7290
if "axis_function" in kwargs:
7391
# allow predefined function to be used
7492
fold_axis_rotation.set_function(kwargs["axis_function"])
7593
else:
76-
fold_axis_rotation.fit_fourier_series(wl=a_wl)
94+
fold_axis_rotation.fit(params={'wavelength': kwargs.get("axis_wl", None)})
7795
self.fold.fold_axis_rotation = fold_axis_rotation
96+
fold_axis_rotation.add_observer(self)
7897

7998
def set_fold_limb_rotation(self):
8099
"""Calculates the limb rotation of the fold and adds it to the fold object"""
81100
kwargs = self.kwargs
101+
# need to calculate the fold axis before the fold limb rotation angle
102+
if self.fold.fold_axis is None:
103+
self.set_fold_axis()
82104
# give option of passing own fold limb rotation function
83-
flr, fld = self.fold.foldframe.calculate_fold_limb_rotation(
84-
self, self.fold.get_fold_axis_orientation
85-
)
86-
fold_limb_rotation = FoldRotationAngle(flr, fld, svario=self.svario)
87-
l_wl = kwargs.get("limb_wl", None)
105+
flr, fld = self.calculate_fold_limb_rotation_angle()
106+
107+
fold_limb_rotation = get_fold_rotation_profile(self.limb_profile_type, flr, fld)
88108
if "limb_function" in kwargs:
89109
# allow for predefined functions to be used
90110
fold_limb_rotation.set_function(kwargs["limb_function"])
91111
else:
92-
fold_limb_rotation.fit_fourier_series(wl=l_wl, **kwargs)
112+
fold_limb_rotation.fit(params={'wavelength': kwargs.get("limb_wl", None)})
113+
93114
self.fold.fold_limb_rotation = fold_limb_rotation
115+
fold_limb_rotation.add_observer(self)
116+
117+
def calculate_fold_limb_rotation_angle(self):
118+
flr, fld = self.fold.foldframe.calculate_fold_limb_rotation(
119+
self, self.fold.get_fold_axis_orientation
120+
)
121+
return flr, fld
94122

123+
# def
95124
def build(self, data_region=None, constrained=None, **kwargs):
96125
"""the main function to run the interpolation and set up the parameters
97126
@@ -115,8 +144,10 @@ def build(self, data_region=None, constrained=None, **kwargs):
115144
self.add_data_to_interpolator(constrained=constrained)
116145
if not self.fold.foldframe[0].is_valid():
117146
raise InterpolatorError("Fold frame main coordinate is not valid")
118-
self.set_fold_axis()
119-
self.set_fold_limb_rotation()
147+
if self.fold.fold_axis is None:
148+
self.set_fold_axis()
149+
if self.fold.fold_limb_rotation is None:
150+
self.set_fold_limb_rotation()
120151
logger.info("Adding fold to {}".format(self.name))
121152
self.interpolator.fold = self.fold
122153
# if we have fold weights use those, otherwise just use default

LoopStructural/modelling/features/builders/_geological_feature_builder.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def __init__(
6767
"interpolator is {} and must be a GeologicalInterpolator".format(type(interpolator))
6868
)
6969
self._interpolator = interpolator
70-
70+
self._up_to_date = self._interpolator.up_to_date
7171
header = (
7272
xyz_names()
7373
+ val_name()
@@ -93,6 +93,13 @@ def __init__(
9393
self._orthogonal_features = {}
9494
self._equality_constraints = {}
9595

96+
def set_not_up_to_date(self, caller):
97+
logger.info(
98+
f"Setting {self.name} to not up to date from an instance of {caller.__class__.__name__}"
99+
)
100+
self._up_to_date = False
101+
self._interpolator.up_to_date = False
102+
96103
@property
97104
def interpolator(self):
98105
return self._interpolator

LoopStructural/modelling/features/builders/_structural_frame_builder.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,8 @@ def update(self):
235235
def up_to_date(self, callback=None):
236236
for i in range(3):
237237
self.builders[i].up_to_date(callback=callback)
238+
239+
def set_not_up_to_date(self, caller):
240+
241+
for i in range(3):
242+
self.builders[i].set_not_up_to_date(caller)

LoopStructural/modelling/features/fold/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,5 @@
44

55
from ._fold import FoldEvent
66
from ._svariogram import SVariogram
7-
from ._fold_rotation_angle_feature import FoldRotationAngleFeature, fourier_series
7+
from ._fold_rotation_angle_feature import FoldRotationAngleFeature
88
from ._foldframe import FoldFrame
9-
from ._fold_rotation_angle import FoldRotationAngle

LoopStructural/modelling/features/fold/_fold_rotation_angle.py

Lines changed: 0 additions & 158 deletions
This file was deleted.

0 commit comments

Comments
 (0)