Skip to content

Commit

Permalink
fix: creating specific builder for folded foliations
Browse files Browse the repository at this point in the history
This moves the fold constraint assembly and the splots from the geological model
to a builder class that inherts from the GeologicalFeatureInterpolator
The folding specific stuff can be removed from the base class
FoldedFoliationBuilder has its own build, which does foldy stuff
then runs base.build()
  • Loading branch information
Lachlan Grose committed Sep 15, 2021
1 parent a6b61fb commit b40ba9a
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 52 deletions.
63 changes: 22 additions & 41 deletions LoopStructural/modelling/core/geological_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@
from LoopStructural.modelling.features import (GeologicalFeatureInterpolator,
RegionFeature,
StructuralFrameBuilder,
UnconformityFeature)
from LoopStructural.modelling.fold import FoldRotationAngle
from LoopStructural.modelling.fold.fold import FoldEvent
from LoopStructural.modelling.fold.foldframe import FoldFrame
UnconformityFeature,
StructuralFrame,
GeologicalFeature)
from LoopStructural.modelling.fold import (FoldRotationAngle,
FoldedFeatureBuilder,
FoldEvent,
FoldFrame)

from LoopStructural.utils.exceptions import LoopBaseException
from LoopStructural.utils.helper import (all_heading, gradient_vec_names,
strike_dip_vector)
Expand Down Expand Up @@ -786,7 +790,11 @@ def create_and_add_fold_frame(self, foldframe_data, tol=None,**kwargs):

return fold_frame

