Skip to content

Commit aebb182

Browse files
committed
(FEATURE) added logging to discrete interpolator
for DOF and can now specify element_volume when adding a feature
1 parent 2240faf commit aebb182

File tree

2 files changed

+35
-16
lines changed

2 files changed

+35
-16
lines changed

LoopStructural/interpolators/discrete_interpolator.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ def __init__(self, support):
5252
self.eq_const_c_ = 0
5353
self.constraints = {}
5454
self.interpolation_weights= {}
55-
55+
logger.info("Creating discrete interpolator with {} degrees of freedom".format(self.nx))
56+
5657
def set_property_name(self, propertyname):
5758
"""
5859
Set the property name attribute, this is usually used to
@@ -89,7 +90,8 @@ def set_region(self, region=None):
8990
self.region_map[self.region] = np.array(
9091
range(0, len(self.region_map[self.region])))
9192
self.nx = len(self.support.nodes[self.region])
92-
93+
logger.info("Interpolation now uses region and has {} degrees of freedom".format(self.nx))
94+
9395
def set_interpolation_weights(self, weights):
9496
"""
9597
Set the interpolation weights dictionary

LoopStructural/modelling/core/geological_model.py

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
from LoopStructural.utils.helper import (all_heading, gradient_vec_names,
3737
strike_dip_vector)
3838

