Skip to content

Commit

Permalink
Merge b4fad7a into ae2f672
Browse files Browse the repository at this point in the history
  • Loading branch information
MuellerSeb committed Mar 29, 2021
2 parents ae2f672 + b4fad7a commit 832866b
Show file tree
Hide file tree
Showing 23 changed files with 390 additions and 107 deletions.
2 changes: 1 addition & 1 deletion AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ and was created by following people.

## Main Authors

- [Lennart Schüler](https://github.com/LSchueler), Email: <lennart@geostat-framework.org>
- [Sebastian Müller](https://github.com/MuellerSeb), Email: <sebastian@geostat-framework.org>
- [Lennart Schüler](https://github.com/LSchueler), Email: <lennart@geostat-framework.org>


## Contributors (in order of contributions)
Expand Down
6 changes: 3 additions & 3 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ def setup(app):
# General information about the project.
curr_year = datetime.datetime.now().year
project = "GSTools"
copyright = "2018 - {}, Lennart Schueler, Sebastian Mueller".format(curr_year)
author = "Lennart Schueler, Sebastian Mueller"
copyright = "2018 - {}, Sebastian Müller, Lennart Schüler".format(curr_year)
author = "Sebastian Müller, Lennart Schüler"

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand Down Expand Up @@ -212,7 +212,7 @@ def setup(app):
master_doc,
"GeoStatTools.tex",
"GeoStatTools Documentation",
"Lennart Schueler, Sebastian Mueller",
"Sebastian Müller, Lennart Schüler",
"manual",
)
]
Expand Down
2 changes: 1 addition & 1 deletion examples/05_kriging/08_measurement_errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# Here we will use Simple kriging (`unbiased=False`) to interpolate the given
# conditions.

krig = gs.krige.Krige(
krig = gs.Krige(
model=model,
cond_pos=cond_pos,
cond_val=cond_val,
Expand Down
58 changes: 58 additions & 0 deletions examples/06_conditioned_fields/01_2D_condition_ensemble.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"""
Creating an Ensemble of conditioned 2D Fields
---------------------------------------------
Let's create an ensemble of conditioned random fields in 2D.
"""
import numpy as np
import matplotlib.pyplot as plt
import gstools as gs


# conditioning data (x, y, value)
cond_pos = [[0.3, 1.9, 1.1, 3.3, 4.7], [1.2, 0.6, 3.2, 4.4, 3.8]]
cond_val = [0.47, 0.56, 0.74, 1.47, 1.74]

# grid definition for output field
x = np.arange(0, 5, 0.1)
y = np.arange(0, 5, 0.1)

model = gs.Gaussian(dim=2, var=0.5, len_scale=5, anis=0.5, angles=-0.5)
krige = gs.Krige(model, cond_pos=cond_pos, cond_val=cond_val)
cond_srf = gs.CondSRF(krige)

###############################################################################
# We create a list containing the generated conditioned fields.

ens_no = 4
field = []
for i in range(ens_no):
field.append(cond_srf.structured([x, y], seed=i))

###############################################################################
# Now let's have a look at the pairwise differences between the generated
# fields. We will see, that they coincide at the given conditions.

fig, ax = plt.subplots(ens_no + 1, ens_no + 1, figsize=(8, 8))
# plotting kwargs for scatter and image
sc_kwargs = dict(c=cond_val, edgecolors="k", vmin=0, vmax=np.max(field))
im_kwargs = dict(extent=2 * [0, 5], origin="lower", vmin=0, vmax=np.max(field))
for i in range(ens_no):
# conditioned fields and conditions
ax[i + 1, 0].imshow(field[i].T, **im_kwargs)
ax[i + 1, 0].scatter(*cond_pos, **sc_kwargs)
ax[i + 1, 0].set_ylabel(f"Field {i+1}", fontsize=10)
ax[0, i + 1].imshow(field[i].T, **im_kwargs)
ax[0, i + 1].scatter(*cond_pos, **sc_kwargs)
ax[0, i + 1].set_title(f"Field {i+1}", fontsize=10)
# absolute differences
for j in range(ens_no):
ax[i + 1, j + 1].imshow(np.abs(field[i] - field[j]).T, **im_kwargs)

# beautify plots
ax[0, 0].axis("off")
for a in ax.flatten():
a.set_xticklabels([]), a.set_yticklabels([])
a.set_xticks([]), a.set_yticks([])
fig.subplots_adjust(wspace=0, hspace=0)
fig.show()
24 changes: 8 additions & 16 deletions examples/06_conditioned_fields/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,21 @@ To generate random fields, that coincide with given observations, but are still
random according to a given covariance model away from the observations proximity,
we provide the generation of conditioned random fields.


The idea behind conditioned random fields builds up on kriging.
First we generate a field with a kriging method, then we generate a random field,
and finally we generate another kriged field to eliminate the error between
the random field and the kriged field of the given observations.

To do so, you can choose between ordinary and simple kriging.
In case of ordinary kriging, the mean of the SRF will be overwritten by the
estimated mean.

The setup of the spatial random field is the same as described in
:ref:`tutorial_02_cov`.
You just need to add the conditions as described in :ref:`tutorial_05_kriging`:

.. code-block:: python
with 0 as mean and 1 as variance that will be multiplied with the kriging
standard deviation.

srf.set_condition(cond_pos, cond_val, "simple")
To do so, you can instantiate a :any:`CondSRF` class with a configured
:any:`Krige` class.

or:
The setup of the a conditioned random field should be as follows:

.. code-block:: python
srf.set_condition(cond_pos, cond_val, "ordinary")
krige = gs.Krige(model, cond_pos, cond_val)
cond_srf = gs.CondSRF(krige)
field = cond_srf(grid)
Examples
--------
40 changes: 40 additions & 0 deletions examples/09_spatio_temporal/README.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,46 @@
Spatio-Temporal Modeling
========================

Spatio-Temporal modelling can provide insights on time depending processes
like rainfall, air temperature or crop yield.

GSTools provides the metric spatio-temporal model for all covariance models
by enhancing the spatial model dimension with a time dimesion to result in
the spatio-temporal dimension ``st_dim`` and setting a
spatio-temporal anisotropy ratio ``st_anis``:

.. code-block:: python
import gstools as gs
dim = 3 # spatial dimension
st_dim = dim + 1
st_anis = 0.4
model = gs.Exponential(dim=st_dim, anis=st_anis)
Since it is given in the name "spatio-temporal",
we will always treat the time as last dimension.

This enables to have spatial anisotropy and rotation defined as in
non-temporal models, without altering the behavior in the time dimension:

.. code-block:: python
anis = [0.4, 0.2] # spatial anisotropy in 3D
angles = [0.5, 0.4, 0.3] # spatial rotation in 3D
model = gs.Exponential(dim=st_dim, anis=anis + [st_anis], angles=angles)
In order to generate spatio-temporal position tuples, GSTools provides a
convenient function :any:`generate_st_grid`:

.. code-block:: python
pos = ...
time = range(10)
st_pos = gs.generate_st_grid(pos, time)
st_rf = SRF(st_model)
st_field = st_rf(st_pos).reshape(-1, len(time))
Then you we access the different time-steps with the last index.

Examples
--------
2 changes: 1 addition & 1 deletion examples/10_normalizer/01_auto_fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

# structured field with edge length of 50
x = y = range(51)
pos = gs.tools.geometric.gen_mesh([x, y])
pos = gs.generate_grid([x, y])
model = gs.Gaussian(dim=2, var=1, len_scale=10)
srf = gs.SRF(model, seed=20170519, normalizer=gs.normalizer.LogNormal())
# generate the original field
Expand Down
8 changes: 4 additions & 4 deletions examples/10_normalizer/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ to input data by minimizing the likelihood function.
Mean, Trend and Normalizers
---------------------------

All Field classes (:any:`SRF` or :any:`Krige`) provide the input of `mean`,
`normalizer` and `trend`:
All Field classes (:any:`SRF`, :any:`Krige` or :any:`CondSRF`) provide the input
of `mean`, `normalizer` and `trend`:

* A `trend` can be a callable function, that represents a trend in input data.
For example a linear decrease of temperature with height.
Expand All @@ -38,8 +38,8 @@ in the context of normally distributed data.
Provided Normalizers
--------------------

The following normalizers can be passed to all Field-classes
(:any:`SRF` or :any:`Krige`) or can be used as standalone tools to analyse data.
The following normalizers can be passed to all Field-classes and variogram
estimation routines or can be used as standalone tools to analyse data.

.. currentmodule:: gstools.normalizer

Expand Down
17 changes: 17 additions & 0 deletions gstools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@
Classes
=======
Kriging
^^^^^^^
Swiss-Army-Knife for Kriging. For short cut classes see: :any:`gstools.krige`
.. currentmodule:: gstools.krige
.. autosummary::
Krige
Spatial Random Field
^^^^^^^^^^^^^^^^^^^^
Classes for (conditioned) random field generation
Expand Down Expand Up @@ -93,6 +102,8 @@
.. autosummary::
rotated_main_axes
generate_grid
generate_st_grid
Variogram Estimation
^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -125,9 +136,12 @@
transform,
normalizer,
)
from gstools.krige import Krige
from gstools.field import SRF, CondSRF
from gstools.tools import (
rotated_main_axes,
generate_grid,
generate_st_grid,
EARTH_RADIUS,
vtk_export,
vtk_export_structured,
Expand Down Expand Up @@ -201,9 +215,12 @@
]

__all__ += [
"Krige",
"SRF",
"CondSRF",
"rotated_main_axes",
"generate_grid",
"generate_st_grid",
"EARTH_RADIUS",
"vtk_export",
"vtk_export_structured",
Expand Down
Loading

0 comments on commit 832866b

Please sign in to comment.