GithubHelp home page GithubHelp logo

loop3d / loopstructural Goto Github PK

View Code? Open in Web Editor NEW
164.0 11.0 34.0 127.73 MB

LoopStructural is an open-source 3D structural geological modelling library.

License: MIT License

Python 98.25% Dockerfile 0.25% Cython 1.50%
geoscience geology interpolation geology-modelling structural-geology folds faults kinematics implicit-modelling 3d-modelling

loopstructural's Introduction

LoopStructural: Loop3D Geological Forward Modeling Engine.

3D model of Hamersley created using loopstructural Continuous integration and deployment Publish Docker Hub PyPI version GitHub license Documentation loop3d.github.io/LoopStructural/

LoopStructural is the 3D geological modelling library for Loop (Loop3d.org). The development of LoopStructural is lead by Lachlan Grose as an ARC (LP170100985) post-doc at Monash University. Laurent Ailleres and Gautier Laurent have made significant contributions to the conceptual design and integration of geological concepts into the geological modelling workflow. Roy Thomson and Yohan de Rose have contributed to the implementation and integration of LoopStructural into the Loop workflow.

Loop is led by Laurent Ailleres (Monash University) with a team of Work Package leaders from:

  • Monash University: Roy Thomson, Lachlan Grose and Robin Armit
  • University of Western Australia: Mark Jessell, Jeremie Giraud, Mark Lindsay and Guillaume Pirot
  • Geological Survey of Canada: Boyan Brodaric and Eric de Kemp

The project benefits from in-kind contributions from the Geological Survey of Canada, the British Geological Survey, the French Bureau de Recherches Geologiques et Minieres, the RING group at the Universite de Lorraine, the RWTH in Aachen, Germany and AUSCOPE

  • Python/cython implementation of a Discrete interpolatiors
  • Fold interpolation using constraints outlined in Laurent 2016 with fold geostatistical tools shown in Grose et al., 2017
  • Fault interpolation

If you want to use LoopStructural the easiest way to get started is to use a docker container and a jupyter notebook environment

  1. Pull the loopstructural docker image docker pull lachlangrose/loopstructural
  2. Start a docker container docker run -it -p 8888:8888 lachlangrose/loopstructural

Documentation

The LoopStructural documentation can be found here

Problems

Any bugs/feature requests/comments please create a new issue.

Acknowledgements

The Loop platform is an open source 3D probabilistic geological and geophysical modelling platform, initiated by Geoscience Australia and the OneGeology consortium. The project is funded by Australian territory, State and Federal Geological Surveys, the Australian Research Council and the MinEx Collaborative Research Centre.

loopstructural's People

Contributors

angrodrigues avatar fer071989 avatar github-actions[bot] avatar lachlangrose avatar rabii-chaarani avatar roythomsonmonash avatar vjf avatar vpicavet avatar yohanderose avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

loopstructural's Issues

[BUG] interface constraints for PLI don't work

Describe the bug
Interface constraints are implemented incorrectly and produce weird solutions.
The interface constraint should try to minimise the difference in the interpolated scalar field value for all pairs of points with the same line.

In FDI this is done using a for loop which is slow, PLI has an attempt to do this using NumPy but does not work.

[FEATURE] Option to use global formation summary thickness file

Is your feature request related to a problem? Please describe.
For the Hamersley stitch it would be great to use a single formation thickness file compiled from all the tiles

Describe the solution you'd like
A flag and file path that allows a single formation thickness file to be accessed. Same format as individual ones.

Describe alternatives you've considered
Having the notebook switch the file in each time = [clunky]

Additional context
Add any other context or screenshots about the feature request here.

import of function calculate_fault_topology_matrix changed

Describe your issue

Not sure if it is a bug or a way to remove partially a function, but
the previous way of importing the calculate_fault_topology_matrix function does not work anymore.

Minimal reproducing code example

# DOES NOT WORK
from LoopStructural.analysis import calculate_fault_topology_matrix

# DOES WORK
from LoopStructural.analysis._topology import calculate_fault_topology_matrix