def create_and_add_folded_foliation(self, foliation_data, fold_frame=None, svario=True, tol=None,
def create_and_add_folded_foliation(self,
foliation_data,
fold_frame=None,
svario=True,
tol=None,
**kwargs):
"""
Create a folded foliation field from data and a fold frame
Expand Down Expand Up @@ -818,51 +826,21 @@ def create_and_add_folded_foliation(self, foliation_data, fold_frame=None, svari
assert type(fold_frame) == FoldFrame, "Please specify a FoldFrame"
fold = FoldEvent(fold_frame,name='Fold_{}'.format(foliation_data))
fold_interpolator = self.get_interpolator("DFI", fold=fold, **kwargs)
series_builder = GeologicalFeatureInterpolator(
series_builder = FoldedFeatureBuilder(
interpolator=fold_interpolator,
fold=fold,
fold_weights=kwargs.get('fold_weights', {}),
name=foliation_data)

series_builder.add_data_from_data_frame(
self.data[self.data['feature_name'] == foliation_data])
self._add_faults(series_builder)
series_builder.add_data_to_interpolator(True)
fold_axis = kwargs.get('fold_axis',None)
if fold_axis is not None:
fold_axis = np.array(fold_axis)
if len(fold_axis.shape) == 1:
fold.fold_axis = fold_axis

if "av_fold_axis" in kwargs:
_calculate_average_intersection(series_builder, fold_frame, fold)
if fold.fold_axis is None:
far, fad = fold_frame.calculate_fold_axis_rotation(
series_builder)
fold_axis_rotation = FoldRotationAngle(far, fad,svario=svario)
a_wl = kwargs.get("axis_wl", None)
if 'axis_function' in kwargs:
# allow predefined function to be used
fold_axis_rotation.set_function(kwargs['axis_function'])
else:
fold_axis_rotation.fit_fourier_series(wl=a_wl)
fold.fold_axis_rotation = fold_axis_rotation
# give option of passing own fold limb rotation function
flr, fld = fold_frame.calculate_fold_limb_rotation(
series_builder, fold.get_fold_axis_orientation)
fold_limb_rotation = FoldRotationAngle(flr, fld,svario=svario)
l_wl = kwargs.get("limb_wl", None)
if 'limb_function' in kwargs:
# allow for predefined functions to be used
fold_limb_rotation.set_function(kwargs['limb_function'])
else:
fold_limb_rotation.fit_fourier_series(wl=l_wl,**kwargs)
fold.fold_limb_rotation = fold_limb_rotation
kwargs['fold_weights'] = kwargs.get('fold_weights', {})

# series_builder.add_data_to_interpolator(True)
self._add_faults(series_builder)
# build feature
kwargs['cgw'] = 0.
kwargs['fold'] = fold

kwargs['tol'] = tol

# series_feature = series_builder.build(**kwargs)
series_feature = series_builder.feature
series_builder.build_arguments = kwargs
Expand Down Expand Up @@ -1606,6 +1584,9 @@ def update(self,verbose=False,progressbar=True):
if f.type=='fault':
nfeatures+=3
total_dof+=f[0].interpolator.nx*3
if isinstance(f,StructuralFrame):
nfeatures+=3
total_dof+=f[0].interpolator.nx*3
if f.type == 'series':
nfeatures+=1
total_dof+=f.interpolator.nx
Expand Down
11 changes: 1 addition & 10 deletions LoopStructural/modelling/features/geological_feature_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,16 +455,7 @@ def build(self, fold=None, fold_weights={}, data_region=None, **kwargs):

self.interpolator.support.maximum = newmax
self.interpolator.set_region(region=region)
# moving this to init because it needs to be done before constraints
# are added?
if fold is not None:
logger.info("Adding fold to %s" % self.name)
self.interpolator.fold = fold
# if we have fold weights use those, otherwise just use default
self.interpolator.add_fold_constraints(**fold_weights)
if 'cgw' not in kwargs:
# try adding very small cg
kwargs['cgw'] = 0.0

self.install_gradient_constraint()
self.install_equality_constraints()
self.interpolator.setup_interpolator(**kwargs)
Expand Down
3 changes: 2 additions & 1 deletion LoopStructural/modelling/fold/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
from .svariogram import SVariogram
from .fold_rotation_angle_feature import FoldRotationAngleFeature, fourier_series
from .foldframe import FoldFrame
from .fold_rotation_angle import FoldRotationAngle
from .fold_rotation_angle import FoldRotationAngle
from .fold_builder import FoldedFeatureBuilder
71 changes: 71 additions & 0 deletions LoopStructural/modelling/fold/fold_builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from ..features import GeologicalFeatureInterpolator

class FoldedFeatureBuilder(GeologicalFeatureInterpolator):

def __init__(self,interpolator,fold,fold_weights={},name='Feature',region=None,**kwargs):
GeologicalFeatureInterpolator.__init__(self,interpolator,name=name,region=region,**kwargs)
self.fold = fold
self.fold_weights = fold_weights
self.kwargs = kwargs


def set_fold_axis(self):
kwargs = self.kwargs
fold_axis = kwargs.get('fold_axis',None)
if fold_axis is not None:
fold_axis = np.array(fold_axis)
if len(fold_axis.shape) == 1:
self.fold.fold_axis = fold_axis

if "av_fold_axis" in kwargs:
_calculate_average_intersection(series_builder, fold_frame, fold)
if self.fold.fold_axis is None:
far, fad = self.fold.fold_frame.calculate_fold_axis_rotation(
self)
fold_axis_rotation = FoldRotationAngle(far, fad,svario=svario)
a_wl = kwargs.get("axis_wl", None)
if 'axis_function' in kwargs:
# allow predefined function to be used
fold_axis_rotation.set_function(kwargs['axis_function'])
else:
fold_axis_rotation.fit_fourier_series(wl=a_wl)
self.fold.fold_axis_rotation = fold_axis_rotation

def set_fold_limb_rotation(self):
kwargs = self.kwargs
# give option of passing own fold limb rotation function
flr, fld = self.fold.fold_frame.calculate_fold_limb_rotation(
self, self.fold.get_fold_axis_orientation)
fold_limb_rotation = FoldRotationAngle(flr, fld,svario=svario)
l_wl = kwargs.get("limb_wl", None)
if 'limb_function' in kwargs:
# allow for predefined functions to be used
fold_limb_rotation.set_function(kwargs['limb_function'])
else:
fold_limb_rotation.fit_fourier_series(wl=l_wl,**kwargs)
fold.fold_limb_rotation = fold_limb_rotation

def build(self, data_region=None, **kwargs):
"""[summary]
Parameters
----------
data_region : [type], optional
[description], by default None
"""
# add the data to the interpolator and force constraints to be
# gradient not norm, to prevent issues with fold norm constraint
# TODO folding norm constraint should be minimising the difference in norm
# not setting the norm
self.add_data_to_interpolator(constrained=True)
self.set_fold_axis()
self.set_fold_limb_rotation()
logger.info("Adding fold to {}".format(self.name))
self.interpolator.fold = self.fold
# if we have fold weights use those, otherwise just use default
self.interpolator.add_fold_constraints(**self.fold_weights)
if 'cgw' not in kwargs:
# try adding very small cg
kwargs['cgw'] = 0.0
# now the fold is set up run the standard interpolation
GeologicalFeatureInterpolator.build(self,data_region=data_region,**kwargs)

0 comments on commit b40ba9a

Please sign in to comment.