39-
from LoopStructural.utils import getLogger
39+
from LoopStructural.utils import getLogger, log_to_file
4040
logger = getLogger(__name__)
4141
if not surfe:
4242
logger.warning("Cannot import Surfe")
@@ -86,7 +86,7 @@ class GeologicalModel:
8686
8787
"""
8888
def __init__(self, origin, maximum, rescale=True, nsteps=(40, 40, 40),
89-
reuse_supports=False):
89+
reuse_supports=False, logfile=None, loglevel='info'):
9090
"""
9191
Parameters
9292
----------
@@ -120,6 +120,11 @@ def __init__(self, origin, maximum, rescale=True, nsteps=(40, 40, 40),
120120
121121
122122
"""
123+
if logfile:
124+
self.logfile = logfile
125+
log_to_file(logfile,loglevel)
126+
127+
logger.info('Initialising geological model')
123128
self.features = []
124129
self.feature_name_index = {}
125130
self.data = None
@@ -128,19 +133,23 @@ def __init__(self, origin, maximum, rescale=True, nsteps=(40, 40, 40),
128133
# we want to rescale the model area so that the maximum length is
129134
# 1
130135
self.origin = np.array(origin).astype(float)
136+
logger.info('Model origin: {} {} {}'.format(self.origin[0],self.origin[1],self.origin[2]))
131137

132138
self.maximum = np.array(maximum).astype(float)
139+
logger.info('Model maximum: {} {} {}'.format(self.maximum[0],self.maximum[1],self.maximum[2]))
133140
lengths = self.maximum - self.origin
134141
self.scale_factor = 1.
135142
self.bounding_box = np.zeros((2, 3))
136143
self.bounding_box[1, :] = self.maximum - self.origin
137144
self.bounding_box[1, :] = self.maximum - self.origin
138145
if rescale:
139146
self.scale_factor = np.max(lengths)
147+
logger.info('Rescaling model using scale factor {}'.format(self.scale_factor))
140148

141149
self.bounding_box /= self.scale_factor
142150
self.support = {}
143151
self.reuse_supports = reuse_supports
152+
logger.info('Reusing interpolation supports: {}'.format(self.reuse_supports))
144153
self.stratigraphic_column = None
145154
self.parameters = {'features': [], 'model': {'bounding_box': self.origin.tolist() + self.maximum.tolist(),
146155
'rescale': rescale,
@@ -167,6 +176,7 @@ def from_map2loop_directory(cls, m2l_directory,**kwargs):
167176
the created geological model and a dictionary of the map2loop data
168177
"""
169178
from LoopStructural.utils import build_model, process_map2loop
179+
logger.info('LoopStructural model initialised from m2l directory: {}'.format(m2l_directory))
170180
m2lflags = kwargs.pop('m2lflags',{})
171181
m2l_data = process_map2loop(m2l_directory,m2lflags)
172182
return build_model(m2l_data,**kwargs), m2l_data
@@ -192,11 +202,12 @@ def from_file(cls, file):
192202
return None
193203
model = pickle.load(open(file,'rb'))
194204
if type(model) == GeologicalModel:
205+
logger.info('GeologicalModel initialised from file')
195206
return model
196207
else:
197208
logger.error('{} does not contain a geological model'.format(file))
198209
return None
199-
210+
200211
def __getitem__(self, feature_name):
201212
"""Accessor for feature in features using feature_name_index
202213
@@ -227,6 +238,7 @@ def to_file(self, file):
227238
"pip install dill")
228239
return
229240
try:
241+
logger.info('Writing GeologicalModel to: {}'.format(file))
230242
pickle.dump(self,open(file,'wb'))
231243
except pickle.PicklingError:
232244
logger.error('Error saving file')
@@ -285,7 +297,7 @@ def set_model_data(self, data):
285297
data = pd.read_csv(data)
286298
except:
287299
logger.error("Could not load pandas data frame from data")
288-
300+
logger.info('Adding data to GeologicalModel with {} data points'.format(len(data)))
289301
self.data = data.copy()
290302
self.data['X'] -= self.origin[0]
291303
self.data['Y'] -= self.origin[1]
@@ -294,7 +306,7 @@ def set_model_data(self, data):
294306
self.data['Y'] /= self.scale_factor
295307
self.data['Z'] /= self.scale_factor
296308
if 'type' in self.data:
297-
logger.warning("'type' is being replaced with 'feature_name' \n")
309+
logger.warning("'type' is depreciated replace with 'feature_name' \n")
298310
self.data.rename(columns={'type':'feature_name'},inplace=True)
299311
for h in all_heading():
300312
if h not in self.data:
@@ -305,6 +317,7 @@ def set_model_data(self, data):
305317
self.data[h] = 0
306318

307319
if 'strike' in self.data and 'dip' in self.data:
320+
logger.info('Converting strike and dip to vectors')
308321
mask = np.all(~np.isnan(self.data.loc[:, ['strike', 'dip']]),
309322
axis=1)
310323
self.data.loc[mask, gradient_vec_names()] = strike_dip_vector(
@@ -359,6 +372,7 @@ def set_stratigraphic_column(self, stratigraphic_column,cmap='tab20'):
359372
"""
360373
# if the colour for a unit hasn't been specified we can just sample from
361374
# a colour map e.g. tab20
375+
logger.info('Adding stratigraphic column to model')
362376
random_colour = True
363377
n_units=0
364378
for g in stratigraphic_column.keys():
@@ -403,7 +417,7 @@ def create_from_feature_list(self, features):
403417
self.create_and_add_folded_foliation(f)
404418

405419
def get_interpolator(self, interpolatortype='PLI', nelements=1e5,
406-
buffer=0.2, **kwargs):
420+
buffer=0.2, element_volume = None, **kwargs):
407421
"""
408422
Returns an interpolator given the arguments, also constructs a
409423
support for a discrete interpolator
@@ -435,11 +449,12 @@ def get_interpolator(self, interpolatortype='PLI', nelements=1e5,
435449
bb[1, :] += buffer # *(bb[1,:]-bb[0,:])
436450
box_vol = (bb[1, 0]-bb[0, 0]) * (bb[1, 1]-bb[0, 1]) * (bb[1, 2]-bb[0, 2])
437451
if interpolatortype == "PLI":
438-
nelements /= 5
439-
ele_vol = box_vol / nelements
452+
if element_volume is None:
453+
nelements /= 5
454+
element_volume = box_vol / nelements
440455
# calculate the step vector of a regular cube
441456
step_vector = np.zeros(3)
442-
step_vector[:] = ele_vol ** (1. / 3.)
457+
step_vector[:] = element_volume ** (1. / 3.)
443458
# step_vector /= np.array([1,1,2])
444459
# number of steps is the length of the box / step vector
445460
nsteps = np.ceil((bb[1, :] - bb[0, :]) / step_vector).astype(int)
@@ -457,10 +472,11 @@ def get_interpolator(self, interpolatortype='PLI', nelements=1e5,
457472

458473
if interpolatortype == 'FDI':
459474
# find the volume of one element
460-
ele_vol = box_vol / nelements
475+
if element_volume is None:
476+
element_volume = box_vol / nelements
461477
# calculate the step vector of a regular cube
462478
step_vector = np.zeros(3)
463-
step_vector[:] = ele_vol ** (1. / 3.)
479+
step_vector[:] = element_volume ** (1. / 3.)
464480
# number of steps is the length of the box / step vector
465481
nsteps = np.ceil((bb[1, :] - bb[0, :]) / step_vector).astype(int)
466482
if np.any(np.less(nsteps, 3)):
@@ -478,11 +494,12 @@ def get_interpolator(self, interpolatortype='PLI', nelements=1e5,
478494
return FDI(grid)
479495

480496
if interpolatortype == "DFI": # "fold" in kwargs:
481-
nelements /= 5
482-
ele_vol = box_vol / nelements
497+
if element_volume is None:
498+
nelements /= 5
499+
element_volume = box_vol / nelements
483500
# calculate the step vector of a regular cube
484501
step_vector = np.zeros(3)
485-
step_vector[:] = ele_vol ** (1. / 3.)
502+
step_vector[:] = element_volume ** (1. / 3.)
486503
# number of steps is the length of the box / step vector
487504
nsteps = np.ceil((bb[1, :] - bb[0, :]) / step_vector).astype(int)
488505
# create a structured grid using the origin and number of steps

0 commit comments

Comments
 (0)