Source code for mhm_tools.pre.create_id_gauges

"""Create mRM idgauges files from gauge coordinates.

The module places one or more gauge IDs on a target grid, optionally snapping
the location to the maximum flow-accumulation cell near the provided
coordinates, and writes the result as an ASCII idgauges map.

Authors
-------
- Simon Lüdke
"""

import logging
from pathlib import Path

import xarray as xr

from mhm_tools.common.constants import NO_DATA
from mhm_tools.common.file_handler import get_xarray_ds_from_file, write_xarray_to_ascii
from mhm_tools.common.logger import ErrorLogger, log_arguments
from mhm_tools.common.xarray_utils import get_coord_key, get_single_data_var

logger = logging.getLogger(__name__)


[docs] def write_gauge_id( ds, id, lat, lon, facc_file=None, data_var=None ): # , threshold=None, facc_value=None ): """Set gauge_id in ds.""" if facc_file: with get_xarray_ds_from_file(file_path=facc_file) as ds_facc: lon_key = get_coord_key(ds_facc, lon=True) lat_key = get_coord_key(ds_facc, lat=True) if "uparea_grid" in ds_facc: var = ds_facc["uparea_grid"] elif "facc" in ds_facc: var = ds_facc["facc"] else: msg = "Neither uparea_grid nor facc in dataset datavars." with ErrorLogger(logger): raise ValueError(msg) var_max = var.where(var == var.max(), drop=True) # Extract x and y coordinate values y_coord = var_max[lat_key].values[0] x_coord = var_max[lon_key].values[0] logger.info(f"Provided coords {lon} / {lat}") logger.info(f"Max facc coords {x_coord} / {y_coord}") lat = y_coord lon = x_coord lon_key = get_coord_key(ds, lon=True) lat_key = get_coord_key(ds, lat=True) if isinstance(ds, xr.Dataset): if data_var is None: data_var = get_single_data_var(ds) if data_var is None: msg = "Dataset has multiple data_vars which is incompatible." with ErrorLogger(logger): raise ValueError(msg) ds[data_var].loc[ ds.sel({lat_key: lat, lon_key: lon}, method="nearest").coords ] = id else: ds.loc[ds.sel({lat_key: lat, lon_key: lon}, method="nearest").coords] = id if data_var is None: data_var = ds.name if ds.name else "data" ds = ds.to_dataset(name=data_var) return ds.astype({data_var: int})
[docs] @log_arguments() def create_id_gauges( id, lon, lat, file, out_path, file_is_idgauges=False, facc_file=None ): """Create id gauges file.""" file = Path(file) out_path = Path(out_path) with get_xarray_ds_from_file(file) as ds: data_name = next(iter(ds.keys())) # if "nodata_value" in ds[data_name].attrs: # missing_value = ds[data_name].attrs["nodata_value"] # else: # missing_value = ds[data_name].encoding.get("_FillValue", int(NO_DATA)) missing_value = int(NO_DATA) logger.info(f"Missing values is {missing_value}") if not file_is_idgauges: for var_name in ds.data_vars: # Set every element of this variable to missing_value: ds[var_name].values[:] = missing_value contains_value = False else: contains_value = bool(ds[data_name] == float(id)).any() if not contains_value: ds_with_id = write_gauge_id( ds, id, lat, lon, facc_file, data_var=data_name ) # , threshold, facc_value) write_xarray_to_ascii(ds_with_id, out_path, data_name) # , fmt="%.0f") else: logger.info("Id {id} is already in {file}.")