Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mean, Normalizer, Trend and Fitting #124

Merged
merged 100 commits into from
Mar 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
eb0671d
normalize: add base class
MuellerSeb Dec 21, 2020
c950ef8
normalize: add normalize transformations
MuellerSeb Dec 21, 2020
15efa3f
normalize: add to gstools init
MuellerSeb Dec 21, 2020
8d2bd32
normalize: add to docs
MuellerSeb Dec 21, 2020
1ebfcf6
Covmodel: use 'sorted' to gain soterd opt-args
MuellerSeb Jan 6, 2021
c0735e2
Normalize: add more likelihood routines
MuellerSeb Jan 6, 2021
6513ffa
Merge branch 'develop' of github.com:GeoStat-Framework/GSTools into n…
MuellerSeb Jan 6, 2021
f42195b
Normalizer: add init value for self._opti
MuellerSeb Jan 11, 2021
9f345bb
Tests: add stats tests for normalizer
MuellerSeb Jan 11, 2021
d4528cf
Normalizer: fix bug in likelihood
MuellerSeb Jan 11, 2021
b47fb2d
Normalizer: fix doc typo
MuellerSeb Jan 11, 2021
b2542af
Tests: add more normalizer tests
MuellerSeb Jan 11, 2021
3ccf703
Normalize: typo
MuellerSeb Jan 27, 2021
d584f71
merge develop
MuellerSeb Jan 27, 2021
086780a
Examples: blackenend
MuellerSeb Jan 27, 2021
e632ef5
Field: outsourcing helper functions
MuellerSeb Jan 28, 2021
a85ee97
Normalize: add name attribute to class
MuellerSeb Jan 28, 2021
98974b1
Tools: add eval_func to misc tools
MuellerSeb Jan 28, 2021
00257da
Field: add mean, normalizer, trend to Field class and refactoring
MuellerSeb Jan 28, 2021
999e0e1
Field: use field_dim in post_field
MuellerSeb Jan 28, 2021
c06294e
SRF: add normalizer and trend
MuellerSeb Jan 28, 2021
8446d9a
Krige: add normalizer and trend to base-class; refactoring; add fit_n…
MuellerSeb Jan 28, 2021
c396873
Krige: add normalizer and trend to methods (Detrended stays the same)
MuellerSeb Jan 28, 2021
185bc0c
Krige: remove moved routines
MuellerSeb Jan 28, 2021
9b8e782
Tests: change calling sequence in Kriging routines (trend was moved)
MuellerSeb Jan 28, 2021
4bacbbb
CondSRF: add support for normalizer and trend
MuellerSeb Jan 28, 2021
7835769
Docs: update docs accordingly
MuellerSeb Jan 28, 2021
6cda28f
Examples: fix call signature in ordinary kriging
MuellerSeb Jan 28, 2021
f626c02
Transform: better description to distinguish from normalizer
MuellerSeb Jan 29, 2021
19519b2
Normalizer: rename subpackage to 'normalizer'
MuellerSeb Jan 29, 2021
5d541b6
Tests: import fix for normalizer
MuellerSeb Jan 29, 2021
d5d2454
Examples: add first normalizer example
MuellerSeb Jan 29, 2021
ea759ac
Examples: update Normalizers
MuellerSeb Jan 29, 2021
2774899
Examples: use bullet points to describe mean, trend, normalizer
MuellerSeb Jan 29, 2021
ab3969a
CondSRF: bug fix for trend property
MuellerSeb Jan 29, 2021
db681d8
CondSRF: consequently forward properties to kriging class
MuellerSeb Jan 29, 2021
bbf19e7
Krige: fix external drift bug (when using ext+int drift); adding defa…
MuellerSeb Jan 29, 2021
5e169a5
Krige: add fit_variogram argument to automatically fit covmodel to gi…
MuellerSeb Jan 29, 2021
542c0cb
Krige: bugfix in ext_drift setting
MuellerSeb Jan 29, 2021
50dfe66
Krige: better doc for normalizer
MuellerSeb Jan 29, 2021
0fed22f
Docs: add normalizer tutorial to toctree
MuellerSeb Jan 29, 2021
1f93a8e
Examples: update normalizer readme
MuellerSeb Jan 29, 2021
788e87b
Examples: add second normalizer example on auto fitting
MuellerSeb Jan 29, 2021
e4a1be5
Examples: update auto-fit normalizer example
MuellerSeb Jan 29, 2021
96d4a07
Examples: update auto-fit normalizer example again
MuellerSeb Jan 29, 2021
9520b35
Examples: update auto-fit normalizer example again
MuellerSeb Jan 29, 2021
8b4e4c2
Examples: update auto-fit normalizer example again
MuellerSeb Jan 29, 2021
3ed157a
Examples: update auto-fit normalizer example again
MuellerSeb Jan 29, 2021
4936a84
Examples: update auto-fit variogram example
MuellerSeb Jan 29, 2021
ecbf937
DOC: update
MuellerSeb Jan 29, 2021
e6b7b48
Docs: update index
MuellerSeb Jan 29, 2021
6b9b535
README: link normalizer models
MuellerSeb Jan 29, 2021
f49b4da
README: fix link
MuellerSeb Jan 30, 2021
058f27b
Field: allow passing uninitialized Normalizer classes
MuellerSeb Jan 30, 2021
cbc305a
Tools: add eval_func to doc; minor fix
MuellerSeb Jan 30, 2021
b8572cd
Krige: get_mean respects normalizer now; set_condition better handles…
MuellerSeb Jan 30, 2021
44aaf72
Filed: fix normalizer setting with class
MuellerSeb Jan 30, 2021
bc3e893
Krige: 'get_mean' add switch to enable processing; fix kriging the mean
MuellerSeb Jan 30, 2021
83126c9
CondSRF: cleanup init; make krige a property
MuellerSeb Jan 30, 2021
0fa29df
Examples: minor updates in normalizer examples
MuellerSeb Jan 30, 2021
f3fc351
Krige: better handling of field-mean in kriging the mean
MuellerSeb Jan 31, 2021
f75ee1c
Field: better formatting of mean, normalizer and trend in repr
MuellerSeb Jan 31, 2021
46db911
Normalizer: ignore nan-data; add range check for data; better subclas…
MuellerSeb Feb 1, 2021
9092ef9
Docs: cleanup doc; Sphinx bugfixes (wrong refs)
MuellerSeb Feb 1, 2021
27a691b
Normalizer: add routines to add/remove mean-normalizer-trend
MuellerSeb Feb 2, 2021
614a6f8
Variogram: add mean, normalizer, trend and fit_normalizer to variogra…
MuellerSeb Feb 2, 2021
48ed439
Field: use apply_mean_normalizer_trend routine
MuellerSeb Feb 2, 2021
2c9dcd9
Doc: minor fix
MuellerSeb Feb 2, 2021
a9771ac
Normalizer: fix some wrong data ranges for negative lambdas
MuellerSeb Feb 2, 2021
7b7278d
Examples: add normalizer comparison example
MuellerSeb Feb 2, 2021
f305995
Examples: saver call of normalize_range
MuellerSeb Feb 2, 2021
9b55002
Field: add 'dim' property that's identical to model.field_dim
MuellerSeb Feb 5, 2021
9bb8daa
Field: allow vector valued mean/trend for vector valued fields
MuellerSeb Feb 12, 2021
56ec497
Field: bugfix in mesh method: transpose vector fields
MuellerSeb Feb 12, 2021
8fe2297
Merge branch 'develop' of github.com:GeoStat-Framework/GSTools into n…
MuellerSeb Feb 12, 2021
619f242
Examples: update 3D vector example to use mesh method
MuellerSeb Feb 12, 2021
2ba9e43
Field: fix repr of vector mean
MuellerSeb Feb 13, 2021
36ac370
CondSRF: simplify field saving; remove unneeded generator value type …
MuellerSeb Feb 22, 2021
d8059ff
Field: skip some string formatting routines in coverage
MuellerSeb Feb 22, 2021
79f7de4
Tools: skip corner case for mean from vector in coverage
MuellerSeb Feb 22, 2021
cf01e0d
VectorField: add test for vector mean
MuellerSeb Feb 22, 2021
12bfaa0
CovModel: remove redundant __ne__ method
MuellerSeb Feb 22, 2021
05eba49
Normalizer: add __eq__ magic method
MuellerSeb Feb 22, 2021
801b6c9
CondSRF: minor fix
MuellerSeb Feb 22, 2021
db02681
Tests: more CondSRF testing
MuellerSeb Feb 22, 2021
7f4af3c
Tests: test comparing normalizers
MuellerSeb Feb 22, 2021
79687ff
Tests: check autofitting normalizer
MuellerSeb Feb 22, 2021
63df1c0
Tests: check auto-init normalizers in krige
MuellerSeb Feb 22, 2021
3a3fd47
Tests: reduce places in comparison (normalizer autofit)
MuellerSeb Feb 22, 2021
3af20e0
Krige: better setting of drift_functions
MuellerSeb Feb 22, 2021
7dce305
Tests: test Error raise for wrong latlon input in vario estimate
MuellerSeb Feb 22, 2021
b1be332
Tests: krige: raise check; better check kriging the mean
MuellerSeb Feb 22, 2021
c6d711f
Krige: remove ext-drift deleter (confusing)
MuellerSeb Feb 22, 2021
5d16fd5
Tests: minor improvements
MuellerSeb Feb 22, 2021
a470040
Fix typos in docstrings and comments
LSchueler Mar 10, 2021
9a875fc
Normalizer: add _dx as class attribute
MuellerSeb Mar 13, 2021
8ac2194
Field: rename mesh_call to generate_on_mesh; minor doc fixes
MuellerSeb Mar 13, 2021
92600ab
BoxCox: (bugfix) use correct data range for lmbda<0
MuellerSeb Mar 13, 2021
bf37471
BoxCoxShift: (bugfix) use correct data range for lmbda<0
MuellerSeb Mar 13, 2021
4b12aed
Examples: change field size in Auto-fit example to prevent confusion …
MuellerSeb Mar 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@

