1.2b: The Implicit coKriging class

Importing GemPy

import gempy as gp

# Importing auxiliary libraries
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

pd.set_option('precision', 2)

The description of the methods nomenclature remains the same as for the data.py module with the particularity that update is slitted in:

  • update_from

    • update current object with the rest of dependencies. This is useful if you change an object and you want to update the fields with the rest of the objects. E.g after a set_surface_points

  • update_to

    • update dataframes from the current object. This is useful if you modify one of the model dependencies and you want to update all the other dependencies

When we initialize a gempy.core.model.Project class we create all the necessary objects already linked with each other.

As expected these dependencies are empty:

X Y Z smooth surface


surface series order_surfaces color id


order_series BottomRelation isActive isFault isFinite
Default series 1 Erosion False False False


The pandas DataFrames are already configured properly to categories:

model._surfaces.df['series'], model._surfaces.df['surface']

Out:

(Series([], Name: series, dtype: category
Categories (1, object): ['Default series']), Series([], Name: surface, dtype: object))

And additional data has everything pretty much empty:

values
Structure isLith True
isFault False
number faults 0
number surfaces 0
number series 1
number surfaces per series [0]
len surfaces surface_points []
len series surface_points [0]
len series orientations [0]
Options dtype float64
output geology
theano_optimizer fast_compile
device cpu
verbosity None
Kriging range 0.0
$C_o$ 0.0
drift equations [3]
Rescaling rescaling factor NaN
centers [nan, nan, nan]


Reading data

Usually data will be imported from external files. GemPy uses pandas.read_table powerful functionality for that. The default format is XYZ surface_name:

data_path = 'https://raw.githubusercontent.com/cgre-aachen/gempy_data/master/'

model.read_data(path_i=data_path + "/data/input_data/tut_chapter1/simple_fault_model_points.csv",
                path_o=data_path + "/data/input_data/tut_chapter1/simple_fault_model_orientations.csv")

Out:

True
X Y Z G_x G_y G_z smooth surface
0 1000 1000 950.0 0.32 1.00e-12 0.95 0.01 Shale
1 400 1000 1400.0 0.32 1.00e-12 0.95 0.01 Sandstone_2
2 500 1000 864.6 -0.95 1.00e-12 0.32 0.01 Main_Fault


model.map_stack_to_surfaces({"Fault_Series": ('Main_Fault', 'Silstone'),
                             "Strat_Series": ('Sandstone_2', 'Sandstone_1', 'Siltstone',
                                              'Shale',)}, )
surface series order_surfaces color id
4 Main_Fault Fault_Series 1 #443988 1
0 Shale Strat_Series 1 #015482 2
1 Sandstone_1 Strat_Series 2 #9f0052 3
2 Siltstone Strat_Series 3 #ffbe00 4
3 Sandstone_2 Strat_Series 4 #728f02 5
5 basement Basement 1 #ff3f20 6


order_series BottomRelation isActive isFault isFinite
Fault_Series 1 Erosion True False False
Strat_Series 2 Erosion True False False
Basement 3 Erosion False False False


surface series order_surfaces color id
4 Main_Fault Fault_Series 1 #443988 1
0 Shale Strat_Series 1 #015482 2
1 Sandstone_1 Strat_Series 2 #9f0052 3
2 Siltstone Strat_Series 3 #ffbe00 4
3 Sandstone_2 Strat_Series 4 #728f02 5
5 basement Basement 1 #ff3f20 6


