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,1398 @@
1
+ """This module implements features related to importing models.
2
+
3
+ The implemented tools are primarily designed for hiding model initialisation routines
4
+ from model users and for allowing writing readable doctests.
5
+ """
6
+
7
+ # import...
8
+ # ...from standard library
9
+ from __future__ import annotations
10
+
11
+ import collections
12
+ import copy
13
+ import os
14
+ import importlib
15
+ import inspect
16
+ import sys
17
+ import types
18
+ import warnings
19
+
20
+ # ...from HydPy
21
+ import hydpy
22
+ from hydpy.core import exceptiontools
23
+ from hydpy.core import filetools
24
+ from hydpy.core import masktools
25
+ from hydpy.core import modeltools
26
+ from hydpy.core import objecttools
27
+ from hydpy.core import parametertools
28
+ from hydpy.core import sequencetools
29
+ from hydpy.core import timetools
30
+ from hydpy.core.typingtools import *
31
+
32
+ TD = TypeVar("TD", Literal[0], Literal[1])
33
+ TM_contra = TypeVar("TM_contra", bound="modeltools.Model", contravariant=True)
34
+ TI_contra = TypeVar(
35
+ "TI_contra", bound="modeltools.SubmodelInterface", contravariant=True
36
+ )
37
+
38
+
39
+ class PrepSub0D(Protocol[TM_contra, TI_contra]):
40
+ """Specification for defining custom "add_submodel" methods to be wrapped by
41
+ function |prepare_submodel| when dealing with scalar submodel references."""
42
+
43
+ __name__: str
44
+
45
+ def __call__(
46
+ self, model: TM_contra, submodel: TI_contra, /, *, refresh: bool
47
+ ) -> None: ...
48
+
49
+
50
+ class PrepSub1D(Protocol[TM_contra, TI_contra]):
51
+ """Specification for model-specific "add_submodel" methods to be wrapped by
52
+ function |prepare_submodel| when dealing with vectorial submodel references."""
53
+
54
+ __name__: str
55
+
56
+ def __call__(
57
+ self, model: TM_contra, submodel: TI_contra, /, *, position: int, refresh: bool
58
+ ) -> None: ...
59
+
60
+
61
+ __HYDPY_AVAILABLE_LOCALS__ = "__hydpy_available_locals__"
62
+ __HYDPY_MODEL_LOCALS__ = "__hydpy_model_locals__"
63
+
64
+
65
+ def parameterstep(timestep: timetools.PeriodConstrArg | None = None) -> None:
66
+ """Define a parameter time step size within a parameter control file.
67
+
68
+ Function |parameterstep| should usually be applied in a line immediately behind the
69
+ model import or behind calling |simulationstep|. Defining the step size of
70
+ time-dependent parameters is a prerequisite to accessing any model-specific
71
+ parameter.
72
+
73
+ Note that |parameterstep| implements some namespace magic utilising the module
74
+ |inspect|, which complicates things for framework developers. Still, it eases the
75
+ definition of parameter control files for framework users.
76
+ """
77
+ if timestep is not None:
78
+ hydpy.pub.options.parameterstep = timestep
79
+ frame = inspect.currentframe()
80
+ assert (frame is not None) and (frame.f_back is not None)
81
+ namespace = frame.f_back.f_locals
82
+ model = namespace.get("model")
83
+ if model is None:
84
+ model = namespace["Model"]()
85
+ namespace["model"] = model
86
+ if hydpy.pub.options.usecython and "cythonizer" in namespace:
87
+ cythonizer = namespace["cythonizer"]
88
+ namespace["cythonmodule"] = cythonizer.cymodule
89
+ model.cymodel = cythonizer.cymodule.Model()
90
+ namespace["cymodel"] = model.cymodel
91
+ if hasattr(cythonizer.cymodule, "Parameters"):
92
+ model.cymodel.parameters = cythonizer.cymodule.Parameters()
93
+ model.cymodel.sequences = cythonizer.cymodule.Sequences()
94
+ for numpars_name in ("NumConsts", "NumVars"):
95
+ if hasattr(cythonizer.cymodule, numpars_name):
96
+ numpars_new = getattr(cythonizer.cymodule, numpars_name)()
97
+ numpars_old = getattr(model, numpars_name.lower())
98
+ for name_numpar, numpar in vars(numpars_old).items():
99
+ setattr(numpars_new, name_numpar, numpar)
100
+ setattr(model.cymodel, numpars_name.lower(), numpars_new)
101
+ for name in dir(model.cymodel):
102
+ if hasattr(model, name) and not (
103
+ name.startswith("_")
104
+ or name.endswith("model_is_mainmodel")
105
+ or isinstance(
106
+ getattr(model, name),
107
+ (modeltools.SubmodelProperty, modeltools.SubmodelsProperty),
108
+ )
109
+ ):
110
+ setattr(model, name, getattr(model.cymodel, name))
111
+ model.parameters = prepare_parameters(namespace)
112
+ model.sequences = prepare_sequences(namespace)
113
+ namespace.pop("cymodel", None)
114
+ namespace.pop("cythonmodule", None)
115
+ if "Masks" in namespace:
116
+ model.masks = namespace["Masks"]()
117
+ else:
118
+ model.masks = masktools.Masks()
119
+ for submodelclass in namespace["Model"].SUBMODELS:
120
+ submodel = submodelclass(model)
121
+ setattr(model, submodel.name, submodel)
122
+ del namespace["model"]
123
+ _add_locals_to_namespace(model=model, namespace=namespace)
124
+
125
+
126
+ def _add_locals_to_namespace(
127
+ model: modeltools.Model, namespace: dict[str, Any]
128
+ ) -> None:
129
+ new_locals: dict[str, Any] = namespace.get("CONSTANTS", {}).copy()
130
+ new_locals["model"] = model
131
+ new_locals["parameters"] = model.parameters
132
+ for pars in model.parameters:
133
+ new_locals[pars.name] = pars
134
+ new_locals["sequences"] = model.sequences
135
+ for seqs in model.sequences:
136
+ new_locals[seqs.name] = seqs
137
+ new_locals["masks"] = model.masks
138
+ focus = namespace.get("focus")
139
+ for par in model.parameters.control:
140
+ if (focus is None) or (par is focus):
141
+ new_locals[par.name] = par
142
+ else:
143
+ new_locals[par.name] = lambda *args, **kwargs: None
144
+ namespace[__HYDPY_MODEL_LOCALS__] = new_locals
145
+ namespace.update(new_locals)
146
+
147
+
148
+ def prepare_parameters(dict_: dict[str, Any]) -> parametertools.Parameters:
149
+ """Prepare a |Parameters| object based on the given dictionary
150
+ information and return it."""
151
+ cls_parameters = dict_.get("Parameters", parametertools.Parameters)
152
+ return cls_parameters(dict_)
153
+
154
+
155
+ def prepare_sequences(dict_: dict[str, Any]) -> sequencetools.Sequences:
156
+ """Prepare a |Sequences| object based on the given dictionary
157
+ information and return it."""
158
+ cls_sequences = dict_.get("Sequences", sequencetools.Sequences)
159
+ return cls_sequences(
160
+ model=dict_.get("model"),
161
+ cls_inlets=dict_.get("InletSequences"),
162
+ cls_receivers=dict_.get("ReceiverSequences"),
163
+ cls_inputs=dict_.get("InputSequences"),
164
+ cls_factors=dict_.get("FactorSequences"),
165
+ cls_fluxes=dict_.get("FluxSequences"),
166
+ cls_states=dict_.get("StateSequences"),
167
+ cls_logs=dict_.get("LogSequences"),
168
+ cls_aides=dict_.get("AideSequences"),
169
+ cls_outlets=dict_.get("OutletSequences"),
170
+ cls_senders=dict_.get("SenderSequences"),
171
+ cymodel=dict_.get("cymodel"),
172
+ cythonmodule=dict_.get("cythonmodule"),
173
+ )
174
+
175
+
176
+ def reverse_model_wildcard_import() -> None:
177
+ """Clear the local namespace from a model wildcard import.
178
+
179
+ This method should remove the critical imports into the local namespace due to the
180
+ last wildcard import of a particular application model. In this manner, it secures
181
+ the repeated preparation of different types of models via wildcard imports. See
182
+ the following example of to apply it.
183
+
184
+ >>> from hydpy import reverse_model_wildcard_import
185
+
186
+ Assume you import |lland_dd|:
187
+
188
+ >>> from hydpy.models.lland_dd import *
189
+
190
+ This import adds, for example, the collection class for handling control parameters
191
+ of `lland_dd` into the local namespace:
192
+
193
+ >>> print(ControlParameters(None).name)
194
+ control
195
+
196
+ Function |parameterstep| prepares, for example, the control parameter object of
197
+ class |lland_control.NHRU|:
198
+
199
+ >>> parameterstep("1d")
200
+ >>> nhru
201
+ nhru(?)
202
+
203
+ Function |reverse_model_wildcard_import| tries to clear the local namespace (even
204
+ from unexpected classes like the one we define now):
205
+
206
+ >>> class Test:
207
+ ... __module__ = "hydpy.models.lland_dd"
208
+ >>> test = Test()
209
+
210
+ >>> reverse_model_wildcard_import()
211
+
212
+ >>> ControlParameters
213
+ Traceback (most recent call last):
214
+ ...
215
+ NameError: name 'ControlParameters' is not defined
216
+
217
+ >>> nhru
218
+ Traceback (most recent call last):
219
+ ...
220
+ NameError: name 'nhru' is not defined
221
+
222
+ >>> Test
223
+ Traceback (most recent call last):
224
+ ...
225
+ NameError: name 'Test' is not defined
226
+
227
+ >>> test
228
+ Traceback (most recent call last):
229
+ ...
230
+ NameError: name 'test' is not defined
231
+ """
232
+ frame = inspect.currentframe()
233
+ assert (frame is not None) and (frame.f_back is not None)
234
+ namespace = frame.f_back.f_locals
235
+ model = namespace.get("model")
236
+ if model is not None:
237
+ for subpars in model.parameters:
238
+ for par in subpars:
239
+ namespace.pop(par.name, None)
240
+ namespace.pop(type(par).__name__, None)
241
+ namespace.pop(subpars.name, None)
242
+ namespace.pop(type(subpars).__name__, None)
243
+ for subseqs in model.sequences:
244
+ for seq in subseqs:
245
+ namespace.pop(seq.name, None)
246
+ namespace.pop(type(seq).__name__, None)
247
+ namespace.pop(subseqs.name, None)
248
+ namespace.pop(type(subseqs).__name__, None)
249
+ for name in (
250
+ "parameters",
251
+ "sequences",
252
+ "masks",
253
+ "model",
254
+ "Parameters",
255
+ "Sequences",
256
+ "Masks",
257
+ "Model",
258
+ "cythonizer",
259
+ "cymodel",
260
+ "cythonmodule",
261
+ ):
262
+ namespace.pop(name, None)
263
+ for key in tuple(namespace):
264
+ try:
265
+ if namespace[key].__module__ == model.__module__:
266
+ del namespace[key]
267
+ except AttributeError:
268
+ pass
269
+ if __HYDPY_AVAILABLE_LOCALS__ in namespace:
270
+ del namespace[__HYDPY_AVAILABLE_LOCALS__]
271
+ if __HYDPY_MODEL_LOCALS__ in namespace:
272
+ del namespace[__HYDPY_MODEL_LOCALS__]
273
+
274
+
275
+ def load_modelmodule(module: types.ModuleType | str, /) -> types.ModuleType:
276
+ """Load the given model module (if necessary) and return it.
277
+
278
+ >>> from hydpy.core.importtools import load_modelmodule
279
+ >>> from hydpy.models import evap_aet_hbv96
280
+ >>> assert evap_aet_hbv96 is load_modelmodule(evap_aet_hbv96)
281
+ >>> assert evap_aet_hbv96 is load_modelmodule("evap_aet_hbv96")
282
+ """
283
+ if isinstance(module, str):
284
+ return importlib.import_module(f"hydpy.models.{module}")
285
+ return module
286
+
287
+
288
+ def prepare_model(module: types.ModuleType | str) -> modeltools.Model:
289
+ """Prepare and return the model of the given module.
290
+
291
+ In usual *HydPy* projects, each control file only prepares an individual model
292
+ instance, which allows for "polluting" the namespace with different model
293
+ attributes. There is no danger of name conflicts as long as we do not perform
294
+ other (wildcard) imports.
295
+
296
+ However, there are situations where we need to load different models into the same
297
+ namespace. Then it is advisable to use function |prepare_model|, which returns a
298
+ reference to the model and nothing else.
299
+
300
+ See the documentation of |dam_v001| on how to apply function |prepare_model|
301
+ properly.
302
+ """
303
+ module = load_modelmodule(module)
304
+ model = module.Model()
305
+ assert isinstance(model, modeltools.Model)
306
+ if hydpy.pub.options.usecython and hasattr(module, "cythonizer"):
307
+ cymodule = module.cythonizer.cymodule
308
+ cymodel = cymodule.Model()
309
+ if hasattr(cymodule, "Parameters"):
310
+ cymodel.parameters = cymodule.Parameters()
311
+ cymodel.sequences = cymodule.Sequences()
312
+ model.cymodel = cymodel
313
+ for numpars_name in ("NumConsts", "NumVars"):
314
+ if hasattr(cymodule, numpars_name):
315
+ numpars_new = getattr(cymodule, numpars_name)()
316
+ numpars_old = getattr(model, numpars_name.lower())
317
+ for name_numpar, numpar in vars(numpars_old).items():
318
+ setattr(numpars_new, name_numpar, numpar)
319
+ setattr(cymodel, numpars_name.lower(), numpars_new)
320
+ for name in dir(cymodel):
321
+ if hasattr(model, name) and not (
322
+ name.startswith("_")
323
+ or name.endswith("model_is_mainmodel")
324
+ or isinstance(
325
+ getattr(model, name),
326
+ (modeltools.SubmodelProperty, modeltools.SubmodelsProperty),
327
+ )
328
+ ):
329
+ setattr(model, name, getattr(cymodel, name))
330
+ dict_ = {"cythonmodule": cymodule, "cymodel": cymodel}
331
+ else:
332
+ dict_ = {}
333
+ dict_.update(vars(module))
334
+ dict_["model"] = model
335
+ model.parameters = prepare_parameters(dict_)
336
+ model.sequences = prepare_sequences(dict_)
337
+ if hasattr(module, "Masks"):
338
+ model.masks = module.Masks()
339
+ else:
340
+ model.masks = masktools.Masks()
341
+ for submodelclass in module.Model.SUBMODELS:
342
+ submodel = submodelclass(model)
343
+ setattr(model, submodel.name, submodel)
344
+ return model
345
+
346
+
347
+ class _DoctestAdder:
348
+ _wrapped: Callable[..., None]
349
+
350
+ def __set_name__(self, objtype: type[modeltools.Model], name: str) -> None:
351
+ assert (module := inspect.getmodule(objtype)) is not None
352
+ test = getattr(module, "__test__", {})
353
+ test[f"{objtype.__name__}.{self._wrapped.__name__}"] = self.__doc__
354
+ module.__dict__["__test__"] = test
355
+
356
+
357
+ @overload
358
+ def prepare_submodel(
359
+ submodelname: str,
360
+ submodelinterface: type[TI_contra],
361
+ *methods: Callable[[NoReturn, NoReturn], None],
362
+ dimensionality: Literal[0] = ...,
363
+ landtype_constants: parametertools.Constants | None = None,
364
+ soiltype_constants: parametertools.Constants | None = None,
365
+ landtype_refindices: type[parametertools.NameParameter] | None = None,
366
+ soiltype_refindices: type[parametertools.NameParameter] | None = None,
367
+ refweights: type[parametertools.Parameter] | None = None,
368
+ ) -> Callable[
369
+ [PrepSub0D[TM_contra, TI_contra]], SubmodelAdder[Literal[0], TM_contra, TI_contra]
370
+ ]: ...
371
+
372
+
373
+ @overload
374
+ def prepare_submodel(
375
+ submodelname: str,
376
+ submodelinterface: type[TI_contra],
377
+ *methods: Callable[[NoReturn, NoReturn], None],
378
+ dimensionality: Literal[1],
379
+ landtype_constants: parametertools.Constants | None = None,
380
+ soiltype_constants: parametertools.Constants | None = None,
381
+ landtype_refindices: type[parametertools.NameParameter] | None = None,
382
+ soiltype_refindices: type[parametertools.NameParameter] | None = None,
383
+ refweights: type[parametertools.Parameter] | None = None,
384
+ ) -> Callable[
385
+ [PrepSub1D[TM_contra, TI_contra]], SubmodelAdder[Literal[1], TM_contra, TI_contra]
386
+ ]: ...
387
+
388
+
389
+ def prepare_submodel(
390
+ submodelname: str,
391
+ submodelinterface: type[TI_contra],
392
+ *methods: Callable[[NoReturn, NoReturn], None],
393
+ dimensionality: TD = 0, # type: ignore[assignment]
394
+ landtype_constants: parametertools.Constants | None = None,
395
+ soiltype_constants: parametertools.Constants | None = None,
396
+ landtype_refindices: type[parametertools.NameParameter] | None = None,
397
+ soiltype_refindices: type[parametertools.NameParameter] | None = None,
398
+ refweights: type[parametertools.Parameter] | None = None,
399
+ ) -> Callable[
400
+ [PrepSub0D[TM_contra, TI_contra] | PrepSub1D[TM_contra, TI_contra]],
401
+ SubmodelAdder[TD, TM_contra, TI_contra],
402
+ ]:
403
+ """Wrap a model-specific method for preparing a submodel into a |SubmodelAdder|
404
+ instance."""
405
+
406
+ def _prepare_submodel(
407
+ wrapped: PrepSub0D[TM_contra, TI_contra] | PrepSub1D[TM_contra, TI_contra],
408
+ ) -> SubmodelAdder[TD, TM_contra, TI_contra]:
409
+ return SubmodelAdder[TD, TM_contra, TI_contra](
410
+ wrapped=cast(Any, wrapped),
411
+ submodelname=submodelname,
412
+ submodelinterface=submodelinterface,
413
+ methods=methods,
414
+ dimensionality=dimensionality,
415
+ landtype_constants=landtype_constants,
416
+ soiltype_constants=soiltype_constants,
417
+ landtype_refindices=landtype_refindices,
418
+ soiltype_refindices=soiltype_refindices,
419
+ refweights=refweights,
420
+ )
421
+
422
+ return _prepare_submodel
423
+
424
+
425
+ class SubmodelAdder(_DoctestAdder, Generic[TD, TM_contra, TI_contra]):
426
+ """Wrapper that extends the functionality of model-specific methods for adding
427
+ submodels to main models.
428
+
429
+ |SubmodelAdder| offers the user-relevant feature of preparing submodels with the
430
+ `with` statement. When entering the `with` block, |SubmodelAdder| uses the given
431
+ string or module to initialise the desired application model and hands it as a
432
+ submodel to the model-specific method, which usually sets some control parameters
433
+ based on the main model's configuration. Next, |SubmodelAdder| makes many
434
+ attributes of the submodel directly available, most importantly, the instances of
435
+ the remaining control parameter, so that users can set their values as conveniently
436
+ as the ones of the main model. As long as no name conflicts occur, all main model
437
+ parameter instances are also accessible:
438
+
439
+ >>> from hydpy.models.lland_knauf import *
440
+ >>> parameterstep()
441
+ >>> nhru(2)
442
+ >>> ft(10.0)
443
+ >>> fhru(0.2, 0.8)
444
+ >>> lnk(ACKER, MISCHW)
445
+ >>> measuringheightwindspeed(10.0)
446
+ >>> lai(3.0)
447
+ >>> wmax(acker=100.0, mischw=200.0)
448
+ >>> with model.add_aetmodel_v1("evap_aet_hbv96"):
449
+ ... nhru
450
+ ... nmbhru
451
+ ... maxsoilwater
452
+ ... soilmoisturelimit(mischw=1.0, acker=0.5)
453
+ nhru(2)
454
+ nmbhru(2)
455
+ maxsoilwater(acker=100.0, mischw=200.0)
456
+ >>> model.aetmodel.parameters.control.soilmoisturelimit
457
+ soilmoisturelimit(acker=0.5, mischw=1.0)
458
+
459
+ After leaving the `with` block, the submodel's parameters are no longer available:
460
+
461
+ >>> nhru
462
+ nhru(2)
463
+ >>> nmbhru
464
+ Traceback (most recent call last):
465
+ ...
466
+ NameError: name 'nmbhru' is not defined
467
+
468
+ By calling the submodel interface method
469
+ |SubmodelInterface.add_mainmodel_as_subsubmodel| when entering the `with` block,
470
+ |SubmodelAdder| enables each submodel to accept the nearest main model as a
471
+ sub-submodel:
472
+
473
+ >>> model.aetmodel.tempmodel is model
474
+ True
475
+
476
+ Additionally, |SubmodelAdder| checks if the selected application model follows the
477
+ appropriate interface:
478
+
479
+ >>> with model.add_aetmodel_v1("ga_garto_submodel1"):
480
+ ... ...
481
+ Traceback (most recent call last):
482
+ ...
483
+ TypeError: While trying to add a submodel to the main model `lland_knauf`, the \
484
+ following error occurred: Submodel `ga_garto_submodel1` does not comply with the \
485
+ `AETModel_V1` interface.
486
+
487
+ Each |SubmodelAdder| instance provides access to the appropriate interface and the
488
+ interface methods the wrapped method uses (this information helps framework
489
+ developers figure out which parameters the submodel prepares on its own):
490
+
491
+ >>> model.add_aetmodel_v1.submodelinterface.__name__
492
+ 'AETModel_V1'
493
+ >>> for method in model.add_aetmodel_v1.methods:
494
+ ... method.__name__
495
+ 'prepare_nmbzones'
496
+ 'prepare_zonetypes'
497
+ 'prepare_subareas'
498
+ 'prepare_water'
499
+ 'prepare_interception'
500
+ 'prepare_soil'
501
+ 'prepare_plant'
502
+ 'prepare_tree'
503
+ 'prepare_conifer'
504
+ 'prepare_measuringheightwindspeed'
505
+ 'prepare_leafareaindex'
506
+ 'prepare_maxsoilwater'
507
+
508
+ |SubmodelAdder| supports arbitrarily deep submodel nesting. It conveniently moves
509
+ some information from main models to sub-submodels or the other way round if the
510
+ intermediate submodel does not consume or provide the corresponding data.
511
+ The following example shows that the main model of type |lland_knauf| shares some
512
+ of its class-level configurations with the sub-submodel of type |evap_pet_hbv96|
513
+ and that the sub-submodel knows about the zone areas of its main model (which the
514
+ submodel is not aware of) and uses it for querying air temperature data:
515
+
516
+ >>> lnk(ACKER, WASSER)
517
+ >>> with model.add_aetmodel_v1("evap_aet_hbv96"):
518
+ ... nmbhru
519
+ ... hasattr(control, "hrualtitude")
520
+ ... soil
521
+ ... excessreduction(acker=1.0)
522
+ ... with model.add_petmodel_v1("evap_pet_hbv96"):
523
+ ... nmbhru
524
+ ... hruarea
525
+ ... hrualtitude(2.0)
526
+ ... evapotranspirationfactor(acker=1.2, default=1.0)
527
+ nmbhru(2)
528
+ False
529
+ soil(acker=True, wasser=False)
530
+ nmbhru(2)
531
+ hruarea(2.0, 8.0)
532
+ >>> model.aetmodel.parameters.control.excessreduction
533
+ excessreduction(1.0)
534
+ >>> model.aetmodel.petmodel.parameters.control.evapotranspirationfactor
535
+ evapotranspirationfactor(acker=1.2, wasser=1.0)
536
+ >>> model is model.aetmodel.tempmodel
537
+ True
538
+ >>> model is model.aetmodel.petmodel.tempmodel
539
+ True
540
+
541
+ |SubmodelAdder| tries to update the submodel's derived parameters at the end of the
542
+ `with` block. Hence, all required information must be available at that time:
543
+
544
+ >>> from hydpy import pub
545
+ >>> pub.timegrids = "2000-01-01", "2000-01-02", "1d"
546
+ >>> with model.add_radiationmodel_v1("meteo_glob_morsim"):
547
+ ... pass
548
+ Traceback (most recent call last):
549
+ ...
550
+ hydpy.core.exceptiontools.AttributeNotReady: While trying to add submodel \
551
+ `meteo_glob_morsim` to the main model `lland_knauf`, the following error occurred: \
552
+ While trying to update parameter `latituderad` of element `?`, the following error \
553
+ occurred: While trying to multiply variable `latitude` and `float` instance \
554
+ `0.017453`, the following error occurred: For variable `latitude`, no value has been \
555
+ defined so far.
556
+
557
+ You can turn off this behaviour by setting `update` to |False|:
558
+
559
+ >>> with model.add_radiationmodel_v1("meteo_glob_morsim", update=False) as \
560
+ meteo_glob_morsim:
561
+ ... pass
562
+
563
+ |meteo_glob_morsim| is a "sharable" submodel, meaning one of its instances can be
564
+ used by multiple main models. We demonstrate this by selecting |evap_aet_morsim|
565
+ as the evaporation submodel, which requires the same radiation-related data as
566
+ |lland_knauf|. We reuse the |meteo_glob_morsim| instance prepared above, which is
567
+ already a submodel of |lland_knauf|, and make it also a submodel of the
568
+ |evap_aet_morsim| instance:
569
+
570
+ >>> with model.add_aetmodel_v1("evap_aet_morsim"):
571
+ ... model.add_radiationmodel_v1(meteo_glob_morsim)
572
+ >>> model.radiationmodel is model.aetmodel.radiationmodel
573
+ True
574
+
575
+ When handing over already initialised submodel instances, the `with` statement
576
+ cannot be used because later modifications of the submodel's configuration would
577
+ affect the submodel's use by both main models.
578
+
579
+ Not all submodels are sharable, and model users might find it hard to see which one
580
+ is. Hence, we introduced |SharableSubmodelInterface| and decided that model
581
+ developers must derive a submodel from this class if convinced it is sharable. For
582
+ safety, |SubmodelAdder| checks if a given model instance inherits from
583
+ |SharableSubmodelInterface|:
584
+
585
+ >>> model.add_radiationmodel_v1(model)
586
+ Traceback (most recent call last):
587
+ ...
588
+ TypeError: While trying to add a submodel to the main model `lland_knauf`, the \
589
+ following error occurred: The given `lland_knauf` instance is not considered sharable.
590
+ """
591
+
592
+ submodelname: str
593
+ """The submodel's attribute name."""
594
+ submodelinterface: type[TI_contra]
595
+ """The relevant submodel interface."""
596
+ dimensionality: TD
597
+ """The dimensionality of the handled submodel reference(s) (either zero or one)."""
598
+ methods: tuple[Callable[[NoReturn, NoReturn], None], ...]
599
+ """The submodel interface methods the wrapped method uses."""
600
+ landtype_refindices: type[parametertools.NameParameter] | None
601
+ """Reference to a land cover type-related index parameter."""
602
+ soiltype_refindices: type[parametertools.NameParameter] | None
603
+ """Reference to a soil type-related index parameter."""
604
+ refweights: type[parametertools.Parameter] | None
605
+ """Reference to a weighting parameter."""
606
+
607
+ __hydpy_maintype2subname2adders__: collections.defaultdict[
608
+ type[modeltools.Model], collections.defaultdict[str, list[SubmodelAdder]]
609
+ ] = collections.defaultdict(lambda: collections.defaultdict(list))
610
+
611
+ _methodnames: frozenset[str]
612
+ _wrapped: PrepSub0D[TM_contra, TI_contra] | PrepSub1D[TM_contra, TI_contra]
613
+ _sharable_configuration: SharableConfiguration
614
+ _mainmodelstack: ClassVar[list[modeltools.Model]] = []
615
+
616
+ # The following attributes are created when required and deleted afterwards:
617
+ _model: TM_contra
618
+ _submodel: modeltools.SubmodelInterface
619
+ _update: bool
620
+ _namespace: dict[str, Any]
621
+ _old_locals: dict[str, Any]
622
+
623
+ @overload
624
+ def __init__(
625
+ self: SubmodelAdder[Literal[0], TM_contra, TI_contra],
626
+ *,
627
+ wrapped: PrepSub0D[TM_contra, TI_contra],
628
+ submodelname: str,
629
+ submodelinterface: type[TI_contra],
630
+ methods: Iterable[Callable[[NoReturn, NoReturn], None]],
631
+ dimensionality: TD,
632
+ landtype_constants: parametertools.Constants | None,
633
+ soiltype_constants: parametertools.Constants | None,
634
+ landtype_refindices: type[parametertools.NameParameter] | None,
635
+ soiltype_refindices: type[parametertools.NameParameter] | None,
636
+ refweights: type[parametertools.Parameter] | None,
637
+ ) -> None: ...
638
+
639
+ @overload
640
+ def __init__(
641
+ self: SubmodelAdder[Literal[1], TM_contra, TI_contra],
642
+ *,
643
+ wrapped: PrepSub1D[TM_contra, TI_contra],
644
+ submodelname: str,
645
+ submodelinterface: type[TI_contra],
646
+ methods: Iterable[Callable[[NoReturn, NoReturn], None]],
647
+ dimensionality: TD,
648
+ landtype_constants: parametertools.Constants | None,
649
+ soiltype_constants: parametertools.Constants | None,
650
+ landtype_refindices: type[parametertools.NameParameter] | None,
651
+ soiltype_refindices: type[parametertools.NameParameter] | None,
652
+ refweights: type[parametertools.Parameter] | None,
653
+ ) -> None: ...
654
+
655
+ def __init__(
656
+ self,
657
+ *,
658
+ wrapped: PrepSub0D[TM_contra, TI_contra] | PrepSub1D[TM_contra, TI_contra],
659
+ submodelname: str,
660
+ submodelinterface: type[TI_contra],
661
+ methods: Iterable[Callable[[NoReturn, NoReturn], None]],
662
+ dimensionality: TD,
663
+ landtype_constants: parametertools.Constants | None,
664
+ soiltype_constants: parametertools.Constants | None,
665
+ landtype_refindices: type[parametertools.NameParameter] | None,
666
+ soiltype_refindices: type[parametertools.NameParameter] | None,
667
+ refweights: type[parametertools.Parameter] | None,
668
+ ) -> None:
669
+ self._wrapped = wrapped
670
+ self.submodelname = submodelname
671
+ self.submodelinterface = submodelinterface
672
+ self.methods = tuple(methods)
673
+ self._methodnames = frozenset(method.__name__ for method in methods)
674
+ self.dimensionality = dimensionality
675
+ self._sharable_configuration = {
676
+ "landtype_constants": landtype_constants,
677
+ "soiltype_constants": soiltype_constants,
678
+ "landtype_refindices": None,
679
+ "soiltype_refindices": None,
680
+ "refweights": None,
681
+ }
682
+ self._landtype_refindices = landtype_refindices
683
+ self._soiltype_refindices = soiltype_refindices
684
+ self._refweights = refweights
685
+ self.__doc__ = wrapped.__doc__
686
+
687
+ @overload
688
+ def get_wrapped(
689
+ self: SubmodelAdder[Literal[0], TM_contra, TI_contra],
690
+ ) -> PrepSub0D[TM_contra, TI_contra]: ...
691
+
692
+ @overload
693
+ def get_wrapped(
694
+ self: SubmodelAdder[Literal[1], TM_contra, TI_contra],
695
+ ) -> PrepSub1D[TM_contra, TI_contra]: ...
696
+
697
+ def get_wrapped(
698
+ self: SubmodelAdder[TD, TM_contra, TI_contra],
699
+ ) -> PrepSub0D[TM_contra, TI_contra] | PrepSub1D[TM_contra, TI_contra]:
700
+ """Return the wrapped, model-specific method for automatically preparing some
701
+ control parameters."""
702
+ return self._wrapped
703
+
704
+ def __get__(
705
+ self, obj: TM_contra | None, type_: type[modeltools.Model]
706
+ ) -> SubmodelAdder[TD, TM_contra, TI_contra]:
707
+ if obj is not None:
708
+ self._model = obj
709
+ return self
710
+
711
+ def __set_name__(self, owner: type[modeltools.Model], name: str) -> None:
712
+ super().__set_name__(owner, name)
713
+ mt2sn2as = self.__hydpy_maintype2subname2adders__
714
+ mt2sn2as[owner][self.submodelname].append(self)
715
+
716
+ @overload
717
+ def __call__(
718
+ self: SubmodelAdder[Literal[0], TM_contra, TI_contra],
719
+ submodel: types.ModuleType | str,
720
+ *,
721
+ update: bool = True,
722
+ ) -> SubmodelAdder[Literal[0], TM_contra, TI_contra]: ...
723
+
724
+ @overload
725
+ def __call__(
726
+ self: SubmodelAdder[Literal[1], TM_contra, TI_contra],
727
+ submodel: types.ModuleType | str,
728
+ *,
729
+ position: int,
730
+ update: bool = True,
731
+ ) -> SubmodelAdder[Literal[1], TM_contra, TI_contra]: ...
732
+
733
+ @overload
734
+ def __call__(
735
+ self: SubmodelAdder[Literal[0], TM_contra, TI_contra],
736
+ submodel: modeltools.SharableSubmodelInterface,
737
+ *,
738
+ update: bool = True,
739
+ ) -> None: ...
740
+
741
+ @overload
742
+ def __call__(
743
+ self: SubmodelAdder[Literal[1], TM_contra, TI_contra],
744
+ submodel: modeltools.SharableSubmodelInterface,
745
+ *,
746
+ position: int,
747
+ update: bool = True,
748
+ ) -> None: ...
749
+
750
+ def __call__(
751
+ self,
752
+ submodel: types.ModuleType | str | modeltools.SharableSubmodelInterface,
753
+ *,
754
+ position: int | None = None,
755
+ update: bool = True,
756
+ ) -> Self | None:
757
+ try:
758
+ assert (model := self._model) is not None
759
+
760
+ if isinstance(submodel, modeltools.SharableSubmodelInterface):
761
+ self._check_submodelinterface(submodeltype=type(submodel))
762
+ self._connect_models(model=model, submodel=submodel, position=position)
763
+ return None
764
+
765
+ if isinstance(submodel, modeltools.Model):
766
+ raise TypeError(
767
+ f"The given `{submodel}` instance is not considered sharable."
768
+ )
769
+
770
+ submodel = load_modelmodule(submodel)
771
+ self._check_submodelinterface(submodeltype=submodel.Model)
772
+
773
+ shared = self._sharable_configuration
774
+ control = model.parameters.control
775
+ if (ltr := self._landtype_refindices) is not None:
776
+ shared["landtype_refindices"] = getattr(control, ltr.name)
777
+ if (str_ := self._soiltype_refindices) is not None: # pragma: no cover
778
+ shared["soiltype_refindices"] = getattr(control, str_.name)
779
+ if (rw := self._refweights) is not None:
780
+ shared["refweights"] = getattr(control, rw.name)
781
+
782
+ self._test = submodel.Model.share_configuration(shared)
783
+ self._test.__enter__()
784
+ try:
785
+ submodel_ = prepare_model(submodel)
786
+ assert isinstance(submodel_, self.submodelinterface)
787
+ self._connect_models(model=model, submodel=submodel_, position=position)
788
+ submodel_._submodeladder = self
789
+ if self.dimensionality == 0:
790
+ self.update(model, submodel_, refresh=False)
791
+ elif self.dimensionality == 1:
792
+ assert position is not None
793
+ self.update(model, submodel_, position=position, refresh=False)
794
+ else:
795
+ assert_never(self.dimensionality)
796
+ assert ((frame1 := inspect.currentframe()) is not None) and (
797
+ (frame2 := frame1.f_back) is not None
798
+ )
799
+ self._namespace = frame2.f_locals
800
+ if __HYDPY_AVAILABLE_LOCALS__ not in self._namespace:
801
+ self._namespace[__HYDPY_AVAILABLE_LOCALS__] = dict(self._namespace)
802
+ self._old_locals = self._namespace.get(__HYDPY_MODEL_LOCALS__, {})
803
+ self._submodel = submodel_
804
+ self._update = update
805
+ except BaseException as exc:
806
+ self._tidy_up()
807
+ raise exc
808
+
809
+ return self
810
+
811
+ except BaseException:
812
+ objecttools.augment_excmessage(
813
+ f"While trying to add a submodel to the main model `{self._model}`"
814
+ )
815
+
816
+ def __enter__(self) -> modeltools.SubmodelInterface:
817
+ _add_locals_to_namespace(self._submodel, self._namespace)
818
+ self._mainmodelstack.append(self._model)
819
+ for mainmodel in reversed(self._mainmodelstack):
820
+ if self._submodel.add_mainmodel_as_subsubmodel(mainmodel):
821
+ break
822
+ else:
823
+ setattr(self._model, f"{self.submodelname}_is_mainmodel", False)
824
+ return self._submodel
825
+
826
+ def __exit__(
827
+ self,
828
+ exception_type: type[BaseException] | None,
829
+ exception_value: BaseException | None,
830
+ traceback: types.TracebackType | None,
831
+ ) -> None:
832
+ try:
833
+ self._mainmodelstack.pop(-1)
834
+ if self._update and (exception_type is None):
835
+ self._submodel.parameters.update()
836
+ except BaseException:
837
+ objecttools.augment_excmessage(
838
+ f"While trying to add submodel `{self._submodel}` to the main model "
839
+ f"`{self._model}`"
840
+ )
841
+ finally:
842
+ available_locals = self._namespace[__HYDPY_AVAILABLE_LOCALS__]
843
+ new_locals = self._namespace[__HYDPY_MODEL_LOCALS__]
844
+ for name in new_locals:
845
+ if name in self._old_locals:
846
+ self._namespace[name] = self._old_locals[name]
847
+ elif name in available_locals:
848
+ self._namespace[name] = available_locals[name]
849
+ else:
850
+ try:
851
+ del self._namespace[name]
852
+ except ValueError: # pragma: no cover
853
+ # Maybe the best we can do for optimised scopes because we
854
+ # "cannot remove local variables from FrameLocalsProxy"
855
+ self._namespace[name] = None
856
+ for name, value in self._old_locals.items():
857
+ if name not in new_locals:
858
+ self._namespace[name] = value
859
+ if self._old_locals:
860
+ self._namespace[__HYDPY_MODEL_LOCALS__] = self._old_locals
861
+ else:
862
+ del self._namespace[__HYDPY_MODEL_LOCALS__]
863
+ del self._namespace[__HYDPY_AVAILABLE_LOCALS__]
864
+ if isinstance(self._model, modeltools.SubmodelInterface):
865
+ self._model.preparemethod2arguments.clear()
866
+ self._tidy_up()
867
+
868
+ def _check_submodelinterface(self, submodeltype: type[modeltools.Model]) -> None:
869
+ if not issubclass(submodeltype, self.submodelinterface):
870
+ raise TypeError(
871
+ f"Submodel `{submodeltype.__HYDPY_NAME__}` does not comply with the "
872
+ f"`{self.submodelinterface.__name__}` interface."
873
+ )
874
+
875
+ def _connect_models(
876
+ self,
877
+ model: modeltools.Model,
878
+ submodel: modeltools.SubmodelInterface,
879
+ position: int | None,
880
+ ) -> None:
881
+ submodel.__hydpy_element__ = model.__hydpy_element__
882
+ typeid = self.submodelinterface.typeid
883
+ if self.dimensionality == 0:
884
+ setattr(model, self.submodelname, submodel)
885
+ setattr(model, f"{self.submodelname}_typeid", typeid)
886
+ elif self.dimensionality == 1:
887
+ assert position is not None
888
+ submodels = getattr(model, self.submodelname)
889
+ assert isinstance(submodels, modeltools.SubmodelsProperty)
890
+ submodels.put_submodel(submodel=submodel, typeid=typeid, position=position)
891
+ else:
892
+ assert_never(self.dimensionality)
893
+
894
+ def _tidy_up(self) -> None:
895
+ self._test.__exit__(*sys.exc_info())
896
+ if hasattr(self, "_submodel"):
897
+ del self._submodel
898
+ if hasattr(self, "_update"):
899
+ del self._update
900
+ if hasattr(self, "_namespace"):
901
+ del self._namespace
902
+ if hasattr(self, "_old_locals"):
903
+ del self._old_locals
904
+
905
+ @overload
906
+ def update(
907
+ self: SubmodelAdder[Literal[0], TM_contra, TI_contra],
908
+ model: TM_contra,
909
+ submodel: TI_contra,
910
+ /,
911
+ *,
912
+ refresh: bool,
913
+ ) -> None: ...
914
+
915
+ @overload
916
+ def update(
917
+ self: SubmodelAdder[Literal[1], TM_contra, TI_contra],
918
+ model: TM_contra,
919
+ submodel: TI_contra,
920
+ /,
921
+ *,
922
+ position: int,
923
+ refresh: bool,
924
+ ) -> None: ...
925
+
926
+ def update(
927
+ self,
928
+ model: TM_contra,
929
+ submodel: TI_contra,
930
+ /,
931
+ *,
932
+ refresh: bool,
933
+ position: int | None = None,
934
+ ) -> None:
935
+ """Update the connections between the given main model and its submodel, which
936
+ can become necessary after disruptive configuration changes.
937
+
938
+ For now, we recommend using |SubmodelAdder.update| only for testing, not
939
+ applications, because we cannot give clear recommendations for using it under
940
+ different settings yet.
941
+ """
942
+ if self.dimensionality == 0:
943
+ self.get_wrapped()(model, submodel, refresh=refresh)
944
+ elif self.dimensionality == 1:
945
+ assert position is not None
946
+ self.get_wrapped()(model, submodel, position=position, refresh=refresh)
947
+ else:
948
+ assert_never(self.dimensionality)
949
+ if isinstance(model, modeltools.SubmodelInterface):
950
+ for methodname, arguments in model.preparemethod2arguments.items():
951
+ if methodname not in self._methodnames:
952
+ if (method := getattr(submodel, methodname, None)) is not None:
953
+ method(*arguments[0], **arguments[1])
954
+
955
+
956
+ def define_targetparameter(
957
+ parameter: type[parametertools.Parameter],
958
+ ) -> Callable[
959
+ [Callable[Concatenate[TM_contra, P], None]], TargetParameterUpdater[TM_contra, P]
960
+ ]:
961
+ """Wrap a submodel-specific method that allows the main model to set the value
962
+ of a single control parameter of the submodel into a |TargetParameterUpdater|
963
+ instance."""
964
+
965
+ def _select_parameter(
966
+ wrapped: Callable[Concatenate[TM_contra, P], None],
967
+ ) -> TargetParameterUpdater[TM_contra, P]:
968
+ return TargetParameterUpdater[TM_contra, P](wrapped, parameter)
969
+
970
+ return _select_parameter
971
+
972
+
973
+ class TargetParameterUpdater(_DoctestAdder, Generic[TM_contra, P]):
974
+ """Wrapper that extends the functionality of a submodel-specific method that allows
975
+ the main model to set the value of a single control parameter of the submodel.
976
+
977
+ When calling a |TargetParameterUpdater| instance, it calls the wrapped method with
978
+ unmodified arguments, so that model users might not even realise the
979
+ |TargetParameterUpdater| instance exists:
980
+
981
+ .. testsetup::
982
+
983
+ >>> from hydpy.models.evap_ret_tw2002 import Model
984
+ >>> Model.prepare_nmbzones.values_orig = {}
985
+ >>> Model.prepare_nmbzones.values_test = {}
986
+
987
+ >>> from hydpy import prepare_model
988
+ >>> model = prepare_model("evap_ret_tw2002")
989
+ >>> model.prepare_nmbzones(3)
990
+ >>> model.parameters.control.nmbhru
991
+ nmbhru(3)
992
+
993
+ However, each |TargetParameterUpdater| instance provides other framework functions
994
+ access to the target control parameter type (the one the wrapped method prepares):
995
+
996
+ >>> model.prepare_nmbzones.targetparameter.__name__
997
+ 'NmbHRU'
998
+
999
+ They also memorise the passed data and resulting parameter values:
1000
+
1001
+ >>> model.prepare_nmbzones.values_orig # doctest: +ELLIPSIS
1002
+ {evap_ret_tw2002: (((3,), {}), 3)}
1003
+
1004
+ With |TargetParameterUpdater.testmode| enabled, |TargetParameterUpdater| instances
1005
+ do not pass the given data to the wrapped method but memorise it together with the
1006
+ already available parameter values in another dictionary:
1007
+
1008
+ >>> type(model.prepare_nmbzones).testmode = True
1009
+ >>> model.prepare_nmbzones(4)
1010
+ >>> model.parameters.control.nmbhru
1011
+ nmbhru(3)
1012
+ >>> model.prepare_nmbzones.values_test # doctest: +ELLIPSIS
1013
+ {evap_ret_tw2002: (((4,), {}), 3)}
1014
+
1015
+ .. testsetup::
1016
+
1017
+ >>> type(model.prepare_nmbzones).testmode = False
1018
+ """
1019
+
1020
+ targetparameter: type[parametertools.Parameter]
1021
+ """The control parameter the wrapped method modifies."""
1022
+ testmode: ClassVar[bool] = False
1023
+ """The mode of all |TargetParameterUpdater| instances.
1024
+
1025
+ |False| indicates the normal "active" mode,
1026
+ where |TargetParameterUpdater| instances actually change the values of their target
1027
+ parameters and save the input data and the resulting parameter values in the
1028
+ |TargetParameterUpdater.values_orig| dictionary. |True| indicates the testing mode
1029
+ where |TargetParameterUpdater| instances just collect the input data and the
1030
+ already available parameter values in the |TargetParameterUpdater.values_test|
1031
+ dictionary.
1032
+ """
1033
+ values_orig: dict[modeltools.Model, tuple[tuple[Any, Any], Any]]
1034
+ """Deep copies of the input data (separated by positional and keyword arguments)
1035
+ and the resulting values of the target parameters of the respective model
1036
+ instances."""
1037
+ values_test: dict[modeltools.Model, tuple[tuple[Any, Any], Any]]
1038
+ """Deep copies of the input data (separated by positional and keyword arguments)
1039
+ and the already available values of the target parameters of the respective model
1040
+ instances."""
1041
+
1042
+ _wrapped: Callable[Concatenate[TM_contra, P], None]
1043
+ """The wrapped, submodel-specific method for setting the value of a single control
1044
+ parameter."""
1045
+ _model: TM_contra | None
1046
+
1047
+ def __init__(
1048
+ self,
1049
+ wrapped: Callable[Concatenate[TM_contra, P], None],
1050
+ targetparameter: type[parametertools.Parameter],
1051
+ ) -> None:
1052
+ self._wrapped = wrapped
1053
+ self.targetparameter = targetparameter
1054
+ self.values_orig = {}
1055
+ self.values_test = {}
1056
+ self.__doc__ = wrapped.__doc__
1057
+
1058
+ def __get__(
1059
+ self, obj: TM_contra | None, type_: type[modeltools.Model]
1060
+ ) -> TargetParameterUpdater[TM_contra, P]:
1061
+ if obj is not None:
1062
+ self._model = obj
1063
+ return self
1064
+
1065
+ def __call__(self, *args: P.args, **kwargs: P.kwargs) -> None:
1066
+ assert (model := self._model) is not None
1067
+ args = copy.deepcopy(args)
1068
+ kwargs = copy.deepcopy(kwargs)
1069
+ model.preparemethod2arguments[self._wrapped.__name__] = args, kwargs
1070
+ control = model.parameters.control
1071
+ if self.testmode:
1072
+ if (name := self.targetparameter.name) in control.names:
1073
+ par = control[name]
1074
+ self.values_test[model] = ((args, kwargs), copy.deepcopy(par.value))
1075
+ else:
1076
+ if (name := self.targetparameter.name) in control.names:
1077
+ self._wrapped(model, *args, **kwargs)
1078
+ par = control[name]
1079
+ self.values_orig[model] = ((args, kwargs), copy.deepcopy(par.value))
1080
+
1081
+
1082
+ def simulationstep(timestep: timetools.PeriodConstrArg) -> None:
1083
+ """Define a simulation time step size within a parameter control file for testing
1084
+ purposes.
1085
+
1086
+ Using |simulationstep| only affects the values of time-dependent parameters when
1087
+ `pub.timegrids.stepsize` is not defined. It thus does not influence usual *HydPy*
1088
+ simulations at all. Use it to check your parameter control files. Write it in a
1089
+ line immediately behind the model import.
1090
+
1091
+ To clarify its purpose, function |simulationstep| raises a warning when executed
1092
+ from within a control file:
1093
+
1094
+ .. testsetup::
1095
+
1096
+ >>> from hydpy import pub
1097
+ >>> del pub.timegrids
1098
+
1099
+ >>> from hydpy.core.testtools import warn_later
1100
+ >>> from hydpy import pub
1101
+ >>> with warn_later(), pub.options.warnsimulationstep(True):
1102
+ ... from hydpy.models.hland_96 import *
1103
+ ... simulationstep("1h")
1104
+ ... parameterstep("1d")
1105
+ UserWarning: Note that the applied function `simulationstep` is intended for \
1106
+ testing purposes only. When doing a HydPy simulation, parameter values are \
1107
+ initialised based on the actual simulation time step as defined under \
1108
+ `pub.timegrids.stepsize` and the value given to `simulationstep` is ignored.
1109
+
1110
+ >>> pub.options.simulationstep
1111
+ Period("1h")
1112
+ """
1113
+ if hydpy.pub.options.warnsimulationstep:
1114
+ warnings.warn(
1115
+ "Note that the applied function `simulationstep` is intended for testing "
1116
+ "purposes only. When doing a HydPy simulation, parameter values are "
1117
+ "initialised based on the actual simulation time step as defined under "
1118
+ "`pub.timegrids.stepsize` and the value given to `simulationstep` is "
1119
+ "ignored."
1120
+ )
1121
+ hydpy.pub.options.simulationstep = timestep
1122
+
1123
+
1124
+ def controlcheck(
1125
+ controldir: str = "default",
1126
+ projectdir: str | None = None,
1127
+ controlfile: str | None = None,
1128
+ firstdate: timetools.DateConstrArg | None = None,
1129
+ stepsize: timetools.PeriodConstrArg | None = None,
1130
+ ) -> None:
1131
+ """Define the corresponding control file within a condition file.
1132
+
1133
+ Function |controlcheck| serves similar purposes as function |parameterstep|. It is
1134
+ why one can interactively access the state and the log sequences within condition
1135
+ files as `land_dill_assl.py` of the example project `HydPy-H-Lahn`. It is called
1136
+ `controlcheck` due to its feature to check for possible inconsistencies between
1137
+ control and condition files. The following test, where we write several soil
1138
+ moisture values (|hland_states.SM|) into condition file `land_dill_assl.py`, which
1139
+ does not agree with the number of hydrological response units
1140
+ (|hland_control.NmbZones|) defined in control file `land_dill_assl.py`, verifies
1141
+ that this works within a separate Python process:
1142
+
1143
+ >>> from hydpy.core.testtools import prepare_full_example_1
1144
+ >>> prepare_full_example_1()
1145
+
1146
+ >>> import os
1147
+ >>> from hydpy import run_subprocess, TestIO
1148
+ >>> cwd = os.path.join("HydPy-H-Lahn", "conditions", "init_1996_01_01_00_00_00")
1149
+ >>> with TestIO(): # doctest: +ELLIPSIS
1150
+ ... os.chdir(cwd)
1151
+ ... with open("land_dill_assl.py") as file_:
1152
+ ... lines = file_.readlines()
1153
+ ... lines[10:12] = "sm(185.13164, 181.18755)", ""
1154
+ ... with open("land_dill_assl.py", "w") as file_:
1155
+ ... _ = file_.write("\\n".join(lines))
1156
+ ... print()
1157
+ ... result = run_subprocess("hyd.py exec_script land_dill_assl.py")
1158
+ <BLANKLINE>
1159
+ ...
1160
+ While trying to set the value(s) of variable `sm`, the following error occurred: \
1161
+ While trying to convert the value(s) `(185.13164, 181.18755)` to a numpy ndarray with \
1162
+ shape `(12,)` and type `float`, the following error occurred: could not broadcast \
1163
+ input array from shape (2...) into shape (12...)
1164
+ ...
1165
+
1166
+ With a little trick, we can fake to be "inside" condition file `land_dill_assl.py`.
1167
+ Calling |controlcheck| then, for example, prepares the shape of sequence
1168
+ |hland_states.Ic| as specified by the value of parameter |hland_control.NmbZones|
1169
+ given in the corresponding control file:
1170
+
1171
+ >>> from hydpy.models.hland_96 import *
1172
+ >>> __file__ = "land_dill_assl.py"
1173
+ >>> with TestIO():
1174
+ ... os.chdir(cwd)
1175
+ ... controlcheck(firstdate="1996-01-01", stepsize="1d")
1176
+ >>> ic.shape
1177
+ (12,)
1178
+
1179
+ In the above example, we use the default names for the project directory (the one
1180
+ containing the executed condition file) and the control directory (`default`). The
1181
+ following example shows how to change them:
1182
+
1183
+ >>> del model
1184
+ >>> with TestIO(): # doctest: +ELLIPSIS
1185
+ ... os.chdir(cwd)
1186
+ ... controlcheck(projectdir="somewhere", controldir="nowhere")
1187
+ Traceback (most recent call last):
1188
+ ...
1189
+ FileNotFoundError: While trying to load the control file `land_dill_assl.py` \
1190
+ from directory `...hydpy/tests/iotesting/somewhere/control/nowhere`, \
1191
+ the following error occurred: ...
1192
+
1193
+ For some models, the appropriate states may depend on the initialisation date. One
1194
+ example is the interception storage (|lland_states.Inzp|) of application model
1195
+ |lland_dd|, which should not exceed the interception capacity
1196
+ (|lland_derived.KInz|). However, |lland_derived.KInz| depends on the leaf
1197
+ area index parameter |lland_control.LAI|, which offers different values depending
1198
+ on land-use type and month. Hence, one can assign higher values to state
1199
+ |lland_states.Inzp| during periods with high leaf area indices than during periods
1200
+ with small leaf area indices.
1201
+
1202
+ To show the related functionalities, we first replace the |hland_96| application
1203
+ model of element `land_dill_assl` with a |lland_dd| model object, define some of its
1204
+ parameter values, and write its control and condition files. Note that the
1205
+ |lland_control.LAI| value of the only relevant land use the
1206
+ (|lland_constants.ACKER|) is 0.5 during January and 5.0 during July:
1207
+
1208
+ >>> from hydpy import HydPy, prepare_model, pub
1209
+ >>> from hydpy.models.lland_dd import ACKER
1210
+ >>> pub.timegrids = "2000-06-01", "2000-07-01", "1d"
1211
+ >>> with TestIO():
1212
+ ... hp = HydPy("HydPy-H-Lahn")
1213
+ ... hp.prepare_network()
1214
+ ... land_dill_assl = hp.elements["land_dill_assl"]
1215
+ ... with pub.options.usedefaultvalues(True):
1216
+ ... land_dill_assl.model = prepare_model("lland_dd")
1217
+ ... control = land_dill_assl.model.parameters.control
1218
+ ... control.nhru(2)
1219
+ ... control.ft(1.0)
1220
+ ... control.fhru(0.5)
1221
+ ... control.lnk(ACKER)
1222
+ ... control.lai.acker_jan = 0.5
1223
+ ... control.lai.acker_jul = 5.0
1224
+ ... land_dill_assl.model.parameters.update()
1225
+ ... land_dill_assl.model.sequences.states.inzp(1.0)
1226
+ ... land_dill_assl.model.save_controls()
1227
+ ... land_dill_assl.model.save_conditions()
1228
+
1229
+ Unfortunately, state |lland_states.Inzp| does not define a |trim| method taking the
1230
+ actual value of parameter |lland_derived.KInz| into account (due to compatibility
1231
+ with the original LARSIM model). As an auxiliary solution, we define such a
1232
+ function within the `land_dill_assl.py` condition file (and modify some warning
1233
+ settings in favour of the next examples):
1234
+
1235
+ >>> cwd = os.path.join("HydPy-H-Lahn", "conditions", "init_2000_07_01_00_00_00")
1236
+ >>> with TestIO():
1237
+ ... os.chdir(cwd)
1238
+ ... with open("land_dill_assl.py") as file_:
1239
+ ... lines = file_.readlines()
1240
+ ... with open("land_dill_assl.py", "w") as file_:
1241
+ ... file_.writelines([
1242
+ ... "from hydpy import pub\\n",
1243
+ ... "pub.options.warnsimulationstep = False\\n",
1244
+ ... "pub.options.warntrim = True\\n",
1245
+ ... "import warnings\\n",
1246
+ ... 'warnings.filterwarnings("error", message="For variable")\\n'])
1247
+ ... file_.writelines(lines[:4])
1248
+ ... file_.writelines([
1249
+ ... "from hydpy.core.variabletools import trim as trim_\\n",
1250
+ ... "def trim(self, lower=None, upper=None):\\n",
1251
+ ... " der = self.subseqs.seqs.model.parameters.derived\\n",
1252
+ ... " trim_(self, 0.0, der.kinz.acker[der.moy[0]])\\n",
1253
+ ... "type(inzp).trim = trim\\n\\n"])
1254
+ ... file_.writelines(lines[4:])
1255
+
1256
+ Now, executing the condition file (and thereby calling function |controlcheck|)
1257
+ does not raise any warnings due to extracting the initialisation date from the name
1258
+ of the condition directory:
1259
+
1260
+ >>> with TestIO():
1261
+ ... os.chdir(cwd)
1262
+ ... result = run_subprocess("hyd.py exec_script land_dill_assl.py")
1263
+
1264
+ If the directory name does imply the initialisation date to be within January 2000
1265
+ instead of July 2000, we correctly get the following warning:
1266
+
1267
+ >>> cwd_old = cwd
1268
+ >>> cwd_new = os.path.join("HydPy-H-Lahn", "conditions", "init_2000_01_01")
1269
+ >>> with TestIO(): # doctest: +ELLIPSIS
1270
+ ... os.rename(cwd_old, cwd_new)
1271
+ ... os.chdir(cwd_new)
1272
+ ... result = run_subprocess("hyd.py exec_script land_dill_assl.py")
1273
+ Invoking hyd.py with arguments `exec_script, land_dill_assl.py` resulted in the \
1274
+ following error:
1275
+ For variable `inzp` at least one value needed to be trimmed. The old and the new \
1276
+ value(s) are `1.0, 1.0` and `0.1, 0.1`, respectively.
1277
+ ...
1278
+
1279
+ One can define an alternative initialisation date via argument `firstdate`:
1280
+
1281
+ >>> text_old = ('controlcheck(projectdir=r"HydPy-H-Lahn", '
1282
+ ... 'controldir="default", stepsize="1d")')
1283
+ >>> text_new = ('controlcheck(projectdir=r"HydPy-H-Lahn", controldir="default", '
1284
+ ... 'firstdate="2100-07-15", stepsize="1d")')
1285
+ >>> with TestIO():
1286
+ ... os.chdir(cwd_new)
1287
+ ... with open("land_dill_assl.py") as file_:
1288
+ ... text = file_.read()
1289
+ ... text = text.replace(text_old, text_new)
1290
+ ... with open("land_dill_assl.py", "w") as file_:
1291
+ ... _ = file_.write(text)
1292
+ ... result = run_subprocess("hyd.py exec_script land_dill_assl.py")
1293
+
1294
+ Default condition directory names do not contain information about the simulation
1295
+ step size. Hence, one needs to define it explicitly for all application models
1296
+ relying on the functionalities of class |Indexer|:
1297
+
1298
+ >>> with TestIO(): # doctest: +ELLIPSIS
1299
+ ... os.chdir(cwd_new)
1300
+ ... with open("land_dill_assl.py") as file_:
1301
+ ... text = file_.read()
1302
+ ... text = text.replace('stepsize="1d"', "")
1303
+ ... with open("land_dill_assl.py", "w") as file_:
1304
+ ... _ = file_.write(text)
1305
+ ... result = run_subprocess("hyd.py exec_script land_dill_assl.py")
1306
+ Invoking hyd.py with arguments `exec_script, land_dill_assl.py` resulted in the \
1307
+ following error:
1308
+ To apply function `controlcheck` requires time information for some model types. \
1309
+ Please define the `Timegrids` object of module `pub` manually or pass the required \
1310
+ information (`stepsize` and eventually `firstdate`) as function arguments.
1311
+ ...
1312
+
1313
+ The same error occurs we do not use the argument `firstdate` to define the
1314
+ initialisation time point, and method |controlcheck| cannot extract it from the
1315
+ directory name:
1316
+
1317
+ >>> cwd_old = cwd_new
1318
+ >>> cwd_new = os.path.join("HydPy-H-Lahn", "conditions", "init")
1319
+ >>> with TestIO(): # doctest: +ELLIPSIS
1320
+ ... os.rename(cwd_old, cwd_new)
1321
+ ... os.chdir(cwd_new)
1322
+ ... with open("land_dill_assl.py") as file_:
1323
+ ... text = file_.read()
1324
+ ... text = text.replace('firstdate="2100-07-15"', 'stepsize="1d"')
1325
+ ... with open("land_dill_assl.py", "w") as file_:
1326
+ ... _ = file_.write(text)
1327
+ ... result = run_subprocess("hyd.py exec_script land_dill_assl.py")
1328
+ Invoking hyd.py with arguments `exec_script, land_dill_assl.py` resulted in the \
1329
+ following error:
1330
+ To apply function `controlcheck` requires time information for some model types. \
1331
+ Please define the `Timegrids` object of module `pub` manually or pass the required \
1332
+ information (`stepsize` and eventually `firstdate`) as function arguments.
1333
+ ...
1334
+
1335
+ Note that the functionalities of function |controlcheck| do not come into action if
1336
+ there is a `model` variable in the namespace, which is the case when a condition
1337
+ file is executed within the context of a complete *HydPy* project.
1338
+ """
1339
+ frame = inspect.currentframe()
1340
+ assert (frame is not None) and (frame.f_back is not None)
1341
+ namespace = frame.f_back.f_locals
1342
+ model = namespace.get("model")
1343
+ if model is None:
1344
+ if not controlfile:
1345
+ controlfile = os.path.split(namespace["__file__"])[-1]
1346
+ if projectdir is None:
1347
+ projectdir = os.path.split(os.path.split(os.path.split(os.getcwd())[0])[0])[
1348
+ -1
1349
+ ]
1350
+ dirpath = os.path.abspath(
1351
+ os.path.join("..", "..", "..", projectdir, "control", controldir)
1352
+ )
1353
+ if not (exceptiontools.attrready(hydpy.pub, "timegrids") or (stepsize is None)):
1354
+ if firstdate is None:
1355
+ try:
1356
+ firstdate = timetools.Date.from_string(
1357
+ os.path.split(os.getcwd())[-1].partition("_")[-1]
1358
+ )
1359
+ except (ValueError, TypeError):
1360
+ pass
1361
+ else:
1362
+ firstdate = timetools.Date(firstdate)
1363
+ if firstdate is not None:
1364
+ stepsize = timetools.Period(stepsize)
1365
+ hydpy.pub.timegrids = (firstdate, firstdate + 1000 * stepsize, stepsize)
1366
+
1367
+ class CM(filetools.ControlManager):
1368
+ """Temporary |ControlManager| class."""
1369
+
1370
+ currentpath = dirpath
1371
+
1372
+ cwd = os.getcwd()
1373
+ try:
1374
+ os.chdir(dirpath)
1375
+ model = CM().load_file(filename=controlfile)["model"]
1376
+ except BaseException:
1377
+ objecttools.augment_excmessage(
1378
+ f"While trying to load the control file `{controlfile}` from "
1379
+ f"directory `{objecttools.repr_(dirpath)}`"
1380
+ )
1381
+ finally:
1382
+ os.chdir(cwd)
1383
+ try:
1384
+ model.update_parameters()
1385
+ except exceptiontools.AttributeNotReady as exc:
1386
+ raise RuntimeError(
1387
+ "To apply function `controlcheck` requires time information for some "
1388
+ "model types. Please define the `Timegrids` object of module `pub` "
1389
+ "manually or pass the required information (`stepsize` and eventually "
1390
+ "`firstdate`) as function arguments."
1391
+ ) from exc
1392
+
1393
+ namespace["model"] = model
1394
+ for name in ("states", "logs"):
1395
+ subseqs = getattr(model.sequences, name, None)
1396
+ if subseqs is not None:
1397
+ for seq in subseqs:
1398
+ namespace[seq.name] = seq