[BUG] unstable model evaluation error
gpirot opened this issue · comments
Describe your issue
When adding a slippling fault perturbation to a dataset it creates some instabilities when evaluating the the model for its stratigraphy on a regular grid. When the fault slip is set to 0, the evaluation runs without problem. When the faultslip is set to 1500, then have a value error as described below.
The data perturbation basically moves all data points on on side of the fault by the faultslip along the slip vector.
Minimal reproducing code example
A notebook example.ipynb is provided in the zip file.
To check for the change of behavior, update the following parameter in the first code cell
# PARAM FAULT 12627 DISPLACEMENT
dispF12627=1500 # 0 or 1500
The third code cell is the one with an unstable behavior
Error message
data.loc[groupSix,"scalar_field"] = model.evaluate_feature_value('stratigraphy',xyzS,scale=True)#,scale=True)
data.loc[groupSix,"scalar_field"] = model.evaluate_feature_value('stratigraphy',xyzS,scale=True)#,scale=True)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-874a38232180> in <module>
----> 1 data.loc[groupSix,"scalar_field"] = model.evaluate_feature_value('stratigraphy',xyzS,scale=True)#,scale=True)
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\core\geological_model.py in evaluate_feature_value(self, feature_name, xyz, scale)
1470 if scale:
1471 scaled_xyz = self.scale(xyz,inplace=False)
-> 1472 return feature.evaluate_value(scaled_xyz)
1473 else:
1474 return np.zeros(xyz.shape[0])
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\features\geological_feature.py in evaluate_value(self, evaluation_points)
124 #if evaluation_points is not a numpy array try and convert
125 #otherwise error
--> 126 self.builder.up_to_date()
127 # check if the points are within the display region
128 v = np.zeros(evaluation_points.shape[0])
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\features\geological_feature_builder.py in up_to_date(self)
88 #has anything changed in the builder since we built the feature? if so update
89 if self._up_to_date == False:
---> 90 self.update()
91 #check if the interpolator is up to date, if not solve
92 if self._interpolator.up_to_date == False:
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\features\geological_feature_builder.py in update(self)
77
78 def update(self):
---> 79 self.build(**self.build_arguments)
80 @property
81 def name(self):
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\features\geological_feature_builder.py in build(self, fold, fold_weights, data_region, **kwargs)
405
406
--> 407 self.add_data_to_interpolator(**kwargs)
408 if data_region is not None:
409 xyz = self.interpolator.get_data_locations()
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\features\geological_feature_builder.py in add_data_to_interpolator(self, constrained, force_constrained, **kwargs)
172 for f in self.faults:
173 data.loc[:,xyz_names()] = f.apply_to_points(
--> 174 self.get_data_locations())
175 # Now check whether there are enough constraints for the
176 # interpolator to be able to solve
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\fault\fault_segment.py in apply_to_points(self, points)
275 gz_future = executor.submit(self.faultframe.features[2].evaluate_value, newp)
276 gx = gx_future.result()
--> 277 gy = gy_future.result()
278 gz = gz_future.result()
279 else:
C:\ProgramData\Anaconda3\lib\concurrent\futures\_base.py in result(self, timeout)
426 raise CancelledError()
427 elif self._state == FINISHED:
--> 428 return self.__get_result()
429
430 self._condition.wait(timeout)
C:\ProgramData\Anaconda3\lib\concurrent\futures\_base.py in __get_result(self)
382 def __get_result(self):
383 if self._exception:
--> 384 raise self._exception
385 else:
386 return self._result
C:\ProgramData\Anaconda3\lib\concurrent\futures\thread.py in run(self)
55
56 try:
---> 57 result = self.fn(*self.args, **self.kwargs)
58 except BaseException as exc:
59 self.future.set_exception(exc)
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\features\geological_feature.py in evaluate_value(self, evaluation_points)
124 #if evaluation_points is not a numpy array try and convert
125 #otherwise error
--> 126 self.builder.up_to_date()
127 # check if the points are within the display region
128 v = np.zeros(evaluation_points.shape[0])
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\features\geological_feature_builder.py in up_to_date(self)
88 #has anything changed in the builder since we built the feature? if so update
89 if self._up_to_date == False:
---> 90 self.update()
91 #check if the interpolator is up to date, if not solve
92 if self._interpolator.up_to_date == False:
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\features\geological_feature_builder.py in update(self)
77
78 def update(self):
---> 79 self.build(**self.build_arguments)
80 @property
81 def name(self):
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\features\geological_feature_builder.py in build(self, fold, fold_weights, data_region, **kwargs)
436 # try adding very small cg
437 kwargs['cgw'] = 0.0
--> 438 self.install_gradient_constraint()
439 self.install_equality_constraints()
440 self.interpolator.setup_interpolator(**kwargs)
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\features\geological_feature_builder.py in install_gradient_constraint(self)
249 for g in self._orthogonal_features.values():
250 feature,w,region,step,B = g
--> 251 vector = feature.evaluate_gradient(self.interpolator.support.barycentre())
252 vector /= np.linalg.norm(vector,axis=1)[:,None]
253 element_idx = np.arange(self.interpolator.support.n_elements)
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\features\geological_feature.py in evaluate_gradient(self, evaluation_points)
158
159 """
--> 160 self.builder.up_to_date()
161 v = np.zeros(evaluation_points.shape)
162 v[:] = np.nan
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\features\geological_feature_builder.py in up_to_date(self)
88 #has anything changed in the builder since we built the feature? if so update
89 if self._up_to_date == False:
---> 90 self.update()
91 #check if the interpolator is up to date, if not solve
92 if self._interpolator.up_to_date == False:
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\features\geological_feature_builder.py in update(self)
77
78 def update(self):
---> 79 self.build(**self.build_arguments)
80 @property
81 def name(self):
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\features\geological_feature_builder.py in build(self, fold, fold_weights, data_region, **kwargs)
438 self.install_gradient_constraint()
439 self.install_equality_constraints()
--> 440 self.interpolator.setup_interpolator(**kwargs)
441 self.interpolator.solve_system(**kwargs)
442 self._up_to_date = True
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\interpolators\geological_interpolator.py in setup_interpolator(self, **kwargs)
171 Runs all of the required setting up stuff
172 """
--> 173 self._setup_interpolator(**kwargs)
174
175 def solve_system(self, **kwargs):
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\interpolators\piecewiselinear_interpolator.py in _setup_interpolator(self, **kwargs)
85 self.n_t, self.n_i, self.propertyname))
86 self.add_gradient_ctr_pts(self.interpolation_weights['gpw'])
---> 87 self.add_norm_ctr_pts(self.interpolation_weights['npw'])
88 self.add_ctr_pts(self.interpolation_weights['cpw'])
89 self.add_tangent_ctr_pts(self.interpolation_weights['tpw'])
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\interpolators\piecewiselinear_interpolator.py in add_norm_ctr_pts(self, w)
312 vol[outside, None],
313 idc[outside],
--> 314 name='norm')
315
316 def add_ctr_pts(self, w=1.0): # for now weight all value points the same
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\interpolators\discrete_interpolator.py in add_constraints_to_least_squares(self, A, B, idc, name)
181
182 self.constraints[name]['A'] = np.vstack([self.constraints[name]['A'],A])
--> 183 self.constraints[name]['B'] = np.hstack([self.constraints[name]['B'], B])
184 self.constraints[name]['idc'] = np.vstack([self.constraints[name]['idc'],
185 idc])
<__array_function__ internals> in hstack(*args, **kwargs)
C:\ProgramData\Anaconda3\lib\site-packages\numpy\core\shape_base.py in hstack(tup)
341 # As a special case, dimension 0 of 1-dimensional arrays is "horizontal"
342 if arrs and arrs[0].ndim == 1:
--> 343 return _nx.concatenate(arrs, 0)
344 else:
345 return _nx.concatenate(arrs, 1)
<__array_function__ internals> in concatenate(*args, **kwargs)
ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 1 dimension(s) and the array at index 1 has 2 dimension(s)
Hi Guillaume,
Can you please upload a working example for me?
I get this error when trying to run your notebook.
`---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
in
113 base_elevation = (np.asarray(stratigraphy.loc[ixunit,'cumulativeThickness'])).flatten() # 'base_elevation' 'cumulativeThickness'
114 ixctc = np.asarray(np.where(contacts["formation"]==unit)).flatten()
--> 115 contacts.loc[ixctc,"val"]=base_elevation
116 contacts.loc[ixctc,"feature_name"]=stratigraphy.loc[ixunit[0],'group']
117 ixori = np.asarray(np.where(orientations["formation"]==unit)).flatten()
/opt/conda/lib/python3.7/site-packages/pandas/core/indexing.py in setitem(self, key, value)
721
722 iloc = self if self.name == "iloc" else self.obj.iloc
--> 723 iloc._setitem_with_indexer(indexer, value, self.name)
724
725 def _validate_key(self, key, axis: int):
/opt/conda/lib/python3.7/site-packages/pandas/core/indexing.py in _setitem_with_indexer(self, indexer, value, name)
1728 if take_split_path:
1729 # We have to operate column-wise
-> 1730 self._setitem_with_indexer_split_path(indexer, value, name)
1731 else:
1732 self._setitem_single_block(indexer, value, name)
/opt/conda/lib/python3.7/site-packages/pandas/core/indexing.py in _setitem_with_indexer_split_path(self, indexer, value, name)
1784
1785 raise ValueError(
-> 1786 "Must have equal len keys and value "
1787 "when setting with an iterable"
1788 )
ValueError: Must have equal len keys and value when setting with an iterable`
Hi Lachie,
Here is an updated notebook. Sorry about that, I do not have this error on my end, so if it persists, let me know and I will provide directly my processed data.
Cheers
Which version of loopstructural are you using? This bug was fixed in 63ea5ec but I have also made another change in 009d2b8 that fix another bug you may have experienced because you don't provide the dimensions of the fault ellipsoid. Can you try updating to the latest commit on master and see if the bug is gone.
Hi Lachie,
I am using version 1.1.0.
I will update my version and check ho it goes.
Cheers
Hi Lachie,
I upgraded to version 1.4.1 and I do not observe these errors anymore, so I will close this issue.
But a set of understandable warnings:
2021-12-09 11:26:17,043 ~ LoopStructural.modelling.core.geological_model ~ WARNING ~ Depreciated method. Model data can now be set using the data attribute
2021-12-09 11:26:17,149 ~ LoopStructural.modelling.core.geological_model ~ WARNING ~ Fault slip vector is nan, estimating from fault normal
2021-12-09 11:26:17,155 ~ LoopStructural.modelling.fault.fault_builder ~ WARNING ~ Fault major axis using map length: 65783.89284117577
2021-12-09 11:26:17,229 ~ LoopStructural.modelling.core.geological_model ~ WARNING ~ Fault slip vector is nan, estimating from fault normal
2021-12-09 11:26:17,235 ~ LoopStructural.modelling.fault.fault_builder ~ WARNING ~ Fault major axis using map length: 97248.09034725242
2021-12-09 11:26:17,305 ~ LoopStructural.modelling.core.geological_model ~ WARNING ~ Fault slip vector is nan, estimating from fault normal
2021-12-09 11:26:17,311 ~ LoopStructural.modelling.fault.fault_builder ~ WARNING ~ Fault major axis using map length: 31228.97524244915
AND a few runtime warnings when my fault slip value is not 0:
WOULD YOU LIKE ME TO OPEN A NEW ISSUE FOR THESE
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\interpolators\structured_tetra.py:121: RuntimeWarning: invalid value encountered in greater
inside *= pos[:, i] > self.origin[None, i]
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\interpolators\structured_tetra.py:125: RuntimeWarning: invalid value encountered in less
- self.step_vector[None, i] * self.nsteps_cells[None, i]
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\interpolators\base_structured_3d_support.py:176: RuntimeWarning: invalid value encountered in floor_divide
ix = ix // self.step_vector[None, 0]
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\interpolators\base_structured_3d_support.py:177: RuntimeWarning: invalid value encountered in floor_divide
iy = iy // self.step_vector[None, 1]
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\interpolators\base_structured_3d_support.py:178: RuntimeWarning: invalid value encountered in floor_divide
iz = iz // self.step_vector[None, 2]
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\interpolators\structured_tetra.py:190: RuntimeWarning: invalid value encountered in greater
mask = np.all(c > 0, axis=2)
2021-12-09 11:30:04,900 ~ LoopStructural.interpolators.discrete_interpolator ~ WARNING ~ No solution, Fault_12627_2 scalar field 0. Add more data.
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\interpolators\piecewiselinear_interpolator.py:438: RuntimeWarning: invalid value encountered in true_divide
vector /= norm[:, None]
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\interpolators\piecewiselinear_interpolator.py:441: RuntimeWarning: divide by zero encountered in true_divide
element_gradients /= norm[:, None, None]
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\interpolators\piecewiselinear_interpolator.py:441: RuntimeWarning: invalid value encountered in true_divide
element_gradients /= norm[:, None, None]
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\interpolators\discrete_interpolator.py:183: RuntimeWarning: invalid value encountered in greater
B[length > 0] /= length[length > 0]
C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\interpolators\discrete_interpolator.py:187: RuntimeWarning: invalid value encountered in greater
A[length > 0, :] /= length[length > 0, None]