X Y Z smooth surface
52 700 1000 900 2.00e-06 Main_Fault
53 600 1000 600 2.00e-06 Main_Fault
54 500 1000 300 2.00e-06 Main_Fault
55 800 1000 1200 2.00e-06 Main_Fault
56 900 1000 1500 2.00e-06 Main_Fault
0 800 50 750 2.00e-06 Shale
1 800 150 700 2.00e-06 Shale
2 800 300 700 2.00e-06 Shale
3 800 500 800 2.00e-06 Shale
4 800 1000 1000 2.00e-06 Shale
5 800 1500 700 2.00e-06 Shale
6 800 1700 600 2.00e-06 Shale
7 800 1950 650 2.00e-06 Shale
8 0 1000 1100 2.00e-06 Shale
9 300 1000 1000 2.00e-06 Shale
10 450 1000 950 2.00e-06 Shale
11 1100 1000 900 2.00e-06 Shale
12 1400 1000 850 2.00e-06 Shale
13 1700 1000 900 2.00e-06 Shale
14 1500 500 800 2.00e-06 Shale
15 1500 1500 750 2.00e-06 Shale
16 800 50 450 2.00e-06 Sandstone_1
17 800 150 400 2.00e-06 Sandstone_1
18 800 300 400 2.00e-06 Sandstone_1
19 800 500 500 2.00e-06 Sandstone_1
20 800 1000 700 2.00e-06 Sandstone_1
21 800 1500 400 2.00e-06 Sandstone_1
22 800 1700 300 2.00e-06 Sandstone_1
23 800 1950 350 2.00e-06 Sandstone_1
24 0 1000 800 2.00e-06 Sandstone_1
25 300 1000 700 2.00e-06 Sandstone_1
26 1100 1000 600 2.00e-06 Sandstone_1
27 1400 1000 550 2.00e-06 Sandstone_1
28 1700 1000 600 2.00e-06 Sandstone_1
29 1500 500 500 2.00e-06 Sandstone_1
30 1500 1500 450 2.00e-06 Sandstone_1
31 900 150 920 2.00e-06 Siltstone
32 900 300 920 2.00e-06 Siltstone
33 900 1500 920 2.00e-06 Siltstone
34 900 1700 820 2.00e-06 Siltstone
35 900 1950 870 2.00e-06 Siltstone
36 0 1000 1300 2.00e-06 Siltstone
37 300 1000 1200 2.00e-06 Siltstone
38 600 1000 1100 2.00e-06 Siltstone
39 1100 1000 1100 2.00e-06 Siltstone
40 1400 1000 1050 2.00e-06 Siltstone
41 1700 1000 1100 2.00e-06 Siltstone
42 1500 500 1000 2.00e-06 Siltstone
43 1500 1500 950 2.00e-06 Siltstone
44 0 1000 1500 2.00e-06 Sandstone_2
45 300 1000 1400 2.00e-06 Sandstone_2
46 600 1000 1300 2.00e-06 Sandstone_2
47 1100 1000 1300 2.00e-06 Sandstone_2
48 1400 1000 1250 2.00e-06 Sandstone_2
49 1700 1000 1300 2.00e-06 Sandstone_2
50 1500 500 1200 2.00e-06 Sandstone_2
51 1500 1500 1150 2.00e-06 Sandstone_2


X Y Z X_c Y_c Z_c G_x G_y G_z dip azimuth polarity surface series id order_series smooth
2 500 1000 864.6 0.41 0.5 0.49 -0.95 1.00e-12 0.32 71.56 270.0 1.0 Main_Fault Fault_Series 1 1 0.01
0 1000 1000 950.0 0.54 0.5 0.51 0.32 1.00e-12 0.95 18.43 90.0 1.0 Shale Strat_Series 2 2 0.01
1 400 1000 1400.0 0.38 0.5 0.63 0.32 1.00e-12 0.95 18.43 90.0 1.0 Sandstone_2 Strat_Series 5 2 0.01


Next we need to categorize each surface into the right series. This will update all the Dataframes depending on Formations and Series to the right categories:

model.map_stack_to_surfaces({"Fault_Series": 'Main_Fault',
                             "Strat_Series": ('Sandstone_2', 'Siltstone',
                                              'Shale', 'Sandstone_1')})
surface series order_surfaces color id
4 Main_Fault Fault_Series 1 #443988 1
0 Shale Strat_Series 1 #015482 2
1 Sandstone_1 Strat_Series 2 #9f0052 3
2 Siltstone Strat_Series 3 #ffbe00 4
3 Sandstone_2 Strat_Series 4 #728f02 5
5 basement Basement 1 #ff3f20 6


Out:

4    Fault_Series
0    Strat_Series
1    Strat_Series
2    Strat_Series
3    Strat_Series
5        Basement
Name: series, dtype: category
Categories (3, object): ['Fault_Series', 'Strat_Series', 'Basement']
surface series order_surfaces color id
4 Main_Fault Fault_Series 1 #443988 1
0 Shale Strat_Series 1 #015482 2
1 Sandstone_1 Strat_Series 2 #9f0052 3
2 Siltstone Strat_Series 3 #ffbe00 4
3 Sandstone_2 Strat_Series 4 #728f02 5
5 basement Basement 1 #ff3f20 6


