Skip to content

Commit

Permalink
Merge pull request #245 from GeoStat-Framework/gstools_latlon_fix
Browse files Browse the repository at this point in the history
GSTools: support latlon models for geographic coordinates
  • Loading branch information
MuellerSeb authored Aug 18, 2022
2 parents abbbd10 + bfead32 commit 7494ca1
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 12 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ sklearn = ["scikit-learn>=0.19"]
test = [
"pytest-cov>=3",
"scikit-learn>=0.19",
# "gstools>=1.3,<2",
"gstools>=1.4,<2",
]

[project.urls]
Expand Down
36 changes: 36 additions & 0 deletions src/pykrige/compat_gstools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# coding: utf-8
# pylint: disable= invalid-name, unused-import
"""For GSTools compatibility."""

# gstools
try:
import gstools as gs

GSTOOLS_INSTALLED = True
GSTOOLS_VERSION = list(map(int, gs.__version__.split(".")[:2]))
except ImportError:
gs = None
GSTOOLS_INSTALLED = False
GSTOOLS_VERSION = None


class GSToolsException(Exception):
"""Exception for GSTools."""


def validate_gstools(model):
"""Validate presence of GSTools."""
if not GSTOOLS_INSTALLED:
raise GSToolsException(
"GSTools needs to be installed in order to use their CovModel class."
)
if not isinstance(model, gs.CovModel):
raise GSToolsException(
"GSTools: given variogram model is not a CovModel instance."
)
if GSTOOLS_VERSION < [1, 3]:
raise GSToolsException("GSTools: need at least GSTools v1.3.")
if model.latlon and GSTOOLS_VERSION < [1, 4]:
raise GSToolsException(
"GSTools: latlon models in PyKrige are only supported from GSTools v1.4."
)
24 changes: 19 additions & 5 deletions src/pykrige/ok.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from scipy.spatial.distance import cdist