Error message

Traceback (most recent call last):

  File "C:.......\AppData\Local\Temp/ipykernel_2060/4188448424.py", line 1, in <module>
    from LoopStructural.analysis import calculate_fault_topology_matrix

ImportError: cannot import name 'calculate_fault_topology_matrix' from 'LoopStructural.analysis' (C:......\lib\site-packages\LoopStructural\analysis\__init__.py)

[BUG] conda install

Describe your issue

Hello, I installed in a conda environment with: conda install -c loop3d loopstructural, but then when I try to import LoopStructural I get an error saying ModuleNotFoundError: No module named 'LoopProjectFile'.

I am on Windows 10, Ananconda last version, Python 3.8.13 (last 3.8).

Thanks!

Minimal reproducing code example

import LoopStructural as loop3d

Error message

Traceback (most recent call last):
  File "C:\Users\bistek\anaconda3\envs\pzero\lib\site-packages\LoopStructural\modelling\input\project_file.py", line 4, in <module>
    from LoopProjectFile import ProjectFile
ModuleNotFoundError: No module named 'LoopProjectFile'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\bistek\anaconda3\envs\pzero\lib\site-packages\LoopStructural\__init__.py", line 21, in <module>
    from .modelling.core.geological_model import GeologicalModel
  File "C:\Users\bistek\anaconda3\envs\pzero\lib\site-packages\LoopStructural\modelling\__init__.py", line 7, in <module>
    from LoopStructural.modelling.input.project_file import LoopProjectfileProcessor
  File "C:\Users\bistek\anaconda3\envs\pzero\lib\site-packages\LoopStructural\modelling\input\project_file.py", line 6, in <module>
    raise LoopImportError("LoopProjectFile cannot be imported")
LoopStructural.utils.exceptions.LoopImportError: LoopProjectFile cannot be imported

[Question] explanation on faults

Hi, and thanks for all your work as usual!

I'm trying to figure out how faults work. It looks like something is changing here.

I summarize what I think I understood:

  1. First you must instantiate a fault frame with FaultBuilder(). The only required parameter is the model, while interpolator, interpolators, and fault_bounding_box_buffer are not mandatory.
  • I do not understand the difference between interpolator and interpolators.

  • How does fault_bounding_box_buffer work? In the code comments you say "the maximum area around the model domain that a fault is modelled." so it looks like the fault will extend out of the modelling domain? Or you mean an extension with respect to the fault data bounding box?

  • Is it necessary to instantiate like this, or calling the function below is enough?

  1. Then you must specify some data, and particularly the slip vector and slip modulus. I understand this is done with FaultBuilder.create_data_from_geometry().
  • Here data is the model dataframe, so the same as model in FaultBuilder()?

  • All other parameters except slip_vector are generated automatically from data (e.g. the fault trace) if not specified, correct?

Thanks very much!

[BUG] Fold failures

Both of the fold examples return the following error when I run them:

AttributeError: 'NoneType' object has no attribute 'fold_limb_rotation'

Would it be possible to verify whether this is reproducible? I am using v1.0.89 via pip3.

AttributeError: 'NoneType' object has no attribute 'set_property_name'[BUG]

Hi,
I am running the code to create the model and I keep getting the Attribute error "NoneType' object has no attribute 'set_property_name".
Although every thing else works, the problem comes from the file geological_feature_builder.py line 39. self._interpolator.set_property_name(self._name).
I dont understand why the interpolator needs to set the property name, it could be any property, secondly this function is being applied to "self.name" which also causes confusion as to what name, the property name or the name of formation?.

An important consideration, i don't have the column for "vals" in my data, I tried to add this column with some arbitrary values just to see if the error goes away, but the error stays.

Minimal working example
The minimal code required to reproduce the bug:

vals = [0,100,250,330,600]

strat_column = {'Permian':{}}
for i in range(len(vals)-1):
strat_column['Permian']['unit_{}'.format(i)] = {'min':vals[i],'max':vals[i+1],'id':i}