gp.get_data(model, 'surface points')
X Y Z smooth surface
52 700 1000 900 2.00e-06 Main_Fault
53 600 1000 600 2.00e-06 Main_Fault
54 500 1000 300 2.00e-06 Main_Fault
55 800 1000 1200 2.00e-06 Main_Fault
56 900 1000 1500 2.00e-06 Main_Fault
0 800 50 750 2.00e-06 Shale
1 800 150 700 2.00e-06 Shale
2 800 300 700 2.00e-06 Shale
3 800 500 800 2.00e-06 Shale
4 800 1000 1000 2.00e-06 Shale
5 800 1500 700 2.00e-06 Shale
6 800 1700 600 2.00e-06 Shale
7 800 1950 650 2.00e-06 Shale
8 0 1000 1100 2.00e-06 Shale
9 300 1000 1000 2.00e-06 Shale
10 450 1000 950 2.00e-06 Shale
11 1100 1000 900 2.00e-06 Shale
12 1400 1000 850 2.00e-06 Shale
13 1700 1000 900 2.00e-06 Shale
14 1500 500 800 2.00e-06 Shale
15 1500 1500 750 2.00e-06 Shale
16 800 50 450 2.00e-06 Sandstone_1
17 800 150 400 2.00e-06 Sandstone_1
18 800 300 400 2.00e-06 Sandstone_1
19 800 500 500 2.00e-06 Sandstone_1
20 800 1000 700 2.00e-06 Sandstone_1
21 800 1500 400 2.00e-06 Sandstone_1
22 800 1700 300 2.00e-06 Sandstone_1
23 800 1950 350 2.00e-06 Sandstone_1
24 0 1000 800 2.00e-06 Sandstone_1
25 300 1000 700 2.00e-06 Sandstone_1
26 1100 1000 600 2.00e-06 Sandstone_1
27 1400 1000 550 2.00e-06 Sandstone_1
28 1700 1000 600 2.00e-06 Sandstone_1
29 1500 500 500 2.00e-06 Sandstone_1
30 1500 1500 450 2.00e-06 Sandstone_1
31 900 150 920 2.00e-06 Siltstone
32 900 300 920 2.00e-06 Siltstone
33 900 1500 920 2.00e-06 Siltstone
34 900 1700 820 2.00e-06 Siltstone
35 900 1950 870 2.00e-06 Siltstone
36 0 1000 1300 2.00e-06 Siltstone
37 300 1000 1200 2.00e-06 Siltstone
38 600 1000 1100 2.00e-06 Siltstone
39 1100 1000 1100 2.00e-06 Siltstone
40 1400 1000 1050 2.00e-06 Siltstone
41 1700 1000 1100 2.00e-06 Siltstone
42 1500 500 1000 2.00e-06 Siltstone
43 1500 1500 950 2.00e-06 Siltstone
44 0 1000 1500 2.00e-06 Sandstone_2
45 300 1000 1400 2.00e-06 Sandstone_2
46 600 1000 1300 2.00e-06 Sandstone_2
47 1100 1000 1300 2.00e-06 Sandstone_2
48 1400 1000 1250 2.00e-06 Sandstone_2
49 1700 1000 1300 2.00e-06 Sandstone_2
50 1500 500 1200 2.00e-06 Sandstone_2
51 1500 1500 1150 2.00e-06 Sandstone_2


order_series BottomRelation isActive isFault isFinite
Fault_Series 1 Erosion True False False
Strat_Series 2 Erosion True False False
Basement 3 Erosion False False False


In the case of having faults we need to assign wich series are faults:

order_series BottomRelation isActive isFault isFinite
Fault_Series 1 Erosion True False False
Strat_Series 2 Erosion True False False
Basement 3 Erosion False False False


model.set_is_fault(['Fault_Series'])

Out:

Fault colors changed. If you do not like this behavior, set change_color to False.
order_series BottomRelation isActive isFault isFinite
Fault_Series 1 Fault True True False
Strat_Series 2 Erosion True False False
Basement 3 Erosion False False False