GeoStatTools provides geostatistical tools for various purposes:
- random field generation
- simple, ordinary, universal and external drift kriging
- conditioned field generation
- incompressible random vector field generation
- simple and ordinary kriging
- variogram estimation and fitting
- (automatted) variogram estimation and fitting
- directional variogram estimation and modelling
- data normalization and transformation
- many readily provided and even user-defined covariance models
- metric spatio-temporal modelling
- plotting and exporting routines


Expand Down Expand Up @@ -83,6 +86,7 @@ The documentation also includes some [tutorials][tut_link], showing the most imp
- [Field transformations][tut7_link]
- [Geographic Coordinates][tut8_link]
- [Spatio-Temporal Modelling][tut9_link]
- [Normalizing Data][tut10_link]
- [Miscellaneous examples][tut0_link]

The associated python scripts are provided in the `examples` folder.
Expand Down Expand Up @@ -219,15 +223,15 @@ cond_val = [0.47, 0.56, 0.74, 1.47, 1.74]

gridx = np.linspace(0.0, 15.0, 151)

# spatial random field class
# conditioned spatial random field class
model = gs.Gaussian(dim=1, var=0.5, len_scale=2)
srf = gs.SRF(model)
srf.set_condition(cond_pos, cond_val, "ordinary")
krige = gs.krige.Ordinary(model, cond_pos, cond_val)
cond_srf = gs.CondSRF(krige)

