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.
Files changed (87) hide show
  1. mhm_tools/__init__.py +31 -0
  2. mhm_tools/_cli/_2d_map.py +119 -0
  3. mhm_tools/_cli/__init__.py +5 -0
  4. mhm_tools/_cli/__main__.py +6 -0
  5. mhm_tools/_cli/_bankfull.py +84 -0
  6. mhm_tools/_cli/_calculate_pet.py +94 -0
  7. mhm_tools/_cli/_create_catchment.py +456 -0
  8. mhm_tools/_cli/_create_header.py +103 -0
  9. mhm_tools/_cli/_create_idgauges.py +114 -0
  10. mhm_tools/_cli/_create_mhm_restart_file.py +294 -0
  11. mhm_tools/_cli/_create_mhm_restart_from_setup.py +452 -0
  12. mhm_tools/_cli/_create_subdomain_masks.py +94 -0
  13. mhm_tools/_cli/_crop_mhm_setup.py +263 -0
  14. mhm_tools/_cli/_difference.py +165 -0
  15. mhm_tools/_cli/_discharge_evaluation.py +239 -0
  16. mhm_tools/_cli/_file_converter.py +105 -0
  17. mhm_tools/_cli/_fill_nearest.py +80 -0
  18. mhm_tools/_cli/_gridded_data_evaluation.py +358 -0
  19. mhm_tools/_cli/_hydrograph.py +117 -0
  20. mhm_tools/_cli/_landcover_ascii_to_nc.py +119 -0
  21. mhm_tools/_cli/_latlon.py +180 -0
  22. mhm_tools/_cli/_link_folder_tree.py +71 -0
  23. mhm_tools/_cli/_long_term_mean.py +147 -0
  24. mhm_tools/_cli/_main.py +704 -0
  25. mhm_tools/_cli/_merge.py +71 -0
  26. mhm_tools/_cli/_mhm_run_overview.py +80 -0
  27. mhm_tools/_cli/_prepare_mhm_forcings.py +151 -0
  28. mhm_tools/_cli/_ratio.py +173 -0
  29. mhm_tools/_cli/_regrid.py +65 -0
  30. mhm_tools/_cli/_relative_difference.py +171 -0
  31. mhm_tools/_cli/_taylor_diagram.py +118 -0
  32. mhm_tools/_version.py +1 -0
  33. mhm_tools/common/__init__.py +74 -0
  34. mhm_tools/common/cli_utils.py +167 -0
  35. mhm_tools/common/constants.py +76 -0
  36. mhm_tools/common/esri_grid.py +402 -0
  37. mhm_tools/common/file_handler.py +1223 -0
  38. mhm_tools/common/logger.py +216 -0
  39. mhm_tools/common/metrics/__init__.py +7 -0
  40. mhm_tools/common/metrics/esp.py +30 -0
  41. mhm_tools/common/metrics/metrics_handler.py +164 -0
  42. mhm_tools/common/metrics/mspaef.py +36 -0
  43. mhm_tools/common/metrics/spaef.py +43 -0
  44. mhm_tools/common/metrics/tsm.py +160 -0
  45. mhm_tools/common/metrics/waspaef.py +51 -0
  46. mhm_tools/common/netcdf.py +420 -0
  47. mhm_tools/common/plotter.py +261 -0
  48. mhm_tools/common/provenance.py +51 -0
  49. mhm_tools/common/resolution_handler.py +187 -0
  50. mhm_tools/common/time_utils.py +285 -0
  51. mhm_tools/common/utils.py +571 -0
  52. mhm_tools/common/xarray_utils.py +542 -0
  53. mhm_tools/post/2d_map.py +59 -0
  54. mhm_tools/post/__init__.py +54 -0
  55. mhm_tools/post/bankfull.py +143 -0
  56. mhm_tools/post/difference.py +107 -0
  57. mhm_tools/post/discharge_evaluation.py +2158 -0
  58. mhm_tools/post/gridded_data_evaluation.py +2675 -0
  59. mhm_tools/post/hydrograph.py +1560 -0
  60. mhm_tools/post/long_term_mean.py +281 -0
  61. mhm_tools/post/mhm_run_overview.py +681 -0
  62. mhm_tools/post/ratio.py +95 -0
  63. mhm_tools/post/relative_difference.py +96 -0
  64. mhm_tools/post/taylor_diagram.py +139 -0
  65. mhm_tools/pre/__init__.py +80 -0
  66. mhm_tools/pre/catchment.py +2985 -0
  67. mhm_tools/pre/create_id_gauges.py +98 -0
  68. mhm_tools/pre/create_mhm_restart_file.py +1419 -0
  69. mhm_tools/pre/create_mhm_restart_from_setup.py +3005 -0
  70. mhm_tools/pre/crop_mhm_setup.py +722 -0
  71. mhm_tools/pre/fill_nearest.py +574 -0
  72. mhm_tools/pre/landcover_ascii_to_nc.py +360 -0
  73. mhm_tools/pre/latlon.py +276 -0
  74. mhm_tools/pre/link_folder_tree.py +51 -0
  75. mhm_tools/pre/merge.py +196 -0
  76. mhm_tools/pre/pet_calc.py +505 -0
  77. mhm_tools/pre/prepare_mhm_forcings.py +191 -0
  78. mhm_tools/pre/regrid.py +193 -0
  79. mhm_tools/pre/subdomain_masks.py +346 -0
  80. mhm_tools-0.2.dist-info/METADATA +99 -0
  81. mhm_tools-0.2.dist-info/RECORD +87 -0
  82. mhm_tools-0.2.dist-info/WHEEL +4 -0
  83. mhm_tools-0.2.dist-info/entry_points.txt +2 -0
  84. mhm_tools-0.2.dist-info/licenses/AUTHORS.md +20 -0
  85. mhm_tools-0.2.dist-info/licenses/COPYING +674 -0
  86. mhm_tools-0.2.dist-info/licenses/COPYING.LESSER +165 -0
  87. 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,5 @@
1
+ """The command line interface."""
2
+
3
+ from ._main import main
4
+
5
+ __all__ = ["main"]
@@ -0,0 +1,6 @@
1
+ """Allow ``python -m mhm_tools._cli`` execution."""
2
+
3
+ from . import main
4
+
5
+ if __name__ == "__main__":
6
+ raise SystemExit(main())
@@ -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
+ )