X Y Z smooth surface
52 700 1000 900 2.00e-06 Main_Fault
53 600 1000 600 2.00e-06 Main_Fault
54 500 1000 300 2.00e-06 Main_Fault
55 800 1000 1200 2.00e-06 Main_Fault
56 900 1000 1500 2.00e-06 Main_Fault
0 800 50 750 2.00e-06 Shale
1 800 150 700 2.00e-06 Shale
2 800 300 700 2.00e-06 Shale
3 800 500 800 2.00e-06 Shale
4 800 1000 1000 2.00e-06 Shale
5 800 1500 700 2.00e-06 Shale
6 800 1700 600 2.00e-06 Shale
7 800 1950 650 2.00e-06 Shale
8 0 1000 1100 2.00e-06 Shale
9 300 1000 1000 2.00e-06 Shale
10 450 1000 950 2.00e-06 Shale
11 1100 1000 900 2.00e-06 Shale
12 1400 1000 850 2.00e-06 Shale
13 1700 1000 900 2.00e-06 Shale
14 1500 500 800 2.00e-06 Shale
15 1500 1500 750 2.00e-06 Shale
16 800 50 450 2.00e-06 Sandstone_1
17 800 150 400 2.00e-06 Sandstone_1
18 800 300 400 2.00e-06 Sandstone_1
19 800 500 500 2.00e-06 Sandstone_1
20 800 1000 700 2.00e-06 Sandstone_1
21 800 1500 400 2.00e-06 Sandstone_1
22 800 1700 300 2.00e-06 Sandstone_1
23 800 1950 350 2.00e-06 Sandstone_1
24 0 1000 800 2.00e-06 Sandstone_1
25 300 1000 700 2.00e-06 Sandstone_1
26 1100 1000 600 2.00e-06 Sandstone_1
27 1400 1000 550 2.00e-06 Sandstone_1
28 1700 1000 600 2.00e-06 Sandstone_1
29 1500 500 500 2.00e-06 Sandstone_1
30 1500 1500 450 2.00e-06 Sandstone_1
31 900 150 920 2.00e-06 Siltstone
32 900 300 920 2.00e-06 Siltstone
33 900 1500 920 2.00e-06 Siltstone
34 900 1700 820 2.00e-06 Siltstone
35 900 1950 870 2.00e-06 Siltstone
36 0 1000 1300 2.00e-06 Siltstone
37 300 1000 1200 2.00e-06 Siltstone
38 600 1000 1100 2.00e-06 Siltstone
39 1100 1000 1100 2.00e-06 Siltstone
40 1400 1000 1050 2.00e-06 Siltstone
41 1700 1000 1100 2.00e-06 Siltstone
42 1500 500 1000 2.00e-06 Siltstone
43 1500 1500 950 2.00e-06 Siltstone
44 0 1000 1500 2.00e-06 Sandstone_2
45 300 1000 1400 2.00e-06 Sandstone_2
46 600 1000 1300 2.00e-06 Sandstone_2
47 1100 1000 1300 2.00e-06 Sandstone_2
48 1400 1000 1250 2.00e-06 Sandstone_2
49 1700 1000 1300 2.00e-06 Sandstone_2
50 1500 500 1200 2.00e-06 Sandstone_2
51 1500 1500 1150 2.00e-06 Sandstone_2


Again as we can see, as long we use the model methods, all the dependent objects change inplace accordingly. If for any reason you do not want this behaviour you can always use the individual methods of the objects (e.g. model.faults.set_is_fault)

values
Structure isLith True
isFault True
number faults 1
number surfaces 5
number series 3
number surfaces per series [1, 4, 0]
len surfaces surface_points [5, 16, 15, 13, 8]
len series surface_points [5, 52, 0]
len series orientations [1, 2, 0]
Options dtype float64
output geology
theano_optimizer fast_compile
device cpu
verbosity None
Kriging range 0.0
$C_o$ 0.0
drift equations [3, 3, 3]
Rescaling rescaling factor 3800.0
centers [850.0, 1000.0, 900.0]


Setting grid

So far we have worked on data that depends exclusively of input (i.e. sequential pile, surface_points, orientations, etc). With things like grid the idea is the same:

Out:

Grid Object. Values:
array([], shape=(0, 3), dtype=float64)
model.set_regular_grid([0, 10, 0, 10, 0, 10], [50, 50, 50])

Out:

Active grids: ['regular']

Grid Object. Values:
array([[0.1, 0.1, 0.1],
       [0.1, 0.1, 0.3],
       [0.1, 0.1, 0.5],
       ...,
       [9.9, 9.9, 9.5],
       [9.9, 9.9, 9.7],
       [9.9, 9.9, 9.9]])

Getting data

Alternatively we can access the dataframe by:

gp.get_data(model, 'surfaces')
surface series order_surfaces color id
4 Main_Fault Fault_Series 1 #527682 1
0 Shale Strat_Series 1 #015482 2
1 Sandstone_1 Strat_Series 2 #9f0052 3
2 Siltstone Strat_Series 3 #ffbe00 4
3 Sandstone_2 Strat_Series 4 #728f02 5
5 basement Basement 1 #ff3f20 6


The class gempy.core.model.Model works as the parent container of our project. Therefore the main step of any project is to create an instance of this class. In the official documentation we use normally geo_model (geo_data in the past) as name of this instance.

When we instantiate a Model object we full data structure is created. By using gp.init_data and set_series we set the default values – given the attributes – to all of fields. Data is stored in pandas dataframes. With gp.get_data and the name of the data object it is possible to have access to the dataframes:

str[‘all’, ‘surface_points’, ‘orientations’, ‘formations’, ‘series’, ‘faults’, ‘faults_relations’, additional data]

These dataframes are stored in specific objects. These objects contain the specific methods to manipulate them. You access these objects with the specific getter or as a attribute of Model

Total running time of the script: ( 0 minutes 1.232 seconds)

Gallery generated by Sphinx-Gallery