# generate the ensemble of field realizations
fields = []
for i in range(100):
fields.append(srf(gridx, seed=i))
fields.append(cond_srf(gridx, seed=i))
plt.plot(gridx, fields[i], color="k", alpha=0.1)
plt.scatter(cond_pos, cond_val, color="k")
plt.show()
Expand Down Expand Up @@ -363,6 +367,7 @@ You can contact us via <[email protected]>.
[tut7_link]: https://geostat-framework.readthedocs.io/projects/gstools/en/stable/examples/07_transformations/index.html
[tut8_link]: https://geostat-framework.readthedocs.io/projects/gstools/en/stable/examples/08_geo_coordinates/index.html
[tut9_link]: https://geostat-framework.readthedocs.io/projects/gstools/en/stable/examples/09_spatio_temporal/index.html
[tut10_link]: https://geostat-framework.readthedocs.io/projects/gstools/en/stable/examples/10_normalizer/index.html
[tut0_link]: https://geostat-framework.readthedocs.io/projects/gstools/en/stable/examples/00_misc/index.html
[cor_link]: https://en.wikipedia.org/wiki/Autocovariance#Normalization
[vtk_link]: https://www.vtk.org/
2 changes: 2 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ def setup(app):
"../../examples/07_transformations/",
"../../examples/08_geo_coordinates/",
"../../examples/09_spatio_temporal/",
"../../examples/10_normalizer/",
],
# path where to save gallery generated examples
"gallery_dirs": [
Expand All @@ -305,6 +306,7 @@ def setup(app):
"examples/07_transformations/",
"examples/08_geo_coordinates/",
"examples/09_spatio_temporal/",
"examples/10_normalizer/",
],
# Pattern to search for example files
"filename_pattern": r"\.py",
Expand Down
10 changes: 0 additions & 10 deletions docs/source/field.base.rst

