HydPy 6.2.dev1__cp313-cp313-win_amd64.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 (890) hide show
  1. hydpy/__init__.py +275 -0
  2. hydpy/aliases.py +2554 -0
  3. hydpy/auxs/__init__.py +0 -0
  4. hydpy/auxs/anntools.py +1305 -0
  5. hydpy/auxs/armatools.py +883 -0
  6. hydpy/auxs/calibtools.py +3337 -0
  7. hydpy/auxs/interptools.py +1094 -0
  8. hydpy/auxs/iuhtools.py +543 -0
  9. hydpy/auxs/networktools.py +597 -0
  10. hydpy/auxs/ppolytools.py +809 -0
  11. hydpy/auxs/quadtools.py +61 -0
  12. hydpy/auxs/roottools.py +228 -0
  13. hydpy/auxs/smoothtools.py +273 -0
  14. hydpy/auxs/statstools.py +2125 -0
  15. hydpy/auxs/validtools.py +81 -0
  16. hydpy/conf/HydPyConfigBase.xsd +68637 -0
  17. hydpy/conf/HydPyConfigBase.xsdt +358 -0
  18. hydpy/conf/HydPyConfigMultipleRuns.xsd +25 -0
  19. hydpy/conf/HydPyConfigSingleRun.xsd +24 -0
  20. hydpy/conf/__init__.py +0 -0
  21. hydpy/conf/a_coefficients_explicit_lobatto_sequence.npy +0 -0
  22. hydpy/conf/support_points_for_smoothpar_logistic2.npy +0 -0
  23. hydpy/config.py +42 -0
  24. hydpy/core/__init__.py +0 -0
  25. hydpy/core/aliastools.py +214 -0
  26. hydpy/core/autodoctools.py +1947 -0
  27. hydpy/core/auxfiletools.py +1169 -0
  28. hydpy/core/devicetools.py +3810 -0
  29. hydpy/core/exceptiontools.py +269 -0
  30. hydpy/core/filetools.py +1985 -0
  31. hydpy/core/hydpytools.py +3089 -0
  32. hydpy/core/importtools.py +1398 -0
  33. hydpy/core/indextools.py +345 -0
  34. hydpy/core/itemtools.py +1849 -0
  35. hydpy/core/masktools.py +460 -0
  36. hydpy/core/modeltools.py +4868 -0
  37. hydpy/core/netcdftools.py +2683 -0
  38. hydpy/core/objecttools.py +2023 -0
  39. hydpy/core/optiontools.py +1045 -0
  40. hydpy/core/parametertools.py +4674 -0
  41. hydpy/core/printtools.py +222 -0
  42. hydpy/core/propertytools.py +643 -0
  43. hydpy/core/pubtools.py +254 -0
  44. hydpy/core/selectiontools.py +1571 -0
  45. hydpy/core/sequencetools.py +4476 -0
  46. hydpy/core/seriestools.py +339 -0
  47. hydpy/core/testtools.py +2483 -0
  48. hydpy/core/timetools.py +3567 -0
  49. hydpy/core/typingtools.py +333 -0
  50. hydpy/core/variabletools.py +2615 -0
  51. hydpy/cythons/__init__.py +24 -0
  52. hydpy/cythons/annutils.pxd +33 -0
  53. hydpy/cythons/annutils.pyi +25 -0
  54. hydpy/cythons/annutils.pyx +120 -0
  55. hydpy/cythons/autogen/__init__.py +0 -0
  56. hydpy/cythons/autogen/annutils.cp313-win_amd64.pyd +0 -0
  57. hydpy/cythons/autogen/annutils.pxd +42 -0
  58. hydpy/cythons/autogen/annutils.pyx +129 -0
  59. hydpy/cythons/autogen/c_arma.cp313-win_amd64.pyd +0 -0
  60. hydpy/cythons/autogen/c_arma.pxd +179 -0
  61. hydpy/cythons/autogen/c_arma.pyx +356 -0
  62. hydpy/cythons/autogen/c_arma_rimorido.cp313-win_amd64.pyd +0 -0
  63. hydpy/cythons/autogen/c_arma_rimorido.pxd +179 -0
  64. hydpy/cythons/autogen/c_arma_rimorido.pyx +356 -0
  65. hydpy/cythons/autogen/c_conv.cp313-win_amd64.pyd +0 -0
  66. hydpy/cythons/autogen/c_conv.pxd +198 -0
  67. hydpy/cythons/autogen/c_conv.pyx +491 -0
  68. hydpy/cythons/autogen/c_conv_idw.cp313-win_amd64.pyd +0 -0
  69. hydpy/cythons/autogen/c_conv_idw.pxd +124 -0
  70. hydpy/cythons/autogen/c_conv_idw.pyx +264 -0
  71. hydpy/cythons/autogen/c_conv_idw_ed.cp313-win_amd64.pyd +0 -0
  72. hydpy/cythons/autogen/c_conv_idw_ed.pxd +197 -0
  73. hydpy/cythons/autogen/c_conv_idw_ed.pyx +481 -0
  74. hydpy/cythons/autogen/c_conv_nn.cp313-win_amd64.pyd +0 -0
  75. hydpy/cythons/autogen/c_conv_nn.pxd +120 -0
  76. hydpy/cythons/autogen/c_conv_nn.pyx +224 -0
  77. hydpy/cythons/autogen/c_dam.cp313-win_amd64.pyd +0 -0
  78. hydpy/cythons/autogen/c_dam.pxd +805 -0
  79. hydpy/cythons/autogen/c_dam.pyx +1477 -0
  80. hydpy/cythons/autogen/c_dam_llake.cp313-win_amd64.pyd +0 -0
  81. hydpy/cythons/autogen/c_dam_llake.pxd +364 -0
  82. hydpy/cythons/autogen/c_dam_llake.pyx +705 -0
  83. hydpy/cythons/autogen/c_dam_lreservoir.cp313-win_amd64.pyd +0 -0
  84. hydpy/cythons/autogen/c_dam_lreservoir.pxd +365 -0
  85. hydpy/cythons/autogen/c_dam_lreservoir.pyx +708 -0
  86. hydpy/cythons/autogen/c_dam_lretention.cp313-win_amd64.pyd +0 -0
  87. hydpy/cythons/autogen/c_dam_lretention.pxd +340 -0
  88. hydpy/cythons/autogen/c_dam_lretention.pyx +625 -0
  89. hydpy/cythons/autogen/c_dam_pump.cp313-win_amd64.pyd +0 -0
  90. hydpy/cythons/autogen/c_dam_pump.pxd +402 -0
  91. hydpy/cythons/autogen/c_dam_pump.pyx +724 -0
  92. hydpy/cythons/autogen/c_dam_pump_sluice.cp313-win_amd64.pyd +0 -0
  93. hydpy/cythons/autogen/c_dam_pump_sluice.pxd +452 -0
  94. hydpy/cythons/autogen/c_dam_pump_sluice.pyx +829 -0
  95. hydpy/cythons/autogen/c_dam_sluice.cp313-win_amd64.pyd +0 -0
  96. hydpy/cythons/autogen/c_dam_sluice.pxd +404 -0
  97. hydpy/cythons/autogen/c_dam_sluice.pyx +726 -0
  98. hydpy/cythons/autogen/c_dam_v001.cp313-win_amd64.pyd +0 -0
  99. hydpy/cythons/autogen/c_dam_v001.pxd +452 -0
  100. hydpy/cythons/autogen/c_dam_v001.pyx +816 -0
  101. hydpy/cythons/autogen/c_dam_v002.cp313-win_amd64.pyd +0 -0
  102. hydpy/cythons/autogen/c_dam_v002.pxd +394 -0
  103. hydpy/cythons/autogen/c_dam_v002.pyx +703 -0
  104. hydpy/cythons/autogen/c_dam_v003.cp313-win_amd64.pyd +0 -0
  105. hydpy/cythons/autogen/c_dam_v003.pxd +417 -0
  106. hydpy/cythons/autogen/c_dam_v003.pyx +744 -0
  107. hydpy/cythons/autogen/c_dam_v004.cp313-win_amd64.pyd +0 -0
  108. hydpy/cythons/autogen/c_dam_v004.pxd +486 -0
  109. hydpy/cythons/autogen/c_dam_v004.pyx +891 -0
  110. hydpy/cythons/autogen/c_dam_v005.cp313-win_amd64.pyd +0 -0
  111. hydpy/cythons/autogen/c_dam_v005.pxd +524 -0
  112. hydpy/cythons/autogen/c_dam_v005.pyx +928 -0
  113. hydpy/cythons/autogen/c_dummy.cp313-win_amd64.pyd +0 -0
  114. hydpy/cythons/autogen/c_dummy.pxd +151 -0
  115. hydpy/cythons/autogen/c_dummy.pyx +263 -0
  116. hydpy/cythons/autogen/c_dummy_interceptedwater.cp313-win_amd64.pyd +0 -0
  117. hydpy/cythons/autogen/c_dummy_interceptedwater.pxd +69 -0
  118. hydpy/cythons/autogen/c_dummy_interceptedwater.pyx +104 -0
  119. hydpy/cythons/autogen/c_dummy_node2node.cp313-win_amd64.pyd +0 -0
  120. hydpy/cythons/autogen/c_dummy_node2node.pxd +89 -0
  121. hydpy/cythons/autogen/c_dummy_node2node.pyx +148 -0
  122. hydpy/cythons/autogen/c_dummy_snowalbedo.cp313-win_amd64.pyd +0 -0
  123. hydpy/cythons/autogen/c_dummy_snowalbedo.pxd +69 -0
  124. hydpy/cythons/autogen/c_dummy_snowalbedo.pyx +104 -0
  125. hydpy/cythons/autogen/c_dummy_snowcover.cp313-win_amd64.pyd +0 -0
  126. hydpy/cythons/autogen/c_dummy_snowcover.pxd +69 -0
  127. hydpy/cythons/autogen/c_dummy_snowcover.pyx +104 -0
  128. hydpy/cythons/autogen/c_dummy_snowycanopy.cp313-win_amd64.pyd +0 -0
  129. hydpy/cythons/autogen/c_dummy_snowycanopy.pxd +69 -0
  130. hydpy/cythons/autogen/c_dummy_snowycanopy.pyx +104 -0
  131. hydpy/cythons/autogen/c_dummy_soilwater.cp313-win_amd64.pyd +0 -0
  132. hydpy/cythons/autogen/c_dummy_soilwater.pxd +69 -0
  133. hydpy/cythons/autogen/c_dummy_soilwater.pyx +104 -0
  134. hydpy/cythons/autogen/c_evap.cp313-win_amd64.pyd +0 -0
  135. hydpy/cythons/autogen/c_evap.pxd +1029 -0
  136. hydpy/cythons/autogen/c_evap.pyx +2601 -0
  137. hydpy/cythons/autogen/c_evap_aet_hbv96.cp313-win_amd64.pyd +0 -0
  138. hydpy/cythons/autogen/c_evap_aet_hbv96.pxd +227 -0
  139. hydpy/cythons/autogen/c_evap_aet_hbv96.pyx +584 -0
  140. hydpy/cythons/autogen/c_evap_aet_minhas.cp313-win_amd64.pyd +0 -0
  141. hydpy/cythons/autogen/c_evap_aet_minhas.pxd +193 -0
  142. hydpy/cythons/autogen/c_evap_aet_minhas.pyx +478 -0
  143. hydpy/cythons/autogen/c_evap_aet_morsim.cp313-win_amd64.pyd +0 -0
  144. hydpy/cythons/autogen/c_evap_aet_morsim.pxd +681 -0
  145. hydpy/cythons/autogen/c_evap_aet_morsim.pyx +1642 -0
  146. hydpy/cythons/autogen/c_evap_pet_ambav1.cp313-win_amd64.pyd +0 -0
  147. hydpy/cythons/autogen/c_evap_pet_ambav1.pxd +532 -0
  148. hydpy/cythons/autogen/c_evap_pet_ambav1.pyx +1296 -0
  149. hydpy/cythons/autogen/c_evap_pet_hbv96.cp313-win_amd64.pyd +0 -0
  150. hydpy/cythons/autogen/c_evap_pet_hbv96.pxd +179 -0
  151. hydpy/cythons/autogen/c_evap_pet_hbv96.pyx +328 -0
  152. hydpy/cythons/autogen/c_evap_pet_m.cp313-win_amd64.pyd +0 -0
  153. hydpy/cythons/autogen/c_evap_pet_m.pxd +124 -0
  154. hydpy/cythons/autogen/c_evap_pet_m.pyx +214 -0
  155. hydpy/cythons/autogen/c_evap_pet_mlc.cp313-win_amd64.pyd +0 -0
  156. hydpy/cythons/autogen/c_evap_pet_mlc.pxd +126 -0
  157. hydpy/cythons/autogen/c_evap_pet_mlc.pyx +214 -0
  158. hydpy/cythons/autogen/c_evap_ret_fao56.cp313-win_amd64.pyd +0 -0
  159. hydpy/cythons/autogen/c_evap_ret_fao56.pxd +305 -0
  160. hydpy/cythons/autogen/c_evap_ret_fao56.pyx +624 -0
  161. hydpy/cythons/autogen/c_evap_ret_io.cp313-win_amd64.pyd +0 -0
  162. hydpy/cythons/autogen/c_evap_ret_io.pxd +112 -0
  163. hydpy/cythons/autogen/c_evap_ret_io.pyx +176 -0
  164. hydpy/cythons/autogen/c_evap_ret_tw2002.cp313-win_amd64.pyd +0 -0
  165. hydpy/cythons/autogen/c_evap_ret_tw2002.pxd +139 -0
  166. hydpy/cythons/autogen/c_evap_ret_tw2002.pyx +273 -0
  167. hydpy/cythons/autogen/c_exch.cp313-win_amd64.pyd +0 -0
  168. hydpy/cythons/autogen/c_exch.pxd +230 -0
  169. hydpy/cythons/autogen/c_exch.pyx +462 -0
  170. hydpy/cythons/autogen/c_exch_branch_hbv96.cp313-win_amd64.pyd +0 -0
  171. hydpy/cythons/autogen/c_exch_branch_hbv96.pxd +134 -0
  172. hydpy/cythons/autogen/c_exch_branch_hbv96.pyx +255 -0
  173. hydpy/cythons/autogen/c_exch_waterlevel.cp313-win_amd64.pyd +0 -0
  174. hydpy/cythons/autogen/c_exch_waterlevel.pxd +54 -0
  175. hydpy/cythons/autogen/c_exch_waterlevel.pyx +78 -0
  176. hydpy/cythons/autogen/c_exch_weir_hbv96.cp313-win_amd64.pyd +0 -0
  177. hydpy/cythons/autogen/c_exch_weir_hbv96.pxd +156 -0
  178. hydpy/cythons/autogen/c_exch_weir_hbv96.pyx +282 -0
  179. hydpy/cythons/autogen/c_ga.cp313-win_amd64.pyd +0 -0
  180. hydpy/cythons/autogen/c_ga.pxd +353 -0
  181. hydpy/cythons/autogen/c_ga.pyx +1204 -0
  182. hydpy/cythons/autogen/c_ga_garto.cp313-win_amd64.pyd +0 -0
  183. hydpy/cythons/autogen/c_ga_garto.pxd +330 -0
  184. hydpy/cythons/autogen/c_ga_garto.pyx +1105 -0
  185. hydpy/cythons/autogen/c_ga_garto_submodel1.cp313-win_amd64.pyd +0 -0
  186. hydpy/cythons/autogen/c_ga_garto_submodel1.pxd +236 -0
  187. hydpy/cythons/autogen/c_ga_garto_submodel1.pyx +944 -0
  188. hydpy/cythons/autogen/c_gland.cp313-win_amd64.pyd +0 -0
  189. hydpy/cythons/autogen/c_gland.pxd +437 -0
  190. hydpy/cythons/autogen/c_gland.pyx +726 -0
  191. hydpy/cythons/autogen/c_gland_gr4.cp313-win_amd64.pyd +0 -0
  192. hydpy/cythons/autogen/c_gland_gr4.pxd +382 -0
  193. hydpy/cythons/autogen/c_gland_gr4.pyx +605 -0
  194. hydpy/cythons/autogen/c_gland_gr5.cp313-win_amd64.pyd +0 -0
  195. hydpy/cythons/autogen/c_gland_gr5.pxd +368 -0
  196. hydpy/cythons/autogen/c_gland_gr5.pyx +568 -0
  197. hydpy/cythons/autogen/c_gland_gr6.cp313-win_amd64.pyd +0 -0
  198. hydpy/cythons/autogen/c_gland_gr6.pxd +420 -0
  199. hydpy/cythons/autogen/c_gland_gr6.pyx +673 -0
  200. hydpy/cythons/autogen/c_hland.cp313-win_amd64.pyd +0 -0
  201. hydpy/cythons/autogen/c_hland.pxd +855 -0
  202. hydpy/cythons/autogen/c_hland.pyx +2486 -0
  203. hydpy/cythons/autogen/c_hland_96.cp313-win_amd64.pyd +0 -0
  204. hydpy/cythons/autogen/c_hland_96.pxd +631 -0
  205. hydpy/cythons/autogen/c_hland_96.pyx +1724 -0
  206. hydpy/cythons/autogen/c_hland_96c.cp313-win_amd64.pyd +0 -0
  207. hydpy/cythons/autogen/c_hland_96c.pxd +621 -0
  208. hydpy/cythons/autogen/c_hland_96c.pyx +1822 -0
  209. hydpy/cythons/autogen/c_hland_96p.cp313-win_amd64.pyd +0 -0
  210. hydpy/cythons/autogen/c_hland_96p.pxd +683 -0
  211. hydpy/cythons/autogen/c_hland_96p.pyx +1911 -0
  212. hydpy/cythons/autogen/c_kinw.cp313-win_amd64.pyd +0 -0
  213. hydpy/cythons/autogen/c_kinw.pxd +509 -0
  214. hydpy/cythons/autogen/c_kinw.pyx +965 -0
  215. hydpy/cythons/autogen/c_kinw_williams.cp313-win_amd64.pyd +0 -0
  216. hydpy/cythons/autogen/c_kinw_williams.pxd +409 -0
  217. hydpy/cythons/autogen/c_kinw_williams.pyx +763 -0
  218. hydpy/cythons/autogen/c_kinw_williams_ext.cp313-win_amd64.pyd +0 -0
  219. hydpy/cythons/autogen/c_kinw_williams_ext.pxd +220 -0
  220. hydpy/cythons/autogen/c_kinw_williams_ext.pyx +440 -0
  221. hydpy/cythons/autogen/c_lland.cp313-win_amd64.pyd +0 -0
  222. hydpy/cythons/autogen/c_lland.pxd +1386 -0
  223. hydpy/cythons/autogen/c_lland.pyx +3679 -0
  224. hydpy/cythons/autogen/c_lland_dd.cp313-win_amd64.pyd +0 -0
  225. hydpy/cythons/autogen/c_lland_dd.pxd +679 -0
  226. hydpy/cythons/autogen/c_lland_dd.pyx +1719 -0
  227. hydpy/cythons/autogen/c_lland_knauf.cp313-win_amd64.pyd +0 -0
  228. hydpy/cythons/autogen/c_lland_knauf.pxd +1096 -0
  229. hydpy/cythons/autogen/c_lland_knauf.pyx +2784 -0
  230. hydpy/cythons/autogen/c_lland_knauf_ic.cp313-win_amd64.pyd +0 -0
  231. hydpy/cythons/autogen/c_lland_knauf_ic.pxd +1369 -0
  232. hydpy/cythons/autogen/c_lland_knauf_ic.pyx +3625 -0
  233. hydpy/cythons/autogen/c_meteo.cp313-win_amd64.pyd +0 -0
  234. hydpy/cythons/autogen/c_meteo.pxd +469 -0
  235. hydpy/cythons/autogen/c_meteo.pyx +879 -0
  236. hydpy/cythons/autogen/c_meteo_clear_glob_io.cp313-win_amd64.pyd +0 -0
  237. hydpy/cythons/autogen/c_meteo_clear_glob_io.pxd +75 -0
  238. hydpy/cythons/autogen/c_meteo_clear_glob_io.pyx +107 -0
  239. hydpy/cythons/autogen/c_meteo_glob_fao56.cp313-win_amd64.pyd +0 -0
  240. hydpy/cythons/autogen/c_meteo_glob_fao56.pxd +209 -0
  241. hydpy/cythons/autogen/c_meteo_glob_fao56.pyx +339 -0
  242. hydpy/cythons/autogen/c_meteo_glob_io.cp313-win_amd64.pyd +0 -0
  243. hydpy/cythons/autogen/c_meteo_glob_io.pxd +63 -0
  244. hydpy/cythons/autogen/c_meteo_glob_io.pyx +91 -0
  245. hydpy/cythons/autogen/c_meteo_glob_morsim.cp313-win_amd64.pyd +0 -0
  246. hydpy/cythons/autogen/c_meteo_glob_morsim.pxd +289 -0
  247. hydpy/cythons/autogen/c_meteo_glob_morsim.pyx +527 -0
  248. hydpy/cythons/autogen/c_meteo_precip_io.cp313-win_amd64.pyd +0 -0
  249. hydpy/cythons/autogen/c_meteo_precip_io.pxd +112 -0
  250. hydpy/cythons/autogen/c_meteo_precip_io.pyx +176 -0
  251. hydpy/cythons/autogen/c_meteo_psun_sun_glob_io.cp313-win_amd64.pyd +0 -0
  252. hydpy/cythons/autogen/c_meteo_psun_sun_glob_io.pxd +87 -0
  253. hydpy/cythons/autogen/c_meteo_psun_sun_glob_io.pyx +123 -0
  254. hydpy/cythons/autogen/c_meteo_sun_fao56.cp313-win_amd64.pyd +0 -0
  255. hydpy/cythons/autogen/c_meteo_sun_fao56.pxd +209 -0
  256. hydpy/cythons/autogen/c_meteo_sun_fao56.pyx +343 -0
  257. hydpy/cythons/autogen/c_meteo_sun_morsim.cp313-win_amd64.pyd +0 -0
  258. hydpy/cythons/autogen/c_meteo_sun_morsim.pxd +286 -0
  259. hydpy/cythons/autogen/c_meteo_sun_morsim.pyx +519 -0
  260. hydpy/cythons/autogen/c_meteo_temp_io.cp313-win_amd64.pyd +0 -0
  261. hydpy/cythons/autogen/c_meteo_temp_io.pxd +112 -0
  262. hydpy/cythons/autogen/c_meteo_temp_io.pyx +176 -0
  263. hydpy/cythons/autogen/c_musk.cp313-win_amd64.pyd +0 -0
  264. hydpy/cythons/autogen/c_musk.pxd +282 -0
  265. hydpy/cythons/autogen/c_musk.pyx +605 -0
  266. hydpy/cythons/autogen/c_musk_classic.cp313-win_amd64.pyd +0 -0
  267. hydpy/cythons/autogen/c_musk_classic.pxd +138 -0
  268. hydpy/cythons/autogen/c_musk_classic.pyx +226 -0
  269. hydpy/cythons/autogen/c_musk_mct.cp313-win_amd64.pyd +0 -0
  270. hydpy/cythons/autogen/c_musk_mct.pxd +282 -0
  271. hydpy/cythons/autogen/c_musk_mct.pyx +609 -0
  272. hydpy/cythons/autogen/c_rconc.cp313-win_amd64.pyd +0 -0
  273. hydpy/cythons/autogen/c_rconc.pxd +119 -0
  274. hydpy/cythons/autogen/c_rconc.pyx +174 -0
  275. hydpy/cythons/autogen/c_rconc_nash.cp313-win_amd64.pyd +0 -0
  276. hydpy/cythons/autogen/c_rconc_nash.pxd +111 -0
  277. hydpy/cythons/autogen/c_rconc_nash.pyx +185 -0
  278. hydpy/cythons/autogen/c_rconc_uh.cp313-win_amd64.pyd +0 -0
  279. hydpy/cythons/autogen/c_rconc_uh.pxd +92 -0
  280. hydpy/cythons/autogen/c_rconc_uh.pyx +125 -0
  281. hydpy/cythons/autogen/c_sw1d.cp313-win_amd64.pyd +0 -0
  282. hydpy/cythons/autogen/c_sw1d.pxd +511 -0
  283. hydpy/cythons/autogen/c_sw1d.pyx +1263 -0
  284. hydpy/cythons/autogen/c_sw1d_channel.cp313-win_amd64.pyd +0 -0
  285. hydpy/cythons/autogen/c_sw1d_channel.pxd +119 -0
  286. hydpy/cythons/autogen/c_sw1d_channel.pyx +300 -0
  287. hydpy/cythons/autogen/c_sw1d_gate_out.cp313-win_amd64.pyd +0 -0
  288. hydpy/cythons/autogen/c_sw1d_gate_out.pxd +240 -0
  289. hydpy/cythons/autogen/c_sw1d_gate_out.pyx +476 -0
  290. hydpy/cythons/autogen/c_sw1d_lias.cp313-win_amd64.pyd +0 -0
  291. hydpy/cythons/autogen/c_sw1d_lias.pxd +320 -0
  292. hydpy/cythons/autogen/c_sw1d_lias.pyx +619 -0
  293. hydpy/cythons/autogen/c_sw1d_lias_sluice.cp313-win_amd64.pyd +0 -0
  294. hydpy/cythons/autogen/c_sw1d_lias_sluice.pxd +325 -0
  295. hydpy/cythons/autogen/c_sw1d_lias_sluice.pyx +644 -0
  296. hydpy/cythons/autogen/c_sw1d_network.cp313-win_amd64.pyd +0 -0
  297. hydpy/cythons/autogen/c_sw1d_network.pxd +90 -0
  298. hydpy/cythons/autogen/c_sw1d_network.pyx +246 -0
  299. hydpy/cythons/autogen/c_sw1d_pump.cp313-win_amd64.pyd +0 -0
  300. hydpy/cythons/autogen/c_sw1d_pump.pxd +256 -0
  301. hydpy/cythons/autogen/c_sw1d_pump.pyx +502 -0
  302. hydpy/cythons/autogen/c_sw1d_q_in.cp313-win_amd64.pyd +0 -0
  303. hydpy/cythons/autogen/c_sw1d_q_in.pxd +224 -0
  304. hydpy/cythons/autogen/c_sw1d_q_in.pyx +383 -0
  305. hydpy/cythons/autogen/c_sw1d_q_out.cp313-win_amd64.pyd +0 -0
  306. hydpy/cythons/autogen/c_sw1d_q_out.pxd +224 -0
  307. hydpy/cythons/autogen/c_sw1d_q_out.pyx +383 -0
  308. hydpy/cythons/autogen/c_sw1d_storage.cp313-win_amd64.pyd +0 -0
  309. hydpy/cythons/autogen/c_sw1d_storage.pxd +193 -0
  310. hydpy/cythons/autogen/c_sw1d_storage.pyx +349 -0
  311. hydpy/cythons/autogen/c_sw1d_weir_out.cp313-win_amd64.pyd +0 -0
  312. hydpy/cythons/autogen/c_sw1d_weir_out.pxd +212 -0
  313. hydpy/cythons/autogen/c_sw1d_weir_out.pyx +404 -0
  314. hydpy/cythons/autogen/c_test.cp313-win_amd64.pyd +0 -0
  315. hydpy/cythons/autogen/c_test.pxd +175 -0
  316. hydpy/cythons/autogen/c_test.pyx +348 -0
  317. hydpy/cythons/autogen/c_test_discontinous.cp313-win_amd64.pyd +0 -0
  318. hydpy/cythons/autogen/c_test_discontinous.pxd +146 -0
  319. hydpy/cythons/autogen/c_test_discontinous.pyx +256 -0
  320. hydpy/cythons/autogen/c_test_stiff0d.cp313-win_amd64.pyd +0 -0
  321. hydpy/cythons/autogen/c_test_stiff0d.pxd +146 -0
  322. hydpy/cythons/autogen/c_test_stiff0d.pyx +250 -0
  323. hydpy/cythons/autogen/c_test_stiff1d.cp313-win_amd64.pyd +0 -0
  324. hydpy/cythons/autogen/c_test_stiff1d.pxd +145 -0
  325. hydpy/cythons/autogen/c_test_stiff1d.pyx +294 -0
  326. hydpy/cythons/autogen/c_whmod.cp313-win_amd64.pyd +0 -0
  327. hydpy/cythons/autogen/c_whmod.pxd +482 -0
  328. hydpy/cythons/autogen/c_whmod.pyx +1156 -0
  329. hydpy/cythons/autogen/c_whmod_rural.cp313-win_amd64.pyd +0 -0
  330. hydpy/cythons/autogen/c_whmod_rural.pxd +411 -0
  331. hydpy/cythons/autogen/c_whmod_rural.pyx +982 -0
  332. hydpy/cythons/autogen/c_whmod_urban.cp313-win_amd64.pyd +0 -0
  333. hydpy/cythons/autogen/c_whmod_urban.pxd +482 -0
  334. hydpy/cythons/autogen/c_whmod_urban.pyx +1155 -0
  335. hydpy/cythons/autogen/c_wland.cp313-win_amd64.pyd +0 -0
  336. hydpy/cythons/autogen/c_wland.pxd +842 -0
  337. hydpy/cythons/autogen/c_wland.pyx +1890 -0
  338. hydpy/cythons/autogen/c_wland_gd.cp313-win_amd64.pyd +0 -0
  339. hydpy/cythons/autogen/c_wland_gd.pxd +829 -0
  340. hydpy/cythons/autogen/c_wland_gd.pyx +1847 -0
  341. hydpy/cythons/autogen/c_wland_wag.cp313-win_amd64.pyd +0 -0
  342. hydpy/cythons/autogen/c_wland_wag.pxd +810 -0
  343. hydpy/cythons/autogen/c_wland_wag.pyx +1780 -0
  344. hydpy/cythons/autogen/c_wq.cp313-win_amd64.pyd +0 -0
  345. hydpy/cythons/autogen/c_wq.pxd +275 -0
  346. hydpy/cythons/autogen/c_wq.pyx +652 -0
  347. hydpy/cythons/autogen/c_wq_trapeze.cp313-win_amd64.pyd +0 -0
  348. hydpy/cythons/autogen/c_wq_trapeze.pxd +170 -0
  349. hydpy/cythons/autogen/c_wq_trapeze.pyx +400 -0
  350. hydpy/cythons/autogen/c_wq_trapeze_strickler.cp313-win_amd64.pyd +0 -0
  351. hydpy/cythons/autogen/c_wq_trapeze_strickler.pxd +243 -0
  352. hydpy/cythons/autogen/c_wq_trapeze_strickler.pyx +578 -0
  353. hydpy/cythons/autogen/c_wq_walrus.cp313-win_amd64.pyd +0 -0
  354. hydpy/cythons/autogen/c_wq_walrus.pxd +61 -0
  355. hydpy/cythons/autogen/c_wq_walrus.pyx +82 -0
  356. hydpy/cythons/autogen/configutils.cp313-win_amd64.pyd +0 -0
  357. hydpy/cythons/autogen/configutils.pxd +17 -0
  358. hydpy/cythons/autogen/configutils.pyx +119 -0
  359. hydpy/cythons/autogen/interfaceutils.cp313-win_amd64.pyd +0 -0
  360. hydpy/cythons/autogen/interfaceutils.pxd +31 -0
  361. hydpy/cythons/autogen/interfaceutils.pyx +82 -0
  362. hydpy/cythons/autogen/interputils.cp313-win_amd64.pyd +0 -0
  363. hydpy/cythons/autogen/interputils.pxd +42 -0
  364. hydpy/cythons/autogen/interputils.pyx +118 -0
  365. hydpy/cythons/autogen/masterinterface.cp313-win_amd64.pyd +0 -0
  366. hydpy/cythons/autogen/masterinterface.pxd +153 -0
  367. hydpy/cythons/autogen/masterinterface.pyx +222 -0
  368. hydpy/cythons/autogen/pointerutils.cp313-win_amd64.pyd +0 -0
  369. hydpy/cythons/autogen/pointerutils.pxd +31 -0
  370. hydpy/cythons/autogen/pointerutils.pyx +650 -0
  371. hydpy/cythons/autogen/ppolyutils.cp313-win_amd64.pyd +0 -0
  372. hydpy/cythons/autogen/ppolyutils.pxd +35 -0
  373. hydpy/cythons/autogen/ppolyutils.pyx +59 -0
  374. hydpy/cythons/autogen/quadutils.cp313-win_amd64.pyd +0 -0
  375. hydpy/cythons/autogen/quadutils.pxd +26 -0
  376. hydpy/cythons/autogen/quadutils.pyx +973 -0
  377. hydpy/cythons/autogen/rootutils.cp313-win_amd64.pyd +0 -0
  378. hydpy/cythons/autogen/rootutils.pxd +28 -0
  379. hydpy/cythons/autogen/rootutils.pyx +109 -0
  380. hydpy/cythons/autogen/sequenceutils.cp313-win_amd64.pyd +0 -0
  381. hydpy/cythons/autogen/sequenceutils.pxd +45 -0
  382. hydpy/cythons/autogen/sequenceutils.pyx +101 -0
  383. hydpy/cythons/autogen/smoothutils.cp313-win_amd64.pyd +0 -0
  384. hydpy/cythons/autogen/smoothutils.pxd +29 -0
  385. hydpy/cythons/autogen/smoothutils.pyx +833 -0
  386. hydpy/cythons/configutils.pxd +8 -0
  387. hydpy/cythons/configutils.pyi +5 -0
  388. hydpy/cythons/configutils.pyx +110 -0
  389. hydpy/cythons/interfaceutils.pxd +22 -0
  390. hydpy/cythons/interfaceutils.pyi +15 -0
  391. hydpy/cythons/interfaceutils.pyx +73 -0
  392. hydpy/cythons/interputils.pxd +33 -0
  393. hydpy/cythons/interputils.pyi +32 -0
  394. hydpy/cythons/interputils.pyx +109 -0
  395. hydpy/cythons/modelutils.py +2990 -0
  396. hydpy/cythons/pointerutils.pxd +22 -0
  397. hydpy/cythons/pointerutils.pyi +89 -0
  398. hydpy/cythons/pointerutils.pyx +641 -0
  399. hydpy/cythons/ppolyutils.pxd +26 -0
  400. hydpy/cythons/ppolyutils.pyi +21 -0
  401. hydpy/cythons/ppolyutils.pyx +50 -0
  402. hydpy/cythons/quadutils.pxd +17 -0
  403. hydpy/cythons/quadutils.pyi +13 -0
  404. hydpy/cythons/quadutils.pyx +964 -0
  405. hydpy/cythons/rootutils.pxd +19 -0
  406. hydpy/cythons/rootutils.pyi +21 -0
  407. hydpy/cythons/rootutils.pyx +100 -0
  408. hydpy/cythons/sequenceutils.pxd +36 -0
  409. hydpy/cythons/sequenceutils.pyi +7 -0
  410. hydpy/cythons/sequenceutils.pyx +92 -0
  411. hydpy/cythons/smoothutils.pxd +20 -0
  412. hydpy/cythons/smoothutils.pyi +15 -0
  413. hydpy/cythons/smoothutils.pyx +824 -0
  414. hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_dill_assl.py +13 -0
  415. hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_lahn_kalk.py +13 -0
  416. hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_lahn_leun.py +14 -0
  417. hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_lahn_marb.py +13 -0
  418. hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/stream_dill_assl_lahn_leun.py +5 -0
  419. hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/stream_lahn_leun_lahn_kalk.py +5 -0
  420. hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/stream_lahn_marb_lahn_leun.py +5 -0
  421. hydpy/data/HydPy-H-Lahn/control/default/land.py +9 -0
  422. hydpy/data/HydPy-H-Lahn/control/default/land_dill_assl.py +57 -0
  423. hydpy/data/HydPy-H-Lahn/control/default/land_lahn_kalk.py +57 -0
  424. hydpy/data/HydPy-H-Lahn/control/default/land_lahn_leun.py +56 -0
  425. hydpy/data/HydPy-H-Lahn/control/default/land_lahn_marb.py +57 -0
  426. hydpy/data/HydPy-H-Lahn/control/default/stream_dill_assl_lahn_leun.py +7 -0
  427. hydpy/data/HydPy-H-Lahn/control/default/stream_lahn_leun_lahn_kalk.py +7 -0
  428. hydpy/data/HydPy-H-Lahn/control/default/stream_lahn_marb_lahn_leun.py +7 -0
  429. hydpy/data/HydPy-H-Lahn/multiple_runs.xml +309 -0
  430. hydpy/data/HydPy-H-Lahn/multiple_runs_alpha.xml +71 -0
  431. hydpy/data/HydPy-H-Lahn/network/default/headwaters.py +11 -0
  432. hydpy/data/HydPy-H-Lahn/network/default/nonheadwaters.py +11 -0
  433. hydpy/data/HydPy-H-Lahn/network/default/streams.py +8 -0
  434. hydpy/data/HydPy-H-Lahn/series/default/dill_assl_obs_q.asc +11387 -0
  435. hydpy/data/HydPy-H-Lahn/series/default/evap_pet_hbv96_input_normalairtemperature.nc +0 -0
  436. hydpy/data/HydPy-H-Lahn/series/default/evap_pet_hbv96_input_normalevapotranspiration.nc +0 -0
  437. hydpy/data/HydPy-H-Lahn/series/default/hland_96_input_p.nc +0 -0
  438. hydpy/data/HydPy-H-Lahn/series/default/hland_96_input_t.nc +0 -0
  439. hydpy/data/HydPy-H-Lahn/series/default/lahn_kalk_obs_q.asc +11387 -0
  440. hydpy/data/HydPy-H-Lahn/series/default/lahn_leun_obs_q.asc +11387 -0
  441. hydpy/data/HydPy-H-Lahn/series/default/lahn_marb_obs_q.asc +11387 -0
  442. hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
  443. hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
  444. hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_hland_96_input_p.asc +11387 -0
  445. hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_hland_96_input_t.asc +11387 -0
  446. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
  447. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
  448. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_hland_96_input_p.asc +11387 -0
  449. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_hland_96_input_t.asc +11387 -0
  450. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
  451. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
  452. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_hland_96_input_p.asc +11387 -0
  453. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_hland_96_input_t.asc +11387 -0
  454. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
  455. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
  456. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_hland_96_input_p.asc +11387 -0
  457. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_hland_96_input_t.asc +11387 -0
  458. hydpy/data/HydPy-H-Lahn/series/default/obs_q.nc +0 -0
  459. hydpy/data/HydPy-H-Lahn/single_run.xml +152 -0
  460. hydpy/data/HydPy-H-Lahn/single_run.xmlt +143 -0
  461. hydpy/data/__init__.py +17 -0
  462. hydpy/docs/__init__.py +0 -0
  463. hydpy/docs/autofigs/__init__.py +0 -0
  464. hydpy/docs/bib/__init__.py +0 -0
  465. hydpy/docs/bib/refs.bib +566 -0
  466. hydpy/docs/combine_docversions.py +133 -0
  467. hydpy/docs/draw_model_sketches.py +1301 -0
  468. hydpy/docs/enable_autodoc.py +7 -0
  469. hydpy/docs/figs/HydPy-G-GR4.png +0 -0
  470. hydpy/docs/figs/HydPy-G-GR5.png +0 -0
  471. hydpy/docs/figs/HydPy-G-GR6.png +0 -0
  472. hydpy/docs/figs/HydPy-H-HBV96-COSERO.png +0 -0
  473. hydpy/docs/figs/HydPy-H-HBV96-PREVAH.png +0 -0
  474. hydpy/docs/figs/HydPy-H-HBV96.png +0 -0
  475. hydpy/docs/figs/HydPy-H-Lahn.png +0 -0
  476. hydpy/docs/figs/HydPy-KinW-Williams.png +0 -0
  477. hydpy/docs/figs/HydPy-L-DD.png +0 -0
  478. hydpy/docs/figs/HydPy-W-Wag.png +0 -0
  479. hydpy/docs/figs/HydPy_Logo.png +0 -0
  480. hydpy/docs/figs/HydPy_Logo_Text.png +0 -0
  481. hydpy/docs/figs/IDLE-editor.png +0 -0
  482. hydpy/docs/figs/IDLE-shell.png +0 -0
  483. hydpy/docs/figs/LAWA_river-basin-bumbers.png +0 -0
  484. hydpy/docs/figs/__init__.py +0 -0
  485. hydpy/docs/html_/__init__.py +0 -0
  486. hydpy/docs/polish_html.py +57 -0
  487. hydpy/docs/prepare.py +224 -0
  488. hydpy/docs/publish_docs.py +53 -0
  489. hydpy/docs/rst/HydPy-ARMA.rst +27 -0
  490. hydpy/docs/rst/HydPy-Conv.rst +22 -0
  491. hydpy/docs/rst/HydPy-Dam.rst +79 -0
  492. hydpy/docs/rst/HydPy-Dummy.rst +21 -0
  493. hydpy/docs/rst/HydPy-Evap.rst +26 -0
  494. hydpy/docs/rst/HydPy-Exch.rst +36 -0
  495. hydpy/docs/rst/HydPy-G.rst +40 -0
  496. hydpy/docs/rst/HydPy-GA.rst +34 -0
  497. hydpy/docs/rst/HydPy-H.rst +24 -0
  498. hydpy/docs/rst/HydPy-KinW.rst +32 -0
  499. hydpy/docs/rst/HydPy-L.rst +42 -0
  500. hydpy/docs/rst/HydPy-Meteo.rst +28 -0
  501. hydpy/docs/rst/HydPy-Musk.rst +21 -0
  502. hydpy/docs/rst/HydPy-Rconc.rst +17 -0
  503. hydpy/docs/rst/HydPy-SW1D.rst +49 -0
  504. hydpy/docs/rst/HydPy-Test.rst +19 -0
  505. hydpy/docs/rst/HydPy-W.rst +20 -0
  506. hydpy/docs/rst/HydPy-WHMod.rst +19 -0
  507. hydpy/docs/rst/HydPy-WQ.rst +20 -0
  508. hydpy/docs/rst/__init__.py +0 -0
  509. hydpy/docs/rst/additional_repositories.rst +40 -0
  510. hydpy/docs/rst/auxiliaries.rst +31 -0
  511. hydpy/docs/rst/continuous_integration.rst +75 -0
  512. hydpy/docs/rst/core.rst +75 -0
  513. hydpy/docs/rst/cythons.rst +47 -0
  514. hydpy/docs/rst/definitions.rst +506 -0
  515. hydpy/docs/rst/developer_guide.rst +54 -0
  516. hydpy/docs/rst/example_projects.rst +40 -0
  517. hydpy/docs/rst/execution.rst +22 -0
  518. hydpy/docs/rst/framework_tools.rst +56 -0
  519. hydpy/docs/rst/how_to_read_the_reference_manual.rst +156 -0
  520. hydpy/docs/rst/hydpydependencies.rst +55 -0
  521. hydpy/docs/rst/index.rst +125 -0
  522. hydpy/docs/rst/installation.rst +155 -0
  523. hydpy/docs/rst/model_families.rst +79 -0
  524. hydpy/docs/rst/model_overview.rst +291 -0
  525. hydpy/docs/rst/modelimports.rst +10 -0
  526. hydpy/docs/rst/options.rst +119 -0
  527. hydpy/docs/rst/programming_style.rst +572 -0
  528. hydpy/docs/rst/project_structure.rst +520 -0
  529. hydpy/docs/rst/quickstart.rst +304 -0
  530. hydpy/docs/rst/reference_manual.rst +29 -0
  531. hydpy/docs/rst/required_tools.rst +50 -0
  532. hydpy/docs/rst/simulation.rst +514 -0
  533. hydpy/docs/rst/submodel_interfaces.rst +32 -0
  534. hydpy/docs/rst/tests_and_documentation.rst +85 -0
  535. hydpy/docs/rst/user_guide.rst +38 -0
  536. hydpy/docs/rst/version_control.rst +116 -0
  537. hydpy/docs/rst/zbibliography.rst +8 -0
  538. hydpy/docs/sphinx/__init__.py +0 -0
  539. hydpy/docs/sphinx/_themes/basic_hydpy/changes/frameset.html +11 -0
  540. hydpy/docs/sphinx/_themes/basic_hydpy/changes/rstsource.html +15 -0
  541. hydpy/docs/sphinx/_themes/basic_hydpy/changes/versionchanges.html +33 -0
  542. hydpy/docs/sphinx/_themes/basic_hydpy/defindex.html +35 -0
  543. hydpy/docs/sphinx/_themes/basic_hydpy/domainindex.html +56 -0
  544. hydpy/docs/sphinx/_themes/basic_hydpy/genindex-single.html +63 -0
  545. hydpy/docs/sphinx/_themes/basic_hydpy/genindex-split.html +41 -0
  546. hydpy/docs/sphinx/_themes/basic_hydpy/genindex.html +76 -0
  547. hydpy/docs/sphinx/_themes/basic_hydpy/globaltoc.html +11 -0
  548. hydpy/docs/sphinx/_themes/basic_hydpy/layout.html +221 -0
  549. hydpy/docs/sphinx/_themes/basic_hydpy/localtoc.html +15 -0
  550. hydpy/docs/sphinx/_themes/basic_hydpy/opensearch.xml +13 -0
  551. hydpy/docs/sphinx/_themes/basic_hydpy/page.html +13 -0
  552. hydpy/docs/sphinx/_themes/basic_hydpy/relations.html +23 -0
  553. hydpy/docs/sphinx/_themes/basic_hydpy/search.html +65 -0
  554. hydpy/docs/sphinx/_themes/basic_hydpy/searchbox.html +21 -0
  555. hydpy/docs/sphinx/_themes/basic_hydpy/searchfield.html +23 -0
  556. hydpy/docs/sphinx/_themes/basic_hydpy/sourcelink.html +18 -0
  557. hydpy/docs/sphinx/_themes/basic_hydpy/static/basic.css_t +925 -0
  558. hydpy/docs/sphinx/_themes/basic_hydpy/static/doctools.js +156 -0
  559. hydpy/docs/sphinx/_themes/basic_hydpy/static/documentation_options.js_t +13 -0
  560. hydpy/docs/sphinx/_themes/basic_hydpy/static/file.png +0 -0
  561. hydpy/docs/sphinx/_themes/basic_hydpy/static/language_data.js_t +26 -0
  562. hydpy/docs/sphinx/_themes/basic_hydpy/static/minus.png +0 -0
  563. hydpy/docs/sphinx/_themes/basic_hydpy/static/plus.png +0 -0
  564. hydpy/docs/sphinx/_themes/basic_hydpy/static/searchtools.js +574 -0
  565. hydpy/docs/sphinx/_themes/basic_hydpy/static/sphinx_highlight.js +154 -0
  566. hydpy/docs/sphinx/_themes/basic_hydpy/theme.conf +16 -0
  567. hydpy/docs/sphinx/_themes/classic_hydpy/layout.html +23 -0
  568. hydpy/docs/sphinx/_themes/classic_hydpy/static/classic.css_t +358 -0
  569. hydpy/docs/sphinx/_themes/classic_hydpy/static/sidebar.js_t +72 -0
  570. hydpy/docs/sphinx/_themes/classic_hydpy/theme.conf +32 -0
  571. hydpy/docs/sphinx/conf.py +398 -0
  572. hydpy/docs/sphinx/defaultlinks_extension.py +36 -0
  573. hydpy/docs/sphinx/integrationtest_extension.py +104 -0
  574. hydpy/docs/sphinx/projectstructure_extension.py +58 -0
  575. hydpy/docs/sphinx/submodelgraph_extension.py +53 -0
  576. hydpy/exe/__init__.py +0 -0
  577. hydpy/exe/commandtools.py +651 -0
  578. hydpy/exe/hyd.py +277 -0
  579. hydpy/exe/modelimports.py +41 -0
  580. hydpy/exe/replacetools.py +216 -0
  581. hydpy/exe/servertools.py +2348 -0
  582. hydpy/exe/xmltools.py +3280 -0
  583. hydpy/interfaces/__init__.py +0 -0
  584. hydpy/interfaces/aetinterfaces.py +94 -0
  585. hydpy/interfaces/dischargeinterfaces.py +45 -0
  586. hydpy/interfaces/petinterfaces.py +117 -0
  587. hydpy/interfaces/precipinterfaces.py +42 -0
  588. hydpy/interfaces/radiationinterfaces.py +79 -0
  589. hydpy/interfaces/rconcinterfaces.py +30 -0
  590. hydpy/interfaces/routinginterfaces.py +324 -0
  591. hydpy/interfaces/soilinterfaces.py +96 -0
  592. hydpy/interfaces/stateinterfaces.py +98 -0
  593. hydpy/interfaces/tempinterfaces.py +46 -0
  594. hydpy/models/__init__.py +0 -0
  595. hydpy/models/arma/__init__.py +14 -0
  596. hydpy/models/arma/arma_control.py +383 -0
  597. hydpy/models/arma/arma_derived.py +204 -0
  598. hydpy/models/arma/arma_fluxes.py +41 -0
  599. hydpy/models/arma/arma_inlets.py +11 -0
  600. hydpy/models/arma/arma_logs.py +19 -0
  601. hydpy/models/arma/arma_model.py +461 -0
  602. hydpy/models/arma/arma_outlets.py +11 -0
  603. hydpy/models/arma_rimorido.py +381 -0
  604. hydpy/models/conv/__init__.py +12 -0
  605. hydpy/models/conv/conv_control.py +303 -0
  606. hydpy/models/conv/conv_derived.py +271 -0
  607. hydpy/models/conv/conv_fluxes.py +54 -0
  608. hydpy/models/conv/conv_inlets.py +11 -0
  609. hydpy/models/conv/conv_model.py +687 -0
  610. hydpy/models/conv/conv_outlets.py +11 -0
  611. hydpy/models/conv_idw.py +120 -0
  612. hydpy/models/conv_idw_ed.py +184 -0
  613. hydpy/models/conv_nn.py +112 -0
  614. hydpy/models/dam/__init__.py +16 -0
  615. hydpy/models/dam/dam_aides.py +17 -0
  616. hydpy/models/dam/dam_control.py +346 -0
  617. hydpy/models/dam/dam_derived.py +559 -0
  618. hydpy/models/dam/dam_factors.py +46 -0
  619. hydpy/models/dam/dam_fluxes.py +179 -0
  620. hydpy/models/dam/dam_inlets.py +29 -0
  621. hydpy/models/dam/dam_logs.py +52 -0
  622. hydpy/models/dam/dam_model.py +5011 -0
  623. hydpy/models/dam/dam_outlets.py +23 -0
  624. hydpy/models/dam/dam_receivers.py +41 -0
  625. hydpy/models/dam/dam_senders.py +23 -0
  626. hydpy/models/dam/dam_solver.py +75 -0
  627. hydpy/models/dam/dam_states.py +11 -0
  628. hydpy/models/dam_llake.py +499 -0
  629. hydpy/models/dam_lreservoir.py +548 -0
  630. hydpy/models/dam_lretention.py +343 -0
  631. hydpy/models/dam_pump.py +278 -0
  632. hydpy/models/dam_pump_sluice.py +339 -0
  633. hydpy/models/dam_sluice.py +319 -0
  634. hydpy/models/dam_v001.py +1127 -0
  635. hydpy/models/dam_v002.py +381 -0
  636. hydpy/models/dam_v003.py +422 -0
  637. hydpy/models/dam_v004.py +665 -0
  638. hydpy/models/dam_v005.py +479 -0
  639. hydpy/models/dummy/__init__.py +15 -0
  640. hydpy/models/dummy/dummy_control.py +22 -0
  641. hydpy/models/dummy/dummy_fluxes.py +11 -0
  642. hydpy/models/dummy/dummy_inlets.py +11 -0
  643. hydpy/models/dummy/dummy_inputs.py +41 -0
  644. hydpy/models/dummy/dummy_model.py +196 -0
  645. hydpy/models/dummy/dummy_outlets.py +11 -0
  646. hydpy/models/dummy_interceptedwater.py +85 -0
  647. hydpy/models/dummy_node2node.py +83 -0
  648. hydpy/models/dummy_snowalbedo.py +84 -0
  649. hydpy/models/dummy_snowcover.py +84 -0
  650. hydpy/models/dummy_snowycanopy.py +86 -0
  651. hydpy/models/dummy_soilwater.py +85 -0
  652. hydpy/models/evap/__init__.py +13 -0
  653. hydpy/models/evap/evap_control.py +354 -0
  654. hydpy/models/evap/evap_derived.py +236 -0
  655. hydpy/models/evap/evap_factors.py +188 -0
  656. hydpy/models/evap/evap_fixed.py +68 -0
  657. hydpy/models/evap/evap_fluxes.py +150 -0
  658. hydpy/models/evap/evap_inputs.py +54 -0
  659. hydpy/models/evap/evap_logs.py +91 -0
  660. hydpy/models/evap/evap_masks.py +48 -0
  661. hydpy/models/evap/evap_model.py +9170 -0
  662. hydpy/models/evap/evap_parameters.py +149 -0
  663. hydpy/models/evap/evap_sequences.py +32 -0
  664. hydpy/models/evap/evap_states.py +18 -0
  665. hydpy/models/evap_aet_hbv96.py +372 -0
  666. hydpy/models/evap_aet_minhas.py +331 -0
  667. hydpy/models/evap_aet_morsim.py +627 -0
  668. hydpy/models/evap_pet_ambav1.py +483 -0
  669. hydpy/models/evap_pet_hbv96.py +147 -0
  670. hydpy/models/evap_pet_m.py +94 -0
  671. hydpy/models/evap_pet_mlc.py +107 -0
  672. hydpy/models/evap_ret_fao56.py +265 -0
  673. hydpy/models/evap_ret_io.py +74 -0
  674. hydpy/models/evap_ret_tw2002.py +165 -0
  675. hydpy/models/exch/__init__.py +14 -0
  676. hydpy/models/exch/exch_control.py +262 -0
  677. hydpy/models/exch/exch_derived.py +36 -0
  678. hydpy/models/exch/exch_factors.py +26 -0
  679. hydpy/models/exch/exch_fluxes.py +48 -0
  680. hydpy/models/exch/exch_inlets.py +11 -0
  681. hydpy/models/exch/exch_logs.py +12 -0
  682. hydpy/models/exch/exch_model.py +451 -0
  683. hydpy/models/exch/exch_outlets.py +17 -0
  684. hydpy/models/exch/exch_receivers.py +17 -0
  685. hydpy/models/exch_branch_hbv96.py +186 -0
  686. hydpy/models/exch_waterlevel.py +73 -0
  687. hydpy/models/exch_weir_hbv96.py +609 -0
  688. hydpy/models/ga/__init__.py +14 -0
  689. hydpy/models/ga/ga_aides.py +17 -0
  690. hydpy/models/ga/ga_control.py +208 -0
  691. hydpy/models/ga/ga_derived.py +77 -0
  692. hydpy/models/ga/ga_fluxes.py +83 -0
  693. hydpy/models/ga/ga_inputs.py +26 -0
  694. hydpy/models/ga/ga_logs.py +17 -0
  695. hydpy/models/ga/ga_model.py +2952 -0
  696. hydpy/models/ga/ga_states.py +87 -0
  697. hydpy/models/ga_garto.py +1001 -0
  698. hydpy/models/ga_garto_submodel1.py +79 -0
  699. hydpy/models/gland/__init__.py +14 -0
  700. hydpy/models/gland/gland_control.py +90 -0
  701. hydpy/models/gland/gland_derived.py +113 -0
  702. hydpy/models/gland/gland_fluxes.py +137 -0
  703. hydpy/models/gland/gland_inputs.py +12 -0
  704. hydpy/models/gland/gland_model.py +1439 -0
  705. hydpy/models/gland/gland_outlets.py +11 -0
  706. hydpy/models/gland/gland_states.py +90 -0
  707. hydpy/models/gland_gr4.py +501 -0
  708. hydpy/models/gland_gr5.py +463 -0
  709. hydpy/models/gland_gr6.py +487 -0
  710. hydpy/models/hland/__init__.py +20 -0
  711. hydpy/models/hland/hland_aides.py +19 -0
  712. hydpy/models/hland/hland_constants.py +37 -0
  713. hydpy/models/hland/hland_control.py +1530 -0
  714. hydpy/models/hland/hland_derived.py +683 -0
  715. hydpy/models/hland/hland_factors.py +57 -0
  716. hydpy/models/hland/hland_fixed.py +42 -0
  717. hydpy/models/hland/hland_fluxes.py +279 -0
  718. hydpy/models/hland/hland_inputs.py +19 -0
  719. hydpy/models/hland/hland_masks.py +107 -0
  720. hydpy/models/hland/hland_model.py +4664 -0
  721. hydpy/models/hland/hland_outlets.py +11 -0
  722. hydpy/models/hland/hland_parameters.py +227 -0
  723. hydpy/models/hland/hland_sequences.py +382 -0
  724. hydpy/models/hland/hland_states.py +236 -0
  725. hydpy/models/hland_96.py +1812 -0
  726. hydpy/models/hland_96c.py +1196 -0
  727. hydpy/models/hland_96p.py +1204 -0
  728. hydpy/models/kinw/__init__.py +18 -0
  729. hydpy/models/kinw/kinw_aides.py +306 -0
  730. hydpy/models/kinw/kinw_control.py +270 -0
  731. hydpy/models/kinw/kinw_derived.py +197 -0
  732. hydpy/models/kinw/kinw_fixed.py +33 -0
  733. hydpy/models/kinw/kinw_fluxes.py +37 -0
  734. hydpy/models/kinw/kinw_inlets.py +11 -0
  735. hydpy/models/kinw/kinw_model.py +3026 -0
  736. hydpy/models/kinw/kinw_outlets.py +11 -0
  737. hydpy/models/kinw/kinw_solver.py +45 -0
  738. hydpy/models/kinw/kinw_states.py +17 -0
  739. hydpy/models/kinw_williams.py +1299 -0
  740. hydpy/models/kinw_williams_ext.py +768 -0
  741. hydpy/models/lland/__init__.py +42 -0
  742. hydpy/models/lland/lland_aides.py +38 -0
  743. hydpy/models/lland/lland_constants.py +88 -0
  744. hydpy/models/lland/lland_control.py +1329 -0
  745. hydpy/models/lland/lland_derived.py +380 -0
  746. hydpy/models/lland/lland_factors.py +18 -0
  747. hydpy/models/lland/lland_fixed.py +128 -0
  748. hydpy/models/lland/lland_fluxes.py +626 -0
  749. hydpy/models/lland/lland_inlets.py +12 -0
  750. hydpy/models/lland/lland_inputs.py +33 -0
  751. hydpy/models/lland/lland_logs.py +17 -0
  752. hydpy/models/lland/lland_masks.py +212 -0
  753. hydpy/models/lland/lland_model.py +7690 -0
  754. hydpy/models/lland/lland_outlets.py +12 -0
  755. hydpy/models/lland/lland_parameters.py +195 -0
  756. hydpy/models/lland/lland_sequences.py +67 -0
  757. hydpy/models/lland/lland_states.py +280 -0
  758. hydpy/models/lland_dd.py +2270 -0
  759. hydpy/models/lland_knauf.py +2156 -0
  760. hydpy/models/lland_knauf_ic.py +1920 -0
  761. hydpy/models/meteo/__init__.py +12 -0
  762. hydpy/models/meteo/meteo_control.py +154 -0
  763. hydpy/models/meteo/meteo_derived.py +159 -0
  764. hydpy/models/meteo/meteo_factors.py +88 -0
  765. hydpy/models/meteo/meteo_fixed.py +19 -0
  766. hydpy/models/meteo/meteo_fluxes.py +46 -0
  767. hydpy/models/meteo/meteo_inputs.py +47 -0
  768. hydpy/models/meteo/meteo_logs.py +30 -0
  769. hydpy/models/meteo/meteo_model.py +2904 -0
  770. hydpy/models/meteo/meteo_parameters.py +14 -0
  771. hydpy/models/meteo/meteo_sequences.py +22 -0
  772. hydpy/models/meteo_clear_glob_io.py +77 -0
  773. hydpy/models/meteo_glob_fao56.py +217 -0
  774. hydpy/models/meteo_glob_io.py +68 -0
  775. hydpy/models/meteo_glob_morsim.py +444 -0
  776. hydpy/models/meteo_precip_io.py +76 -0
  777. hydpy/models/meteo_psun_sun_glob_io.py +83 -0
  778. hydpy/models/meteo_sun_fao56.py +188 -0
  779. hydpy/models/meteo_sun_morsim.py +466 -0
  780. hydpy/models/meteo_temp_io.py +76 -0
  781. hydpy/models/musk/__init__.py +15 -0
  782. hydpy/models/musk/musk_control.py +328 -0
  783. hydpy/models/musk/musk_derived.py +32 -0
  784. hydpy/models/musk/musk_factors.py +53 -0
  785. hydpy/models/musk/musk_fluxes.py +24 -0
  786. hydpy/models/musk/musk_inlets.py +11 -0
  787. hydpy/models/musk/musk_masks.py +15 -0
  788. hydpy/models/musk/musk_model.py +838 -0
  789. hydpy/models/musk/musk_outlets.py +11 -0
  790. hydpy/models/musk/musk_sequences.py +88 -0
  791. hydpy/models/musk/musk_solver.py +68 -0
  792. hydpy/models/musk/musk_states.py +64 -0
  793. hydpy/models/musk_classic.py +228 -0
  794. hydpy/models/musk_mct.py +1247 -0
  795. hydpy/models/rconc/__init__.py +12 -0
  796. hydpy/models/rconc/rconc_control.py +473 -0
  797. hydpy/models/rconc/rconc_derived.py +76 -0
  798. hydpy/models/rconc/rconc_fluxes.py +19 -0
  799. hydpy/models/rconc/rconc_logs.py +74 -0
  800. hydpy/models/rconc/rconc_model.py +260 -0
  801. hydpy/models/rconc/rconc_states.py +11 -0
  802. hydpy/models/rconc_nash.py +48 -0
  803. hydpy/models/rconc_uh.py +53 -0
  804. hydpy/models/sw1d/__init__.py +17 -0
  805. hydpy/models/sw1d/sw1d_control.py +356 -0
  806. hydpy/models/sw1d/sw1d_derived.py +85 -0
  807. hydpy/models/sw1d/sw1d_factors.py +78 -0
  808. hydpy/models/sw1d/sw1d_fixed.py +12 -0
  809. hydpy/models/sw1d/sw1d_fluxes.py +55 -0
  810. hydpy/models/sw1d/sw1d_inlets.py +17 -0
  811. hydpy/models/sw1d/sw1d_model.py +3385 -0
  812. hydpy/models/sw1d/sw1d_outlets.py +11 -0
  813. hydpy/models/sw1d/sw1d_receivers.py +11 -0
  814. hydpy/models/sw1d/sw1d_senders.py +11 -0
  815. hydpy/models/sw1d/sw1d_states.py +23 -0
  816. hydpy/models/sw1d_channel.py +2051 -0
  817. hydpy/models/sw1d_gate_out.py +599 -0
  818. hydpy/models/sw1d_lias.py +105 -0
  819. hydpy/models/sw1d_lias_sluice.py +531 -0
  820. hydpy/models/sw1d_network.py +1219 -0
  821. hydpy/models/sw1d_pump.py +448 -0
  822. hydpy/models/sw1d_q_in.py +79 -0
  823. hydpy/models/sw1d_q_out.py +81 -0
  824. hydpy/models/sw1d_storage.py +78 -0
  825. hydpy/models/sw1d_weir_out.py +75 -0
  826. hydpy/models/test/__init__.py +14 -0
  827. hydpy/models/test/test_control.py +28 -0
  828. hydpy/models/test/test_fluxes.py +17 -0
  829. hydpy/models/test/test_model.py +201 -0
  830. hydpy/models/test/test_solver.py +48 -0
  831. hydpy/models/test/test_states.py +17 -0
  832. hydpy/models/test_discontinous.py +46 -0
  833. hydpy/models/test_stiff0d.py +47 -0
  834. hydpy/models/test_stiff1d.py +42 -0
  835. hydpy/models/whmod/__init__.py +21 -0
  836. hydpy/models/whmod/whmod_constants.py +77 -0
  837. hydpy/models/whmod/whmod_control.py +333 -0
  838. hydpy/models/whmod/whmod_derived.py +210 -0
  839. hydpy/models/whmod/whmod_factors.py +9 -0
  840. hydpy/models/whmod/whmod_fluxes.py +105 -0
  841. hydpy/models/whmod/whmod_inputs.py +15 -0
  842. hydpy/models/whmod/whmod_masks.py +178 -0
  843. hydpy/models/whmod/whmod_model.py +2091 -0
  844. hydpy/models/whmod/whmod_parameters.py +155 -0
  845. hydpy/models/whmod/whmod_sequences.py +193 -0
  846. hydpy/models/whmod/whmod_states.py +73 -0
  847. hydpy/models/whmod_rural.py +794 -0
  848. hydpy/models/whmod_urban.py +1011 -0
  849. hydpy/models/wland/__init__.py +43 -0
  850. hydpy/models/wland/wland_aides.py +55 -0
  851. hydpy/models/wland/wland_constants.py +103 -0
  852. hydpy/models/wland/wland_control.py +508 -0
  853. hydpy/models/wland/wland_derived.py +330 -0
  854. hydpy/models/wland/wland_factors.py +11 -0
  855. hydpy/models/wland/wland_fixed.py +12 -0
  856. hydpy/models/wland/wland_fluxes.py +166 -0
  857. hydpy/models/wland/wland_inputs.py +33 -0
  858. hydpy/models/wland/wland_masks.py +54 -0
  859. hydpy/models/wland/wland_model.py +3755 -0
  860. hydpy/models/wland/wland_outlets.py +11 -0
  861. hydpy/models/wland/wland_parameters.py +214 -0
  862. hydpy/models/wland/wland_sequences.py +108 -0
  863. hydpy/models/wland/wland_solver.py +45 -0
  864. hydpy/models/wland/wland_states.py +56 -0
  865. hydpy/models/wland_gd.py +888 -0
  866. hydpy/models/wland_wag.py +1244 -0
  867. hydpy/models/wq/__init__.py +14 -0
  868. hydpy/models/wq/wq_control.py +117 -0
  869. hydpy/models/wq/wq_derived.py +182 -0
  870. hydpy/models/wq/wq_factors.py +79 -0
  871. hydpy/models/wq/wq_fluxes.py +17 -0
  872. hydpy/models/wq/wq_model.py +1889 -0
  873. hydpy/models/wq_trapeze.py +168 -0
  874. hydpy/models/wq_trapeze_strickler.py +101 -0
  875. hydpy/models/wq_walrus.py +57 -0
  876. hydpy/py.typed +0 -0
  877. hydpy/tests/.coveragerc +22 -0
  878. hydpy/tests/__init__.py +0 -0
  879. hydpy/tests/check_consistency.py +32 -0
  880. hydpy/tests/hydpydoctestcustomize.pth +1 -0
  881. hydpy/tests/hydpydoctestcustomize.py +15 -0
  882. hydpy/tests/iotesting/__init__.py +0 -0
  883. hydpy/tests/run_doctests.py +233 -0
  884. hydpy-6.2.dev1.data/scripts/hyd.py +277 -0
  885. hydpy-6.2.dev1.dist-info/LICENSE +165 -0
  886. hydpy-6.2.dev1.dist-info/METADATA +163 -0
  887. hydpy-6.2.dev1.dist-info/RECORD +890 -0
  888. hydpy-6.2.dev1.dist-info/WHEEL +5 -0
  889. hydpy-6.2.dev1.dist-info/licenses_hydpy_installer.txt +42 -0
  890. hydpy-6.2.dev1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1849 @@
