Skip to content

Commit 83c85f8

Browse files
authored
Merge pull request #308 from GeoStat-Framework/add_time_feature
Add 'temporal', 'spatial_dim' and 'geo_scale' attributes to Covmodel
2 parents f60f2cb + 0881384 commit 83c85f8

File tree

29 files changed

+675
-192
lines changed

29 files changed

+675
-192
lines changed

CHANGELOG.md

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,34 @@
22

33
All notable changes to **GSTools** will be documented in this file.
44

5+
## [Unreleased] - ? - 2023-?
6+
7+
### Enhancements
8+
- added `temporal` flag to `CovModel` to explicitly specify spatio-temporal models [#308](https://github.com/GeoStat-Framework/GSTools/pull/308)
9+
- rotation between spatial and temporal dimension will be ignored
10+
- added `spatial_dim` to `CovModel` to explicitly set spatial dimension for spatio-temporal models
11+
- if not using `spatial_dim`, the provided `dim` needs to include the possible temporal dimension
12+
- `spatial_dim` is always one less than `field_dim` for spatio-temporal models
13+
- also works with `latlon=True` to have a spatio-temporal model with geographic coordinates
14+
- all plotting routines respect this
15+
- the `Field` class now has a `temporal` attribute which forwards the model attribute
16+
- automatic variogram fitting in kriging classes for `temporal=True` and `latlon=True` will raise an error
17+
- added `geo_scale` to `CovModel` to have a more consistent way to set the units of the model length scale for geographic coordinates [#308](https://github.com/GeoStat-Framework/GSTools/pull/308)
18+
- no need to use `rescale` for this anymore (was rather a hack)
19+
- added `gs.KM_SCALE` which is the same as `gs.EARTH_RADIUS` for kilometer scaling
20+
- added `gs.DEGREE_SCALE` for great circle distance in degrees
21+
- added `gs.RADIAN_SCALE` for great circle distance in radians (default and previous behavior)
22+
- yadrenko variogram respects this and assumes the great circle distances is given in the respective unit
23+
- `vario_estimate` also has `geo_scale` now to control the units of the bins
24+
- `vario_estimate` now forwards additional kwargs to `standard_bins` (`bin_no`, `max_dist`) [#308](https://github.com/GeoStat-Framework/GSTools/pull/308)
25+
26+
### Changes
27+
- `CovModel`s expect special arguments by keyword now [#308](https://github.com/GeoStat-Framework/GSTools/pull/308)
28+
- always use f-strings internally [#283](https://github.com/GeoStat-Framework/GSTools/pull/283)
29+
30+
### Bugfixes
31+
- latex equations were not rendered correctly in docs [#290](https://github.com/GeoStat-Framework/GSTools/pull/290)
32+
533

634
## [1.4.1] - Sassy Sapphire - 2022-11
735

@@ -25,7 +53,7 @@ All notable changes to **GSTools** will be documented in this file.
2553
- better support for custom generators [#250](https://github.com/GeoStat-Framework/GSTools/pull/250) [#259](https://github.com/GeoStat-Framework/GSTools/pull/259)
2654
- add `valid_value_types` class variable to all field classes [#250](https://github.com/GeoStat-Framework/GSTools/pull/250)
2755
- PyKrige: fix passed variogram in case of latlon models [#254](https://github.com/GeoStat-Framework/GSTools/pull/254)
28-
- add bounds checks for optional arguments of CovModel when resetting by class attribute [#255](https://github.com/GeoStat-Framework/GSTools/pull/255)
56+
- add bounds checks for optional arguments of `CovModel` when resetting by class attribute [#255](https://github.com/GeoStat-Framework/GSTools/pull/255)
2957
- minor coverage improvements [#255](https://github.com/GeoStat-Framework/GSTools/pull/255)
3058
- documentation: readability improvements [#257](https://github.com/GeoStat-Framework/GSTools/pull/257)
3159

@@ -181,7 +209,7 @@ See: [#197](https://github.com/GeoStat-Framework/GSTools/issues/197)
181209
- added new `len_rescaled` attribute to the `CovModel` class, which is the rescaled `len_scale`: `len_rescaled = len_scale / rescale`
182210
- new method `default_rescale` to provide default rescale factor (can be overridden)
183211
- remove `doctest` calls
184-
- docstring updates in CovModel and derived models
212+
- docstring updates in `CovModel` and derived models
185213
- updated all models to use the `cor` routine and make use of the `rescale` argument (See: [#90](https://github.com/GeoStat-Framework/GSTools/issues/90))
186214
- TPL models got a separate base class to not repeat code
187215
- added **new models** (See: [#88](https://github.com/GeoStat-Framework/GSTools/issues/88)):
@@ -208,7 +236,7 @@ See: [#197](https://github.com/GeoStat-Framework/GSTools/issues/197)
208236
#### Arbitrary dimensions ([#112](https://github.com/GeoStat-Framework/GSTools/issues/112))
209237
- allow arbitrary dimensions in all routines (CovModel, Krige, SRF, variogram)
210238
- anisotropy and rotation following a generalization of tait-bryan angles
211-
- CovModel provides `isometrize` and `anisometrize` routines to convert points
239+
- `CovModel` provides `isometrize` and `anisometrize` routines to convert points
212240

213241
#### New Class for Conditioned Random Fields ([#130](https://github.com/GeoStat-Framework/GSTools/issues/130))
214242
- **THIS BREAKS BACKWARD COMPATIBILITY**
@@ -232,7 +260,7 @@ See: [#197](https://github.com/GeoStat-Framework/GSTools/issues/197)
232260

233261
### Changes
234262
- drop support for Python 3.5 [#146](https://github.com/GeoStat-Framework/GSTools/pull/146)
235-
- added a finit limit for shape-parameters in some CovModels [#147](https://github.com/GeoStat-Framework/GSTools/pull/147)
263+
- added a finit limit for shape-parameters in some `CovModel`s [#147](https://github.com/GeoStat-Framework/GSTools/pull/147)
236264
- drop usage of `pos2xyz` and `xyz2pos`
237265
- remove structured option from generators (structured pos need to be converted first)
238266
- explicitly assert dim=2,3 when generating vector fields
@@ -248,7 +276,7 @@ See: [#197](https://github.com/GeoStat-Framework/GSTools/issues/197)
248276
- typo in keyword argument for vario_estimate_structured [#80](https://github.com/GeoStat-Framework/GSTools/issues/80)
249277
- isotropic rotation of SRF was not possible [#100](https://github.com/GeoStat-Framework/GSTools/issues/100)
250278
- `CovModel.opt_arg` now sorted [#103](https://github.com/GeoStat-Framework/GSTools/issues/103)
251-
- CovModel.fit: check if weights are given as a string (numpy comparison error) [#111](https://github.com/GeoStat-Framework/GSTools/issues/111)
279+
- `CovModel.fit`: check if weights are given as a string (numpy comparison error) [#111](https://github.com/GeoStat-Framework/GSTools/issues/111)
252280
- several pylint fixes ([#159](https://github.com/GeoStat-Framework/GSTools/pull/159))
253281

254282

@@ -266,7 +294,7 @@ See: [#197](https://github.com/GeoStat-Framework/GSTools/issues/197)
266294
### Enhancements
267295
- different variogram estimator functions can now be used #51
268296
- the TPLGaussian and TPLExponential now have analytical spectra #67
269-
- added property ``is_isotropic`` to CovModel #67
297+
- added property `is_isotropic` to `CovModel` #67
270298
- reworked the whole krige sub-module to provide multiple kriging methods #67
271299
- Simple
272300
- Ordinary
@@ -279,7 +307,7 @@ See: [#197](https://github.com/GeoStat-Framework/GSTools/issues/197)
279307

280308
### Changes
281309
- Python versions 2.7 and 3.4 are no longer supported #40 #43
282-
- CovModel: in 3D the input of anisotropy is now treated slightly different: #67
310+
- `CovModel`: in 3D the input of anisotropy is now treated slightly different: #67
283311
- single given anisotropy value [e] is converted to [1, e] (it was [e, e] before)
284312
- two given length-scales [l_1, l_2] are converted to [l_1, l_2, l_2] (it was [l_1, l_2, l_1] before)
285313

@@ -297,31 +325,31 @@ See: [#197](https://github.com/GeoStat-Framework/GSTools/issues/197)
297325

298326
### Bugfixes
299327
- define spectral_density instead of spectrum in covariance models since Cov-base derives spectrum. See: [commit 00f2747](https://github.com/GeoStat-Framework/GSTools/commit/00f2747fd0503ff8806f2eebfba36acff813416b)
300-
- better boundaries for CovModel parameters. See: https://github.com/GeoStat-Framework/GSTools/issues/37
328+
- better boundaries for `CovModel` parameters. See: https://github.com/GeoStat-Framework/GSTools/issues/37
301329

302330

303331
## [1.1.0] - Reverberating Red - 2019-10-01
304332

305333
### Enhancements
306334
- by using Cython for all the heavy computations, we could achieve quite some speed ups and reduce the memory consumption significantly #16
307335
- parallel computation in Cython is now supported with the help of OpenMP and the performance increase is nearly linear with increasing cores #16
308-
- new submodule ``krige`` providing simple (known mean) and ordinary (estimated mean) kriging working analogous to the srf class
309-
- interface to pykrige to use the gstools CovModel with the pykrige routines (https://github.com/bsmurphy/PyKrige/issues/124)
310-
- the srf class now provides a ``plot`` and a ``vtk_export`` routine
336+
- new submodule `krige` providing simple (known mean) and ordinary (estimated mean) kriging working analogous to the srf class
337+
- interface to pykrige to use the gstools `CovModel` with the pykrige routines (https://github.com/bsmurphy/PyKrige/issues/124)
338+
- the srf class now provides a `plot` and a `vtk_export` routine
311339
- incompressible flow fields can now be generated #14
312340
- new submodule providing several field transformations like: Zinn&Harvey, log-normal, bimodal, ... #13
313341
- Python 3.4 and 3.7 wheel support #19
314342
- field can now be generated directly on meshes from [meshio](https://github.com/nschloe/meshio) and [ogs5py](https://github.com/GeoStat-Framework/ogs5py), see: [commit f4a3439](https://github.com/GeoStat-Framework/GSTools/commit/f4a3439400b81d8d9db81a5f7fbf6435f603cf05)
315-
- the srf and kriging classes now store the last ``pos``, ``mesh_type`` and ``field`` values to keep them accessible, see: [commit 29f7f1b](https://github.com/GeoStat-Framework/GSTools/commit/29f7f1b029866379ce881f44765f72534d757fae)
343+
- the srf and kriging classes now store the last `pos`, `mesh_type` and `field` values to keep them accessible, see: [commit 29f7f1b](https://github.com/GeoStat-Framework/GSTools/commit/29f7f1b029866379ce881f44765f72534d757fae)
316344
- tutorials on all important features of GSTools have been written for you guys #20
317345
- a new interface to pyvista is provided to export fields to python vtk representation, which can be used for plotting, exploring and exporting fields #29
318346

319347
### Changes
320348
- the license was changed from GPL to LGPL in order to promote the use of this library #25
321349
- the rotation angles are now interpreted in positive direction (counter clock wise)
322-
- the ``force_moments`` keyword was removed from the SRF call method, it is now in provided as a field transformation #13
350+
- the `force_moments` keyword was removed from the SRF call method, it is now in provided as a field transformation #13
323351
- drop support of python implementations of the variogram estimators #18
324-
- the ``variogram_normed`` method was removed from the ``CovModel`` class due to redundance [commit 25b1647](https://github.com/GeoStat-Framework/GSTools/commit/25b164722ac6744ebc7e03f3c0bf1c30be1eba89)
352+
- the `variogram_normed` method was removed from the `CovModel` class due to redundance [commit 25b1647](https://github.com/GeoStat-Framework/GSTools/commit/25b164722ac6744ebc7e03f3c0bf1c30be1eba89)
325353
- the position vector of 1D fields does not have to be provided in a list-like object with length 1 [commit a6f5be8](https://github.com/GeoStat-Framework/GSTools/commit/a6f5be8bfd2db1f002e7889ecb8e9a037ea08886)
326354

327355
### Bugfixes
@@ -353,7 +381,7 @@ See: [#197](https://github.com/GeoStat-Framework/GSTools/issues/197)
353381

354382
### Changes
355383
- release is not downwards compatible with release v0.4.0
356-
- SRF creation has been adapted for the CovModel
384+
- SRF creation has been adapted for the `CovModel`
357385
- a tuple `pos` is now used instead of `x`, `y`, and `z` for the axes
358386
- renamed `estimate_unstructured` and `estimate_structured` to `vario_estimate_unstructured` and `vario_estimate_structured` for less ambiguity
359387

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ import cartopy.crs as ccrs
147147
import gstools as gs
148148
# define a structured field by latitude and longitude
149149
lat = lon = range(-80, 81)
150-
model = gs.Gaussian(latlon=True, len_scale=777, rescale=gs.EARTH_RADIUS)
150+
model = gs.Gaussian(latlon=True, len_scale=777, geo_scale=gs.KM_SCALE)
151151
srf = gs.SRF(model, seed=12345)
152152
field = srf.structured((lat, lon))
153153
# Orthographic plotting with cartopy

docs/source/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ This works perfectly well with `cartopy <https://scitools.org.uk/cartopy/docs/la
200200
import gstools as gs
201201
# define a structured field by latitude and longitude
202202
lat = lon = range(-80, 81)
203-
model = gs.Gaussian(latlon=True, len_scale=777, rescale=gs.EARTH_RADIUS)
203+
model = gs.Gaussian(latlon=True, len_scale=777, geo_scale=gs.KM_SCALE)
204204
srf = gs.SRF(model, seed=12345)
205205
field = srf.structured((lat, lon))
206206
# Orthographic plotting with cartopy

examples/03_variogram/06_auto_bin_latlon.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@
4444
# Since the overall range of these meteo-stations is too low, we can use the
4545
# data-variance as additional information during the fit of the variogram.
4646

47-
emp_v = gs.vario_estimate(pos, field, latlon=True)
48-
sph = gs.Spherical(latlon=True, rescale=gs.EARTH_RADIUS)
47+
emp_v = gs.vario_estimate(pos, field, latlon=True, geo_scale=gs.KM_SCALE)
48+
sph = gs.Spherical(latlon=True, geo_scale=gs.KM_SCALE)
4949
sph.fit_variogram(*emp_v, sill=np.var(field))
50-
ax = sph.plot(x_max=2 * np.max(emp_v[0]))
50+
ax = sph.plot("vario_yadrenko", x_max=2 * np.max(emp_v[0]))
5151
ax.scatter(*emp_v, label="Empirical variogram")
5252
ax.legend()
5353
print(sph)

examples/08_geo_coordinates/00_field_generation.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,19 @@
88
First we setup a model, with ``latlon=True``, to get the associated
99
Yadrenko model.
1010
11-
In addition, we will use the earth radius provided by :any:`EARTH_RADIUS`,
12-
to have a meaningful length scale in km.
11+
In addition, we will use a kilometer scale provided by :any:`KM_SCALE`
12+
as ``geo_scale`` to have a meaningful length scale in km.
13+
By default the length scale would be given in radians (:any:`RADIAN_SCALE`).
14+
A third option is a length scale in degrees (:any:`DEGREE_SCALE`).
1315
1416
To generate the field, we simply pass ``(lat, lon)`` as the position tuple
1517
to the :any:`SRF` class.
1618
"""
19+
import numpy as np
20+
1721
import gstools as gs
1822

19-
model = gs.Gaussian(latlon=True, var=1, len_scale=777, rescale=gs.EARTH_RADIUS)
23+
model = gs.Gaussian(latlon=True, len_scale=777, geo_scale=gs.KM_SCALE)
2024

2125
lat = lon = range(-80, 81)
2226
srf = gs.SRF(model, seed=1234)
@@ -32,7 +36,7 @@
3236
#
3337
# As we will see, everthing went well... phew!
3438

35-
bin_edges = [0.01 * i for i in range(30)]
39+
bin_edges = np.linspace(0, 777 * 3, 30)
3640
bin_center, emp_vario = gs.vario_estimate(
3741
(lat, lon),
3842
field,
@@ -41,11 +45,12 @@
4145
mesh_type="structured",
4246
sampling_size=2000,
4347
sampling_seed=12345,
48+
geo_scale=gs.KM_SCALE,
4449
)
4550

46-
ax = model.plot("vario_yadrenko", x_max=0.3)
51+
ax = model.plot("vario_yadrenko", x_max=max(bin_center))
4752
model.fit_variogram(bin_center, emp_vario, nugget=False)
48-
model.plot("vario_yadrenko", ax=ax, label="fitted", x_max=0.3)
53+
model.plot("vario_yadrenko", ax=ax, label="fitted", x_max=max(bin_center))
4954
ax.scatter(bin_center, emp_vario, color="k")
5055
print(model)
5156

examples/08_geo_coordinates/01_dwd_krige.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,17 @@ def get_dwd_temperature(date="2020-06-09 12:00:00"):
7676

7777
###############################################################################
7878
# First we will estimate the variogram of our temperature data.
79-
# As the maximal bin distance we choose 8 degrees, which corresponds to a
80-
# chordal length of about 900 km.
79+
# As the maximal bin distance we choose 900 km.
8180

82-
bins = gs.standard_bins((lat, lon), max_dist=np.deg2rad(8), latlon=True)
83-
bin_c, vario = gs.vario_estimate((lat, lon), temp, bins, latlon=True)
81+
bin_center, vario = gs.vario_estimate(
82+
(lat, lon), temp, latlon=True, geo_scale=gs.KM_SCALE, max_dist=900
83+
)
8484

8585
###############################################################################
8686
# Now we can use this estimated variogram to fit a model to it.
8787
# Here we will use a :any:`Spherical` model. We select the ``latlon`` option
8888
# to use the `Yadrenko` variant of the model to gain a valid model for lat-lon
89-
# coordinates and we rescale it to the earth-radius. Otherwise the length
89+
# coordinates and we set the ``geo_scale`` to the earth-radius. Otherwise the length
9090
# scale would be given in radians representing the great-circle distance.
9191
#
9292
# We deselect the nugget from fitting and plot the result afterwards.
@@ -97,10 +97,10 @@ def get_dwd_temperature(date="2020-06-09 12:00:00"):
9797
# still holds the ordinary routine that is not respecting the great-circle
9898
# distance.
9999

100-
model = gs.Spherical(latlon=True, rescale=gs.EARTH_RADIUS)
101-
model.fit_variogram(bin_c, vario, nugget=False)
102-
ax = model.plot("vario_yadrenko", x_max=bins[-1])
103-
ax.scatter(bin_c, vario)
100+
model = gs.Spherical(latlon=True, geo_scale=gs.KM_SCALE)
101+
model.fit_variogram(bin_center, vario, nugget=False)
102+
ax = model.plot("vario_yadrenko", x_max=max(bin_center))
103+
ax.scatter(bin_center, vario)
104104
print(model)
105105

106106
###############################################################################

examples/08_geo_coordinates/README.rst

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,35 +22,36 @@ in your desired model (see :any:`CovModel`):
2222
By doing so, the model will use the associated `Yadrenko` model on a sphere
2323
(see `here <https://onlinelibrary.wiley.com/doi/abs/10.1002/sta4.84>`_).
2424
The `len_scale` is given in radians to scale the arc-length.
25-
In order to have a more meaningful length scale, one can use the ``rescale``
25+
In order to have a more meaningful length scale, one can use the ``geo_scale``
2626
argument:
2727

2828
.. code-block:: python
2929
3030
import gstools as gs
3131
32-
model = gs.Gaussian(latlon=True, var=2, len_scale=500, rescale=gs.EARTH_RADIUS)
32+
model = gs.Gaussian(latlon=True, var=2, len_scale=500, geo_scale=gs.KM_SCALE)
3333
3434
Then ``len_scale`` can be interpreted as given in km.
3535

3636
A `Yadrenko` model :math:`C` is derived from a valid
3737
isotropic covariance model in 3D :math:`C_{3D}` by the following relation:
3838

3939
.. math::
40-
C(\zeta)=C_{3D}\left(2 \cdot \sin\left(\frac{\zeta}{2}\right)\right)
40+
C(\zeta)=C_{3D}\left(2r \cdot \sin\left(\frac{\zeta}{2r}\right)\right)
4141
4242
Where :math:`\zeta` is the
43-
`great-circle distance <https://en.wikipedia.org/wiki/Great-circle_distance>`_.
43+
`great-circle distance <https://en.wikipedia.org/wiki/Great-circle_distance>`_
44+
and :math:`r` is the ``geo_scale``.
4445

4546
.. note::
4647

4748
``lat`` and ``lon`` are given in degree, whereas the great-circle distance
48-
:math:`zeta` is given in radians.
49+
:math:`zeta` is given in units of the ``geo_scale``.
4950

50-
Note, that :math:`2 \cdot \sin(\frac{\zeta}{2})` is the
51+
Note, that :math:`2r \cdot \sin(\frac{\zeta}{2r})` is the
5152
`chordal distance <https://en.wikipedia.org/wiki/Chord_(geometry)>`_
52-
of two points on a sphere, which means we simply think of the earth surface
53-
as a sphere, that is cut out of the surrounding three dimensional space,
53+
of two points on a sphere with radius :math:`r`, which means we simply think of the
54+
earth surface as a sphere, that is cut out of the surrounding three dimensional space,
5455
when using the `Yadrenko` model.
5556

5657
.. note::

examples/09_spatio_temporal/01_precip_1d.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@
2626
# half daily timesteps over three months
2727
t = np.arange(0.0, 90.0, 0.5)
2828

29-
# total spatio-temporal dimension
30-
st_dim = 1 + 1
3129
# space-time anisotropy ratio given in units d / km
3230
st_anis = 0.4
3331

3432
# an exponential variogram with a corr. lengths of 2d and 5km
35-
model = gs.Exponential(dim=st_dim, var=1.0, len_scale=5.0, anis=st_anis)
33+
model = gs.Exponential(
34+
temporal=True, spatial_dim=1, var=1, len_scale=5, anis=st_anis
35+
)
3636
# create a spatial random field instance
3737
srf = gs.SRF(model, seed=seed)
3838

examples/09_spatio_temporal/02_precip_2d.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@
2727
# half daily timesteps over three months
2828
t = np.arange(0.0, 90.0, 0.5)
2929

30-
# total spatio-temporal dimension
31-
st_dim = 2 + 1
3230
# space-time anisotropy ratio given in units d / km
3331
st_anis = 0.4
3432

3533
# an exponential variogram with a corr. lengths of 5km, 5km, and 2d
36-
model = gs.Exponential(dim=st_dim, var=1.0, len_scale=5.0, anis=st_anis)
34+
model = gs.Exponential(
35+
temporal=True, spatial_dim=2, var=1, len_scale=5, anis=st_anis
36+
)
3737
# create a spatial random field instance
3838
srf = gs.SRF(model, seed=seed)
3939

0 commit comments

Comments
 (0)