This file was deleted.

5 changes: 0 additions & 5 deletions docs/source/field.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ gstools.field
=============

.. automodule:: gstools.field
:members:
:undoc-members:
:inherited-members:
:show-inheritance:

.. raw:: latex

Expand All @@ -16,4 +12,3 @@ gstools.field

field.generator.rst
field.upscaling.rst
field.base.rst
26 changes: 17 additions & 9 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,18 @@ GSTools Quickstart
:width: 150px
:align: center

GeoStatTools provides geostatistical tools for random field generation and
variogram estimation based on many readily provided and even user-defined
covariance models.
GeoStatTools provides geostatistical tools for various purposes:

- random field generation
- simple, ordinary, universal and external drift kriging
- conditioned field generation
- incompressible random vector field generation
- (automatted) variogram estimation and fitting
- directional variogram estimation and modelling
- data normalization and transformation
- many readily provided and even user-defined covariance models
- metric spatio-temporal modelling
- plotting and exporting routines


Installation
Expand Down Expand Up @@ -99,10 +108,9 @@ showing the most important use cases of GSTools, which are
- `Field transformations <examples/07_transformations/index.html>`__
- `Geographic Coordinates <examples/08_geo_coordinates/index.html>`__
- `Spatio-Temporal Modelling <examples/09_spatio_temporal/index.html>`__
- `Normalizing Data <examples/10_normalizer/index.html>`__
- `Miscellaneous examples <examples/00_misc/index.html>`__

Some more examples are provided in the examples folder.


Spatial Random Field Generation
===============================
Expand Down Expand Up @@ -253,15 +261,15 @@ generate 100 realizations and plot them:

gridx = np.linspace(0.0, 15.0, 151)

# spatial random field class
# conditioned spatial random field class
model = gs.Gaussian(dim=1, var=0.5, len_scale=2)
srf = gs.SRF(model)
srf.set_condition(cond_pos, cond_val, "ordinary")
krige = gs.krige.Ordinary(model, cond_pos, cond_val)
cond_srf = gs.CondSRF(krige)

# generate the ensemble of field realizations
fields = []
for i in range(100):
fields.append(srf(gridx, seed=i))
fields.append(cond_srf(gridx, seed=i))
plt.plot(gridx, fields[i], color="k", alpha=0.1)
plt.scatter(cond_pos, cond_val, color="k")
plt.show()
Expand Down
8 changes: 8 additions & 0 deletions docs/source/normalizer.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
gstools.normalizer
==================