1
+ """This module implements so-called exchange items that simplify modifying the values
2
+ of |Parameter| and |Sequence_| objects."""
3
+
4
+ # import...
5
+ # ...from standard library
6
+ from __future__ import annotations
7
+ import itertools
8
+ import warnings
9
+
10
+ # ...from site-packages
11
+ import numpy
12
+
13
+ # ...from HydPy
14
+ import hydpy
15
+ from hydpy import config
16
+ from hydpy.core import devicetools
17
+ from hydpy.core import exceptiontools
18
+ from hydpy.core import objecttools
19
+ from hydpy.core import parametertools
20
+ from hydpy.core import selectiontools
21
+ from hydpy.core import sequencetools
22
+ from hydpy.core import variabletools
23
+ from hydpy.core.typingtools import *
24
+
25
+ Device2Target: TypeAlias = dict[
26
+ devicetools.Node | devicetools.Element, variabletools.Variable
27
+ ]
28
+ Selection2Targets: TypeAlias = dict[str, tuple[variabletools.Variable, ...]]
29
+ LevelType: TypeAlias = Literal["global", "selection", "device", "subunit"]
30
+
31
+
32
+ class ExchangeSpecification:
33
+ """Specification of a concrete |Parameter| or |Sequence_| type.
34
+
35
+ |ExchangeSpecification| is a helper class for |ExchangeItem| and its subclasses.
36
+ Its constructor interprets two strings and one optional string (without any
37
+ plausibility checks) and makes their information available as attributes. The
38
+ following tests list the expected cases:
39
+
40
+ >>> from hydpy.core.itemtools import ExchangeSpecification
41
+ >>> ExchangeSpecification(master="musk_classic", variable="control.nmbsequences",
42
+ ... keyword="lag")
43
+ ExchangeSpecification(master="musk_classic", variable="control.nmbsequences", \
44
+ keyword="lag")
45
+ >>> ExchangeSpecification(master="hland_96", variable="fluxes.qt")
46
+ ExchangeSpecification(master="hland_96", variable="fluxes.qt")
47
+ >>> ExchangeSpecification(master="hland_96", variable="fluxes.qt.series")
48
+ ExchangeSpecification(master="hland_96", variable="fluxes.qt.series")
49
+ >>> ExchangeSpecification(master="node", variable="sim")
50
+ ExchangeSpecification(master="node", variable="sim")
51
+ >>> ExchangeSpecification(master="node", variable="sim.series")
52
+ ExchangeSpecification(master="node", variable="sim.series")
53
+
54
+ The following attributes are accessible:
55
+
56
+ >>> spec = ExchangeSpecification(master="musk_classic",
57
+ ... variable="control.nmbsequences", keyword="lag")
58
+ >>> spec.master
59
+ 'musk_classic'
60
+ >>> spec.subgroup
61
+ 'control'
62
+ >>> spec.variable
63
+ 'nmbsequences'
64
+ >>> spec.series
65
+ False
66
+ >>> spec.keyword
67
+ 'lag'
68
+ """
69
+
70
+ master: str
71
+ """Either "node" or the name of the relevant base or application model (e. g.
72
+ "hland_96")."""
73
+ variable: str
74
+ """Name of the target or base variable."""
75
+ keyword: str | None
76
+ """(Optional) name of the target keyword argument of the target or base variable."""
77
+ series: bool
78
+ """Flag indicating whether to tackle the target variable's actual values (|False|)
79
+ or complete time series (|True|)."""
80
+ subgroup: str | None
81
+ """For model variables, the name of the parameter or sequence subgroup of the
82
+ target or base variable; for node sequences, |None|."""
83
+
84
+ def __init__(
85
+ self, *, master: str, variable: str, keyword: str | None = None
86
+ ) -> None:
87
+ self.master = master
88
+ entries = variable.split(".")
89
+ self.series = entries[-1] == "series"
90
+ if self.series:
91
+ del entries[-1]
92
+ try:
93
+ self.subgroup, self.variable = entries
94
+ except ValueError:
95
+ self.subgroup, self.variable = None, entries[0]
96
+ self.keyword = keyword
97
+
98
+ @property
99
+ def specstring(self) -> str:
100
+ """The string corresponding to the current values of `subgroup`, `state`, and
101
+ `variable`.
102
+
103
+ >>> from hydpy.core.itemtools import ExchangeSpecification
104
+ >>> spec = ExchangeSpecification(master="hland_96", variable="fluxes.qt")
105
+ >>> spec.specstring
106
+ 'fluxes.qt'
107
+ >>> spec.series = True
108
+ >>> spec.specstring
109
+ 'fluxes.qt.series'
110
+ >>> spec.subgroup = None
111
+ >>> spec.specstring
112
+ 'qt.series'
113
+ """
114
+ if self.subgroup is None:
115
+ variable = self.variable
116
+ else:
117
+ variable = f"{self.subgroup}.{self.variable}"
118
+ if self.series:
119
+ variable = f"{variable}.series"
120
+ return variable
121
+
122
+ def __repr__(self) -> str:
123
+ keyword = "" if self.keyword is None else f', keyword="{self.keyword}"'
124
+ return (
125
+ f'ExchangeSpecification(master="{self.master}", '
126
+ f'variable="{self.specstring}"{keyword})'
127
+ )
128
+
129
+
130
+ class ExchangeItem:
131
+ """Base class for exchanging values with multiple |Parameter| or |Sequence_|
132
+ objects of a concrete type."""
133
+
134
+ name: Name
135
+ """The name of the exchange item."""
136
+ targetspecs: ExchangeSpecification
137
+ """The exchange specification for the chosen target variable."""
138
+ device2target: Device2Target
139
+ """A target variable object for each device."""
140
+ selection2targets: Selection2Targets
141
+ """A tuple of target variable objects for each selection."""
142
+
143
+ @property
144
+ def ndim(self) -> int:
145
+ """The number of dimensions of the handled value vector.
146
+
147
+ Property |ExchangeItem.ndim| needs to be overwritten by the concrete
148
+ subclasses:
149
+
150
+ >>> from hydpy.core.itemtools import ExchangeItem
151
+ >>> ExchangeItem().ndim
152
+ Traceback (most recent call last):
153
+ ...
154
+ NotImplementedError
155
+ """
156
+ raise NotImplementedError()
157
+
158
+ def _iter_relevantelements(
159
+ self, selection: selectiontools.Selection
160
+ ) -> Iterator[devicetools.Element]:
161
+ for element in selection.elements:
162
+ for model in element.model.find_submodels(include_mainmodel=True).values():
163
+ name1 = model.name
164
+ name2 = name1.rpartition("_")[0]
165
+ if self.targetspecs.master in (name1, name2):
166
+ yield element
167
+ break
168
+
169
+ @staticmethod
170
+ def _query_elementvariable(
171
+ element: devicetools.Element, properties: ExchangeSpecification
172
+ ) -> variabletools.Variable:
173
+ # ToDo: Return more then one variable (possible for similar submodels).
174
+ p = properties
175
+ for model in element.model.find_submodels(include_mainmodel=True).values():
176
+ for group in (model.parameters, model.sequences):
177
+ if (
178
+ ((subgroupname := p.subgroup) is not None)
179
+ and ((subgroup := getattr(group, subgroupname, None)) is not None)
180
+ and ((variable := getattr(subgroup, p.variable, None)) is not None)
181
+ ):
182
+ assert isinstance(variable, variabletools.Variable)
183
+ return variable
184
+ raise RuntimeError(
185
+ f"No model of element `{element.name}` handles a parameter or sequence "
186
+ f"named `{p.variable}` in subgroup `{p.subgroup}`."
187
+ )
188
+
189
+ @staticmethod
190
+ def _query_nodevariable(
191
+ node: devicetools.Node, properties: ExchangeSpecification
192
+ ) -> sequencetools.NodeSequence:
193
+ sequence = getattr(node.sequences, properties.variable)
194
+ assert isinstance(sequence, sequencetools.NodeSequence)
195
+ return sequence
196
+
197
+ def collect_variables(self, selections: selectiontools.Selections) -> None:
198
+ """Collect the relevant target variables handled by the devices of the given
199
+ |Selections| object.
200
+
201
+ We prepare the `HydPy-H-Lahn` example project to be able to use its
202
+ |Selections| object:
203
+
204
+ >>> from hydpy.core.testtools import prepare_full_example_2
205
+ >>> hp, pub, TestIO = prepare_full_example_2()
206
+
207
+ We change the type of a specific application model to the type of its base
208
+ model for reasons explained later:
209
+
210
+ >>> from hydpy.models.hland import Model
211
+ >>> hp.elements.land_lahn_kalk.model.__class__ = Model
212
+
213
+ We prepare an |ExchangeItem| as an example, handling all |hland_states.Ic|
214
+ sequences corresponding to any application models derived from |hland|:
215
+
216
+ >>> from hydpy.core.itemtools import ExchangeItem, ExchangeSpecification
217
+ >>> item = ExchangeItem()
218
+
219
+ |ExchangeItem| is only a base class. Hence we need to prepare some missing
220
+ attributes manually:
221
+
222
+ >>> item.targetspecs = ExchangeSpecification(master="hland",
223
+ ... variable="states.ic")
224
+ >>> item.level = "global"
225
+ >>> item.device2target = {}
226
+ >>> item.selection2targets = {}
227
+
228
+ Applying method |ExchangeItem.collect_variables| connects the |ExchangeItem|
229
+ object with all four relevant |hland_states.Ic| objects:
230
+
231
+ >>> item.collect_variables(pub.selections)
232
+ >>> land_dill_assl = hp.elements.land_dill_assl
233
+ >>> for element in sorted(item.device2target, key=lambda x: x.name):
234
+ ... print(element)
235
+ land_dill_assl
236
+ land_lahn_kalk
237
+ land_lahn_leun
238
+ land_lahn_marb
239
+ >>> ic_states = land_dill_assl.model.sequences.states.ic
240
+ >>> item.device2target[land_dill_assl] is ic_states
241
+ True
242
+
243
+ Asking for |hland_states.Ic| objects corresponding to application model
244
+ |hland_96| only results in skipping the |Element| `land_lahn_kalk` (handling
245
+ the |hland| base model due to the hack above):
246
+
247
+ >>> item.targetspecs.master = "hland_96"
248
+ >>> item.device2target.clear()
249
+ >>> item.collect_variables(pub.selections)
250
+ >>> for element in sorted(item.device2target, key=lambda x: x.name):
251
+ ... print(element)
252
+ land_dill_assl
253
+ land_lahn_leun
254
+ land_lahn_marb
255
+ >>> ic_states = land_dill_assl.model.sequences.states.ic
256
+ >>> item.device2target[land_dill_assl] is ic_states
257
+ True
258
+
259
+ The value of sub-attribute |ExchangeSpecification.series| of attribute
260
+ |ExchangeItem.targetspecs| does not affect the results obtained with method
261
+ |ExchangeItem.collect_variables|:
262
+
263
+ >>> item.targetspecs.series = True
264
+ >>> item.collect_variables(pub.selections)
265
+ >>> ic_states = land_dill_assl.model.sequences.states.ic
266
+ >>> item.device2target[land_dill_assl] is ic_states
267
+ True
268
+
269
+ An ill-defined subgroup name results in the following error:
270
+
271
+ >>> item.targetspecs.subgroup = "wrong_group"
272
+ >>> item.collect_variables(pub.selections)
273
+ Traceback (most recent call last):
274
+ ...
275
+ RuntimeError: No model of element `land_dill_assl` handles a parameter or \
276
+ sequence named `ic` in subgroup `wrong_group`.
277
+
278
+ Collecting the |Sim| or |Obs| sequences of |Node| objects works similarly:
279
+
280
+ >>> item.targetspecs.master = "node"
281
+ >>> item.targetspecs.variable = "sim"
282
+ >>> item.targetspecs.subgroup = None
283
+ >>> item.targetspecs.series = False
284
+ >>> item.device2target.clear()
285
+ >>> item.collect_variables(pub.selections)
286
+ >>> dill_assl = hp.nodes.dill_assl
287
+ >>> for node in sorted(item.device2target, key=lambda x: x.name):
288
+ ... print(node)
289
+ dill_assl
290
+ lahn_kalk
291
+ lahn_leun
292
+ lahn_marb
293
+ >>> item.device2target[dill_assl] is dill_assl.sequences.sim
294
+ True
295
+ """
296
+ variable: variabletools.Variable
297
+ variables: list[variabletools.Variable]
298
+ if self.targetspecs.master in ("node", "nodes"):
299
+ for selection in selections:
300
+ variables = []
301
+ for node in selection.nodes:
302
+ variable = self._query_nodevariable(node, self.targetspecs)
303
+ self.device2target[node] = variable
304
+ variables.append(variable)
305
+ if variables:
306
+ self.selection2targets[selection.name] = tuple(variables)
307
+ else:
308
+ for selection in selections:
309
+ variables = []
310
+ for element in self._iter_relevantelements(selection):
311
+ variable = self._query_elementvariable(element, self.targetspecs)
312
+ self.device2target[element] = variable
313
+ variables.append(variable)
314
+ if variables:
315
+ self.selection2targets[selection.name] = tuple(variables)
316
+
317
+
318
+ def _make_subunit_name(
319
+ device: devicetools.Device, target: variabletools.Variable
320
+ ) -> Mayberable1[str]:
321
+ """
322
+ >>> from hydpy.core.itemtools import _make_subunit_name as make
323
+ >>> device = type("D", (), {"name": "dev"})()
324
+ >>> make(device, type("V", (), {"NDIM": 0, "shape": 0})())
325
+ 'dev'
326
+ >>> print(*make(device, type("V", (), {"NDIM": 1, "shape": (2,)})()))
327
+ dev_0 dev_1
328
+ >>> print(*make(device, type("V", (), {"NDIM": 3, "shape": (1, 2, 3)})()))
329
+ dev_0_0_0 dev_0_0_1 dev_0_0_2 dev_0_1_0 dev_0_1_1 dev_0_1_2
330
+ """
331
+ name = device.name
332
+ if target.NDIM == 0:
333
+ return name
334
+ ranges = (range(length) for length in target.shape)
335
+ return (
336
+ f"{name}_{'_'.join(str(idx) for idx in idxs)}"
337
+ for idxs in itertools.product(*ranges)
338
+ )
339
+
340
+
341
+ class ChangeItem(ExchangeItem):
342
+ """Base class for changing the values of multiple |Parameter| or |Sequence_|
343
+ objects of a specific type."""
344
+
345
+ level: LevelType
346
+ """The level at which the values of the change item are valid."""
347
+ _shape: tuple[()] | tuple[int] | None
348
+ _value: NDArrayFloat | None
349
+
350
+ @property
351
+ def ndim(self) -> int:
352
+ """The number of dimensions of the handled value vector."""
353
+ return (self.level != "global") + self.targetspecs.series
354
+
355
+ @property
356
+ def shape(self) -> tuple[()] | tuple[int]:
357
+ """The shape of the target variables.
358
+
359
+ Trying to access property |ChangeItem.shape| before calling method
360
+ |ChangeItem.collect_variables| results in the following error:
361
+
362
+ >>> from hydpy import SetItem
363
+ >>> SetItem(name="name", master="master", target="target", level="global").shape
364
+ Traceback (most recent call last):
365
+ ...
366
+ RuntimeError: The shape of SetItem `name` has not been determined so far.
367
+
368
+ See method |ChangeItem.collect_variables| for further information.
369
+ """
370
+ if self._shape is not None:
371
+ return self._shape
372
+ raise RuntimeError(
373
+ f"The shape of {type(self).__name__} `{self.name}` has not been "
374
+ f"determined so far."
375
+ )
376
+
377
+ @property
378
+ def seriesshape(self) -> tuple[int] | tuple[int, int]:
379
+ """The shape of the target variables' whole time series.
380
+
381
+ |ChangeItem.seriesshape| extends the |ChangeItem.shape| tuple by the length of
382
+ the current simulation period:
383
+
384
+ >>> from hydpy.core.testtools import prepare_full_example_2
385
+ >>> hp, pub, TestIO = prepare_full_example_2()
386
+ >>> from hydpy import SetItem
387
+ >>> for level in ("global", "selection", "device", "subunit"):
388
+ ... item = SetItem(name="t", master="hland", target="inputs.t.series",
389
+ ... level=level)
390
+ ... item.collect_variables(pub.selections)
391
+ ... print(level, item.shape, item.seriesshape)
392
+ global () (4,)
393
+ selection (2,) (2, 4)
394
+ device (4,) (4, 4)
395
+ subunit (4,) (4, 4)
396
+ """
397
+ if self.shape:
398
+ return self.shape[0], len(hydpy.pub.timegrids.sim)
399
+ return (len(hydpy.pub.timegrids.sim),)
400
+
401
+ @property
402
+ def subnames(self) -> tuple[()] | tuple[str, ...] | None:
403
+ """Artificial subnames of all values of all target variables.
404
+
405
+ Property |ChangeItem.subnames| offers a way to identify specific entries of the
406
+ vector returned by property |ChangeItem.value|. See method
407
+ |ChangeItem.collect_variables| for further information.
408
+ """
409
+ if self.level == "global":
410
+ return None
411
+ if self.level == "selection":
412
+ return tuple(self.selection2targets)
413
+ if self.level == "device":
414
+ return tuple(device.name for device in self.device2target)
415
+ if self.level == "subunit":
416
+ subnames: list[str] = []
417
+ for device, target in self.device2target.items():
418
+ subsubnames = _make_subunit_name(device, target)
419
+ if isinstance(subsubnames, str):
420
+ subnames.append(subsubnames)
421
+ else:
422
+ subnames.extend(subsubnames)
423
+ return tuple(subnames)
424
+ assert_never(self.level)
425
+
426
+ @property
427
+ def value(self) -> NDArrayFloat:
428
+ """The item value(s) changing the values of target variables through applying
429
+ method |ChangeItem.update_variables| of class |ChangeItem|.
430
+
431
+ >>> from hydpy.core.testtools import prepare_full_example_2
432
+ >>> hp, pub, TestIO = prepare_full_example_2()
433
+
434
+ The first example deals with "global" state values:
435
+
436
+ >>> from hydpy import print_matrix, round_, SetItem
437
+ >>> item = SetItem(name="ic", master="hland", target="states.ic",
438
+ ... level="global")
439
+ >>> item.collect_variables(pub.selections)
440
+ >>> item.value
441
+ Traceback (most recent call last):
442
+ ...
443
+ hydpy.core.exceptiontools.AttributeNotReady: The value(s) of the SetItem \
444
+ `ic` has/have not been prepared so far.
445
+
446
+ >>> item.value = 1.0
447
+ >>> round_(item.value)
448
+ 1.0
449
+
450
+ >>> item.value = 1.0, 2.0
451
+ Traceback (most recent call last):
452
+ ...
453
+ ValueError: When trying to convert the value(s) `(1.0, 2.0)` assigned to \
454
+ SetItem `ic` to a numpy array of shape `()` and type `float`, the following error \
455
+ occurred: could not broadcast input array from shape (2,) into shape ()
456
+
457
+ The second example deals with "selection-wide" input time series values:
458
+
459
+ >>> item = SetItem(name="t", master="hland", target="inputs.t.series",
460
+ ... level="selection")
461
+ >>> item.collect_variables(pub.selections)
462
+
463
+ >>> item.value = [1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0]
464
+ >>> print_matrix(item.value)
465
+ | 1.0, 2.0, 3.0, 4.0 |
466
+ | 5.0, 6.0, 7.0, 8.0 |
467
+
468
+ >>> item.value = 1.0, 2.0
469
+ Traceback (most recent call last):
470
+ ...
471
+ ValueError: When trying to convert the value(s) `(1.0, 2.0)` assigned to \
472
+ SetItem `t` to a numpy array of shape `(2, 4)` and type `float`, the following error \
473
+ occurred: could not broadcast input array from shape (2,) into shape (2,4)
474
+ """
475
+ if self._value is None:
476
+ raise exceptiontools.AttributeNotReady(
477
+ f"The value(s) of the {type(self).__name__} `{self.name}` has/have "
478
+ f"not been prepared so far."
479
+ )
480
+ return self._value
481
+
482
+ @value.setter
483
+ def value(self, value: NDArrayFloat) -> None:
484
+ try:
485
+ shape = self.seriesshape if self.targetspecs.series else self.shape
486
+ self._value = numpy.full(shape, value, dtype=config.NP_FLOAT)
487
+ except BaseException:
488
+ objecttools.augment_excmessage(
489
+ f"When trying to convert the value(s) `{value}` assigned to "
490
+ f"{type(self).__name__} `{self.name}` to a numpy array of shape "
491
+ f"`{shape}` and type `float`"
492
+ )
493
+
494
+ def collect_variables(self, selections: selectiontools.Selections) -> None:
495
+ """Apply method |ExchangeItem.collect_variables| of the base class
496
+ |ExchangeItem| and determine the |ChangeItem.shape| of the current |ChangeItem|
497
+ object afterwards.
498
+
499
+ For the following examples, we prepare the `HydPy-H-Lahn` example project:
500
+
501
+ >>> from hydpy.core.testtools import prepare_full_example_2
502
+ >>> hp, pub, TestIO = prepare_full_example_2()
503
+
504
+ After calling method |ChangeItem.collect_variables|, attribute
505
+ |ExchangeItem.device2target| assigns all relevant devices to the chosen target
506
+ variables:
507
+
508
+ >>> from hydpy import SetItem
509
+ >>> item = SetItem(name="ic", master="hland", target="states.ic",
510
+ ... level="global")
511
+ >>> item.collect_variables(pub.selections)
512
+ >>> for device, target in item.device2target.items():
513
+ ... print(device, target) # doctest: +ELLIPSIS
514
+ land_dill_assl ic(0.9694, ..., 1.47487)
515
+ land_lahn_marb ic(0.96404, ..., 1.46719)
516
+ land_lahn_kalk ic(0.96064, ..., 1.46444)
517
+ land_lahn_leun ic(0.96159, ..., 1.46393)
518
+
519
+ Similarly, attribute |ExchangeItem.selection2targets| maps all relevant
520
+ selections to the chosen target variables:
521
+
522
+ >>> for selection, targets in item.selection2targets.items():
523
+ ... print(selection, targets) # doctest: +ELLIPSIS
524
+ headwaters (ic(0.9694, ..., 1.47487), ic(0.96404, ..., 1.46719))
525
+ nonheadwaters (ic(0.96064, ..., 1.46444), ic(0.96159, ..., 1.46393))
526
+
527
+ The properties |ChangeItem.shape| and |ChangeItem.subnames| of a |ChangeItem|
528
+ object depend on the intended aggregation |ChangeItem.level|. For the "global"
529
+ level, we need only one scalar value for all target variables. Property
530
+ |ChangeItem.shape| indicates this by returning an empty tuple and property
531
+ |ChangeItem.subnames| by returning |None|:
532
+
533
+ >>> item.shape
534
+ ()
535
+ >>> item.subnames
536
+
537
+ For the "selection" level, we need one value for each relevant selection.
538
+ Therefore, we use the plain selection names as sub-names:
539
+
540
+ >>> item = SetItem(name="ic", master="hland", target="states.ic",
541
+ ... level="selection")
542
+ >>> item.collect_variables(pub.selections)
543
+ >>> item.shape
544
+ (2,)
545
+ >>> item.subnames
546
+ ('headwaters', 'nonheadwaters')
547
+
548
+ For the "device" level, we need one value for each relevant device. Therefore,
549
+ we use the plain device names as sub-names:
550
+
551
+ >>> item = SetItem(name="ic", master="hland", target="states.ic",
552
+ ... level="device")
553
+ >>> item.collect_variables(pub.selections)
554
+ >>> item.shape
555
+ (4,)
556
+ >>> item.subnames
557
+ ('land_dill_assl', 'land_lahn_marb', 'land_lahn_kalk', 'land_lahn_leun')
558
+
559
+ For the "subunit" level, we need one value for each vector entry of all target
560
+ variables. When using the 1-dimensional parameter |hland_states.IC| of the base
561
+ model |hland| as an example, property |ChangeItem.shape| agrees with the total
562
+ number of hydrological response units. Property |ChangeItem.subnames| combines
563
+ the device names with the zero-based index numbers of the vector entries of the
564
+ respective target variables:
565
+
566
+ >>> item = SetItem(name="ic", master="hland", target="states.ic",
567
+ ... level="subunit")
568
+ >>> item.collect_variables(pub.selections)
569
+ >>> item.shape
570
+ (49,)
571
+ >>> item.subnames # doctest: +ELLIPSIS
572
+ ('land_dill_assl_0', 'land_dill_assl_1', ..., 'land_lahn_leun_9')
573
+
574
+ For 2-dimensional sequences, |ChangeItem.shape| returns the total number of
575
+ matrix entries, and each sub-name indicates the row and the column of a specific
576
+ matrix entry:
577
+
578
+ >>> dill_assl = hp.elements.land_dill_assl.model
579
+ >>> dill_assl.parameters.control.sclass(2)
580
+ >>> item = SetItem(name="sp", master="hland", target="states.sp",
581
+ ... level="subunit")
582
+ >>> item.collect_variables(pub.selections)
583
+ >>> item.shape
584
+ (61,)
585
+ >>> item.subnames # doctest: +ELLIPSIS
586
+ ('land_dill_assl_0_0', 'land_dill_assl_0_1', ..., \
587
+ 'land_dill_assl_1_10', 'land_dill_assl_1_11', ..., 'land_lahn_leun_0_9')
588
+
589
+ For 0-dimensional sequences, |ChangeItem.shape| equals their number, and all
590
+ sub-names are identical to the corresponding device names:
591
+
592
+ >>> item = SetItem(name="lz", master="hland", target="states.lz",
593
+ ... level="subunit")
594
+ >>> item.collect_variables(pub.selections)
595
+ >>> item.shape
596
+ (4,)
597
+ >>> item.subnames # doctest: +ELLIPSIS
598
+ ('land_dill_assl', 'land_lahn_marb', 'land_lahn_kalk', 'land_lahn_leun')
599
+
600
+ Everything works as explained above when specifying a keyword argument for
601
+ defining values, except there is no support for the `subunit` level. We show
602
+ this for the parameter |musk_control.NmbSegments| of base model |musk|, which
603
+ accepts a custom keyword argument named `lag`:
604
+
605
+ >>> item = SetItem(name="lag", master="musk", target="control.nmbsegments",
606
+ ... keyword="lag", level="global")
607
+ >>> item.collect_variables(pub.selections)
608
+ >>> item.shape
609
+ ()
610
+ >>> item.subnames
611
+
612
+ >>> item = SetItem(name="lag", master="musk", target="control.nmbsegments",
613
+ ... keyword="lag", level="selection")
614
+ >>> item.collect_variables(pub.selections)
615
+ >>> item.shape
616
+ (1,)
617
+ >>> item.subnames
618
+ ('streams',)
619
+
620
+ >>> item = SetItem(name="lag", master="musk", target="control.nmbsegments",
621
+ ... keyword="lag", level="device")
622
+ >>> item.collect_variables(pub.selections)
623
+ >>> item.shape
624
+ (3,)
625
+ >>> item.subnames
626
+ ('stream_dill_assl_lahn_leun', 'stream_lahn_leun_lahn_kalk', \
627
+ 'stream_lahn_marb_lahn_leun')
628
+
629
+ >>> item = SetItem(name="lag", master="musk", target="control.nmbsegments",
630
+ ... keyword="lag", level="subunit")
631
+ >>> item.collect_variables(pub.selections)
632
+ Traceback (most recent call last):
633
+ ...
634
+ ValueError: Incorrect configuration for exchange item `lag`: When defining a \
635
+ keyword for an exchange item, its aggregation level cannot be `subunit`.
636
+ """
637
+ super().collect_variables(selections)
638
+ if self.level == "global":
639
+ self._shape = ()
640
+ elif self.level == "selection":
641
+ self._shape = (len(self.selection2targets),)
642
+ elif self.level == "device":
643
+ self._shape = (len(self.device2target),)
644
+ elif self.level == "subunit":
645
+ if self.targetspecs.keyword is not None:
646
+ raise ValueError(
647
+ f"Incorrect configuration for exchange item `{self.name}`: When "
648
+ f"defining a keyword for an exchange item, its aggregation level "
649
+ f"cannot be `subunit`."
650
+ )
651
+ self._shape = (
652
+ sum(target.numberofvalues for target in self.device2target.values()),
653
+ )
654
+ else:
655
+ assert_never(self.level)
656
+
657
+ def update_variable(
658
+ self, variable: variabletools.Variable, value: NDArrayFloat
659
+ ) -> None:
660
+ """Assign the given value(s) to the given target or base variable.
661
+
662
+ If the assignment fails, |ChangeItem.update_variable| raises an error like the
663
+ following:
664
+
665
+ >>> from hydpy.core.testtools import prepare_full_example_2
666
+ >>> hp, pub, TestIO = prepare_full_example_2()
667
+ >>> from hydpy.core.itemtools import ChangeItem, ExchangeSpecification
668
+ >>> item = ChangeItem()
669
+ >>> item.name = "alpha"
670
+ >>> item.targetspecs = ExchangeSpecification(master="hland_96",
671
+ ... variable="control.alpha")
672
+ >>> item.level = "global"
673
+ >>> item.device2target = {}
674
+ >>> item.selection2targets = {}
675
+ >>> item._value = "wrong"
676
+ >>> item.collect_variables(pub.selections)
677
+ >>> item.update_variables() # doctest: +ELLIPSIS
678
+ Traceback (most recent call last):
679
+ ...
680
+ TypeError: When trying to update a target variable of ChangeItem `alpha` with \
681
+ the value(s) `wrong`, the following error occurred: While trying to set the value(s) \
682
+ of variable `alpha` of element `land_dill_assl`, the following error occurred: The \
683
+ given value `wrong` cannot be converted to type `float`.
684
+ """
685
+ try:
686
+ if self.targetspecs.series:
687
+ assert isinstance(variable, sequencetools.IOSequence)
688
+ variable.simseries = value
689
+ elif self.targetspecs.keyword is None:
690
+ variable(value)
691
+ else:
692
+ assert isinstance(variable, parametertools.Parameter)
693
+ keywordarguments = variable.keywordarguments
694
+ keywordarguments.valid = True
695
+ keywordarguments[self.targetspecs.keyword] = value.item()
696
+ variable(**dict(keywordarguments))
697
+ except BaseException:
698
+ objecttools.augment_excmessage(
699
+ f"When trying to update a target variable of {type(self).__name__} "
700
+ f"`{self.name}` with the value(s) `{value}`"
701
+ )
702
+
703
+ def update_variables(self) -> None:
704
+ """Assign the current |ChangeItem.value| to the values or time series of the
705
+ target variables.
706
+
707
+ For the following examples, we prepare the `HydPy-H-Lahn` example project:
708
+
709
+ >>> from hydpy.core.testtools import prepare_full_example_2
710
+ >>> hp, pub, TestIO = prepare_full_example_2()
711
+
712
+ "Global" |SetItem| objects assign the same value to all chosen 0-dimensional
713
+ target variables (we use parameter |hland_control.Alpha| as an example):
714
+
715
+ >>> from hydpy import print_vector, round_, SetItem
716
+ >>> item = SetItem(name="alpha", master="hland_96", target="control.alpha",
717
+ ... level="global")
718
+ >>> item
719
+ SetItem(name="alpha", master="hland_96", target="control.alpha", level="global")
720
+ >>> item.collect_variables(pub.selections)
721
+ >>> land_dill_assl = hp.elements.land_dill_assl
722
+ >>> land_dill_assl.model.parameters.control.alpha
723
+ alpha(1.0)
724
+ >>> item.value = 2.0
725
+ >>> round_(item.value)
726
+ 2.0
727
+ >>> land_dill_assl.model.parameters.control.alpha
728
+ alpha(1.0)
729
+ >>> item.update_variables()
730
+ >>> for element in hp.elements.catchment:
731
+ ... print(element, element.model.parameters.control.alpha)
732
+ land_dill_assl alpha(2.0)
733
+ land_lahn_kalk alpha(2.0)
734
+ land_lahn_leun alpha(2.0)
735
+ land_lahn_marb alpha(2.0)
736
+
737
+ Similar holds for "Global" |SetItem| objects that modify the time series of
738
+ their target variables, which we demonstrate for the input time series
739
+ |hland_inputs.T|:
740
+
741
+ >>> item = SetItem(name="t", master="hland_96", target="inputs.t.series",
742
+ ... level="global")
743
+ >>> item.collect_variables(pub.selections)
744
+ >>> item.value = 0.5, 1.0, 1.5, 2.0
745
+ >>> item.update_variables()
746
+ >>> for element in hp.elements.catchment:
747
+ ... print(element, end=": ")
748
+ ... print_vector(element.model.sequences.inputs.t.series)
749
+ land_dill_assl: 0.5, 1.0, 1.5, 2.0
750
+ land_lahn_kalk: 0.5, 1.0, 1.5, 2.0
751
+ land_lahn_leun: 0.5, 1.0, 1.5, 2.0
752
+ land_lahn_marb: 0.5, 1.0, 1.5, 2.0
753
+
754
+ Some |Parameter| subclasses support setting their values via custom keyword
755
+ arguments. "Global" |SetItem| objects can use such keyword arguments. We show
756
+ this for the parameter |musk_control.NmbSegments| of base model |musk|, which
757
+ accepts a custom keyword argument named `lag`:
758
+
759
+ >>> item = SetItem(name="lag", master="musk", target="control.nmbsegments",
760
+ ... keyword="lag", level="global")
761
+ >>> item
762
+ SetItem(name="lag", master="musk", target="control.nmbsegments", \
763
+ keyword="lag", level="global")
764
+ >>> item.collect_variables(pub.selections)
765
+ >>> stream_lahn_marb_lahn_leun = hp.elements.stream_lahn_marb_lahn_leun
766
+ >>> stream_lahn_marb_lahn_leun.model.parameters.control.nmbsegments
767
+ nmbsegments(lag=0.583)
768
+ >>> item.value = 2.0
769
+ >>> round_(item.value)
770
+ 2.0
771
+ >>> stream_lahn_marb_lahn_leun.model.parameters.control.nmbsegments
772
+ nmbsegments(lag=0.583)
773
+ >>> item.update_variables()
774
+ >>> for element in hp.elements.river:
775
+ ... print(element, element.model.parameters.control.nmbsegments)
776
+ stream_dill_assl_lahn_leun nmbsegments(lag=2.0)
777
+ stream_lahn_leun_lahn_kalk nmbsegments(lag=2.0)
778
+ stream_lahn_marb_lahn_leun nmbsegments(lag=2.0)
779
+
780
+ For 1-dimensional target variables like the parameter |hland_control.FC|, a
781
+ "global" |SetItem| assigns the same value to each vector entry or the selected
782
+ keyword argument:
783
+
784
+ >>> item = SetItem(name="fc", master="hland_96", target="control.fc",
785
+ ... level="global")
786
+ >>> item.collect_variables(pub.selections)
787
+ >>> item.value = 200.0
788
+ >>> land_dill_assl.model.parameters.control.fc
789
+ fc(278.0)
790
+ >>> item.update_variables()
791
+ >>> land_dill_assl.model.parameters.control.fc
792
+ fc(200.0)
793
+
794
+ >>> item = SetItem(name="fc", master="hland_96", target="control.fc",
795
+ ... keyword="forest", level="global")
796
+ >>> item.collect_variables(pub.selections)
797
+ >>> item.value = 300.0
798
+ >>> land_dill_assl.model.parameters.control.fc
799
+ fc(200.0)
800
+ >>> item.update_variables()
801
+ >>> land_dill_assl.model.parameters.control.fc
802
+ fc(field=200.0, forest=300.0)
803
+
804
+ The same holds for 2-dimensional target variables like the sequence
805
+ |hland_states.SP| (we increase the number of snow classes and thus the length
806
+ of the first axis for demonstration purposes):
807
+
808
+ >>> land_dill_assl.model.parameters.control.sclass(2)
809
+ >>> item = SetItem(name="sp", master="hland_96", target="states.sp",
810
+ ... level="global")
811
+ >>> item.collect_variables(pub.selections)
812
+ >>> item.value = 5.0
813
+ >>> land_dill_assl.model.sequences.states.sp
814
+ sp([[nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan],
815
+ [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]])
816
+ >>> item.update_variables()
817
+ >>> land_dill_assl.model.sequences.states.sp
818
+ sp([[5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0],
819
+ [5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]])
820
+
821
+ When working on the "selection" level, a |SetItem| object assigns one specific
822
+ value to the target variables of each relevant selection, regardless of target
823
+ variable's dimensionality:
824
+
825
+ >>> item = SetItem(name="ic", master="hland_96", target="states.ic",
826
+ ... level="selection")
827
+ >>> item.collect_variables(pub.selections)
828
+ >>> land_dill_assl.model.sequences.states.ic # doctest: +ELLIPSIS
829
+ ic(0.9694, ..., 1.47487)
830
+ >>> item.value = 0.5, 1.0
831
+ >>> item.update_variables()
832
+ >>> for element in hp.elements.catchment: # doctest: +ELLIPSIS
833
+ ... print(element, element.model.sequences.states.ic)
834
+ land_dill_assl ic(0.5, 0.5, ..., 0.5, 0.5)
835
+ land_lahn_kalk ic(1.0, 1.0, ..., 1.0, 1.0)
836
+ land_lahn_leun ic(1.0, 1.0, ..., 1.0, 1.0)
837
+ land_lahn_marb ic(0.5, 0.5, ..., 0.5, 0.5)
838
+
839
+ >>> item = SetItem(name="t", master="hland_96", target="inputs.t.series",
840
+ ... level="selection")
841
+ >>> item.collect_variables(pub.selections)
842
+ >>> item.value = [0.5, 1.0, 1.5, 2.0], [2.5, 3.0, 3.5, 4.0]
843
+ >>> item.update_variables()
844
+ >>> for element in hp.elements.catchment:
845
+ ... print(element, end=": ")
846
+ ... print_vector(element.model.sequences.inputs.t.series)
847
+ land_dill_assl: 0.5, 1.0, 1.5, 2.0
848
+ land_lahn_kalk: 2.5, 3.0, 3.5, 4.0
849
+ land_lahn_leun: 2.5, 3.0, 3.5, 4.0
850
+ land_lahn_marb: 0.5, 1.0, 1.5, 2.0
851
+
852
+ >>> item = SetItem(name="tt", master="hland_96", target="control.tt",
853
+ ... keyword="field", level="selection")
854
+ >>> item.collect_variables(pub.selections)
855
+ >>> item.value = [0.0, 1.0]
856
+ >>> land_dill_assl.model.parameters.control.tt
857
+ tt(0.55824)
858
+ >>> item.update_variables()
859
+ >>> for element in hp.elements.catchment: # doctest: +ELLIPSIS
860
+ ... print(element, element.model.parameters.control.tt)
861
+ land_dill_assl tt(field=0.0, forest=0.55824)
862
+ land_lahn_kalk tt(field=1.0, forest=0.0)
863
+ land_lahn_leun tt(field=1.0, forest=0.0)
864
+ land_lahn_marb tt(field=0.0, forest=0.59365)
865
+
866
+ In contrast, each device receives one specific value when working on the
867
+ "device" level:
868
+
869
+ >>> item = SetItem(name="ic", master="hland_96", target="states.ic",
870
+ ... level="device")
871
+ >>> item.collect_variables(pub.selections)
872
+ >>> item.value = 0.5, 1.0, 1.5, 2.0
873
+ >>> item.update_variables()
874
+ >>> for element in hp.elements.catchment: # doctest: +ELLIPSIS
875
+ ... print(element, element.model.sequences.states.ic)
876
+ land_dill_assl ic(0.5, 0.5, ..., 0.5, 0.5)
877
+ land_lahn_kalk ic(1.5, 1.5, ..., 1.5, 1.5)
878
+ land_lahn_leun ic(2.0, 2.0, ..., 2.0, 2.0)
879
+ land_lahn_marb ic(1.0, 1.0, ... 1.0, 1.0)
880
+
881
+ >>> item = SetItem(name="t", master="hland_96", target="inputs.t.series",
882
+ ... level="device")
883
+ >>> item.collect_variables(pub.selections)
884
+ >>> item.value = [[0.5, 1.0, 1.5, 2.0], [2.5, 3.0, 3.5, 4.0],
885
+ ... [4.5, 5.0, 5.5, 6.0], [6.5, 7.0, 7.5, 8.0]]
886
+ >>> item.update_variables()
887
+ >>> for element in hp.elements.catchment:
888
+ ... print(element, end=": ")
889
+ ... print_vector(element.model.sequences.inputs.t.series)
890
+ land_dill_assl: 0.5, 1.0, 1.5, 2.0
891
+ land_lahn_kalk: 4.5, 5.0, 5.5, 6.0
892
+ land_lahn_leun: 6.5, 7.0, 7.5, 8.0
893
+ land_lahn_marb: 2.5, 3.0, 3.5, 4.0
894
+
895
+ >>> item = SetItem(name="beta", master="hland_96", target="control.beta",
896
+ ... keyword="forest", level="device")
897
+ >>> item.collect_variables(pub.selections)
898
+ >>> item.value = [1.0, 2.0, 3.0, 4.0]
899
+ >>> land_dill_assl.model.parameters.control.beta
900
+ beta(2.54011)
901
+ >>> item.update_variables()
902
+ >>> for element in hp.elements.catchment: # doctest: +ELLIPSIS
903
+ ... print(element, element.model.parameters.control.beta)
904
+ land_dill_assl beta(field=2.54011, forest=1.0)
905
+ land_lahn_kalk beta(field=1.51551, forest=3.0)
906
+ land_lahn_leun beta(field=2.5118, forest=4.0)
907
+ land_lahn_marb beta(field=1.45001, forest=2.0)
908
+
909
+ For the most detailed "subunit" level and 1-dimensional variables as
910
+ |hland_states.IC|, the |SetItem| object handles one value for each of the 49
911
+ hydrological response units of the complete `Lahn` river basin:
912
+
913
+ >>> item = SetItem(name="ic", master="hland_96", target="states.ic",
914
+ ... level="subunit")
915
+ >>> item.collect_variables(pub.selections)
916
+ >>> item.value = [value/100 for value in range(49)]
917
+ >>> item.update_variables()
918
+ >>> for element in hp.elements.catchment: # doctest: +ELLIPSIS
919
+ ... print(element, element.model.sequences.states.ic)
920
+ land_dill_assl ic(0.0, 0.01, ..., 0.1, 0.11)
921
+ land_lahn_kalk ic(0.25, 0.26, ..., 0.37, 0.38)
922
+ land_lahn_leun ic(0.39, 0.4, ..., 0.47, 0.48)
923
+ land_lahn_marb ic(0.12, 0.13, ... 0.23, 0.24)
924
+
925
+ We increased the number of snow classes per zone to two for element
926
+ `land_dill_assl`. Hence, its snow-related |hland_states.SP| object handles 22
927
+ instead of 11 values, and we need to assign 61 instead of 49 values to the
928
+ |SetItem| object. Each item value relates to a specific matrix entry of a
929
+ specific target variable:
930
+
931
+ >>> item = SetItem(name="sp", master="hland_96", target="states.sp",
932
+ ... level="subunit")
933
+ >>> item.collect_variables(pub.selections)
934
+ >>> item.value = [value/100 for value in range(61)]
935
+ >>> item.update_variables()
936
+ >>> for element in hp.elements.catchment: # doctest: +ELLIPSIS
937
+ ... print(element, element.model.sequences.states.sp)
938
+ land_dill_assl sp([[0.0, ...0.11],
939
+ [0.12, ...0.23]])
940
+ land_lahn_kalk sp(0.37, ...0.5)
941
+ land_lahn_leun sp(0.51, ...0.6)
942
+ land_lahn_marb sp(0.24, ...0.36)
943
+ """
944
+ values = self.value
945
+ if self.level == "global":
946
+ for variable in self.device2target.values():
947
+ self.update_variable(variable, values)
948
+ elif self.level == "selection":
949
+ for variables, value in zip(self.selection2targets.values(), values):
950
+ for variable in variables:
951
+ self.update_variable(variable, value)
952
+ elif self.level == "device":
953
+ for variable, value in zip(self.device2target.values(), values):
954
+ self.update_variable(variable, value)
955
+ elif self.level == "subunit":
956
+ idx0 = 0
957
+ for variable in self.device2target.values():
958
+ idx1 = idx0 + variable.numberofvalues
959
+ subvalues = values[idx0:idx1]
960
+ if variable.NDIM > 1:
961
+ subvalues = subvalues.reshape(variable.shape)
962
+ self.update_variable(variable, subvalues)
963
+ idx0 = idx1
964
+ else:
965
+ assert_never(self.level)
966
+
967
+
968
+ class SetItem(ChangeItem):
969
+ """Exchange item for assigning |ChangeItem.value| to multiple |Parameter| or
970
+ |Sequence_| objects of a specific type."""
971
+
972
+ def __init__(
973
+ self,
974
+ *,
975
+ name: str,
976
+ master: str,
977
+ target: str,
978
+ level: LevelType,
979
+ keyword: str | None = None,
980
+ ) -> None:
981
+ self.name = Name(name)
982
+ self.targetspecs = ExchangeSpecification(
983
+ master=master, variable=target, keyword=keyword
984
+ )
985
+ self.level = level
986
+ self._value = None
987
+ self._shape = None
988
+ self.device2target = {}
989
+ self.selection2targets = {}
990
+
991
+ def extract_values(self) -> None:
992
+ """Extract the target variables' values.
993
+
994
+ Method |SetItem.extract_values| implements the inverse functionality of method
995
+ |ChangeItem.update_variables|. It queries the values of the target variables,
996
+ aggregates them when necessary, and assigns them to the current |SetItem|
997
+ object. Please read the documentation on method |ChangeItem.update_variables|
998
+ first, explaining the "aggregation level" concept.
999
+
1000
+ For the following examples, we prepare the `HydPy-H-Lahn` example project:
1001
+
1002
+ >>> from hydpy.core.testtools import prepare_full_example_2
1003
+ >>> hp, pub, _ = prepare_full_example_2()
1004
+
1005
+ We define three |SetItem| objects, which handle states of different
1006
+ dimensionality. `lz` addresses the 0-dimensional sequence |hland_states.LZ|,
1007
+ `sm` the 1-dimensional sequence |hland_states.SM|, and `sp` the 2-dimensional
1008
+ sequence |hland_states.SP|:
1009
+
1010
+ >>> from hydpy import print_vector, round_, SetItem
1011
+ >>> lz = SetItem(name="lz", master="hland_96", target="states.lz",
1012
+ ... level="to be defined")
1013
+ >>> sm = SetItem(name="sm", master="hland_96", target="states.sm",
1014
+ ... level="to be defined")
1015
+ >>> sp = SetItem(name="sp", master="hland_96", target="states.sp",
1016
+ ... level="to be defined")
1017
+
1018
+ The additional |SetItem| objects `uz`, `ic`, and `wc` address the time series
1019
+ of the 0-dimensional sequence |hland_states.UZ|, the 1-dimensional sequence
1020
+ |hland_states.Ic|, and the 2-dimensional sequence |hland_states.WC|:
1021
+
1022
+ >>> uz = SetItem(name="uz", master="hland_96", target="states.uz.series",
1023
+ ... level="to be defined")
1024
+ >>> ic = SetItem(name="ic", master="hland_96", target="states.ic.series",
1025
+ ... level="to be defined")
1026
+ >>> wc = SetItem(name="wc", master="hland_96", target="states.wc.series",
1027
+ ... level="to be defined")
1028
+
1029
+ The following test function updates the aggregation level and calls
1030
+ |SetItem.extract_values| for all six items:
1031
+
1032
+ >>> def test(level):
1033
+ ... for item in (lz, sm, sp, uz, ic, wc):
1034
+ ... item.level = level
1035
+ ... item.collect_variables(pub.selections)
1036
+ ... item.extract_values()
1037
+
1038
+ We mainly focus on the sequences of the application model of element
1039
+ `land_dill_assl` when comparing results:
1040
+
1041
+ >>> dill_assl = hp.elements.land_dill_assl.model
1042
+
1043
+ For rigorous testing, we increase the number of snow classes of this model
1044
+ instance and, thus, the length of the first axis of its |hland_states.SP| and
1045
+ its |hland_states.WC| object:
1046
+
1047
+ >>> import numpy
1048
+ >>> dill_assl.parameters.control.sclass(2)
1049
+
1050
+ After this change, we must define new test data for the current state of the
1051
+ |hland_states.SP| object of element `land_dill_assl`:
1052
+
1053
+ >>> dill_assl.sequences.states.sp = numpy.arange(2*12).reshape(2, 12)
1054
+
1055
+ Also, we must prepare test data for all considered time series:
1056
+
1057
+ >>> dill_assl.sequences.states.uz.series = numpy.arange(4).reshape(4)
1058
+ >>> dill_assl.sequences.states.ic.series = numpy.arange(4*12).reshape(4, 12)
1059
+ >>> dill_assl.sequences.states.wc.series = numpy.arange(4*2*12).reshape(4,
1060
+ ... 2, 12)
1061
+
1062
+ For all aggregation levels except `subunit`, |SetItem.extract_values| relies on
1063
+ the (spatial) aggregation of data, which is not possible beyond the `device`
1064
+ level. Therefore, until the implementation of a more general spatial data
1065
+ concept into *HydPy*, |SetItem.extract_values| raises the following error when
1066
+ being applied to items working on the `global` or `selection` level:
1067
+
1068
+ >>> test("global")
1069
+ Traceback (most recent call last):
1070
+ ...
1071
+ NotImplementedError: HydPy does not support averaging values across different \
1072
+ elements so far. So, it is not possible to aggregate to the global level.
1073
+
1074
+ >>> test("selection")
1075
+ Traceback (most recent call last):
1076
+ ...
1077
+ NotImplementedError: HydPy does not support averaging values across different \
1078
+ elements so far. So, it is not possible to aggregate to the selection level.
1079
+
1080
+ For the `device` level and non-scalar variables, |SetItem.extract_values| uses
1081
+ the |Variable.average_values| method of class |Variable| or the
1082
+ |IOSequence.average_series| method of class |IOSequence| for calculating the
1083
+ individual exchange item values:
1084
+
1085
+ >>> test("device")
1086
+ >>> print_vector(lz.value)
1087
+ 8.70695, 8.18711, 7.52648, 10.14007
1088
+ >>> dill_assl.sequences.states.lz
1089
+ lz(8.70695)
1090
+ >>> print_vector(sm.value)
1091
+ 211.47288, 115.77717, 114.733823, 147.057048
1092
+ >>> round_(dill_assl.sequences.states.sm.average_values())
1093
+ 211.47288
1094
+ >>> print_vector(sp.value)
1095
+ 11.103987, 0.0, 0.0, 0.0
1096
+ >>> round_(dill_assl.sequences.states.sp.average_values())
1097
+ 11.103987
1098
+ >>> for series in uz.value:
1099
+ ... print_vector(series)
1100
+ 0.0, 1.0, 2.0, 3.0
1101
+ nan, nan, nan, nan
1102
+ nan, nan, nan, nan
1103
+ nan, nan, nan, nan
1104
+ >>> print_vector(dill_assl.sequences.states.uz.series)
1105
+ 0.0, 1.0, 2.0, 3.0
1106
+ >>> for series in ic.value:
1107
+ ... print_vector(series)
1108
+ 5.103987, 17.103987, 29.103987, 41.103987
1109
+ nan, nan, nan, nan
1110
+ nan, nan, nan, nan
1111
+ nan, nan, nan, nan
1112
+ >>> print_vector(dill_assl.sequences.states.ic.average_series())
1113
+ 5.103987, 17.103987, 29.103987, 41.103987
1114
+ >>> for series in wc.value:
1115
+ ... print_vector(series)
1116
+ 11.103987, 35.103987, 59.103987, 83.103987
1117
+ nan, nan, nan, nan
1118
+ nan, nan, nan, nan
1119
+ nan, nan, nan, nan
1120
+ >>> print_vector(dill_assl.sequences.states.wc.average_series())
1121
+ 11.103987, 35.103987, 59.103987, 83.103987
1122
+
1123
+ For the `subunit` level, no aggregation is necessary:
1124
+
1125
+ >>> test("subunit")
1126
+ >>> print_vector(lz.value)
1127
+ 8.70695, 8.18711, 7.52648, 10.14007
1128
+ >>> dill_assl.sequences.states.lz
1129
+ lz(8.70695)
1130
+ >>> print_vector(sm.value) # doctest: +ELLIPSIS
1131
+ 185.13164, 181.18755, 199.80432, 196.55888, 212.04018, 209.48859,
1132
+ 222.12115, 220.12671, 230.30756, 228.70779, 236.91943, 235.64427,
1133
+ 99.27505, 96.17726, 109.16576, 106.39745, 117.97304, 115.56252,
1134
+ 125.81523, 123.73198, 132.80035, 130.91684, 138.95523, 137.25983,
1135
+ 142.84148, 101.31248, 97.225, 111.3861, 107.64977, 120.59559,
1136
+ 117.26499, 129.01711, 126.0465, 136.66663, 134.01408, 143.59799,
1137
+ 141.24428, 147.75786, 153.54053, 138.31396, 135.71124, 147.54968,
1138
+ 145.47142, 154.96405, 153.32805, 160.91917, 159.62434, 165.65575,
1139
+ 164.63255
1140
+ >>> dill_assl.sequences.states.sm
1141
+ sm(185.13164, 181.18755, 199.80432, 196.55888, 212.04018, 209.48859,
1142
+ 222.12115, 220.12671, 230.30756, 228.70779, 236.91943, 235.64427)
1143
+ >>> hp.elements.land_lahn_kalk.model.sequences.states.sm
1144
+ sm(101.31248, 97.225, 111.3861, 107.64977, 120.59559, 117.26499,
1145
+ 129.01711, 126.0465, 136.66663, 134.01408, 143.59799, 141.24428,
1146
+ 147.75786, 153.54053)
1147
+ >>> print_vector(sp.value)
1148
+ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0,
1149
+ 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 0.0,
1150
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
1151
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
1152
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
1153
+ >>> for series in uz.value:
1154
+ ... print_vector(series)
1155
+ 0.0, 1.0, 2.0, 3.0
1156
+ nan, nan, nan, nan
1157
+ nan, nan, nan, nan
1158
+ nan, nan, nan, nan
1159
+ >>> print_vector(dill_assl.sequences.states.uz.series)
1160
+ 0.0, 1.0, 2.0, 3.0
1161
+ >>> for series in ic.value: # doctest: +ELLIPSIS
1162
+ ... print_vector(series)
1163
+ 0.0, 12.0, 24.0, 36.0
1164
+ 1.0, 13.0, 25.0, 37.0
1165
+ ...
1166
+ 10.0, 22.0, 34.0, 46.0
1167
+ 11.0, 23.0, 35.0, 47.0
1168
+ nan, nan, nan, nan
1169
+ ...
1170
+ >>> for idx in range(12): # doctest: +ELLIPSIS
1171
+ ... print_vector(dill_assl.sequences.states.ic.series[:, idx])
1172
+ 0.0, 12.0, 24.0, 36.0
1173
+ 1.0, 13.0, 25.0, 37.0
1174
+ ...
1175
+ 10.0, 22.0, 34.0, 46.0
1176
+ 11.0, 23.0, 35.0, 47.0
1177
+ >>> for series in wc.value: # doctest: +ELLIPSIS
1178
+ ... print_vector(series)
1179
+ 0.0, 24.0, 48.0, 72.0
1180
+ 12.0, 36.0, 60.0, 84.0
1181
+ 1.0, 25.0, 49.0, 73.0
1182
+ 13.0, 37.0, 61.0, 85.0
1183
+ ...
1184
+ 10.0, 34.0, 58.0, 82.0
1185
+ 22.0, 46.0, 70.0, 94.0
1186
+ 11.0, 35.0, 59.0, 83.0
1187
+ 23.0, 47.0, 71.0, 95.0
1188
+ nan, nan, nan, nan
1189
+ ...
1190
+ >>> for jdx in range(12): # doctest: +ELLIPSIS
1191
+ ... for idx in range(2):
1192
+ ... print_vector(dill_assl.sequences.states.wc.series[:, idx, jdx])
1193
+ 0.0, 24.0, 48.0, 72.0
1194
+ 12.0, 36.0, 60.0, 84.0
1195
+ 1.0, 25.0, 49.0, 73.0
1196
+ 13.0, 37.0, 61.0, 85.0
1197
+ ...
1198
+ 10.0, 34.0, 58.0, 82.0
1199
+ 22.0, 46.0, 70.0, 94.0
1200
+ 11.0, 35.0, 59.0, 83.0
1201
+ 23.0, 47.0, 71.0, 95.0
1202
+
1203
+ Due to the current limitation regarding the `global` and the `selection` level
1204
+ and the circumstance that parameter-specific keyword arguments hardly ever
1205
+ resolve the `subunit` level, extracting the values of keyword arguments works
1206
+ only for the `device` level:
1207
+
1208
+ >>> cfmax = SetItem(name="lag", master="hland_96", target="control.cfmax",
1209
+ ... keyword="forest", level="device")
1210
+ >>> cfmax.collect_variables(pub.selections)
1211
+ >>> cfmax.extract_values()
1212
+ >>> dill_assl.parameters.control.cfmax
1213
+ cfmax(field=4.55853, forest=2.735118)
1214
+ >>> print_vector(cfmax.value)
1215
+ 2.735118, 3.0, 2.1, 2.1
1216
+
1217
+ Method |SetItem.extract_values| cannot extract its complete data if the time
1218
+ series of any relevant variable is missing. We disable the |IOSequence.series|
1219
+ attribute of the considered sequences to show how things work then:
1220
+
1221
+ >>> dill_assl.sequences.states.uz.prepare_series(False)
1222
+ >>> dill_assl.sequences.states.ic.prepare_series(False)
1223
+ >>> dill_assl.sequences.states.wc.prepare_series(False)
1224
+
1225
+ Method |SetItem.extract_values| emits a warning when encountering the first
1226
+ unprepared |IOSequence.series| attribute and, if existing, deletes already
1227
+ available data:
1228
+
1229
+ >>> from hydpy.core.testtools import warn_later
1230
+ >>> with warn_later():
1231
+ ... test("device")
1232
+ AttributeNotReadyWarning: While trying to query the values of exchange item \
1233
+ `uz`, the following error occured: While trying to calculate the mean value of the \
1234
+ internal time series of sequence `uz` of element `land_dill_assl`, the following error \
1235
+ occurred: Sequence `uz` of element `land_dill_assl` is not requested to make any time \
1236
+ series data available.
1237
+ AttributeNotReadyWarning: While trying to query the values of exchange item \
1238
+ `ic`, the following error occured: While trying to calculate the mean value of the \
1239
+ internal time series of sequence `ic` of element `land_dill_assl`, the following error \
1240
+ occurred: Sequence `ic` of element `land_dill_assl` is not requested to make any time \
1241
+ series data available.
1242
+ AttributeNotReadyWarning: While trying to query the values of exchange item \
1243
+ `wc`, the following error occured: While trying to calculate the mean value of the \
1244
+ internal time series of sequence `wc` of element `land_dill_assl`, the following error \
1245
+ occurred: Sequence `wc` of element `land_dill_assl` is not requested to make any time \
1246
+ series data available.
1247
+
1248
+ >>> for series in uz.value:
1249
+ ... print_vector(series) # doctest: +ELLIPSIS
1250
+ Traceback (most recent call last):
1251
+ ...
1252
+ hydpy.core.exceptiontools.AttributeNotReady: The value(s) of the SetItem `uz` \
1253
+ has/have not been prepared so far.
1254
+ >>> for series in ic.value:
1255
+ ... print_vector(series) # doctest: +ELLIPSIS
1256
+ Traceback (most recent call last):
1257
+ ...
1258
+ hydpy.core.exceptiontools.AttributeNotReady: The value(s) of the SetItem `ic` \
1259
+ has/have not been prepared so far.
1260
+ >>> for series in wc.value:
1261
+ ... print_vector(series) # doctest: +ELLIPSIS
1262
+ Traceback (most recent call last):
1263
+ ...
1264
+ hydpy.core.exceptiontools.AttributeNotReady: The value(s) of the SetItem `wc` \
1265
+ has/have not been prepared so far.
1266
+
1267
+ >>> with warn_later():
1268
+ ... test("subunit")
1269
+ AttributeNotReadyWarning: While trying to query the values of exchange item \
1270
+ `uz`, the following error occured: Sequence `uz` of element `land_dill_assl` is not \
1271
+ requested to make any time series data available.
1272
+ AttributeNotReadyWarning: While trying to query the values of exchange item \
1273
+ `ic`, the following error occured: Sequence `ic` of element `land_dill_assl` is not \
1274
+ requested to make any time series data available.
1275
+ AttributeNotReadyWarning: While trying to query the values of exchange item \
1276
+ `wc`, the following error occured: Sequence `wc` of element `land_dill_assl` is not \
1277
+ requested to make any time series data available.
1278
+
1279
+ >>> for series in uz.value:
1280
+ ... print_vector(series) # doctest: +ELLIPSIS
1281
+ Traceback (most recent call last):
1282
+ ...
1283
+ hydpy.core.exceptiontools.AttributeNotReady: The value(s) of the SetItem `uz` \
1284
+ has/have not been prepared so far.
1285
+ >>> for series in ic.value: # doctest: +ELLIPSIS
1286
+ ... print_vector(series)
1287
+ Traceback (most recent call last):
1288
+ ...
1289
+ hydpy.core.exceptiontools.AttributeNotReady: The value(s) of the SetItem `ic` \
1290
+ has/have not been prepared so far.
1291
+ >>> for series in wc.value: # doctest: +ELLIPSIS
1292
+ ... print_vector(series)
1293
+ Traceback (most recent call last):
1294
+ ...
1295
+ hydpy.core.exceptiontools.AttributeNotReady: The value(s) of the SetItem `wc` \
1296
+ has/have not been prepared so far.
1297
+ """
1298
+ series = self.targetspecs.series
1299
+ shape = self.seriesshape if series else self.shape
1300
+ itemvalues: NDArrayFloat = numpy.empty(shape, dtype=config.NP_FLOAT)
1301
+ jdx0, jdx1 = hydpy.pub.timegrids.simindices
1302
+ if self.level == "device":
1303
+ for idx, variable in enumerate(self.device2target.values()):
1304
+ if series:
1305
+ assert isinstance(variable, sequencetools.IOSequence)
1306
+ try:
1307
+ itemvalues[idx] = variable.average_series()[jdx0:jdx1]
1308
+ except exceptiontools.AttributeNotReady as exc:
1309
+ self._value = None
1310
+ warnings.warn(
1311
+ f"While trying to query the values of exchange item "
1312
+ f"`{self.name}`, the following error occured: {exc}",
1313
+ exceptiontools.AttributeNotReadyWarning,
1314
+ )
1315
+ return
1316
+ elif self.targetspecs.keyword is None:
1317
+ itemvalues[idx] = variable.average_values()
1318
+ else:
1319
+ assert isinstance(variable, parametertools.Parameter)
1320
+ itemvalues[idx] = variable.keywordarguments[
1321
+ self.targetspecs.keyword
1322
+ ]
1323
+ elif self.level == "subunit":
1324
+ idx0 = 0
1325
+ for variable in self.device2target.values():
1326
+ idx1 = idx0 + variable.numberofvalues
1327
+ if series:
1328
+ assert isinstance(variable, sequencetools.IOSequence)
1329
+ try:
1330
+ targetvalues = variable.simseries.T
1331
+ if variable.NDIM > 0:
1332
+ targetvalues = targetvalues.reshape(
1333
+ -1, targetvalues.shape[-1]
1334
+ )
1335
+ except exceptiontools.AttributeNotReady as exc:
1336
+ self._value = None
1337
+ warnings.warn(
1338
+ f"While trying to query the values of exchange item "
1339
+ f"`{self.name}`, the following error occured: {exc}",
1340
+ exceptiontools.AttributeNotReadyWarning,
1341
+ )
1342
+ return
1343
+ else:
1344
+ targetvalues = variable.values
1345
+ if variable.NDIM > 1:
1346
+ targetvalues = targetvalues.flatten()
1347
+ itemvalues[idx0:idx1] = targetvalues
1348
+ idx0 = idx1
1349
+ # pylint: disable=consider-using-in
1350
+ elif (self.level == "selection") or (self.level == "global"):
1351
+ raise NotImplementedError(
1352
+ f"HydPy does not support averaging values across different elements so "
1353
+ f"far. So, it is not possible to aggregate to the {self.level} level."
1354
+ )
1355
+ else:
1356
+ assert_never(self.level)
1357
+ self.value = itemvalues
1358
+ return
1359
+
1360
+ def __repr__(self) -> str:
1361
+ ts = self.targetspecs
1362
+ keyword = "" if ts.keyword is None else f'keyword="{ts.keyword}", '
1363
+ return (
1364
+ f"{type(self).__name__}("
1365
+ f'name="{self.name}", '
1366
+ f'master="{ts.master}", '
1367
+ f'target="{ts.specstring}", '
1368
+ f"{keyword}"
1369
+ f'level="{self.level}")'
1370
+ )
1371
+
1372
+
1373
+ class MathItem(ChangeItem):
1374
+ """This base class performs some mathematical operations on the given values before
1375
+ assigning them to the handled target variables.
1376
+
1377
+ Subclasses of |MathItem| like |AddItem| handle not only target variables but also
1378
+ base variables:
1379
+
1380
+ >>> from hydpy.core.itemtools import MathItem
1381
+ >>> item = MathItem(name="sfcf", master="hland_96", target="control.sfcf",
1382
+ ... base="control.rfcf", level="global")
1383
+ >>> item
1384
+ MathItem(name="sfcf", master="hland_96", target="control.sfcf", \
1385
+ base="control.rfcf", level="global")
1386
+ >>> item.targetspecs
1387
+ ExchangeSpecification(master="hland_96", variable="control.sfcf")
1388
+ >>> item.basespecs
1389
+ ExchangeSpecification(master="hland_96", variable="control.rfcf")
1390
+
1391
+ Generally, each |MathItem| object calculates the value of the target variable of
1392
+ a |Device| object by using its current |ChangeItem.value| and the value(s) of the
1393
+ base variable of the same |Device|.
1394
+ """
1395
+
1396
+ basespecs: ExchangeSpecification
1397
+ """The exchange specification for the chosen base variable."""
1398
+ target2base: dict[variabletools.Variable, variabletools.Variable]
1399
+ """All target variable objects and their related base variable objects."""
1400
+
1401
+ def __init__(
1402
+ self, *, name: str, master: str, target: str, base: str, level: LevelType
1403
+ ) -> None:
1404
+ self.name = Name(name)
1405
+ self.targetspecs = ExchangeSpecification(master=master, variable=target)
1406
+ self.basespecs = ExchangeSpecification(master=master, variable=base)
1407
+ self.level = level
1408
+ self._value = None
1409
+ self._shape = None
1410
+ self.device2target = {}
1411
+ self.selection2targets = {}
1412
+ self.target2base = {}
1413
+
1414
+ def collect_variables(self, selections: selectiontools.Selections) -> None:
1415
+ """Apply method |ChangeItem.collect_variables| of the base class |ChangeItem|
1416
+ and also prepare the dictionary |MathItem.target2base|, which maps each target
1417
+ variable object to its base variable object.
1418
+
1419
+ >>> from hydpy.core.testtools import prepare_full_example_2
1420
+ >>> hp, pub, TestIO = prepare_full_example_2()
1421
+ >>> from hydpy import AddItem
1422
+ >>> item = AddItem(name="alpha", master="hland_96", target="control.sfcf",
1423
+ ... base="control.rfcf", level="global")
1424
+ >>> item.collect_variables(pub.selections)
1425
+ >>> land_dill_assl = hp.elements.land_dill_assl
1426
+ >>> control = land_dill_assl.model.parameters.control
1427
+ >>> item.device2target[land_dill_assl] is control.sfcf
1428
+ True
1429
+ >>> item.target2base[control.sfcf] is control.rfcf
1430
+ True
1431
+ >>> len(item.target2base)
1432
+ 4
1433
+ """
1434
+ super().collect_variables(selections)
1435
+ basename = self.basespecs.variable
1436
+ basegroup = self.basespecs.subgroup
1437
+ assert basegroup is not None
1438
+ allowed_bases = (parametertools.Parameters, sequencetools.Sequences)
1439
+ for target in self.device2target.values():
1440
+ vars_ = target.subvars.vars
1441
+ assert isinstance(vars_, allowed_bases)
1442
+ self.target2base[target] = vars_[basegroup][basename]
1443
+
1444
+ def __repr__(self) -> str:
1445
+ return (
1446
+ f"{type(self).__name__}("
1447
+ f'name="{self.name}", '
1448
+ f'master="{self.targetspecs.master}", '
1449
+ f'target="{self.targetspecs.specstring}", '
1450
+ f'base="{self.basespecs.specstring}", '
1451
+ f'level="{self.level}")'
1452
+ )
1453
+
1454
+
1455
+ class AddItem(MathItem):
1456
+ """|MathItem| subclass performing additions.
1457
+
1458
+ The following examples relate closely to the ones explained in the documentation of
1459
+ the method |ChangeItem.update_variables| of class |ChangeItem|. Therefore, we
1460
+ similarly repeat them all to show that our |AddItem| always uses the sum of its own
1461
+ value(s) and the value(s) of the related base variable to update the value(s) of
1462
+ the target variable.
1463
+
1464
+ We prepare the `HydPy-H-Lahn` example project:
1465
+
1466
+ >>> from hydpy.core.testtools import prepare_full_example_2
1467
+ >>> hp, pub, TestIO = prepare_full_example_2()
1468
+
1469
+ We use the rainfall correction parameter (|hland_control.RfCF|) of the application
1470
+ model |hland_96| as the base variable. Defining a different correction factor for
1471
+ each of the 49 hydrological response units allows strict testing:
1472
+
1473
+ >>> value = 0.8
1474
+ >>> for element in hp.elements.catchment:
1475
+ ... rfcf = element.model.parameters.control.rfcf
1476
+ ... for idx in range(len(rfcf)):
1477
+ ... rfcf[idx] = value
1478
+ ... value += 0.01
1479
+ ... print(element, rfcf) # doctest: +ELLIPSIS
1480
+ land_dill_assl rfcf(0.8, ... 0.91)
1481
+ land_lahn_kalk rfcf(0.92, ... 1.05)
1482
+ land_lahn_leun rfcf(1.06, ... 1.15)
1483
+ land_lahn_marb rfcf(1.16, ... 1.28)
1484
+
1485
+ We choose the snowfall correction parameter (|hland_control.SfCF|) as the target
1486
+ variable. The following test calculations show the expected results for all
1487
+ available aggregation levels:
1488
+
1489
+ >>> from hydpy.core.itemtools import AddItem
1490
+ >>> item = AddItem(name="sfcf", master="hland_96", target="control.sfcf",
1491
+ ... base="control.rfcf", level="global")
1492
+ >>> item.collect_variables(pub.selections)
1493
+ >>> item.value = 0.1
1494
+ >>> item.update_variables()
1495
+ >>> for element in hp.elements.catchment: # doctest: +ELLIPSIS
1496
+ ... print(element, element.model.parameters.control.sfcf)
1497
+ land_dill_assl sfcf(0.9, ... 1.01)
1498
+ land_lahn_kalk sfcf(1.02, ... 1.15)
1499
+ land_lahn_leun sfcf(1.16, ... 1.25)
1500
+ land_lahn_marb sfcf(1.26, ... 1.38)
1501
+
1502
+ >>> item.level = "selection"
1503
+ >>> item.collect_variables(pub.selections)
1504
+ >>> item.value = -0.1, 0.0
1505
+ >>> item.update_variables()
1506
+ >>> for element in hp.elements.catchment: # doctest: +ELLIPSIS
1507
+ ... print(element, element.model.parameters.control.sfcf)
1508
+ land_dill_assl sfcf(0.7, ... 0.81)
1509
+ land_lahn_kalk sfcf(0.92, ... 1.05)
1510
+ land_lahn_leun sfcf(1.06, ... 1.15)
1511
+ land_lahn_marb sfcf(1.06, ... 1.18)
1512
+
1513
+ >>> item = AddItem(name="sfcf", master="hland_96", target="control.sfcf",
1514
+ ... base="control.rfcf", level="device")
1515
+ >>> item.collect_variables(pub.selections)
1516
+ >>> item.value = -0.1, 0.0, 0.1, 0.2
1517
+ >>> item.update_variables()
1518
+ >>> for element in hp.elements.catchment: # doctest: +ELLIPSIS
1519
+ ... print(element, element.model.parameters.control.sfcf)
1520
+ land_dill_assl sfcf(0.7, ... 0.81)
1521
+ land_lahn_kalk sfcf(1.02, ... 1.15)
1522
+ land_lahn_leun sfcf(1.26, ... 1.35)
1523
+ land_lahn_marb sfcf(1.16, ... 1.28)
1524
+
1525
+ >>> item = AddItem(name="sfcf", master="hland_96", target="control.sfcf",
1526
+ ... base="control.rfcf", level="subunit")
1527
+ >>> item.collect_variables(pub.selections)
1528
+ >>> item.value = [idx/100 for idx in range(-20, 29)]
1529
+ >>> item.update_variables()
1530
+ >>> for element in hp.elements.catchment: # doctest: +ELLIPSIS
1531
+ ... print(element, element.model.parameters.control.sfcf)
1532
+ land_dill_assl sfcf(0.6, ... 0.82)
1533
+ land_lahn_kalk sfcf(0.97, ... 1.23)
1534
+ land_lahn_leun sfcf(1.25, ... 1.43)
1535
+ land_lahn_marb sfcf(1.08, ... 1.32)
1536
+ """
1537
+
1538
+ def update_variable(
1539
+ self, variable: variabletools.Variable, value: NDArrayFloat
1540
+ ) -> None:
1541
+ """Assign the sum of the given value(s) and the value(s) of the base variable
1542
+ to the given target variable.
1543
+
1544
+ If the addition fails, |AddItem.update_variable| raises an error like the
1545
+ following:
1546
+
1547
+ >>> from hydpy.core.testtools import prepare_full_example_2
1548
+ >>> hp, pub, TestIO = prepare_full_example_2()
1549
+ >>> from hydpy.core.itemtools import AddItem
1550
+ >>> item = AddItem(name="sfcf", master="hland_96", target="control.sfcf",
1551
+ ... base="control.rfcf", level="global")
1552
+ >>> item.collect_variables(pub.selections)
1553
+ >>> item._value = 0.1, 0.2
1554
+ >>> item.update_variables() # doctest: +ELLIPSIS
1555
+ Traceback (most recent call last):
1556
+ ...
1557
+ ValueError: When trying to add the value(s) `(0.1, 0.2)` of AddItem `sfcf` \
1558
+ and the value(s) `[1.04283 ... 1.04283]` of variable `rfcf` of element \
1559
+ `land_dill_assl`, the following error occurred: operands could not be broadcast \
1560
+ together with shapes (12,) (2,)...
1561
+ """
1562
+ base = self.target2base[variable]
1563
+ try:
1564
+ result = base.value + value
1565
+ except BaseException:
1566
+ objecttools.augment_excmessage(
1567
+ f"When trying to add the value(s) `{value}` of AddItem "
1568
+ f"`{self.name}` and the value(s) `{base.value}` of variable "
1569
+ f"{objecttools.devicephrase(base)}"
1570
+ )
1571
+ super().update_variable(variable, result)
1572
+
1573
+
1574
+ class MultiplyItem(MathItem):
1575
+ """|MathItem| subclass performing multiplications.
1576
+
1577
+ Besides performing a multiplication instead of an addition, class |MultiplyItem|
1578
+ behaves exactly like class |AddItem|. We adopt a single example of the
1579
+ documentation on class |AddItem| to demonstrate this difference:
1580
+
1581
+ >>> from hydpy.core.testtools import prepare_full_example_2
1582
+ >>> hp, pub, TestIO = prepare_full_example_2()
1583
+
1584
+ >>> value = 0.8
1585
+ >>> for element in hp.elements.catchment:
1586
+ ... rfcf = element.model.parameters.control.rfcf
1587
+ ... for idx in range(len(rfcf)):
1588
+ ... rfcf[idx] = value
1589
+ ... value += 0.01
1590
+ ... print(element, rfcf) # doctest: +ELLIPSIS
1591
+ land_dill_assl rfcf(0.8, ... 0.91)
1592
+ land_lahn_kalk rfcf(0.92, ... 1.05)
1593
+ land_lahn_leun rfcf(1.06, ... 1.15)
1594
+ land_lahn_marb rfcf(1.16, ... 1.28)
1595
+
1596
+ >>> from hydpy.core.itemtools import MultiplyItem
1597
+ >>> item = MultiplyItem(name="sfcf", master="hland_96", target="control.sfcf",
1598
+ ... base="control.rfcf", level="global")
1599
+ >>> item.collect_variables(pub.selections)
1600
+ >>> item.value = 2.0
1601
+ >>> item.update_variables()
1602
+ >>> for element in hp.elements.catchment: # doctest: +ELLIPSIS
1603
+ ... print(element, element.model.parameters.control.sfcf)
1604
+ land_dill_assl sfcf(1.6, ... 1.82)
1605
+ land_lahn_kalk sfcf(1.84, ... 2.1)
1606
+ land_lahn_leun sfcf(2.12, ... 2.3)
1607
+ land_lahn_marb sfcf(2.32, ... 2.56)
1608
+ """
1609
+
1610
+ def update_variable(
1611
+ self, variable: variabletools.Variable, value: NDArrayFloat
1612
+ ) -> None:
1613
+ """Assign the product of the given value(s) and the value(s) of the base
1614
+ variable to the given target variable.
1615
+
1616
+ If the multiplication fails, |MultiplyItem.update_variable| raises an error
1617
+ like the following:
1618
+
1619
+ >>> from hydpy.core.testtools import prepare_full_example_2
1620
+ >>> hp, pub, TestIO = prepare_full_example_2()
1621
+ >>> from hydpy.core.itemtools import MultiplyItem
1622
+ >>> item = MultiplyItem(name="sfcf", master="hland_96", target="control.sfcf",
1623
+ ... base="control.rfcf", level="global")
1624
+ >>> item.collect_variables(pub.selections)
1625
+ >>> item._value = 0.1, 0.2
1626
+ >>> item.update_variables() # doctest: +ELLIPSIS
1627
+ Traceback (most recent call last):
1628
+ ...
1629
+ ValueError: When trying to multiply the value(s) `(0.1, 0.2)` of AddItem \
1630
+ `sfcf` and the value(s) `[1.04283 ... 1.04283]` of variable `rfcf` of element \
1631
+ `land_dill_assl`, the following error occurred: operands could not be broadcast \
1632
+ together with shapes (12,) (2,)...
1633
+ """
1634
+ base = self.target2base[variable]
1635
+ try:
1636
+ result = base.value * value
1637
+ except BaseException:
1638
+ objecttools.augment_excmessage(
1639
+ f"When trying to multiply the value(s) `{value}` of AddItem "
1640
+ f"`{self.name}` and the value(s) `{base.value}` of variable "
1641
+ f"{objecttools.devicephrase(base)}"
1642
+ )
1643
+ super().update_variable(variable, result)
1644
+
1645
+
1646
+ class GetItem(ExchangeItem):
1647
+ """Base class for querying the values of multiple |Parameter| or |Sequence_|
1648
+ objects of a specific type."""
1649
+
1650
+ _device2name: dict[devicetools.Node | devicetools.Element, Name]
1651
+ _ndim: int | None = None
1652
+
1653
+ def __init__(self, *, name: Name, master: str, target: str) -> None:
1654
+ self.name = name
1655
+ self.target = target.replace(".", "_")
1656
+ self.targetspecs = ExchangeSpecification(master=master, variable=target)
1657
+ self.device2target = {}
1658
+ self.selection2targets = {}
1659
+ self._device2name = {}
1660
+
1661
+ @property
1662
+ def ndim(self) -> int:
1663
+ """The number of dimensions of the handled value vector.
1664
+
1665
+ Trying to access property |GetItem.ndim| before calling method
1666
+ |GetItem.collect_variables| results in the following error message:
1667
+
1668
+ >>> from hydpy.core.itemtools import GetItem
1669
+ >>> GetItem(name="temp", master="hland_96", target="states.lz").ndim
1670
+ Traceback (most recent call last):
1671
+ ...
1672
+ hydpy.core.exceptiontools.AttributeNotReady: Attribute `ndim` of GetItem \
1673
+ `temp` is not ready.
1674
+
1675
+ See the documentation of the method |GetItem.collect_variables| for further
1676
+ information.
1677
+ """
1678
+ if self._ndim is None:
1679
+ raise exceptiontools.AttributeNotReady(
1680
+ f"Attribute `ndim` of {type(self).__name__} `{self.name}` is not ready."
1681
+ )
1682
+ return self._ndim
1683
+
1684
+ def collect_variables(self, selections: selectiontools.Selections) -> None:
1685
+ """Apply method |ExchangeItem.collect_variables| of the base class
1686
+ |ExchangeItem| and determine the |GetItem.ndim| attribute of the current
1687
+ |GetItem| object afterwards.
1688
+
1689
+ The value of |GetItem.ndim| depends on whether the target variable's values or
1690
+ time series are of interest:
1691
+
1692
+ >>> from hydpy.core.testtools import prepare_full_example_2
1693
+ >>> hp, pub, TestIO = prepare_full_example_2()
1694
+ >>> from hydpy.core.itemtools import GetItem
1695
+ >>> for target in ("states.lz", "states.lz.series",
1696
+ ... "states.sm", "states.sm.series"):
1697
+ ... item = GetItem(name="temp", master="hland_96", target=target)
1698
+ ... item.collect_variables(pub.selections)
1699
+ ... print(item, item.ndim)
1700
+ GetItem(name="temp", master="hland_96", target="states.lz") 0
1701
+ GetItem(name="temp", master="hland_96", target="states.lz.series") 1
1702
+ GetItem(name="temp", master="hland_96", target="states.sm") 1
1703
+ GetItem(name="temp", master="hland_96", target="states.sm.series") 2
1704
+ """
1705
+ super().collect_variables(selections)
1706
+ for device in sorted(self.device2target.keys(), key=lambda x: x.name):
1707
+ self._device2name[device] = Name(f"{device.name}_{self.target}")
1708
+ for target in self.device2target.values():
1709
+ self._ndim = target.NDIM
1710
+ if self.targetspecs.series:
1711
+ self._ndim += 1
1712
+ break
1713
+
1714
+ def yield_name2subnames(
1715
+ self,
1716
+ ) -> Iterator[tuple[Name, str | tuple[()] | tuple[str, ...]]]:
1717
+ """Sequentially return pairs of the item name and its artificial sub-names.
1718
+
1719
+ The purpose and definition of the sub-names are similar to those returned by
1720
+ property |ChangeItem.subnames| of class |ChangeItem| described in the
1721
+ documentation on method |ChangeItem.collect_variables|. However, class
1722
+ |GetItem| does not support different aggregation levels and each |GetItem|
1723
+ object operates on the device level. Therefore, the returned sub-names rely on
1724
+ the device names; and, for non-scalar target variables, additionally on the
1725
+ individual vector or matrix indices.
1726
+
1727
+ Each item name is automatically generated and contains the name of the
1728
+ respective |Variable| object's |Device| and the target description.
1729
+
1730
+ For 0-dimensional variables, there is only one sub-name that is identical to
1731
+ the device name:
1732
+
1733
+ >>> from hydpy.core.testtools import prepare_full_example_2
1734
+ >>> hp, pub, TestIO = prepare_full_example_2()
1735
+ >>> from hydpy import SetItem
1736
+ >>> item = GetItem(name="lz", master="hland_96", target="states.lz")
1737
+ >>> item.collect_variables(pub.selections)
1738
+ >>> for name, subnames in item.yield_name2subnames():
1739
+ ... print(name, subnames)
1740
+ land_dill_assl_states_lz land_dill_assl
1741
+ land_lahn_kalk_states_lz land_lahn_kalk
1742
+ land_lahn_leun_states_lz land_lahn_leun
1743
+ land_lahn_marb_states_lz land_lahn_marb
1744
+
1745
+ >>> item = GetItem(name="sim", master="nodes", target="sim.series")
1746
+ >>> item.collect_variables(pub.selections)
1747
+ >>> for name, subnames in item.yield_name2subnames():
1748
+ ... print(name, subnames)
1749
+ dill_assl_sim_series dill_assl
1750
+ lahn_kalk_sim_series lahn_kalk
1751
+ lahn_leun_sim_series lahn_leun
1752
+ lahn_marb_sim_series lahn_marb
1753
+
1754
+ For non-scalar variables, the sub-names combine the device name and all
1755
+ possible index combinations for the current shape of the target variable:
1756
+
1757
+ >>> item = GetItem(name="sm", master="hland_96", target="states.sm")
1758
+ >>> item.collect_variables(pub.selections)
1759
+ >>> for name, subnames in item.yield_name2subnames():
1760
+ ... print(name, subnames) # doctest: +ELLIPSIS
1761
+ land_dill_assl_states_sm ('land_dill_assl_0', ..., 'land_dill_assl_11')
1762
+ land_lahn_kalk_states_sm ('land_lahn_kalk_0', ..., 'land_lahn_kalk_13')
1763
+ land_lahn_leun_states_sm ('land_lahn_leun_0', ..., 'land_lahn_leun_9')
1764
+ land_lahn_marb_states_sm ('land_lahn_marb_0', ..., 'land_lahn_marb_12')
1765
+
1766
+ >>> item = GetItem(name="sp", master="hland_96", target="states.sp")
1767
+ >>> item.collect_variables(pub.selections)
1768
+ >>> for name, subnames in item.yield_name2subnames():
1769
+ ... print(name, subnames) # doctest: +ELLIPSIS
1770
+ land_dill_assl_states_sp ('land_dill_assl_0_0', ..., 'land_dill_assl_0_11')
1771
+ land_lahn_kalk_states_sp ('land_lahn_kalk_0_0', ..., 'land_lahn_kalk_0_13')
1772
+ land_lahn_leun_states_sp ('land_lahn_leun_0_0', ..., 'land_lahn_leun_0_9')
1773
+ land_lahn_marb_states_sp ('land_lahn_marb_0_0', ..., 'land_lahn_marb_0_12')
1774
+ """
1775
+ for device, name in self._device2name.items():
1776
+ subnames = _make_subunit_name(device, self.device2target[device])
1777
+ if isinstance(subnames, str):
1778
+ yield name, subnames
1779
+ else:
1780
+ yield name, tuple(subnames)
1781
+
1782
+ def yield_name2value(
1783
+ self, idx1: int | None = None, idx2: int | None = None
1784
+ ) -> Iterator[tuple[Name, str]]:
1785
+ """Sequentially return name-value pairs describing the current state of the
1786
+ target variables.
1787
+
1788
+ The item names are automatically generated and contain both the name of the
1789
+ |Device| of the respective |Variable| object and the target description:
1790
+
1791
+ >>> from hydpy.core.testtools import prepare_full_example_2
1792
+ >>> hp, pub, TestIO = prepare_full_example_2()
1793
+ >>> from hydpy import SetItem
1794
+ >>> item = GetItem(name="lz", master="hland_96", target="states.lz")
1795
+ >>> item.collect_variables(pub.selections)
1796
+ >>> hp.elements.land_dill_assl.model.sequences.states.lz = 100.0
1797
+ >>> for name, value in item.yield_name2value():
1798
+ ... print(name, value)
1799
+ land_dill_assl_states_lz 100.0
1800
+ land_lahn_kalk_states_lz 7.52648
1801
+ land_lahn_leun_states_lz 10.14007
1802
+ land_lahn_marb_states_lz 8.18711
1803
+ >>> item = GetItem(name="sm", master="hland_96", target="states.sm")
1804
+ >>> item.collect_variables(pub.selections)
1805
+ >>> hp.elements.land_dill_assl.model.sequences.states.sm = 2.0
1806
+ >>> for name, value in item.yield_name2value():
1807
+ ... print(name, value) # doctest: +ELLIPSIS
1808
+ land_dill_assl_states_sm [2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, \
1809
+ 2.0, 2.0, 2.0, 2.0]
1810
+ land_lahn_kalk_states_sm [101.31248, ..., 153.54053]
1811
+ ...
1812
+
1813
+ When querying time series, one can restrict the span of interest by passing
1814
+ index values:
1815
+
1816
+ >>> item = GetItem(name="sim", master="nodes", target="sim.series")
1817
+ >>> item.collect_variables(pub.selections)
1818
+ >>> hp.nodes.dill_assl.sequences.sim.series = 1.0, 2.0, 3.0, 4.0
1819
+ >>> for name, value in item.yield_name2value():
1820
+ ... print(name, value) # doctest: +ELLIPSIS
1821
+ dill_assl_sim_series [1.0, 2.0, 3.0, 4.0]
1822
+ lahn_kalk_sim_series [nan, ...
1823
+ ...
1824
+ >>> for name, value in item.yield_name2value(2, 3):
1825
+ ... print(name, value) # doctest: +ELLIPSIS
1826
+ dill_assl_sim_series [3.0]
1827
+ lahn_kalk_sim_series [nan]
1828
+ ...
1829
+ """
1830
+ for device, name in self._device2name.items():
1831
+ target = self.device2target[device]
1832
+ if self.targetspecs.series:
1833
+ assert isinstance(target, sequencetools.IOSequence)
1834
+ values = target.series[idx1:idx2]
1835
+ else:
1836
+ values = target.values
1837
+ if self.ndim == 0:
1838
+ values = objecttools.repr_(float(values))
1839
+ else:
1840
+ values = objecttools.repr_list(values.tolist())
1841
+ yield name, values
1842
+
1843
+ def __repr__(self) -> str:
1844
+ return (
1845
+ f"{type(self).__name__}("
1846
+ f'name="{self.name}", '
1847
+ f'master="{self.targetspecs.master}", '
1848
+ f'target="{self.targetspecs.specstring}")'
1849
+ )