model.set_stratigraphic_column(strat_column)

formation = model.create_and_add_foliation("Permian",
interpolatortype="FDI", # try changing this to 'PLI'
nelements=5e4, # try changing between 1e3 and 5e4
buffer=0.3,
solver='pyamg',
damp=True
)

Expected behavior
Computation of the desired geological model.

Screenshots

attribute_error

[BUG] Docker not working?

Hello, I tried to run LoopStructural with Docker, following your instructions, but I cannot have it working.

I am running Docker on Windows 10 64bit, but this should not matter (I guess).

I pull the image with docker pull lachlangrose/loopstructural and it seems OK in Docker Desktop:

image

Then I start the container with docker run -it -p 8888:8888 lachlangrose/loopstructural and I get:

[I 18:14:31.073 NotebookApp] Writing notebook server cookie secret to /home/jovyan/.local/share/jupyter/runtime/notebook_cookie_secret
[W 18:14:31.413 NotebookApp] All authentication is disabled.  Anyone who can connect to this server will be able to run code.
[I 18:14:31.441 NotebookApp] [jupyter_nbextensions_configurator] enabled 0.4.1
[I 18:14:31.980 NotebookApp] Serving notebooks from local directory: /home/jovyan
[I 18:14:31.980 NotebookApp] Jupyter Notebook 6.1.1 is running at:
[I 18:14:31.981 NotebookApp] http://1d6ee7319fc7:8888/
[I 18:14:31.981 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).

...so I copy the link http://1d6ee7319fc7:8888/ and paste it into Firefox, but I get this error:

image

I also tried starting the image from Docker Desktop, and apparently it runs, but with no browser output:

image

Do you have any suggestion?

Thanks very much!

[FEATURE] - add fold constraints to finite difference interpolator

Is your feature request related to a problem? Please describe.
Add the folding constraints to the finite different interpolator following a similar structure to the discrete fold interpolator.

Need to work out how to regularise the gaussian curvature wrt the fold frame coordinates

[Question] vocabulary / rdf

Hi Loopers,
Does LoopStructural connect to the vocabularies or use a syntax that's compatible?
Or, would we need to parse a vocabulary with a bit of translation between?

Thanks

AttributeError: 'SurfeRBFInterpolator' object has no attribute 'copy'[BUG]

Hi,
I am trying to create Faults using the RBF (surfe) interpolator. And i get the attribute error as mentioned in the heading. The error doesnot arise when i create a foliation instead of fault.

Here is the code that produces the error:

code_to_generate_fault_surfe_attribute_error

Expected behavior_

add a fault surface to the model

Screenshots
attribute_error_creating_fault_with_surfe

attribute_error_creating_fault_with_surfe2

Additionally!! The fault is created and added to the model when i Use PLI as the interpolator, but i cannot visualize it somehow. i guess that can be another bug/error.

Fault surface doesnt produce any displacement[BUG]

Hi,

i Generated a model which has some surfaces of geological layers/formations and some faults. The faults in the model do not show any displacement.

The fault surfaces are generated using :
model.create_and_add_fault()

An image of the model:
RBF+PLI_Loopstructural

[Question] how to export as vtk .ts?

Hi again,
I searched the loop Structural docs and couldn't find anything obvious that allows me to export the fault surfaces I'm generating.
I can get it from vtk to .ts by myself if there isn't already a .ts output built.

Thanks
Matt

[BUG] - map2loop scalar values increase with depth

Describe the bug
When using process_map2loop the scalar values assigned to the series are in assending order. This means that the unconformity is added to the top of the youngest unit which is not true.

  1. Provide value of unconformity or;
  2. Reverse scalar values

LoopStructural.modelling.core.geological_model ~ WARNING ~ No data for Darling, skipping[BUG]

Hi,
I get the warning "No data for Darling(name of the formation) when i run:
data_example
formation

model.create_and_add_foliation("Darling",
interpolatortype="PLI",
nelements=1e4,
buffer=0.3,
solver='pyamg',
damp=True
)