.. automodule:: gstools.normalizer

.. raw:: latex

\clearpage
1 change: 1 addition & 0 deletions docs/source/package.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ GSTools API
random.rst
tools.rst
transform.rst
normalizer.rst
1 change: 1 addition & 0 deletions docs/source/tutorials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ explore its whole beauty and power.
examples/07_transformations/index
examples/08_geo_coordinates/index
examples/09_spatio_temporal/index
examples/10_normalizer/index
examples/00_misc/index
2 changes: 0 additions & 2 deletions docs/source/variogram.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ gstools.variogram
=================

.. automodule:: gstools.variogram
:members:
:undoc-members:

.. raw:: latex

Expand Down
14 changes: 13 additions & 1 deletion examples/03_variogram/06_auto_bin_latlon.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,17 @@
###############################################################################
# Looks good, doesn't it?
#
# This workflow is also implemented in the :any:`Krige` class, by setting
# ``fit_variogram=True``. Then the whole procedure shortens:

krige = gs.krige.Ordinary(sph, pos, field, fit_variogram=True)
krige.structured((grid_lat, grid_lon))

# plot the result
krige.plot()
# show the fitting results
print(krige.model)

###############################################################################
# This example shows, that setting up variogram estimation and kriging routines
# is straight forward with GSTools. ;-)
# is straight forward with GSTools!
MuellerSeb marked this conversation as resolved.
Show resolved Hide resolved
17 changes: 3 additions & 14 deletions examples/04_vector_field/01_3d_vector_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
externally defined and it will be generated by PyVista.
"""
# sphinx_gallery_thumbnail_path = 'pics/GS_3d_vector_field.png'
import numpy as np
import gstools as gs
import pyvista as pv

Expand All @@ -16,25 +15,15 @@

###############################################################################
# create a uniform grid with PyVista
nx, ny, nz = 40, 30, 10
dim, spacing, origin = (40, 30, 10), (1, 1, 1), (-10, 0, 0)
mesh = pv.UniformGrid(dim, spacing, origin)
x = mesh.points[:, 0]
y = mesh.points[:, 1]
z = mesh.points[:, 2]
MuellerSeb marked this conversation as resolved.
Show resolved Hide resolved

###############################################################################
# create an incompressible random 3d velocity field on the given mesh
# with added mean velocity in x-direction
model = gs.Gaussian(dim=3, var=3, len_scale=1.5)
srf = gs.SRF(model, generator='VectorField', seed=198412031)
srf((x, y, z), mesh_type='unstructured')

# add a mean velocity in x-direction
srf.field[0, :] += 0.5

###############################################################################
# add the velocity field to the mesh object
mesh["Velocity"] = srf.field.T
srf = gs.SRF(model, mean=(0.5, 0, 0), generator="VectorField", seed=198412031)
srf.mesh(mesh, points="points", name="Velocity")

###############################################################################
# Now, we can do the plotting
Expand Down
2 changes: 1 addition & 1 deletion examples/05_kriging/07_detrended_ordinary_kriging.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def trend(x):
drift_field = drift(gridx) + trend(gridx)
# kriging
model = Gaussian(dim=1, var=0.1, len_scale=2)
krig_trend = krige.Ordinary(model, cond_pos, cond_val, trend)
krig_trend = krige.Ordinary(model, cond_pos, cond_val, trend=trend)
krig_trend(gridx)
ax = krig_trend.plot()
ax.scatter(cond_pos, cond_val, color="k", zorder=10, label="Conditions")
Expand Down
19 changes: 14 additions & 5 deletions examples/05_kriging/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,20 @@ the features you want:
In contrast to the internal drift, that is evaluated at the desired points with
the given functions, the external drift has to given for each point form an "external"
source. This results in :any:`ExtDrift` kriging.
* `trend_function`: If you already have fitted a trend model, that is provided as a
callable, you can give it to the kriging routine. This trend is subtracted from the
conditional values before the kriging is done, meaning, that only the residuals are
used for kriging. This can be used with separate regression of your data.
This results in :any:`Detrended` kriging.
* `trend`, `mean`, `normalizer`: These are used to pre- and post-process data.
If you already have fitted a trend model that is provided as a callable function,
you can give it to the kriging routine. Normalizer are power-transformations
to gain normality.
`mean` behaves similar to `trend` but is applied at another position:

1. conditioning data is de-trended (substracting trend)
2. detrended conditioning data is then normalized (in order to follow a normal distribution)
3. normalized conditioning data is set to zero mean (subtracting mean)

Cosequently, when there is no normalizer given, trend and mean are the same thing
and only one should be used.
:any:`Detrended` kriging is a shortcut to provide only a trend and simple kriging
with normal data.
* `exact` and `cond_err`: To incorporate the nugget effect and/or measurement errors,
one can set `exact` to `False` and provide either individual measurement errors
for each point or set the nugget as a constant measurement error everywhere.
Expand Down
10 changes: 7 additions & 3 deletions examples/09_spatio_temporal/02_precip_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,15 @@
###############################################################################
# plot the 2d precipitation field over time as an animation.


def _update_ani(time_step):
im.set_array(srf.field[:, :, time_step].T)
return im,
return (im,)
MuellerSeb marked this conversation as resolved.
Show resolved Hide resolved


fig, ax = plt.subplots()
im = ax.imshow(
srf.field[:,:,0].T,
srf.field[:, :, 0].T,
cmap="Blues",
interpolation="bicubic",
origin="lower",
Expand All @@ -68,4 +70,6 @@ def _update_ani(time_step):
ax.set_xlabel(r"$x$ / km")
ax.set_ylabel(r"$y$ / km")

ani = animation.FuncAnimation(fig, _update_ani, len(t), interval=100, blit=True)
ani = animation.FuncAnimation(
fig, _update_ani, len(t), interval=100, blit=True
)
53 changes: 53 additions & 0 deletions examples/10_normalizer/00_lognormal_kriging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
r"""
Log-Normal Kriging
------------------

