5.13.2-dev0
mHM
The mesoscale Hydrological Model
Loading...
Searching...
No Matches
tools.py
Go to the documentation of this file.
1"""!
2Tools to interact with mHM.
3
4@copyright Copyright 2005-@today, the mHM Developers, Luis Samaniego, Sabine Attinger: All rights reserved.
5 mHM is released under the LGPLv3+ license @license_note
6@ingroup mhm
7"""
8
9import numpy as np
10
11from . import wrapper as wr
12
13
14def get_parameter():
15 """
16 Get parameter names and configuration.
17
18 @retval names (List[Str]): Names of all used parameters in mHM.
19 @retval config (numpy.ndarray): Configuration for all used parameters (min, max, value, flag, scale).
20 """
21 para_n = wr.get.parameter_length()
22 names = [
23 wr.get.parameter_name(i).decode("utf-8").strip() for i in range(1, para_n + 1)
24 ]
25 config = wr.get.parameter_config(para_n)
26 return names, config
27
28
30 """
31 Get 2D array of runoff time-series for all gauges.
32
33 @retval runoff (numpy.ndarray): The runoff for all gauges with dims (time, gauge).
34 """
35 shp = wr.get.runoff_shape()
36 return wr.get.runoff(*shp)
37
38
39def get_runoff_eval(gauge_id):
40 """
41 Get 2D array of simulated and observed runoff time-series for selected gauges.
42
43 @retval runoff (numpy.ndarray(TS, 2)): The runoff for selected gauges with dims (time-steps, 2).
44 """
45 length = wr.get.runoff_eval_length(gauge_id)
46 return wr.get.runoff_eval(gauge_id, length)
47
48
49def get_mask(level, indexing="ij", selection=False):
50 """
51 Get mask for a certain mHM level.
52
53 @param level (str): Name level ("L0", "L1", "L11", "L2")
54 @param indexing (str, optional): Indexing for the 2D mask,
55 either "xy" or "ij" (yx order), by default "ij"
56 @param selection (bool): A masked value in mHM indicates cells inside the domain.
57 In numpy, masked values are outside the domain. That means, by default False
58 @retval mask (numpy.ndarray): Boolean numpy array holding the mask.
59 @throws ValueError: If the level is not in ["L0", "L1", "L11" or "L2"].
60 """
61 level = level.lower()
62 shp = getattr(wr.get, level + "_domain_shape")()
63 # mask in mHM is the opposite in numpy
64 mask = np.array(
65 getattr(wr.get, level + "_domain_mask")(m=shp[0], n=shp[1]), dtype=bool
66 )
67 if not selection:
68 mask = ~mask
69 return mask.T if indexing == "ij" else mask
70
71
72def get_variable(name, index=1, indexing="ij", compressed=False):
73 """
74 Get a specific variable from mHM in the current time-step.
75
76 @param name (str): Name of the variable
77 @param index (int, optional): If the variable has an additional dimension
78 (e.g. the horizon), one needs to specify an index, by default 1
79 @param indexing (str, optional): Indexing for the 2D variable,
80 either "xy" or "ij", by default "ij"
81 @param compressed (bool): Whether the data should be flattened and only contain
82 values for each unmasked domain cell. By default False
83 @retval variable (numpy.ndarray): Numpy array holding the desired variable.
84 @throws ValueError: If the variable name doesn't start with "L0", "L1", "L11" or "L2".
85 """
86 name = name.upper() # convention
87 grid = name.split("_")[0].lower()
88 if grid not in ["l0", "l1", "l11", "l2"]:
89 raise ValueError(f"Unknown variable: {name}")
90 n = getattr(wr.get, grid + "_domain_size")()
91 var = getattr(wr.get, grid + "_variable")(name=name, n=n, idx=index)
92 if compressed:
93 return np.asarray(var, dtype=float)
94 # ncols, nrows, ncells, xll, yll, cell_size, no_data
95 grid_info = getattr(wr.get, grid + "_domain_info")()
96 # mask in mHM is the opposite in numpy (selection)
97 sel = get_mask(grid, indexing="xy", selection=True)
98 sel = sel.ravel(order="F")
99 output = np.ma.empty_like(sel, dtype=float)
100 output.fill_value = grid_info[-1]
101 output.mask = ~sel
102 output[sel] = var
103 output = output.reshape((grid_info[0], grid_info[1]), order="C")
104 return output.T if indexing == "xy" else output
105
106
107def set_meteo(
108 time,
109 pre=None,
110 temp=None,
111 pet=None,
112 tmin=None,
113 tmax=None,
114 netrad=None,
115 absvappress=None,
116 windspeed=None,
117 ssrd=None,
118 strd=None,
119 tann=None,
120 compressed=False,
121 indexing="ij",
122):
123 """
124 Set meteo data with a time stamp in mHM.
125
126 @param time (datetime.datetime): Timestamp
127 @param pre (numpy.ndarray, optional): [mm] Precipitation
128 @param temp (numpy.ndarray, optional): [degC] Air temperature
129 @param pet (numpy.ndarray, optional): [mm TS-1] Potential evapotranspiration
130 @param tmin (numpy.ndarray, optional): [degC] minimum daily air temperature
131 @param tmax (numpy.ndarray, optional): [degC] maximum daily air temperature
132 @param netrad (numpy.ndarray, optional): [W m2] net radiation
133 @param absvappress (numpy.ndarray, optional): [Pa] absolute vapour pressure
134 @param windspeed (numpy.ndarray, optional): [m s-1] windspeed
135 @param ssrd (numpy.ndarray, optional): [W m2] short wave radiation
136 @param strd (numpy.ndarray, optional): [W m2] long wave radiation
137 @param tann (numpy.ndarray, optional): [degC] annual mean air temperature
138 @param compressed (bool): Whether the data is flattened and only contains
139 values for each unmasked domain cell. By default False
140 @param indexing (str, optional): Indexing for 2D arrays if data is not compressed,
141 either "xy" or "ij" (yx order), by default "ij"
142 """
143 sel = slice(None) if compressed else get_mask("L1", indexing, selection=True)
144 if pre is not None:
145 wr.set.meteo(pre[sel], "PRE", time.year, time.month, time.day, time.hour)
146 if temp is not None:
147 wr.set.meteo(temp[sel], "TEMP", time.year, time.month, time.day, time.hour)
148 if pet is not None:
149 wr.set.meteo(pet[sel], "PET", time.year, time.month, time.day, time.hour)
150 if tmin is not None:
151 wr.set.meteo(tmin[sel], "TMIN", time.year, time.month, time.day, time.hour)
152 if tmax is not None:
153 wr.set.meteo(tmax[sel], "TMAX", time.year, time.month, time.day, time.hour)
154 if netrad is not None:
155 wr.set.meteo(netrad[sel], "NETRAD", time.year, time.month, time.day, time.hour)
156 if absvappress is not None:
157 wr.set.meteo(
158 absvappress[sel], "ABSVAPPRESS", time.year, time.month, time.day, time.hour
159 )
160 if windspeed is not None:
161 wr.set.meteo(
162 windspeed[sel], "WINDSPEED", time.year, time.month, time.day, time.hour
163 )
164 if ssrd is not None:
165 wr.set.meteo(ssrd[sel], "SSRD", time.year, time.month, time.day, time.hour)
166 if strd is not None:
167 wr.set.meteo(strd[sel], "STRD", time.year, time.month, time.day, time.hour)
168 if tann is not None:
169 wr.set.meteo(tann[sel], "TANN", time.year, time.month, time.day, time.hour)
get_runoff()
Get 2D array of runoff time-series for all gauges.
Definition tools.py:29