Darling is the formation for which i have the dip and azimuth.

The data i have is attached as a screenshot with this report.

LoopStructural/modelling/core/geological_model.py line 605 to 609 it gives the reason for warning,

add data

    series_data = self.data[self.data['feature_name'] == series_surface_data]
    if series_data.shape[0] == 0:
        logger.warning("No data for %s, skipping" % series_surface_data)
        return

which seems not the case with my data.

LavaVu not working[BUG]

AttributeError: 'LavaVuModelViewer' object has no attribute 'lv'

The Class 'LavaVuModelViewer' does have the attribute 'lv' as seen in the file 'model_visualization.py' Line 62. "self.lv = lavavu.Viewer(**kwargs)"

The error occurs Even though i have installed the Lavavu library using Pip.

Secondly: on running the third example following error shows up:

AttributeError: 'LavaVuModelViewer' object has no attribute 'bounding_box'
it seems some problem in the 'LavaVuModelViewer' class

Expected behavior
import the 'lavavumodelviewer' object and import the lavavu library in this class. And Plot a surface from the data
lavavu

Screenshots
If applicable, add screenshots to help explain your problem.

  • OS: windows
    • Python environment [anaconda, python 3.7.1]

Additional context
Add any other context about the problem here.

[BUG] Lavvu conflicts with vtk output

Describe the bug
Lavavu model does not display in notebook if filename parameter used in view.add_model_surfaces()
Minimal working example

Run a map2loop model with filename paramter in view.add_model_surfaces()

Expected behavior
See lavavu rendered model in notebook

Screenshots
see attached
image

Desktop (please complete the following information):

  • OS: windows 10
  • Python environment [anaconda, python3.7]

inconsistency between origin, maximal extent and bounding box

Describe your issue

Hi Lachlan,
When specifying the model dimensions model = GeologicalModel([xmin,ymin,zmin],[xmax,ymax,zmax])
with an origin different than [0,0,0], LoopStructural seems to shift the origin of the bounding box to [0,0,0].

Example:
Bounding Box values:
[[ 0. 0. 0.]
[10. 4. 6.]]
Defined Model Extent values:
[[ 2 0 -6]
[12 4 0]]

Though it does not impact the input data considered for modelling, it affects the evaluation of the model (e.g. evaluate_model() or calculate_fault_topology_matrix(model,xyz)) at xyz locations, that apparently have to be rescaled accordingly with the extent of the bounding box and not the initially defined extent.

boudingbox-vs-modelextent.zip

Minimal reproducing code example

see example in notebook above for impact on the `evaluate_model` function

Error message

None

[Question] Type in input data

Hello, I am wondering what are the legal types of input data and what is their definition according to classical structural geology terminology.

In core/geological_model.py, at line 333, I find:

Type can be any unique identifier for the feature the data point 'eg' 'S0', 'S2', 'F1_axis' it is then used by the create functions to get the correct data.

I suspect that 'eg' is not a type but means e.g., then I understand that S0 is bedding or layering, S1, S2, etc. are different generations of foliation/schistosity, F1_axis is clear, but what is the type for e.g. a fold axial surface? And the letters should be capitalized or not? In some examples they are lower case.

More in general, is there a general definition of types of these structural data. Unfortunately I cannot find it.

In addition, I have the impression that columns for structural data are somehow redundant. They are: strike, dip, dip_dir, plunge, plunge_dir, azimuth.

strike -> is this defined according to right hand rule with respect to dip direction? I.e. strike = dip_dir - 90°? Is strike or dip_dir "prevailing" in case they are both defined?

plunge, plunge_dir -> I suppose that plunge is used for axes and lineations, and that plunge_dir is actually "trend". Correct?

azimuth (the last column) -> what is this for? Also strike, dip_dir and plunge_dir are azimuths.

Thanks very much!

[BUG] faults are cropped when using rescale = True

Describe the bug
When using the rescale flag for building the model, the faults seem to be cropped. Only an issue since the support is resized on the fly. The issue does not appear when the model isn't rescaled so for now the best way to avoid is to turn this flag off

