4.a Building a model using the ProcessInputData#

There is a disconnect between the input data required by 3D modelling software and a geological map. In LoopStructural the geological model is a collection of implicit functions that can be mapped to the distribution of stratigraphic units and the location of fault surfaces. Each implicit function is approximated from the observations of the stratigraphy, this requires grouping conformable geological units together as a singla implicit function, mapping the different stratigraphic horizons to a value of the implicit function and determining the relationship with geological structures such as faults. In this tutorial the ProcessInputData class will be used to convert geologically meaningful datasets to input for LoopStructural. The ProcessInputData class uses: * stratigraphic contacts* stratigraphic orientations* stratigraphic thickness* stratigraphic order To build a model of stratigraphic horizons and:* fault locations* fault orientations * fault properties* fault edges To use incorporate faults into the geological model.

Imports#

from LoopStructural.modelling import ProcessInputData
from LoopStructural import GeologicalModel
from LoopStructural.visualisation import Loop3DView
from LoopStructural.datasets import load_geological_map_data

import matplotlib.pyplot as plt

Read stratigraphy from csv#

(
    contacts,
    stratigraphic_orientations,
    stratigraphic_thickness,
    stratigraphic_order,
    bbox,
    fault_locations,
    fault_orientations,
    fault_properties,
    fault_edges,
) = load_geological_map_data()

thicknesses = dict(
    zip(
        list(stratigraphic_thickness["name"]),
        list(stratigraphic_thickness["thickness"]),
    )
)

Stratigraphic Contacts#

contacts

fig, ax = plt.subplots(1)
ax.scatter(contacts["X"], contacts["Y"], c=contacts["name"].astype("category").cat.codes)
ax.set_title("Contact data")
Contact data
Text(0.5, 1.0, 'Contact data')

Stratigraphic orientations#

Stratigraphic orientations needs to have X, Y, Z and either azimuth and dip, dipdirection and dip, strike and dip (RH thumb rule) or the vector components of the normal vector (nx, ny, nz)

stratigraphic_orientations
X Y Z azimuth dip polarity formation source
0 535257.611616 7.499030e+06 516.933711 360.000000 40.000000 1 Jeerinah_Formation observed
1 548279.320612 7.493304e+06 547.201842 190.000000 50.000000 1 Jeerinah_Formation observed
2 548279.320612 7.493304e+06 547.201842 190.000000 55.000000 1 Jeerinah_Formation observed
3 541013.160392 7.493387e+06 540.217972 150.000000 28.000000 1 Bunjinah_Formation observed
4 536742.232168 7.490698e+06 500.982205 110.000000 28.000000 1 Bunjinah_Formation observed
... ... ... ... ... ... ... ... ...
201 543123.310952 7.491848e+06 603.965999 108.413106 26.895259 1 Wittenoom_Formation contact_orientations
202 544238.128958 7.492249e+06 606.486202 140.129808 20.872559 1 Wittenoom_Formation contact_orientations
203 546356.500042 7.493059e+06 584.507590 180.231910 25.229506 1 Wittenoom_Formation contact_orientations
204 548354.744485 7.492679e+06 567.312965 178.569396 55.725098 1 Wittenoom_Formation contact_orientations
205 550574.233917 7.493345e+06 625.412651 157.358988 65.845552 1 Wittenoom_Formation contact_orientations

206 rows × 8 columns



Stratigraphic thickness#

Stratigraphic thickness should be a dictionary containing the unit name (which should be in the contacts table) and the corresponding thickness of this unit.

thicknesses
{'Mount_McRae_Shale_and_Mount_Sylvia_Formation': 224.5, 'Marra_Mamba_Iron_Formation': 152.0, 'Boolgeeda_Iron_Formation': 166.5, 'Woongarra_Rhyolite': 389.0, 'Jeerinah_Formation': 600.0, 'Brockman_Iron_Formation': 557.0, 'Wittenoom_Formation': 236.0, 'Weeli_Wolli_Formation': 241.5, 'Turee_Creek_Group': 162.0, 'Fortescue_Group': 236.0, 'Bunjinah_Formation': 236.0, 'Pyradie_Formation': 236.0}

Bounding box#

  • Origin - bottom left corner of the model # * Maximum - top right hand corner of the model

origin = bbox.loc["origin"].to_numpy()  # np.array(bbox[0].split(',')[1:],dtype=float)
maximum = bbox.loc["maximum"].to_numpy()  # np.array(bbox[1].split(',')[1:],dtype=float)

bbox
X Y Z
origin 519572.569 7489723.89 -4800.0
maximum 551978.745 7516341.01 1200.0


Stratigraphic column#

The order of stratrigraphic units is defined a list of tuples containing the name of the group and the order of units within the group. For example there are 7 units in the following example that form two groups.

# example nested list
[
    ("youngest_group", ["unit1", "unit2", "unit3", "unit4"]),
    ("older_group", ["unit5", "unit6", "unit7"]),
]

stratigraphic_order

order = [("supergroup_0", list(stratigraphic_order["unit name"]))]

Building a stratigraphic model#

A ProcessInputData onject can be built from these datasets using the argument names. A full list of possible arguments can be found in the documentation.

processor = ProcessInputData(
    contacts=contacts,
    contact_orientations=stratigraphic_orientations.rename({"formation": "name"}, axis=1),
    thicknesses=thicknesses,
    stratigraphic_order=order,
    origin=origin,
    maximum=maximum,
)
processor.foliation_properties["supergroup_0"] = {"regularisation": 1.0}

The process input data can be used to directly build a geological model

Or build directly from the dataframe and processor attributes.

Visualising model#

view = Loop3DView(model)
view.plot_model_surfaces()
view.display()
plot model from geological map

Adding faults#

fault_orientations


fault_edges


fault_properties

processor = ProcessInputData(
    contacts=contacts,
    contact_orientations=stratigraphic_orientations.rename({"formation": "name"}, axis=1),
    thicknesses=thicknesses,
    stratigraphic_order=order,
    origin=origin,
    maximum=maximum,
    fault_edges=fault_edges,
    fault_orientations=fault_orientations,
    fault_locations=fault_locations,
    fault_properties=fault_properties,
)
processor.foliation_properties['supergroup_0']['regularisation'] = 1.0
model = GeologicalModel.from_processor(processor)
model.update()

view = Loop3DView(model)
view.plot_model_surfaces()
view.display()
plot model from geological map

Visualise stratigraphic column ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

from LoopStructural.visualisation import StratigraphicColumnView

scv = StratigraphicColumnView(model)
scv.plot()
plot model from geological map
<Figure size 200x1000 with 1 Axes>

Total running time of the script: (1 minutes 57.194 seconds)

Gallery generated by Sphinx-Gallery