Skip to content

Commit 12024ba

Browse files
committed
Merge branch 'main' into outsource_cython
2 parents d5a6338 + 1399d98 commit 12024ba

39 files changed

+3145
-379
lines changed

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ GSTools provides geostatistical tools for various purposes:
4343
- data normalization and transformation
4444
- many readily provided and even user-defined covariance models
4545
- metric spatio-temporal modelling
46+
- plurigaussian field simulations (PGS)
4647
- plotting and exporting routines
4748

4849

@@ -110,6 +111,7 @@ The documentation also includes some [tutorials][tut_link], showing the most imp
110111
- [Geographic Coordinates][tut8_link]
111112
- [Spatio-Temporal Modelling][tut9_link]
112113
- [Normalizing Data][tut10_link]
114+
- [Plurigaussian Field Generation (PGS)][tut11_link]
113115
- [Miscellaneous examples][tut0_link]
114116

115117
The associated python scripts are provided in the `examples` folder.
@@ -321,6 +323,51 @@ yielding
321323
[kraichnan_link]: https://doi.org/10.1063/1.1692799
322324

323325

326+
## Plurigaussian Field Simulation (PGS)
327+
328+
With PGS, more complex categorical (or discrete) fields can be created.
329+
330+
331+
### Example
332+
333+
```python
334+
import gstools as gs
335+
import numpy as np
336+
import matplotlib.pyplot as plt
337+
338+
N = [180, 140]
339+
340+
x, y = range(N[0]), range(N[1])
341+
342+
# we need 2 SRFs
343+
model = gs.Gaussian(dim=2, var=1, len_scale=5)
344+
srf = gs.SRF(model)
345+
field1 = srf.structured([x, y], seed=20170519)
346+
field2 = srf.structured([x, y], seed=19970221)
347+
348+
# with `lithotypes`, we prescribe the categorical data and its relations
349+
# here, we use 2 categories separated by a rectangle.
350+
rect = [40, 32]
351+
lithotypes = np.zeros(N)
352+
lithotypes[
353+
N[0] // 2 - rect[0] // 2 : N[0] // 2 + rect[0] // 2,
354+
N[1] // 2 - rect[1] // 2 : N[1] // 2 + rect[1] // 2,
355+
] = 1
356+
357+
pgs = gs.PGS(2, [field1, field2])
358+
P = pgs(lithotypes)
359+
360+
fig, axs = plt.subplots(1, 2)
361+
axs[0].imshow(lithotypes, cmap="copper")
362+
axs[1].imshow(P, cmap="copper")
363+
plt.show()
364+
```
365+
366+
<p align="center">
367+
<img src="https://raw.githubusercontent.com/GeoStat-Framework/GSTools/main/docs/source/pics/2d_pgs.png" alt="PGS" width="600px"/>
368+
</p>
369+
370+
324371
## VTK/PyVista Export
325372

326373
After you have created a field, you may want to save it to file, so we provide
@@ -393,6 +440,7 @@ You can contact us via <info@geostat-framework.org>.
393440
[tut8_link]: https://geostat-framework.readthedocs.io/projects/gstools/en/stable/examples/08_geo_coordinates/index.html
394441
[tut9_link]: https://geostat-framework.readthedocs.io/projects/gstools/en/stable/examples/09_spatio_temporal/index.html
395442
[tut10_link]: https://geostat-framework.readthedocs.io/projects/gstools/en/stable/examples/10_normalizer/index.html
443+
[tut11_link]: https://geostat-framework.readthedocs.io/projects/gstools/en/stable/examples/11_plurigaussian/index.html
396444
[tut0_link]: https://geostat-framework.readthedocs.io/projects/gstools/en/stable/examples/00_misc/index.html
397445
[cor_link]: https://en.wikipedia.org/wiki/Autocovariance#Normalization
398446
[vtk_link]: https://www.vtk.org/

docs/source/conf.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ def setup(app):
199199

200200
# -- Options for LaTeX output ---------------------------------------------
201201
# latex_engine = 'lualatex'
202-
# logo to big
202+
# logo too big
203203
latex_logo = "pics/gstools_150.png"
204204

