mhm-tools 0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mhm_tools/__init__.py +31 -0
- mhm_tools/_cli/_2d_map.py +119 -0
- mhm_tools/_cli/__init__.py +5 -0
- mhm_tools/_cli/__main__.py +6 -0
- mhm_tools/_cli/_bankfull.py +84 -0
- mhm_tools/_cli/_calculate_pet.py +94 -0
- mhm_tools/_cli/_create_catchment.py +456 -0
- mhm_tools/_cli/_create_header.py +103 -0
- mhm_tools/_cli/_create_idgauges.py +114 -0
- mhm_tools/_cli/_create_mhm_restart_file.py +294 -0
- mhm_tools/_cli/_create_mhm_restart_from_setup.py +452 -0
- mhm_tools/_cli/_create_subdomain_masks.py +94 -0
- mhm_tools/_cli/_crop_mhm_setup.py +263 -0
- mhm_tools/_cli/_difference.py +165 -0
- mhm_tools/_cli/_discharge_evaluation.py +239 -0
- mhm_tools/_cli/_file_converter.py +105 -0
- mhm_tools/_cli/_fill_nearest.py +80 -0
- mhm_tools/_cli/_gridded_data_evaluation.py +358 -0
- mhm_tools/_cli/_hydrograph.py +117 -0
- mhm_tools/_cli/_landcover_ascii_to_nc.py +119 -0
- mhm_tools/_cli/_latlon.py +180 -0
- mhm_tools/_cli/_link_folder_tree.py +71 -0
- mhm_tools/_cli/_long_term_mean.py +147 -0
- mhm_tools/_cli/_main.py +704 -0
- mhm_tools/_cli/_merge.py +71 -0
- mhm_tools/_cli/_mhm_run_overview.py +80 -0
- mhm_tools/_cli/_prepare_mhm_forcings.py +151 -0
- mhm_tools/_cli/_ratio.py +173 -0
- mhm_tools/_cli/_regrid.py +65 -0
- mhm_tools/_cli/_relative_difference.py +171 -0
- mhm_tools/_cli/_taylor_diagram.py +118 -0
- mhm_tools/_version.py +1 -0
- mhm_tools/common/__init__.py +74 -0
- mhm_tools/common/cli_utils.py +167 -0
- mhm_tools/common/constants.py +76 -0
- mhm_tools/common/esri_grid.py +402 -0
- mhm_tools/common/file_handler.py +1223 -0
- mhm_tools/common/logger.py +216 -0
- mhm_tools/common/metrics/__init__.py +7 -0
- mhm_tools/common/metrics/esp.py +30 -0
- mhm_tools/common/metrics/metrics_handler.py +164 -0
- mhm_tools/common/metrics/mspaef.py +36 -0
- mhm_tools/common/metrics/spaef.py +43 -0
- mhm_tools/common/metrics/tsm.py +160 -0
- mhm_tools/common/metrics/waspaef.py +51 -0
- mhm_tools/common/netcdf.py +420 -0
- mhm_tools/common/plotter.py +261 -0
- mhm_tools/common/provenance.py +51 -0
- mhm_tools/common/resolution_handler.py +187 -0
- mhm_tools/common/time_utils.py +285 -0
- mhm_tools/common/utils.py +571 -0
- mhm_tools/common/xarray_utils.py +542 -0
- mhm_tools/post/2d_map.py +59 -0
- mhm_tools/post/__init__.py +54 -0
- mhm_tools/post/bankfull.py +143 -0
- mhm_tools/post/difference.py +107 -0
- mhm_tools/post/discharge_evaluation.py +2158 -0
- mhm_tools/post/gridded_data_evaluation.py +2675 -0
- mhm_tools/post/hydrograph.py +1560 -0
- mhm_tools/post/long_term_mean.py +281 -0
- mhm_tools/post/mhm_run_overview.py +681 -0
- mhm_tools/post/ratio.py +95 -0
- mhm_tools/post/relative_difference.py +96 -0
- mhm_tools/post/taylor_diagram.py +139 -0
- mhm_tools/pre/__init__.py +80 -0
- mhm_tools/pre/catchment.py +2985 -0
- mhm_tools/pre/create_id_gauges.py +98 -0
- mhm_tools/pre/create_mhm_restart_file.py +1419 -0
- mhm_tools/pre/create_mhm_restart_from_setup.py +3005 -0
- mhm_tools/pre/crop_mhm_setup.py +722 -0
- mhm_tools/pre/fill_nearest.py +574 -0
- mhm_tools/pre/landcover_ascii_to_nc.py +360 -0
- mhm_tools/pre/latlon.py +276 -0
- mhm_tools/pre/link_folder_tree.py +51 -0
- mhm_tools/pre/merge.py +196 -0
- mhm_tools/pre/pet_calc.py +505 -0
- mhm_tools/pre/prepare_mhm_forcings.py +191 -0
- mhm_tools/pre/regrid.py +193 -0
- mhm_tools/pre/subdomain_masks.py +346 -0
- mhm_tools-0.2.dist-info/METADATA +99 -0
- mhm_tools-0.2.dist-info/RECORD +87 -0
- mhm_tools-0.2.dist-info/WHEEL +4 -0
- mhm_tools-0.2.dist-info/entry_points.txt +2 -0
- mhm_tools-0.2.dist-info/licenses/AUTHORS.md +20 -0
- mhm_tools-0.2.dist-info/licenses/COPYING +674 -0
- mhm_tools-0.2.dist-info/licenses/COPYING.LESSER +165 -0
- mhm_tools-0.2.dist-info/licenses/LICENSE.md +48 -0
mhm_tools/__init__.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Tools to pre- and post-process data for and from mHM.
|
|
2
|
+
|
|
3
|
+
.. toctree::
|
|
4
|
+
:hidden:
|
|
5
|
+
|
|
6
|
+
self
|
|
7
|
+
|
|
8
|
+
Subpackages
|
|
9
|
+
===========
|
|
10
|
+
|
|
11
|
+
Built-in processing and tool functions.
|
|
12
|
+
|
|
13
|
+
.. autosummary::
|
|
14
|
+
:toctree: api
|
|
15
|
+
:caption: Subpackages
|
|
16
|
+
|
|
17
|
+
common
|
|
18
|
+
post
|
|
19
|
+
pre
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
from ._version import __version__
|
|
24
|
+
except ModuleNotFoundError: # pragma: no cover
|
|
25
|
+
# package is not installed
|
|
26
|
+
__version__ = "not_available"
|
|
27
|
+
|
|
28
|
+
from . import common, post, pre
|
|
29
|
+
|
|
30
|
+
__all__ = ["__version__"]
|
|
31
|
+
__all__ += ["common", "post", "pre"]
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
Compute and plot a 2D map for a given NetCDF dataset.
|
|
4
|
+
|
|
5
|
+
This CLI reads a CF-compliant NetCDF file, extracts a specified variable, and
|
|
6
|
+
invokes mhm_tools.common.plotter.plot_map to generate and save a geo-aware
|
|
7
|
+
2D map plot with customizable labels, colormap, and spatial or data limits.
|
|
8
|
+
|
|
9
|
+
Authors
|
|
10
|
+
-------
|
|
11
|
+
- Jeisson Leal
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import argparse
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
import xarray as xr
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def str2float(value):
|
|
21
|
+
"""Convert a string to float, but let None remain None."""
|
|
22
|
+
if value is None or (isinstance(value, str) and value.lower() == "none"):
|
|
23
|
+
return None
|
|
24
|
+
try:
|
|
25
|
+
return float(value)
|
|
26
|
+
except (TypeError, ValueError) as err:
|
|
27
|
+
msg = f"{value!r} is not a valid float."
|
|
28
|
+
raise argparse.ArgumentTypeError(msg) from err
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def add_args(parser: argparse.ArgumentParser):
|
|
32
|
+
"""Add CLI arguments for the 2d_map subcommand."""
|
|
33
|
+
parser.description = (
|
|
34
|
+
"Compute and plot a 2D spatial map for a specified variable from a NetCDF file."
|
|
35
|
+
)
|
|
36
|
+
parser.epilog = (
|
|
37
|
+
"Example:\n"
|
|
38
|
+
"mhm-tools 2d_map \\\n"
|
|
39
|
+
"--input-file /path/to/data.nc \\\n"
|
|
40
|
+
"--var temperature \\\n"
|
|
41
|
+
"--colorbar-label 'Temp (°C)' \\\n"
|
|
42
|
+
"--title 'Surface Temperature' \\\n"
|
|
43
|
+
"--x-min -10 --x-max 30 --y-min 40 --y-max 70 \\\n"
|
|
44
|
+
"--cmap viridis --vmin -5 --vmax 5 \\\n"
|
|
45
|
+
"-o /out/dir --output-file_png map.png"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# required arguments
|
|
49
|
+
req = parser.add_argument_group("required arguments")
|
|
50
|
+
req.add_argument(
|
|
51
|
+
"--input-file", required=True, help="Path to the input NetCDF file"
|
|
52
|
+
)
|
|
53
|
+
req.add_argument(
|
|
54
|
+
"--var", required=True, help="Variable name in the NetCDF dataset to plot"
|
|
55
|
+
)
|
|
56
|
+
req.add_argument(
|
|
57
|
+
"-o",
|
|
58
|
+
"--output-dir",
|
|
59
|
+
required=True,
|
|
60
|
+
help="Directory where the output PNG will be saved",
|
|
61
|
+
)
|
|
62
|
+
req.add_argument(
|
|
63
|
+
"--output-file-png", required=True, help="Filename for the output PNG"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# optional arguments
|
|
67
|
+
optional = parser.add_argument_group("optional arguments")
|
|
68
|
+
optional.add_argument("--colorbar-label", default="", help="Label for the colorbar")
|
|
69
|
+
optional.add_argument("--title", default="", help="Title for the plot")
|
|
70
|
+
optional.add_argument(
|
|
71
|
+
"--x-min", type=str2float, default=None, help="Minimum longitude to display"
|
|
72
|
+
)
|
|
73
|
+
optional.add_argument(
|
|
74
|
+
"--x-max", type=str2float, default=None, help="Maximum longitude to display"
|
|
75
|
+
)
|
|
76
|
+
optional.add_argument(
|
|
77
|
+
"--y-min", type=str2float, default=None, help="Minimum latitude to display"
|
|
78
|
+
)
|
|
79
|
+
optional.add_argument(
|
|
80
|
+
"--y-max", type=str2float, default=None, help="Maximum latitude to display"
|
|
81
|
+
)
|
|
82
|
+
optional.add_argument(
|
|
83
|
+
"--cmap", default="RdBu_r", help="Matplotlib colormap name to use"
|
|
84
|
+
)
|
|
85
|
+
optional.add_argument(
|
|
86
|
+
"--vmin", type=str2float, default=None, help="Minimum data value for colormap"
|
|
87
|
+
)
|
|
88
|
+
optional.add_argument(
|
|
89
|
+
"--vmax", type=str2float, default=None, help="Maximum data value for colormap"
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def run(args: argparse.Namespace):
|
|
94
|
+
"""Entry point: read NetCDF, extract data array, and call plot_map."""
|
|
95
|
+
# Load dataset and variable
|
|
96
|
+
ds = xr.open_dataset(args.input_file)
|
|
97
|
+
data = ds[args.var]
|
|
98
|
+
|
|
99
|
+
# Build output path
|
|
100
|
+
output_dir = Path(args.output_dir)
|
|
101
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
102
|
+
out_path = output_dir / args.output_file_png
|
|
103
|
+
|
|
104
|
+
# Call the plotting utility
|
|
105
|
+
from mhm_tools.common.plotter import plot_map
|
|
106
|
+
|
|
107
|
+
plot_map(
|
|
108
|
+
data=data,
|
|
109
|
+
cb_label=args.colorbar_label,
|
|
110
|
+
title=args.title,
|
|
111
|
+
out_path=out_path,
|
|
112
|
+
cmap=args.cmap,
|
|
113
|
+
x_min=args.x_min,
|
|
114
|
+
x_max=args.x_max,
|
|
115
|
+
y_min=args.y_min,
|
|
116
|
+
y_max=args.y_max,
|
|
117
|
+
vmin=args.vmin,
|
|
118
|
+
vmax=args.vmax,
|
|
119
|
+
)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""Calculate the river discharge at bankfull conditions and the bankfull width.
|
|
2
|
+
|
|
3
|
+
Bankfull discharge is determined as the yearly peak flow with a
|
|
4
|
+
recurrence interval given by "return_period", which is 1.5 years by
|
|
5
|
+
default. The wetted perimeter is estimated from bankfull discharge with
|
|
6
|
+
Lacey's formula.
|
|
7
|
+
|
|
8
|
+
This routine will simply use the closest flood event in terms of its
|
|
9
|
+
recurrence interval. Also, any input time-stepping is accepted but daily
|
|
10
|
+
or sub-daily data is preferred. Ouput variables in the created NetCDF
|
|
11
|
+
file are called "Q_bkfl" and "P_bkfl".
|
|
12
|
+
|
|
13
|
+
Authors
|
|
14
|
+
-------
|
|
15
|
+
- Sebastian Müller
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def add_args(parser):
|
|
20
|
+
"""Add cli arguments for the bankfull subcommand.
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
parser : argparse.ArgumentParser
|
|
25
|
+
the main argument parser
|
|
26
|
+
"""
|
|
27
|
+
optional = parser.add_argument_group("optional arguments")
|
|
28
|
+
flags = parser.add_argument_group("flags")
|
|
29
|
+
optional.add_argument(
|
|
30
|
+
"-r",
|
|
31
|
+
"--return-period",
|
|
32
|
+
type=float,
|
|
33
|
+
default=1.5,
|
|
34
|
+
help="The return period of the flood in years.",
|
|
35
|
+
)
|
|
36
|
+
flags.add_argument(
|
|
37
|
+
"-w",
|
|
38
|
+
"--wetted-perimeter",
|
|
39
|
+
action="store_true",
|
|
40
|
+
default=False,
|
|
41
|
+
help="Additionally estimate the wetted perimeter.",
|
|
42
|
+
)
|
|
43
|
+
optional.add_argument(
|
|
44
|
+
"-v",
|
|
45
|
+
"--var",
|
|
46
|
+
default="Qrouted",
|
|
47
|
+
help="Variable name for routed streamflow in the NetCDF file",
|
|
48
|
+
)
|
|
49
|
+
required_args = parser.add_argument_group("required arguments")
|
|
50
|
+
required_args.add_argument(
|
|
51
|
+
"-i",
|
|
52
|
+
"--input-file",
|
|
53
|
+
"--input",
|
|
54
|
+
dest="in_file",
|
|
55
|
+
required=True,
|
|
56
|
+
help="The path of the mRM NetCDF file with the discharge data.",
|
|
57
|
+
)
|
|
58
|
+
required_args.add_argument(
|
|
59
|
+
"-o",
|
|
60
|
+
"--output-file",
|
|
61
|
+
"--output",
|
|
62
|
+
dest="out_file",
|
|
63
|
+
required=True,
|
|
64
|
+
help="The path of the output NetCDF file.",
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def run(args):
|
|
69
|
+
"""Calculate the bankfull discharge.
|
|
70
|
+
|
|
71
|
+
Parameters
|
|
72
|
+
----------
|
|
73
|
+
args : argparse.Namespace
|
|
74
|
+
parsed command line arguments
|
|
75
|
+
"""
|
|
76
|
+
from ..post.bankfull import bankfull_discharge
|
|
77
|
+
|
|
78
|
+
bankfull_discharge(
|
|
79
|
+
in_file=args.in_file,
|
|
80
|
+
out_file=args.out_file,
|
|
81
|
+
return_period=args.return_period,
|
|
82
|
+
wetted_perimeter=args.wetted_perimeter,
|
|
83
|
+
var=args.var,
|
|
84
|
+
)
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""Calculating pet.
|
|
2
|
+
|
|
3
|
+
Contains multiple different pet methods mainly temperature based.
|
|
4
|
+
|
|
5
|
+
Authors
|
|
6
|
+
-------
|
|
7
|
+
- Matthias Kelbling
|
|
8
|
+
- Simon Lüdke
|
|
9
|
+
- Stephan Thober
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import logging
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def add_args(parser):
|
|
18
|
+
"""Add CLI arguments for calculate_pet subcommand."""
|
|
19
|
+
# Description and epilog
|
|
20
|
+
parser.description = (
|
|
21
|
+
# "Utility functions for mHM processing netCDF precipitation and temperature forcings, "
|
|
22
|
+
# "including unit conversion, coordinate ordering, setting correct variable name and "
|
|
23
|
+
# "units as well as missing and fill values, and spatial cropping."
|
|
24
|
+
)
|
|
25
|
+
parser.epilog = "See mhm-tools documentation for detailed examples and usage."
|
|
26
|
+
|
|
27
|
+
# Required arguments
|
|
28
|
+
required = parser.add_argument_group("required arguments")
|
|
29
|
+
required.add_argument(
|
|
30
|
+
"-o",
|
|
31
|
+
"--output-file",
|
|
32
|
+
required=True,
|
|
33
|
+
help="Output directory for processed files",
|
|
34
|
+
)
|
|
35
|
+
optional = parser.add_argument_group("optional arguments")
|
|
36
|
+
optional.add_argument(
|
|
37
|
+
"--tavg",
|
|
38
|
+
required=False,
|
|
39
|
+
default=None,
|
|
40
|
+
help="Temperature average file",
|
|
41
|
+
)
|
|
42
|
+
optional.add_argument(
|
|
43
|
+
"--tmax",
|
|
44
|
+
required=False,
|
|
45
|
+
default=None,
|
|
46
|
+
help="Temperature maximum file",
|
|
47
|
+
)
|
|
48
|
+
optional.add_argument(
|
|
49
|
+
"--tmin",
|
|
50
|
+
required=False,
|
|
51
|
+
default=None,
|
|
52
|
+
help="Temperature minimum file",
|
|
53
|
+
)
|
|
54
|
+
optional.add_argument(
|
|
55
|
+
"-f",
|
|
56
|
+
"--freq",
|
|
57
|
+
required=False,
|
|
58
|
+
default=None,
|
|
59
|
+
help="Frequency of pet output, daily or hourly.",
|
|
60
|
+
)
|
|
61
|
+
optional.add_argument(
|
|
62
|
+
"--method",
|
|
63
|
+
required=False,
|
|
64
|
+
default="oudin",
|
|
65
|
+
help="Method of pet calculation. Currently implemented: hargreaves_samani, oudin, jensen_haise, mcguinness_bordne, hamon, blaney_criddle.",
|
|
66
|
+
)
|
|
67
|
+
optional.add_argument(
|
|
68
|
+
"--ncpus",
|
|
69
|
+
required=False,
|
|
70
|
+
default=1,
|
|
71
|
+
type=int,
|
|
72
|
+
help=("Number of cores used for parallelisation."),
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def run(args):
|
|
77
|
+
"""Calculate PET from temperature inputs and write output.
|
|
78
|
+
|
|
79
|
+
Parameters
|
|
80
|
+
----------
|
|
81
|
+
args : argparse.Namespace
|
|
82
|
+
parsed command line arguments
|
|
83
|
+
"""
|
|
84
|
+
from mhm_tools.pre.pet_calc import calculate_pet
|
|
85
|
+
|
|
86
|
+
calculate_pet(
|
|
87
|
+
tavg_file=args.tavg,
|
|
88
|
+
tmax_file=args.tmax,
|
|
89
|
+
tmin_file=args.tmin,
|
|
90
|
+
stat_freq=args.freq,
|
|
91
|
+
out_file=args.output_file,
|
|
92
|
+
max_workers=args.ncpus,
|
|
93
|
+
method=args.method,
|
|
94
|
+
)
|