Getting started in Python 3.8 environment - problems

Successfully installed LoopStructural with 'pip install LoopStructural' in Anaconda Prompt. Then I opened the project in PyCharm with a Python 3.8 Environment but I cannot run any of the examples in the 'examples' folder, such as 'example_surfe', 'plot_2_surface_modelling'...
Any help in running these in Python 3.8 environment would be really appreciated. Thanks!

error when specifying fault_slip_vector in create_and_add_fault

Describe your issue

Hi Lachie,

Providing a fault_slip_vector during the creation of a fault causes an error.
Without, or when commenting the input, there is no issue.

test-slipvector.zip

Minimal reproducing code example

See the attached example.

Error message

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-02dd0df01bea> in <module>
     13                                     steps=4,
     14                                     interpolatortype='PLI',
---> 15                                   buffer=0.3)
     16 ixcf =1
     17 flt2 = model.create_and_add_fault(df_faults.loc[ixcf,'Name'],

C:\ProgramData\Anaconda3\lib\site-packages\LoopStructural\modelling\core\geological_model.py in create_and_add_fault(self, fault_surface_data, displacement, tol, fault_slip_vector, fault_center, major_axis, minor_axis, intermediate_axis, faultfunction, **kwargs)
   1407                     .to_numpy()
   1408                 )
-> 1409         if np.any(np.isnan(fault_slip_vector)):
   1410             logger.warning("Fault slip vector is nan, estimating from fault normal")
   1411             strike_vector, dip_vector = get_vectors(fault_normal_vector[None, :])

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

[FEATURE]

Is your feature request related to a problem? Please describe.
A new function to add the observations for each horizon (as per the strat column) to the model viewer. This will ideally add the observations as separate objects for each unit.

Running Plot 1 -- Plot 5: Successes and possible bugs

Notes on running examples in https://github.com/Loop3D/LoopStructural/tree/master/examples/1_basic, aside from #59.

andy@cuesta:~/dataanalysis/LoopStructural/examples/1_basic$ python3 plot_2_surface_modelling.py 
2021-03-14 12:41:24,186 ~ LoopStructural.visualisation.model_visualisation ~ ERROR      ~ Plot area has not been defined.
2021-03-14 12:41:24,186 ~ LoopStructural.visualisation.model_visualisation ~ ERROR      ~ Plot area has not been defined.
2021-03-14 12:41:24,186 ~ LoopStructural.visualisation.model_visualisation ~ ERROR      ~ Plot area has not been defined.
Traceback (most recent call last):
  File "plot_2_surface_modelling.py", line 165, in <module>
    viewer.add_model_surfaces(cmap='tab20')
  File "/home/andy/.local/lib/python3.8/site-packages/LoopStructural/visualisation/model_visualisation.py", line 565, in add_model_surfaces
    cmap = cm.get_cmap(cmap,n_units)
UnboundLocalError: local variable 'cm' referenced before assignment

This seems like a potential bug.

  • plot_3_model_visualisation.py: Success, and returned this image:
    image
  • plot_3_multiple_groups.py
    • Following error, installed pyamg with pip3. Add to dependencies?
    • Following this, the example remains nonfunctional:
andy@cuesta:~/dataanalysis/LoopStructural/examples/1_basic$ python3 plot_3_multiple_groups.py
2021-03-14 12:49:41,684 ~ LoopStructural.visualisation.model_visualisation ~ WARNING    ~ Isovalue doesn't exist inside bounding box
2021-03-14 12:49:41,684 ~ LoopStructural.visualisation.model_visualisation ~ WARNING    ~ Isovalue doesn't exist inside bounding box
2021-03-14 12:49:41,684 ~ LoopStructural.visualisation.model_visualisation ~ WARNING    ~ Isovalue doesn't exist inside bounding box
2021-03-14 12:49:41,684 ~ LoopStructural.visualisation.model_visualisation ~ WARNING    ~ Isovalue doesn't exist inside bounding box
2021-03-14 12:49:41,684 ~ LoopStructural.visualisation.model_visualisation ~ WARNING    ~ Isovalue doesn't exist inside bounding box
2021-03-14 12:49:41,684 ~ LoopStructural.visualisation.model_visualisation ~ WARNING    ~ Isovalue doesn't exist inside bounding box
/home/andy/.local/lib/python3.8/site-packages/skimage/measure/_marching_cubes_lewiner.py:301: RuntimeWarning: invalid value encountered in greater
  if level < volume.min() or level > volume.max():