205205
# latex_show_urls = 'footnote'
@@ -300,6 +300,8 @@ def setup(app):
300300
"../../examples/08_geo_coordinates/",
301301
"../../examples/09_spatio_temporal/",
302302
"../../examples/10_normalizer/",
303+
"../../examples/11_plurigaussian/",
304+
"../../examples/12_sum_model/",
303305
],
304306
# path where to save gallery generated examples
305307
"gallery_dirs": [
@@ -314,6 +316,8 @@ def setup(app):
314316
"examples/08_geo_coordinates/",
315317
"examples/09_spatio_temporal/",
316318
"examples/10_normalizer/",
319+
"examples/11_plurigaussian/",
320+
"examples/12_sum_model/",
317321
],
318322
# Pattern to search for example files
319323
"filename_pattern": r"\.py",

docs/source/index.rst

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ GSTools provides geostatistical tools for various purposes:
3333
- data normalization and transformation
3434
- many readily provided and even user-defined covariance models
3535
- metric spatio-temporal modelling
36+
- plurigaussian field simulations (PGS)
3637
- plotting and exporting routines
3738

3839

@@ -163,6 +164,7 @@ showing the most important use cases of GSTools, which are
163164
- `Geographic Coordinates <examples/08_geo_coordinates/index.html>`__
164165
- `Spatio-Temporal Modelling <examples/09_spatio_temporal/index.html>`__
165166
- `Normalizing Data <examples/10_normalizer/index.html>`__
167+
- `Plurigaussian Field Generation (PGS) <examples/11_plurigaussian/index.html>`__
166168
- `Miscellaneous examples <examples/00_misc/index.html>`__
167169

168170

@@ -390,6 +392,53 @@ yielding
390392
:align: center
391393

392394

395+
Plurigaussian Field Simulation (PGS)
396+
====================================
397+
398+
With PGS, more complex categorical (or discrete) fields can be created.
399+
400+
401+
Example
402+
-------
403+
404+
.. code-block:: python
405+
406+
import gstools as gs
407+
import numpy as np
408+
import matplotlib.pyplot as plt
409+
410+
N = [180, 140]
411+
412+
x, y = range(N[0]), range(N[1])
413+
414+
# we need 2 SRFs
415+
model = gs.Gaussian(dim=2, var=1, len_scale=5)
416+
srf = gs.SRF(model)
417+
field1 = srf.structured([x, y], seed=20170519)
418+
field2 = srf.structured([x, y], seed=19970221)
419+
420+
# with `lithotypes`, we prescribe the categorical data and its relations
421+
# here, we use 2 categories separated by a rectangle.
422+
rect = [40, 32]
423+
lithotypes = np.zeros(N)
424+
lithotypes[
425+
N[0] // 2 - rect[0] // 2 : N[0] // 2 + rect[0] // 2,
426+
N[1] // 2 - rect[1] // 2 : N[1] // 2 + rect[1] // 2,
427+
] = 1
428+
429+
pgs = gs.PGS(2, [field1, field2])
430+
P = pgs(lithotypes)
431+
432+
fig, axs = plt.subplots(1, 2)
433+
axs[0].imshow(lithotypes, cmap="copper")
434+
axs[1].imshow(P, cmap="copper")
435+
plt.show()
436+
437+
.. image:: https://raw.githubusercontent.com/GeoStat-Framework/GSTools/main/docs/source/pics/2d_pgs.png
438+
:width: 600px
439+
:align: center
440+
441+
393442
VTK/PyVista Export
394443
==================
395444

docs/source/pics/2d_pgs.png

68.3 KB
Loading

docs/source/pics/3d_pgs.png

137 KB
Loading

docs/source/tutorials.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ explore its whole beauty and power.
2222
examples/08_geo_coordinates/index
2323
examples/09_spatio_temporal/index
2424
examples/10_normalizer/index
25+
examples/11_plurigaussian/index
26+
examples/12_sum_model/index
2527
examples/00_misc/index
2628

2729
.. only:: html

examples/00_misc/01_export.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@
2020
###############################################################################
2121
# The result displayed with Paraview:
2222
#
23-
# .. image:: https://raw.githubusercontent.com/GeoStat-Framework/GeoStat-Framework.github.io/master/img/paraview.png
23+
# .. image:: ../../pics/paraview.png
2424
# :width: 400px
2525
# :align: center