Log Normal kriging is a term to describe a special workflow for kriging to
deal with log-normal data, like conductivity or transmissivity in hydrogeology.

It simply means to first convert the input data to a normal distribution, i.e.
applying a logarithic function, then interpolating these values with kriging
and transforming the result back with the exponential function.

The resulting kriging variance describes the error variance of the log-values
of the target variable.

In this example we will use ordinary kriging.
"""
import numpy as np
import gstools as gs

# condtions
cond_pos = [0.3, 1.9, 1.1, 3.3, 4.7]
cond_val = [0.47, 0.56, 0.74, 1.47, 1.74]
# resulting grid
gridx = np.linspace(0.0, 15.0, 151)
# stable covariance model
model = gs.Stable(dim=1, var=0.5, len_scale=2.56, alpha=1.9)

###############################################################################
# In order to result in log-normal kriging, we will use the :any:`LogNormal`
# Normalizer. This is a parameter-less normalizer, so we don't have to fit it.
normalizer = gs.normalizer.LogNormal

###############################################################################
# Now we generate the interpolated field as well as the mean field.
# This can be done by setting `only_mean=True` in :any:`Krige.__call__`.
# The result is then stored as `mean_field`.
#
# In terms of log-normal kriging, this mean represents the geometric mean of
# the field.
krige = gs.krige.Ordinary(model, cond_pos, cond_val, normalizer=normalizer)
# interpolate the field
krige(gridx)
# also generate the mean field
krige(gridx, only_mean=True)

###############################################################################
# And that's it. Let's have a look at the results.
ax = krige.plot()
# plotting the geometric mean
krige.plot("mean_field", ax=ax)
# plotting the conditioning data
ax.scatter(cond_pos, cond_val, color="k", zorder=10, label="Conditions")
ax.legend()
Loading