Skip to content

Commit

Permalink
Merge pull request #13 from NHFLO/bodemlagen_pwn_2024
Browse files Browse the repository at this point in the history
Bodemlagen pwn 2024
  • Loading branch information
bdestombe authored Dec 27, 2024
2 parents 03a2760 + d784cb5 commit 7d9ff6f
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 12 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
scratch
.DS_Store

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down Expand Up @@ -132,6 +133,6 @@ dmypy.json
# Pyre type checker
.pyre/


bin/
*.code-workspace
**/model_ws
22 changes: 11 additions & 11 deletions src/nhflotools/pwnlayers/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def read_pwn_data2(
ds_mask_transition : xarray Dataset
mask dataset. True in transition zone.
"""
modelgrid = nlmod.dims.grid.modelgrid_from_ds(ds)
modelgrid = nlmod.dims.grid.modelgrid_from_ds(ds, rotated=False)
ix = GridIntersect(modelgrid, method="vertex")

ds_out = xr.Dataset(
Expand Down Expand Up @@ -163,7 +163,7 @@ def read_pwn_data2(
return ds_out


@cache.cache_netcdf(coords_2d=True)
@cache.cache_netcdf(datavars=["top"], coords_2d=True)
def _read_bergen_basis_aquitards(
ds,
pathname=None,
Expand Down Expand Up @@ -271,7 +271,7 @@ def _read_bergen_basis_aquitards(
return ds_out


@cache.cache_netcdf(coords_2d=True)
@cache.cache_netcdf(datavars=["top"], coords_2d=True)
def _read_bergen_c_aquitards(ds, pathname, length_transition=100.0, ix=None):
"""Read vertical resistance of layers.
Expand Down Expand Up @@ -313,7 +313,7 @@ def _read_bergen_c_aquitards(ds, pathname, length_transition=100.0, ix=None):
return ds_out


@cache.cache_netcdf(coords_2d=True)
@cache.cache_netcdf(datavars=["top"], coords_2d=True)
def _read_bergen_thickness_aquitards(
ds,
pathname=None,
Expand Down Expand Up @@ -419,7 +419,7 @@ def _read_bergen_thickness_aquitards(
return ds_out


@cache.cache_netcdf(coords_2d=True)
@cache.cache_netcdf(datavars=["top"], coords_2d=True)
def _read_top_of_aquitards(ds, pathname, length_transition=100.0, ix=None):
"""Read top of aquitards.
Expand Down Expand Up @@ -461,7 +461,7 @@ def _read_top_of_aquitards(ds, pathname, length_transition=100.0, ix=None):
return ds_out


@cache.cache_netcdf(coords_2d=True)
@cache.cache_netcdf(datavars=["top"], coords_2d=True)
def _read_thickness_of_aquitards(ds, pathname, length_transition=100.0, ix=None):
"""Read thickness of aquitards.
Expand Down Expand Up @@ -505,7 +505,7 @@ def _read_thickness_of_aquitards(ds, pathname, length_transition=100.0, ix=None)
return ds_out


@cache.cache_netcdf(coords_2d=True)
@cache.cache_netcdf(datavars=["top"], coords_2d=True)
def _read_kd_of_aquitards(ds, pathname, length_transition=100.0, ix=None):
"""Read kd of aquitards.
Expand Down Expand Up @@ -546,7 +546,7 @@ def _read_kd_of_aquitards(ds, pathname, length_transition=100.0, ix=None):
return ds_out


@cache.cache_netcdf(coords_2d=True)
@cache.cache_netcdf(datavars=["top"], coords_2d=True)
def _read_mask_of_aquifers(ds, pathname, length_transition=100.0, ix=None):
"""Read mask of aquifers.
Expand Down Expand Up @@ -593,7 +593,7 @@ def _read_mask_of_aquifers(ds, pathname, length_transition=100.0, ix=None):
return ds_out


@cache.cache_netcdf(coords_2d=True)
@cache.cache_netcdf(datavars=["top"], coords_2d=True)
def _read_layer_kh(ds, pathname, length_transition=100.0, ix=None):
"""Read hydraulic conductivity of layers.
Expand Down Expand Up @@ -636,7 +636,7 @@ def _read_layer_kh(ds, pathname, length_transition=100.0, ix=None):
return ds_out


@cache.cache_netcdf(coords_2d=True)
@cache.cache_netcdf(datavars=["top"], coords_2d=True)
def _read_kv_area(ds, pathname, length_transition=100.0, ix=None): # noqa: ARG001
"""Read vertical resistance of layers.
Expand Down Expand Up @@ -711,7 +711,7 @@ def _read_kv_area(ds, pathname, length_transition=100.0, ix=None): # noqa: ARG0
return ds_out


@cache.cache_netcdf(coords_2d=True)
@cache.cache_netcdf(datavars=["top"], coords_2d=True)
def _read_topsysteem(ds, pathname):
"""Read topsysteem.
Expand Down
Empty file.
114 changes: 114 additions & 0 deletions src/nhflotools/pwnlayers2/layers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
"""Module containing functions to retrieve PWN bodemlagen."""

import logging
from pathlib import Path

import geopandas as gpd
import numpy as np
import pykrige.ok
import xarray as xr
from flopy.discretization.vertexgrid import VertexGrid
from flopy.utils.gridintersect import GridIntersect
from nlmod.dims.grid import modelgrid_from_ds
from shapely.ops import unary_union

logger = logging.getLogger(__name__)


def get_pwn_aquitard_data(ds: xr.Dataset, ix: GridIntersect, modelgrid: VertexGrid, data_dir: Path, transition_length: float) -> dict:
"""
Interpolate the thickness of the aquitard layers and the top of the aquitard layers using Kriging.
The thickness of the aquitard layers is interpolated using the points in the file
`dikte_aquitard/D{layer_name}/D{layer_name}_interpolation_points.geojson`.
The top of the aquitard layers is interpolated using the points in the file
`top_aquitard/T{layer_name}/T{layer_name}_interpolation_points.geojson`.
The mask of the aquitard layers is defined in the file
`dikte_aquitard/D{layer_name}/D{layer_name}_mask_combined.geojson`.
Parameters
----------
ds : xr.Dataset
The model dataset that contains the vertex grid information.
ix : flopy.utils.GridIntersect
The index of the model grid.
modelgrid : flopy.discretization.VertexGrid
The model grid.
data_dir : Path
The directory containing the data. Contains folders `dikte_aquitard` and `top_aquitard`.
transition_length : float
The length of the transition zone in meters.
Returns
-------
dict
A dictionary containing the interpolated values of the aquitard layers.
"""
verbose = logger.level <= logging.DEBUG

if ix is None and modelgrid is None and ds is not None:
modelgrid = modelgrid_from_ds(ds)

if ix is None and modelgrid is not None:
ix = GridIntersect(modelgrid, method="vertex")

ncell = len(ix.mfgrid.cell2d)
layer_names = ["S11", "S12", "S13", "S21", "S22", "S31", "S32"]
data = {}

for name in layer_names:
# Compute where the layer is _not_ present
logger.info("Interpolating aquitard layer %s data and its transition zone", name)
fp_mask = data_dir / "dikte_aquitard" / f"D{name}" / f"D{name}_mask_combined.geojson"
gdf_mask = gpd.read_file(fp_mask)

multipolygon = unary_union(gdf_mask.geometry)
ids = ix.intersect(multipolygon, contains_centroid=False, min_area_fraction=0.5).cellids.astype(int)
data[f"{name}_mask"] = np.zeros(ncell, dtype=bool)
data[f"{name}_mask"][ids] = True

# Compute where the layer transitions to REGIS
multipolygon_transition = multipolygon.buffer(transition_length).difference(multipolygon)
ids_trans = ix.intersect(
multipolygon_transition, contains_centroid=False, min_area_fraction=0.5
).cellids.astype(int)
data[f"{name}_transition"] = np.zeros(ncell, dtype=bool)
data[f"{name}_transition"][ids_trans] = True

# Interpolate thickness points using Kriging
fp_pts = data_dir / "dikte_aquitard" / f"D{name}" / f"D{name}_interpolation_points.geojson"
gdf_pts = gpd.read_file(fp_pts)
ok = pykrige.ok.OrdinaryKriging(
gdf_pts.geometry.x.values,
gdf_pts.geometry.y.values,
gdf_pts.value.values,
variogram_model="linear",
verbose=verbose,
enable_plotting=False,
)
xq = ix.mfgrid.xcellcenters[~data[f"{name}_mask"]]
yq = ix.mfgrid.ycellcenters[~data[f"{name}_mask"]]
kriging_result = ok.execute("points", xq, yq)
data[f"D{name}_value"] = np.zeros(ncell)
data[f"D{name}_value"][~data[f"{name}_mask"]] = kriging_result[0]
data[f"D{name}_value_unc"] = np.zeros(ncell)
data[f"D{name}_value_unc"][~data[f"{name}_mask"]] = kriging_result[1]

# Interpolate top aquitard points using Kriging
fp_pts = data_dir / "top_aquitard" / f"T{name}" / f"T{name}_interpolation_points.geojson"
gdf_pts = gpd.read_file(fp_pts)
ok = pykrige.ok.OrdinaryKriging(
gdf_pts.geometry.x.values,
gdf_pts.geometry.y.values,
gdf_pts.value.values,
variogram_model="linear",
verbose=verbose,
enable_plotting=False,
)
kriging_result = ok.execute("points", xq, yq)
data[f"T{name}_value"] = np.zeros(ncell)
data[f"T{name}_value"][~data[f"{name}_mask"]] = kriging_result[0]
data[f"T{name}_value_unc"] = np.zeros(ncell)
data[f"T{name}_value_unc"][~data[f"{name}_mask"]] = kriging_result[1]

return data

0 comments on commit 7d9ff6f

Please sign in to comment.