from . import core, variogram_models
from .compat_gstools import validate_gstools
from .core import (
P_INV,
_adjust_for_anisotropy,
Expand Down Expand Up @@ -217,12 +218,20 @@ def __init__(
raise ValueError("exact_values has to be boolean True or False")
self.exact_values = exact_values

self.coordinates_type = coordinates_type

# check if a GSTools covariance model is given
if hasattr(self.variogram_model, "pykrige_kwargs"):
# save the model in the class
self.model = self.variogram_model
if self.model.dim == 3:
validate_gstools(self.model)
if self.model.field_dim == 3:
raise ValueError("GSTools: model dim is not 1 or 2")
# check if coordinate types match
if self.model.latlon and (self.coordinates_type == "euclidean"):
raise ValueError(
"GSTools: latlon models require geographic coordinates"
)
self.variogram_model = "custom"
variogram_function = self.model.pykrige_vario
variogram_parameters = []
Expand Down Expand Up @@ -265,7 +274,7 @@ def __init__(

# adjust for anisotropy... only implemented for euclidean (rectangular)
# coordinates, as anisotropy is ambiguous for geographic coordinates...
if coordinates_type == "euclidean":
if self.coordinates_type == "euclidean":
self.XCENTER = (np.amax(self.X_ORIG) + np.amin(self.X_ORIG)) / 2.0
self.YCENTER = (np.amax(self.Y_ORIG) + np.amin(self.Y_ORIG)) / 2.0
self.anisotropy_scaling = anisotropy_scaling
Expand All @@ -278,7 +287,7 @@ def __init__(
[self.anisotropy_scaling],
[self.anisotropy_angle],
).T
elif coordinates_type == "geographic":
elif self.coordinates_type == "geographic":
# Leave everything as is in geographic case.
# May be open to discussion?
if anisotropy_scaling != 1.0:
Expand All @@ -298,7 +307,6 @@ def __init__(
"Only 'euclidean' and 'geographic' are valid "
"values for coordinates-keyword."
)
self.coordinates_type = coordinates_type

if self.verbose:
print("Initializing variogram model...")
Expand Down Expand Up @@ -422,8 +430,14 @@ def update_variogram_model(
if hasattr(self.variogram_model, "pykrige_kwargs"):
# save the model in the class
self.model = self.variogram_model
if self.model.dim == 3:
validate_gstools(self.model)
if self.model.field_dim == 3:
raise ValueError("GSTools: model dim is not 1 or 2")
# check if coordinate types match
if self.model.latlon and (self.coordinates_type == "euclidean"):
raise ValueError(
"GSTools: latlon models require geographic coordinates"
)
self.variogram_model = "custom"
variogram_function = self.model.pykrige_vario
variogram_parameters = []
Expand Down
7 changes: 5 additions & 2 deletions src/pykrige/ok3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from scipy.spatial.distance import cdist

from . import core, variogram_models
from .compat_gstools import validate_gstools
from .core import (
P_INV,
_adjust_for_anisotropy,
Expand Down Expand Up @@ -234,7 +235,8 @@ def __init__(
if hasattr(self.variogram_model, "pykrige_kwargs"):
# save the model in the class
self.model = self.variogram_model
if self.model.dim < 3:
validate_gstools(self.model)
if self.model.field_dim < 3:
raise ValueError("GSTools: model dim is not 3")
self.variogram_model = "custom"
variogram_function = self.model.pykrige_vario
Expand Down Expand Up @@ -430,7 +432,8 @@ def update_variogram_model(
if hasattr(self.variogram_model, "pykrige_kwargs"):
# save the model in the class
self.model = self.variogram_model
if self.model.dim < 3:
validate_gstools(self.model)
if self.model.field_dim < 3:
raise ValueError("GSTools: model dim is not 3")
self.variogram_model = "custom"
variogram_function = self.model.pykrige_vario
Expand Down
15 changes: 13 additions & 2 deletions src/pykrige/uk.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from scipy.spatial.distance import cdist

from . import core, variogram_models
from .compat_gstools import validate_gstools
from .core import (
P_INV,
_adjust_for_anisotropy,
Expand Down Expand Up @@ -267,8 +268,13 @@ def __init__(
if hasattr(self.variogram_model, "pykrige_kwargs"):
# save the model in the class
self.model = self.variogram_model
if self.model.dim == 3:
validate_gstools(self.model)
if self.model.field_dim == 3:
raise ValueError("GSTools: model dim is not 1 or 2")
if self.model.latlon:
raise ValueError(
"GSTools: latlon models not supported for universal kriging"
)
self.variogram_model = "custom"
variogram_function = self.model.pykrige_vario
variogram_parameters = []
Expand Down Expand Up @@ -673,8 +679,13 @@ def update_variogram_model(
if hasattr(self.variogram_model, "pykrige_kwargs"):
# save the model in the class
self.model = self.variogram_model
if self.model.dim == 3:
validate_gstools(self.model)
if self.model.field_dim == 3:
raise ValueError("GSTools: model dim is not 1 or 2")
if self.model.latlon:
raise ValueError(
"GSTools: latlon models not supported for universal kriging"
)
self.variogram_model = "custom"
variogram_function = self.model.pykrige_vario
variogram_parameters = []
Expand Down
7 changes: 5 additions & 2 deletions src/pykrige/uk3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from scipy.spatial.distance import cdist

from . import core, variogram_models
from .compat_gstools import validate_gstools
from .core import (
P_INV,
_adjust_for_anisotropy,
Expand Down Expand Up @@ -262,7 +263,8 @@ def __init__(
if hasattr(self.variogram_model, "pykrige_kwargs"):
# save the model in the class
self.model = self.variogram_model
if self.model.dim < 3:
validate_gstools(self.model)
if self.model.field_dim < 3:
raise ValueError("GSTools: model dim is not 3")
self.variogram_model = "custom"
variogram_function = self.model.pykrige_vario
Expand Down Expand Up @@ -515,7 +517,8 @@ def update_variogram_model(
if hasattr(self.variogram_model, "pykrige_kwargs"):
# save the model in the class
self.model = self.variogram_model
if self.model.dim < 3:
validate_gstools(self.model)
if self.model.field_dim < 3:
raise ValueError("GSTools: model dim is not 3")
self.variogram_model = "custom"
variogram_function = self.model.pykrige_vario
Expand Down

0 comments on commit 7494ca1

Please sign in to comment.