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

Remove delr and delc from ds #346

Merged
merged 4 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 5 additions & 9 deletions nlmod/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -692,12 +692,6 @@ def ds_contains(
datavars.append("yv")
datavars.append("icvert")

# TODO: temporary fix until delr/delc are completely removed
if "delr" in datavars:
datavars.remove("delr")
if "delc" in datavars:
datavars.remove("delc")

if "angrot" in ds.attrs:
attrs.append("angrot")

Expand All @@ -721,14 +715,16 @@ def ds_contains(
if "time" not in ds.coords:
msg = "time not in dataset. Run nlmod.time.set_ds_time() first."
raise ValueError(msg)

# Check if time-coord is complete
time_attrs_required = ["start", "time_units"]

for t_attr in time_attrs_required:
if t_attr not in ds["time"].attrs:
msg = f"{t_attr} not in dataset['time'].attrs. " +\
"Run nlmod.time.set_ds_time() to set time."
msg = (
f"{t_attr} not in dataset['time'].attrs. "
+ "Run nlmod.time.set_ds_time() to set time."
)
raise ValueError(msg)

# User-unfriendly error messages
Expand Down
7 changes: 0 additions & 7 deletions nlmod/dims/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,6 @@ def to_model_ds(
)
elif isinstance(delr, np.ndarray) and isinstance(delc, np.ndarray):
ds["area"] = ("y", "x"), np.outer(delc, delr)
ds["delr"] = ("x"), delr
ds["delc"] = ("y"), delc
else:
raise TypeError("unexpected type for delr and/or delc")

Expand Down Expand Up @@ -366,11 +364,6 @@ def _get_structured_grid_ds(
coords=coords,
attrs=attrs,
)
# set delr and delc
delr = np.diff(xedges)
ds["delr"] = ("x"), delr
delc = -np.diff(yedges)
ds["delc"] = ("y"), delc

if crs is not None:
ds.rio.set_crs(crs)
Expand Down
42 changes: 8 additions & 34 deletions nlmod/dims/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
get_affine_mod_to_world,
get_affine_world_to_mod,
structured_da_to_ds,
get_delr,
get_delc,
)

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -211,17 +213,9 @@ def modelgrid_from_ds(ds, rotated=True, nlay=None, top=None, botm=None, **kwargs
raise TypeError(
f"extent should be a list, tuple or numpy array, not {type(ds.extent)}"
)
if "delc" in ds:
delc = ds["delc"].values
else:
raise KeyError("delc not in dataset")
if "delr" in ds:
delr = ds["delr"].values
else:
raise KeyError("delr not in dataset")
modelgrid = StructuredGrid(
delc=delc,
delr=delr,
delc=get_delc(ds),
delr=get_delr(ds),
**kwargs,
)
elif ds.gridtype == "vertex":
Expand Down Expand Up @@ -455,8 +449,8 @@ def refine(
gwf,
nrow=len(ds.y),
ncol=len(ds.x),
delr=ds.delr,
delc=ds.delc,
delr=get_delr(ds),
delc=get_delc(ds),
xorigin=ds.extent[0],
yorigin=ds.extent[2],
)
Expand Down Expand Up @@ -1940,28 +1934,8 @@ def polygons_from_model_ds(model_ds):
"""

if model_ds.gridtype == "structured":
# TODO: update with new delr/delc calculation
# check if coordinates are consistent with delr/delc values
delr_x = np.unique(model_ds.x.values[1:] - model_ds.x.values[:-1])
delc_y = np.unique(model_ds.y.values[:-1] - model_ds.y.values[1:])

delr = np.unique(model_ds.delr)
if len(delr) > 1:
raise ValueError("delr is variable")
else:
delr = delr.item()

delc = np.unique(model_ds.delc)
if len(delc) > 1:
raise ValueError("delc is variable")
else:
delc = delc.item()

if not ((delr_x == delr) and (delc_y == delc)):
raise ValueError(
"delr and delc attributes of model_ds inconsistent "
"with x and y coordinates"
)
delr = get_delr(model_ds)
delc = get_delc(model_ds)

xmins = model_ds.x - (delr * 0.5)
xmaxs = model_ds.x + (delr * 0.5)
Expand Down
66 changes: 58 additions & 8 deletions nlmod/dims/resample.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,58 @@ def get_xy_mid_structured(extent, delr, delc, descending_y=True):
raise TypeError("unexpected type for delr and/or delc")


def get_delr(ds):
"""
Get the distance along rows (delr) from the x-coordinate of a structured model
dataset.

Parameters
----------
ds : xarray.Dataset
A model dataset containing an x-coordinate and an attribute 'extent'.

Returns
-------
delr : np.ndarray
The cell-size along rows (of length ncol).

"""
assert ds.gridtype == "structured"
x = (ds.x - ds.extent[0]).values
delr = _get_delta_along_axis(x)
return delr


def get_delc(ds):
"""
Get the distance along columns (delc) from the y-coordinate of a structured model
dataset.

Parameters
----------
ds : xarray.Dataset
A model dataset containing an y-coordinate and an attribute 'extent'.

Returns
-------
delc : np.ndarray
The cell-size along columns (of length nrow).

"""
assert ds.gridtype == "structured"
y = (ds.extent[3] - ds.y).values
delc = _get_delta_along_axis(y)
return delc


def _get_delta_along_axis(x):
"""Internal method to determine delr or delc from x or y relative to xmin or ymax"""
delr = [x[0] * 2]
for xi in x[1:]:
delr.append((xi - np.sum(delr)) * 2)
return np.array(delr)


def ds_to_structured_grid(
ds_in,
extent,
Expand Down Expand Up @@ -163,17 +215,11 @@ def ds_to_structured_grid(
x=x, y=y, method=method, kwargs={"fill_value": "extrapolate"}
)
ds_out.attrs = attrs
# ds_out = ds_out.expand_dims({"ncol": len(x), "nrow": len(y)})
ds_out["delr"] = ("ncol",), delr
ds_out["delc"] = ("nrow",), delc
return ds_out

ds_out = xr.Dataset(coords={"y": y, "x": x, "layer": ds_in.layer.data}, attrs=attrs)
for var in ds_in.data_vars:
ds_out[var] = structured_da_to_ds(ds_in[var], ds_out, method=method)
# ds_out = ds_out.expand_dims({"ncol": len(x), "nrow": len(y)})
ds_out["delr"] = ("x",), delr
ds_out["delc"] = ("y",), delc
return ds_out


Expand Down Expand Up @@ -658,9 +704,13 @@ def get_affine(ds, sx=None, sy=None):
"""Get the affine-transformation, from pixel to real-world coordinates."""
attrs = _get_attrs(ds)
if sx is None:
sx = attrs["delr"]
sx = get_delr(ds)
assert len(np.unique(sx)) == 1, "Affine-transformation needs a constant delr"
sx = sx[0]
if sy is None:
sy = -attrs["delc"]
sy = get_delc(ds)
assert len(np.unique(sy)) == 1, "Affine-transformation needs a constant delc"
sy = sy[0]

if "angrot" in attrs:
xorigin = attrs["xorigin"]
Expand Down
7 changes: 1 addition & 6 deletions nlmod/gis.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,6 @@ def struc_da_to_gdf(model_ds, data_variables, polygons=None, dealing_with_time="
raise ValueError(
f"expected dimensions ('layer', 'y', 'x'), got {da.dims}"
)
# TODO: remove when delr/delc are removed as data vars
elif da_name in ["delr", "delc"]:
continue
else:
raise NotImplementedError(
f"expected two or three dimensions got {no_dims} for data variable {da_name}"
Expand Down Expand Up @@ -289,9 +286,7 @@ def ds_to_vector_file(
if model_ds.gridtype == "structured":
gdf = struc_da_to_gdf(model_ds, (da_name,), polygons=polygons)
elif model_ds.gridtype == "vertex":
# TODO: remove when delr/dec are removed
if da_name not in ["delr", "delc"]:
gdf = vertex_da_to_gdf(model_ds, (da_name,), polygons=polygons)
gdf = vertex_da_to_gdf(model_ds, (da_name,), polygons=polygons)
if driver == "GPKG":
gdf.to_file(fname_gpkg, layer=da_name, driver=driver)
else:
Expand Down
15 changes: 5 additions & 10 deletions nlmod/gwf/gwf.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
import warnings

import flopy
import numpy as np
import xarray as xr

from ..dims import grid
from ..dims.resample import get_delr, get_delc
from ..dims.layers import get_idomain
from ..sim import ims, sim, tdis
from ..util import _get_value_from_ds_attr, _get_value_from_ds_datavar
Expand Down Expand Up @@ -109,11 +109,6 @@ def _dis(ds, model, length_units="METERS", pname="dis", **kwargs):
return disv(ds, model, length_units=length_units)

# check attributes
for att in ["delr", "delc"]:
if att in ds.attrs:
if isinstance(ds.attrs[att], np.float32):
ds.attrs[att] = float(ds.attrs[att])

if "angrot" in ds.attrs and ds.attrs["angrot"] != 0.0:
xorigin = ds.attrs["xorigin"]
yorigin = ds.attrs["yorigin"]
Expand All @@ -135,8 +130,8 @@ def _dis(ds, model, length_units="METERS", pname="dis", **kwargs):
nlay=ds.sizes["layer"],
nrow=ds.sizes["y"],
ncol=ds.sizes["x"],
delr=ds["delr"].values if "delr" in ds else ds.delr,
delc=ds["delc"].values if "delc" in ds else ds.delc,
delr=get_delr(ds),
delc=get_delc(ds),
top=ds["top"].data,
botm=ds["botm"].data,
idomain=idomain,
Expand All @@ -154,8 +149,8 @@ def _dis(ds, model, length_units="METERS", pname="dis", **kwargs):
nlay=ds.sizes["layer"],
nrow=ds.sizes["y"],
ncol=ds.sizes["x"],
delr=ds["delr"].values if "delr" in ds else ds.delr,
delc=ds["delc"].values if "delc" in ds else ds.delc,
delr=get_delr(ds),
delc=get_delc(ds),
top=ds["top"].data,
botm=ds["botm"].data,
idomain=idomain,
Expand Down
8 changes: 6 additions & 2 deletions nlmod/gwf/surface_water.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from ..dims.grid import gdf_to_grid
from ..dims.layers import get_idomain
from ..dims.resample import get_extent_polygon, extent_to_polygon
from ..dims.resample import get_extent_polygon, extent_to_polygon, get_delr, get_delc
from ..read import bgt, waterboard
from ..cache import cache_pickle

Expand Down Expand Up @@ -147,7 +147,11 @@ def agg_de_lange(group, cid, ds, c1=0.0, c0=1.0, N=1e-3, crad_positive=True):
# correction if group contains multiple shapes
# but covers whole cell
if group.area.sum() == A:
li = A / np.max([ds.delr, ds.delc])
delr = get_delr(ds)
assert len(np.unique(delr)) == 1, "Variable grid size is not yet supported"
delc = get_delc(ds)
assert len(np.unique(delc)) == 1, "Variable grid size is not yet supported"
li = A / np.max([delr[0], delc[0]])

# width
B = group.area.sum(skipna=True) / li
Expand Down
6 changes: 2 additions & 4 deletions nlmod/read/rws.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ def get_gdf_surface_water(ds):
return gdf_swater


# TODO: temporary fix until delr/delc are removed completely
@cache.cache_netcdf(coords_3d=True, datavars=["delr", "delc"])
@cache.cache_netcdf(coords_3d=True)
def get_surface_water(ds, da_basename):
"""create 3 data-arrays from the shapefile with surface water:

Expand Down Expand Up @@ -92,8 +91,7 @@ def get_surface_water(ds, da_basename):
return ds_out


# TODO: temporary fix until delr/delc are removed completely
@cache.cache_netcdf(coords_2d=True, datavars=["delc", "delr"])
@cache.cache_netcdf(coords_2d=True)
def get_northsea(ds, da_name="northsea"):
"""Get Dataset which is 1 at the northsea and 0 everywhere else. Sea is
defined by rws surface water shapefile.
Expand Down
Loading