/home/andy/.local/lib/python3.8/site-packages/skimage/measure/_marching_cubes_lewiner.py:301: RuntimeWarning: invalid value encountered in less
  if level < volume.min() or level > volume.max():
/home/andy/.local/lib/python3.8/site-packages/LoopStructural/interpolators/structured_tetra.py:135: RuntimeWarning: invalid value encountered in greater
  inside *= pos[:, i] > self.origin[None, i]
/home/andy/.local/lib/python3.8/site-packages/LoopStructural/interpolators/structured_tetra.py:136: RuntimeWarning: invalid value encountered in less
  inside *= pos[:, i] < self.origin[None, i] + \
/home/andy/.local/lib/python3.8/site-packages/LoopStructural/interpolators/structured_tetra.py:525: RuntimeWarning: invalid value encountered in floor_divide
  ix = ix // self.step_vector[None, 0]
/home/andy/.local/lib/python3.8/site-packages/LoopStructural/interpolators/structured_tetra.py:526: RuntimeWarning: invalid value encountered in floor_divide
  iy = iy // self.step_vector[None, 1]
/home/andy/.local/lib/python3.8/site-packages/LoopStructural/interpolators/structured_tetra.py:527: RuntimeWarning: invalid value encountered in floor_divide
  iz = iz // self.step_vector[None, 2]
/home/andy/.local/lib/python3.8/site-packages/LoopStructural/interpolators/structured_tetra.py:197: RuntimeWarning: invalid value encountered in greater
  mask = np.all(c > 0, axis=2)
/home/andy/.local/lib/python3.8/site-packages/LoopStructural/modelling/features/unconformity_feature.py:40: RuntimeWarning: invalid value encountered in less
  return self.feature.evaluate_value(pos) < self.value
  • plot_4_using_stratigraphic_column.py
andy@cuesta:~/dataanalysis/LoopStructural/examples/1_basic$ python3 plot_4_using_stratigraphic_column.py
/home/andy/.local/lib/python3.8/site-packages/LoopStructural/modelling/core/geological_model.py:1349: RuntimeWarning: invalid value encountered in less
  strat_id[np.logical_and(vals < series.get('max',feature.max()), vals > series.get('min',feature.min()))] = series['id']
/home/andy/.local/lib/python3.8/site-packages/LoopStructural/modelling/core/geological_model.py:1349: RuntimeWarning: invalid value encountered in greater
  strat_id[np.logical_and(vals < series.get('max',feature.max()), vals > series.get('min',feature.min()))] = series['id']
  • plot_5_using_logging.py: Success, and returned two copies (default.png and default-00001.png -- perhaps a minor error here in the output code?) of this image:
    image

[BUG] invalid indexing of tetrahedron when area is outside of tetrahedral mesh.

Describe the bug
Using PLI if you try and evaluate the mesh outside of the model area it has an indexing problem.
Seems to occur when modelling faults.

packages/LoopStructural/interpolators/structured_tetra.py", line 109, in evaluate_value
values[inside] = np.sum(c[inside,:]*self.properties[prop][tetras[inside,:]],axis=1)
IndexError: index 29086 is out of bounds for axis 0 with size 26880

Need to make sure that inside is working correctly and maybe add a unit test for this.

Minimal working example
The minimal code required to reproduce the bug:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Python environment [anaconda, python3.6]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

[FEATURE] depth to top of unit

Request from @markdlindsay and @markjessell
Is your feature request related to a problem? Please describe.
Calculate the depth to the top of a unit

  • May need to improve how dtms are integrated and be able to return a surface or grid with the z values being current height.