examples/01_random_field/06_pyvista_support.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
###############################################################################
5454
# The result should look like this:
5555
#
56-
# .. image:: https://github.com/GeoStat-Framework/GeoStat-Framework.github.io/raw/master/img/GS_pyvista_cut.png
56+
# .. image:: ../../pics/GS_pyvista_cut.png
5757
# :width: 400px
5858
# :align: center

examples/04_vector_field/01_3d_vector_field.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,6 @@
5959
###############################################################################
6060
# The result should look like this:
6161
#
62-
# .. image:: https://github.com/GeoStat-Framework/GeoStat-Framework.github.io/raw/master/img/GS_3d_vector_field.png
62+
# .. image:: ../../pics/GS_3d_vector_field.png
6363
# :width: 400px
6464
# :align: center
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"""
2+
A First and Simple Example
3+
--------------------------
4+
5+
As a first example, we will create a two dimensional plurigaussian field
6+
(PGS). Thus, we need two spatial random fields(SRF) and on top of that, we
7+
need a field describing the categorical data and its spatial relation.
8+
We will start off by creating the two SRFs with a Gaussian variogram, which
9+
makes the fields nice and smooth. But before that, we will import all
10+
necessary libraries and define a few variables, like the number of grid
11+
cells in each dimension.
12+
"""
13+
14+
import matplotlib.pyplot as plt
15+
import numpy as np
16+
17+
import gstools as gs
18+
19+
dim = 2
20+
# no. of cells in both dimensions
21+
N = [180, 140]
22+
23+
x = np.arange(N[0])
24+
y = np.arange(N[1])
25+
26+
###############################################################################
27+
# In this first example we will use the same geostatistical parameters for
28+
# both fields for simplicity. Thus, we can use the same SRF instance for the
29+
# two fields.
30+
31+
model = gs.Gaussian(dim=dim, var=1, len_scale=10)
32+
srf = gs.SRF(model)
33+
field1 = srf.structured([x, y], seed=20170519)
34+
field2 = srf.structured([x, y], seed=19970221)
35+
36+
###############################################################################
37+
# Now, we will create the lithotypes field describing the categorical data. For
38+
# now, we will only have two categories and we will address them by the
39+
# integers 0 and 1. We start off by creating a matrix of 0s from which we will
40+
# select a rectangle and fill that with 1s. This field does not have to match
41+
# the shape of the SRFs.
42+
43+
centroid = [200, 160]
44+
45+
# size of the rectangle
46+
rect = [40, 32]
47+
48+
lithotypes = np.zeros(centroid)
49+
lithotypes[
50+
centroid[0] // 2 - rect[0] // 2 : centroid[0] // 2 + rect[0] // 2,
51+
centroid[1] // 2 - rect[1] // 2 : centroid[1] // 2 + rect[1] // 2,
52+
] = 1
53+
54+
###############################################################################
55+
# With the two SRFs and the L-field ready, we can create our first PGS. First, we
56+
# set up an instance of the PGS class and then we are ready to calculate the
57+
# field by calling the instance and handing over the L-field.
58+
59+
pgs = gs.PGS(dim, [field1, field2])
60+
P = pgs(lithotypes)
61+
62+
###############################################################################
63+
# Finally, we can plot the PGS, but we will also show the L-field and the two
64+
# original Gaussian fields.
65+
66+
fig, axs = plt.subplots(2, 2)
67+
68+
axs[0, 0].imshow(field1, cmap="copper", origin="lower")
69+
axs[0, 1].imshow(field2, cmap="copper", origin="lower")
70+
axs[1, 0].imshow(lithotypes, cmap="copper", origin="lower")
71+
axs[1, 1].imshow(P, cmap="copper", origin="lower")
72+
73+
# For more information on Plurigaussian fields and how they naturally extend
74+
# truncated Gaussian fields, we can recommend the book
75+
# [Plurigaussian Simulations in Geosciences](https://doi.org/10.1007/978-3-642-19607-2)

0 commit comments

Comments
 (0)