Describe the solution you'd like
Should be as simple as evaluating the scalar field on the dtm points and determine the difference to the value of the stratigraphic unit in the stratigraphic column.

[BUG] PyPI Binary incompatibility on numpy array

LoopStructural fails on import LoopStructural with the message:

ValueError: numpy.ndarray size changed, may indicate binary incompatibility. Expected 88 from C header, got 80 from PyObject

LoopStructural-1.0.86 was installed for Python 3.8.5 on Ubuntu 20.04 with pip3 install LoopStructural. I note that the current PyPI version is 1.0.87; I will wait a moment and see if pip updates with this new release.

[BUG] using unconformities doubles time to evaluate model

Describe the bug
If unconformities are added into the model the time taken to evaluate the model increases by about double. Map2loop example 130 seconds without unconformities 260 seconds with unconformities. Its only really an issue when dealing with big models.

This is because the unconformity is a copy of the stratigraphy and so we have to evaluate the whole fault network before being able to evaluate the location of the unconformity.

No obvious workarounds.

Need to integrate the unconformity into the scalar field of the stratigraphy.

Runtime error when using RBF(surfe) as interpolator type[BUG]

I am using the 'RBF' interpolator called 'surfe' to creater foliations, the model is created but when i use the Lavavuviewr to plot the iso-surfaces by using :

viewer.add_isosurface(formation_Coomallo, slices=[0,-60,-250,-330],
paint_with=formation_Coomallo)

i get the following error:

runtime_error1

runtime_error2

runtime_error3

[FEATURE] Export surfaces to obj/vtk formats

Is your feature request related to a problem? Please describe.
Add in method to export surfaces to common formats.

Describe the solution you'd like
Either modify the LavaVuModelViewer class to save surfaces to file, or create an export class to write model objects to file (or both)

[BUG] Fault error

The fault example returns the following when I run it:

andy@cuesta:~/dataanalysis/LoopStructural/examples/3_fault$ python3 plot_faulted_intrusion.py 
Traceback (most recent call last):
  File "plot_faulted_intrusion.py", line 91, in <module>
    viewer.add_isosurface(strati,
  File "/home/andy/.local/lib/python3.8/site-packages/LoopStructural/visualisation/model_visualisation.py", line 264, in add_isosurface
    val = geological_feature.evaluate_value(points)
  File "/home/andy/.local/lib/python3.8/site-packages/LoopStructural/modelling/features/geological_feature.py", line 126, in evaluate_value
    self.builder.up_to_date()
  File "/home/andy/.local/lib/python3.8/site-packages/LoopStructural/modelling/features/geological_feature_builder.py", line 89, in up_to_date
    self.update()
  File "/home/andy/.local/lib/python3.8/site-packages/LoopStructural/modelling/features/geological_feature_builder.py", line 78, in update
    self.build(**self.build_arguments)
  File "/home/andy/.local/lib/python3.8/site-packages/LoopStructural/modelling/features/geological_feature_builder.py", line 379, in build
    self.add_data_to_interpolator(**kwargs)
  File "/home/andy/.local/lib/python3.8/site-packages/LoopStructural/modelling/features/geological_feature_builder.py", line 172, in add_data_to_interpolator
    data.loc[:,xyz_names()] = f.apply_to_points(
  File "/home/andy/.local/lib/python3.8/site-packages/LoopStructural/modelling/fault/fault_segment.py", line 244, in apply_to_points
    gx = gx_future.result()
  File "/usr/lib/python3.8/concurrent/futures/_base.py", line 439, in result
    return self.__get_result()
  File "/usr/lib/python3.8/concurrent/futures/_base.py", line 388, in __get_result
    raise self._exception
  File "/usr/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/andy/.local/lib/python3.8/site-packages/LoopStructural/modelling/features/geological_feature.py", line 126, in evaluate_value
    self.builder.up_to_date()
  File "/home/andy/.local/lib/python3.8/site-packages/LoopStructural/modelling/features/geological_feature_builder.py", line 89, in up_to_date
    self.update()
  File "/home/andy/.local/lib/python3.8/site-packages/LoopStructural/modelling/features/geological_feature_builder.py", line 78, in update
    self.build(**self.build_arguments)
  File "/home/andy/.local/lib/python3.8/site-packages/LoopStructural/modelling/features/geological_feature_builder.py", line 412, in build
    self.interpolator.solve_system(**kwargs)
  File "/home/andy/.local/lib/python3.8/site-packages/LoopStructural/interpolators/geological_interpolator.py", line 179, in solve_system
    self._solve(**kwargs)
  File "/home/andy/.local/lib/python3.8/site-packages/LoopStructural/interpolators/discrete_interpolator.py", line 509, in _solve
    A, B = self.build_matrix(damp=damp)
  File "/home/andy/.local/lib/python3.8/site-packages/LoopStructural/interpolators/discrete_interpolator.py", line 317, in build_matrix
    BT = A.T.dot(B)
  File "/usr/lib/python3/dist-packages/scipy/sparse/base.py", line 363, in dot
    return self * other
  File "/usr/lib/python3/dist-packages/scipy/sparse/base.py", line 499, in __mul__
    raise ValueError('dimension mismatch')
ValueError: dimension mismatch

Would it be possible to verify whether this is reproducible? I am using v1.0.89 via pip3.

empty fault topology matrix

Describe your issue

Hi Lachlan,

I am trying to export the topology matrices for the different faults defined in my model.
So far it does not matter when I create_and_add_fault to my model if I define a fault centre, extent, influence and vertical radius or not: either way, when I calculate_fault_topology_matrix, I obtain an empty array.
I am using LoopStructural 1.4.1.

Cheers,
Guillaume

topology-test.zip

Minimal reproducing code example

I attached a self-contained example in a python notebook.

After building my model, I call:

fault_topo_mat = calculate_fault_topology_matrix(model)

Error message

And when assessing fault_topo_mat, I get the following empty array:

array([], shape=(240, 0), dtype=int32)

Applying a dataset with coordinates, Dip and Azimuth[Question]

Hi,
For my work i need to use a data set which has two types of data, First one has XYZ coordinates of foliations/geological surfaces and their Dip and Azimuth and the second has surface points XYZ, without any directional information. I want to use this data for modelling with loopstructural 3D. How can i calculate the gradient norms nx,ny,nz , with my available data. Thanks

[BUG] unstable model evaluation error

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.

stability-test.zip

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)

[FEATURE] - add elevation to models for section and cutting surfaces

Is your feature request related to a problem? Please describe.
Add in a digital elevation model to the model area either:

  1. interpolate a scalar field where underground < 0 and above ground >0
  2. a 2d function where the z value is evaluated.

Integrate into section viewer and into the clipping of surfaces - option 1 is preferable here.

WARNING ~ No solution, Urella_North_1 scalar field 0. Add more data.[BUG]

Hi,
I am trying to create fault surfaces using the function "model.create_and_add_fault()". I have given all the required parameters for the fault geometry, but when the code runs it gives the warning for all the fault surfaces i want to create. The text of the warning is as below:
LoopStructural.interpolators.discrete_interpolator ~ WARNING ~ No solution, Urella_North_1 scalar field 0. Add more data.

and this warning shows up for all the faults which i want to create

example of the code which generates the warning(Note: the parameter, "fault_displacement = 30." in the code example below):
fault_geometry_parameters

Expected behavior:
I would expect the warning to go away and the fault surface to be created and added to the model,

screenshot of the warning:

warning_add_more_data_to_faults

In Addition to this:

The same code when I use PLI as the interpolation method instead of FDI, gives a value error stated as:

"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)"

The minimal example to reproduce this error:

code_for_PLI_valueerror_creating_fault

Screenshots of the full error:

value_error_PLI_creating_fault
value_error_PLI_creating_fault2
value_error_PLI_creating_fault3

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.