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.
- hydpy/__init__.py +275 -0
- hydpy/aliases.py +2554 -0
- hydpy/auxs/__init__.py +0 -0
- hydpy/auxs/anntools.py +1305 -0
- hydpy/auxs/armatools.py +883 -0
- hydpy/auxs/calibtools.py +3337 -0
- hydpy/auxs/interptools.py +1094 -0
- hydpy/auxs/iuhtools.py +543 -0
- hydpy/auxs/networktools.py +597 -0
- hydpy/auxs/ppolytools.py +809 -0
- hydpy/auxs/quadtools.py +61 -0
- hydpy/auxs/roottools.py +228 -0
- hydpy/auxs/smoothtools.py +273 -0
- hydpy/auxs/statstools.py +2125 -0
- hydpy/auxs/validtools.py +81 -0
- hydpy/conf/HydPyConfigBase.xsd +68637 -0
- hydpy/conf/HydPyConfigBase.xsdt +358 -0
- hydpy/conf/HydPyConfigMultipleRuns.xsd +25 -0
- hydpy/conf/HydPyConfigSingleRun.xsd +24 -0
- hydpy/conf/__init__.py +0 -0
- hydpy/conf/a_coefficients_explicit_lobatto_sequence.npy +0 -0
- hydpy/conf/support_points_for_smoothpar_logistic2.npy +0 -0
- hydpy/config.py +42 -0
- hydpy/core/__init__.py +0 -0
- hydpy/core/aliastools.py +214 -0
- hydpy/core/autodoctools.py +1947 -0
- hydpy/core/auxfiletools.py +1169 -0
- hydpy/core/devicetools.py +3810 -0
- hydpy/core/exceptiontools.py +269 -0
- hydpy/core/filetools.py +1985 -0
- hydpy/core/hydpytools.py +3089 -0
- hydpy/core/importtools.py +1398 -0
- hydpy/core/indextools.py +345 -0
- hydpy/core/itemtools.py +1849 -0
- hydpy/core/masktools.py +460 -0
- hydpy/core/modeltools.py +4868 -0
- hydpy/core/netcdftools.py +2683 -0
- hydpy/core/objecttools.py +2023 -0
- hydpy/core/optiontools.py +1045 -0
- hydpy/core/parametertools.py +4674 -0
- hydpy/core/printtools.py +222 -0
- hydpy/core/propertytools.py +643 -0
- hydpy/core/pubtools.py +254 -0
- hydpy/core/selectiontools.py +1571 -0
- hydpy/core/sequencetools.py +4476 -0
- hydpy/core/seriestools.py +339 -0
- hydpy/core/testtools.py +2483 -0
- hydpy/core/timetools.py +3567 -0
- hydpy/core/typingtools.py +333 -0
- hydpy/core/variabletools.py +2615 -0
- hydpy/cythons/__init__.py +24 -0
- hydpy/cythons/annutils.pxd +33 -0
- hydpy/cythons/annutils.pyi +25 -0
- hydpy/cythons/annutils.pyx +120 -0
- hydpy/cythons/autogen/__init__.py +0 -0
- hydpy/cythons/autogen/annutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/annutils.pxd +42 -0
- hydpy/cythons/autogen/annutils.pyx +129 -0
- hydpy/cythons/autogen/c_arma.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_arma.pxd +179 -0
- hydpy/cythons/autogen/c_arma.pyx +356 -0
- hydpy/cythons/autogen/c_arma_rimorido.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_arma_rimorido.pxd +179 -0
- hydpy/cythons/autogen/c_arma_rimorido.pyx +356 -0
- hydpy/cythons/autogen/c_conv.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_conv.pxd +198 -0
- hydpy/cythons/autogen/c_conv.pyx +491 -0
- hydpy/cythons/autogen/c_conv_idw.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_conv_idw.pxd +124 -0
- hydpy/cythons/autogen/c_conv_idw.pyx +264 -0
- hydpy/cythons/autogen/c_conv_idw_ed.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_conv_idw_ed.pxd +197 -0
- hydpy/cythons/autogen/c_conv_idw_ed.pyx +481 -0
- hydpy/cythons/autogen/c_conv_nn.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_conv_nn.pxd +120 -0
- hydpy/cythons/autogen/c_conv_nn.pyx +224 -0
- hydpy/cythons/autogen/c_dam.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam.pxd +805 -0
- hydpy/cythons/autogen/c_dam.pyx +1477 -0
- hydpy/cythons/autogen/c_dam_llake.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_llake.pxd +364 -0
- hydpy/cythons/autogen/c_dam_llake.pyx +705 -0
- hydpy/cythons/autogen/c_dam_lreservoir.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_lreservoir.pxd +365 -0
- hydpy/cythons/autogen/c_dam_lreservoir.pyx +708 -0
- hydpy/cythons/autogen/c_dam_lretention.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_lretention.pxd +340 -0
- hydpy/cythons/autogen/c_dam_lretention.pyx +625 -0
- hydpy/cythons/autogen/c_dam_pump.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_pump.pxd +402 -0
- hydpy/cythons/autogen/c_dam_pump.pyx +724 -0
- hydpy/cythons/autogen/c_dam_pump_sluice.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_pump_sluice.pxd +452 -0
- hydpy/cythons/autogen/c_dam_pump_sluice.pyx +829 -0
- hydpy/cythons/autogen/c_dam_sluice.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_sluice.pxd +404 -0
- hydpy/cythons/autogen/c_dam_sluice.pyx +726 -0
- hydpy/cythons/autogen/c_dam_v001.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_v001.pxd +452 -0
- hydpy/cythons/autogen/c_dam_v001.pyx +816 -0
- hydpy/cythons/autogen/c_dam_v002.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_v002.pxd +394 -0
- hydpy/cythons/autogen/c_dam_v002.pyx +703 -0
- hydpy/cythons/autogen/c_dam_v003.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_v003.pxd +417 -0
- hydpy/cythons/autogen/c_dam_v003.pyx +744 -0
- hydpy/cythons/autogen/c_dam_v004.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_v004.pxd +486 -0
- hydpy/cythons/autogen/c_dam_v004.pyx +891 -0
- hydpy/cythons/autogen/c_dam_v005.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_v005.pxd +524 -0
- hydpy/cythons/autogen/c_dam_v005.pyx +928 -0
- hydpy/cythons/autogen/c_dummy.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy.pxd +151 -0
- hydpy/cythons/autogen/c_dummy.pyx +263 -0
- hydpy/cythons/autogen/c_dummy_interceptedwater.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_interceptedwater.pxd +69 -0
- hydpy/cythons/autogen/c_dummy_interceptedwater.pyx +104 -0
- hydpy/cythons/autogen/c_dummy_node2node.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_node2node.pxd +89 -0
- hydpy/cythons/autogen/c_dummy_node2node.pyx +148 -0
- hydpy/cythons/autogen/c_dummy_snowalbedo.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_snowalbedo.pxd +69 -0
- hydpy/cythons/autogen/c_dummy_snowalbedo.pyx +104 -0
- hydpy/cythons/autogen/c_dummy_snowcover.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_snowcover.pxd +69 -0
- hydpy/cythons/autogen/c_dummy_snowcover.pyx +104 -0
- hydpy/cythons/autogen/c_dummy_snowycanopy.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_snowycanopy.pxd +69 -0
- hydpy/cythons/autogen/c_dummy_snowycanopy.pyx +104 -0
- hydpy/cythons/autogen/c_dummy_soilwater.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_soilwater.pxd +69 -0
- hydpy/cythons/autogen/c_dummy_soilwater.pyx +104 -0
- hydpy/cythons/autogen/c_evap.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap.pxd +1029 -0
- hydpy/cythons/autogen/c_evap.pyx +2601 -0
- hydpy/cythons/autogen/c_evap_aet_hbv96.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_aet_hbv96.pxd +227 -0
- hydpy/cythons/autogen/c_evap_aet_hbv96.pyx +584 -0
- hydpy/cythons/autogen/c_evap_aet_minhas.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_aet_minhas.pxd +193 -0
- hydpy/cythons/autogen/c_evap_aet_minhas.pyx +478 -0
- hydpy/cythons/autogen/c_evap_aet_morsim.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_aet_morsim.pxd +681 -0
- hydpy/cythons/autogen/c_evap_aet_morsim.pyx +1642 -0
- hydpy/cythons/autogen/c_evap_pet_ambav1.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_pet_ambav1.pxd +532 -0
- hydpy/cythons/autogen/c_evap_pet_ambav1.pyx +1296 -0
- hydpy/cythons/autogen/c_evap_pet_hbv96.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_pet_hbv96.pxd +179 -0
- hydpy/cythons/autogen/c_evap_pet_hbv96.pyx +328 -0
- hydpy/cythons/autogen/c_evap_pet_m.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_pet_m.pxd +124 -0
- hydpy/cythons/autogen/c_evap_pet_m.pyx +214 -0
- hydpy/cythons/autogen/c_evap_pet_mlc.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_pet_mlc.pxd +126 -0
- hydpy/cythons/autogen/c_evap_pet_mlc.pyx +214 -0
- hydpy/cythons/autogen/c_evap_ret_fao56.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_ret_fao56.pxd +305 -0
- hydpy/cythons/autogen/c_evap_ret_fao56.pyx +624 -0
- hydpy/cythons/autogen/c_evap_ret_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_ret_io.pxd +112 -0
- hydpy/cythons/autogen/c_evap_ret_io.pyx +176 -0
- hydpy/cythons/autogen/c_evap_ret_tw2002.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_ret_tw2002.pxd +139 -0
- hydpy/cythons/autogen/c_evap_ret_tw2002.pyx +273 -0
- hydpy/cythons/autogen/c_exch.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_exch.pxd +230 -0
- hydpy/cythons/autogen/c_exch.pyx +462 -0
- hydpy/cythons/autogen/c_exch_branch_hbv96.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_exch_branch_hbv96.pxd +134 -0
- hydpy/cythons/autogen/c_exch_branch_hbv96.pyx +255 -0
- hydpy/cythons/autogen/c_exch_waterlevel.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_exch_waterlevel.pxd +54 -0
- hydpy/cythons/autogen/c_exch_waterlevel.pyx +78 -0
- hydpy/cythons/autogen/c_exch_weir_hbv96.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_exch_weir_hbv96.pxd +156 -0
- hydpy/cythons/autogen/c_exch_weir_hbv96.pyx +282 -0
- hydpy/cythons/autogen/c_ga.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_ga.pxd +353 -0
- hydpy/cythons/autogen/c_ga.pyx +1204 -0
- hydpy/cythons/autogen/c_ga_garto.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_ga_garto.pxd +330 -0
- hydpy/cythons/autogen/c_ga_garto.pyx +1105 -0
- hydpy/cythons/autogen/c_ga_garto_submodel1.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_ga_garto_submodel1.pxd +236 -0
- hydpy/cythons/autogen/c_ga_garto_submodel1.pyx +944 -0
- hydpy/cythons/autogen/c_gland.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_gland.pxd +437 -0
- hydpy/cythons/autogen/c_gland.pyx +726 -0
- hydpy/cythons/autogen/c_gland_gr4.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_gland_gr4.pxd +382 -0
- hydpy/cythons/autogen/c_gland_gr4.pyx +605 -0
- hydpy/cythons/autogen/c_gland_gr5.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_gland_gr5.pxd +368 -0
- hydpy/cythons/autogen/c_gland_gr5.pyx +568 -0
- hydpy/cythons/autogen/c_gland_gr6.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_gland_gr6.pxd +420 -0
- hydpy/cythons/autogen/c_gland_gr6.pyx +673 -0
- hydpy/cythons/autogen/c_hland.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_hland.pxd +855 -0
- hydpy/cythons/autogen/c_hland.pyx +2486 -0
- hydpy/cythons/autogen/c_hland_96.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_hland_96.pxd +631 -0
- hydpy/cythons/autogen/c_hland_96.pyx +1724 -0
- hydpy/cythons/autogen/c_hland_96c.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_hland_96c.pxd +621 -0
- hydpy/cythons/autogen/c_hland_96c.pyx +1822 -0
- hydpy/cythons/autogen/c_hland_96p.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_hland_96p.pxd +683 -0
- hydpy/cythons/autogen/c_hland_96p.pyx +1911 -0
- hydpy/cythons/autogen/c_kinw.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_kinw.pxd +509 -0
- hydpy/cythons/autogen/c_kinw.pyx +965 -0
- hydpy/cythons/autogen/c_kinw_williams.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_kinw_williams.pxd +409 -0
- hydpy/cythons/autogen/c_kinw_williams.pyx +763 -0
- hydpy/cythons/autogen/c_kinw_williams_ext.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_kinw_williams_ext.pxd +220 -0
- hydpy/cythons/autogen/c_kinw_williams_ext.pyx +440 -0
- hydpy/cythons/autogen/c_lland.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_lland.pxd +1386 -0
- hydpy/cythons/autogen/c_lland.pyx +3679 -0
- hydpy/cythons/autogen/c_lland_dd.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_lland_dd.pxd +679 -0
- hydpy/cythons/autogen/c_lland_dd.pyx +1719 -0
- hydpy/cythons/autogen/c_lland_knauf.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_lland_knauf.pxd +1096 -0
- hydpy/cythons/autogen/c_lland_knauf.pyx +2784 -0
- hydpy/cythons/autogen/c_lland_knauf_ic.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_lland_knauf_ic.pxd +1369 -0
- hydpy/cythons/autogen/c_lland_knauf_ic.pyx +3625 -0
- hydpy/cythons/autogen/c_meteo.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo.pxd +469 -0
- hydpy/cythons/autogen/c_meteo.pyx +879 -0
- hydpy/cythons/autogen/c_meteo_clear_glob_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_clear_glob_io.pxd +75 -0
- hydpy/cythons/autogen/c_meteo_clear_glob_io.pyx +107 -0
- hydpy/cythons/autogen/c_meteo_glob_fao56.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_glob_fao56.pxd +209 -0
- hydpy/cythons/autogen/c_meteo_glob_fao56.pyx +339 -0
- hydpy/cythons/autogen/c_meteo_glob_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_glob_io.pxd +63 -0
- hydpy/cythons/autogen/c_meteo_glob_io.pyx +91 -0
- hydpy/cythons/autogen/c_meteo_glob_morsim.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_glob_morsim.pxd +289 -0
- hydpy/cythons/autogen/c_meteo_glob_morsim.pyx +527 -0
- hydpy/cythons/autogen/c_meteo_precip_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_precip_io.pxd +112 -0
- hydpy/cythons/autogen/c_meteo_precip_io.pyx +176 -0
- hydpy/cythons/autogen/c_meteo_psun_sun_glob_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_psun_sun_glob_io.pxd +87 -0
- hydpy/cythons/autogen/c_meteo_psun_sun_glob_io.pyx +123 -0
- hydpy/cythons/autogen/c_meteo_sun_fao56.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_sun_fao56.pxd +209 -0
- hydpy/cythons/autogen/c_meteo_sun_fao56.pyx +343 -0
- hydpy/cythons/autogen/c_meteo_sun_morsim.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_sun_morsim.pxd +286 -0
- hydpy/cythons/autogen/c_meteo_sun_morsim.pyx +519 -0
- hydpy/cythons/autogen/c_meteo_temp_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_temp_io.pxd +112 -0
- hydpy/cythons/autogen/c_meteo_temp_io.pyx +176 -0
- hydpy/cythons/autogen/c_musk.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_musk.pxd +282 -0
- hydpy/cythons/autogen/c_musk.pyx +605 -0
- hydpy/cythons/autogen/c_musk_classic.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_musk_classic.pxd +138 -0
- hydpy/cythons/autogen/c_musk_classic.pyx +226 -0
- hydpy/cythons/autogen/c_musk_mct.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_musk_mct.pxd +282 -0
- hydpy/cythons/autogen/c_musk_mct.pyx +609 -0
- hydpy/cythons/autogen/c_rconc.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_rconc.pxd +119 -0
- hydpy/cythons/autogen/c_rconc.pyx +174 -0
- hydpy/cythons/autogen/c_rconc_nash.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_rconc_nash.pxd +111 -0
- hydpy/cythons/autogen/c_rconc_nash.pyx +185 -0
- hydpy/cythons/autogen/c_rconc_uh.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_rconc_uh.pxd +92 -0
- hydpy/cythons/autogen/c_rconc_uh.pyx +125 -0
- hydpy/cythons/autogen/c_sw1d.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d.pxd +511 -0
- hydpy/cythons/autogen/c_sw1d.pyx +1263 -0
- hydpy/cythons/autogen/c_sw1d_channel.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_channel.pxd +119 -0
- hydpy/cythons/autogen/c_sw1d_channel.pyx +300 -0
- hydpy/cythons/autogen/c_sw1d_gate_out.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_gate_out.pxd +240 -0
- hydpy/cythons/autogen/c_sw1d_gate_out.pyx +476 -0
- hydpy/cythons/autogen/c_sw1d_lias.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_lias.pxd +320 -0
- hydpy/cythons/autogen/c_sw1d_lias.pyx +619 -0
- hydpy/cythons/autogen/c_sw1d_lias_sluice.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_lias_sluice.pxd +325 -0
- hydpy/cythons/autogen/c_sw1d_lias_sluice.pyx +644 -0
- hydpy/cythons/autogen/c_sw1d_network.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_network.pxd +90 -0
- hydpy/cythons/autogen/c_sw1d_network.pyx +246 -0
- hydpy/cythons/autogen/c_sw1d_pump.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_pump.pxd +256 -0
- hydpy/cythons/autogen/c_sw1d_pump.pyx +502 -0
- hydpy/cythons/autogen/c_sw1d_q_in.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_q_in.pxd +224 -0
- hydpy/cythons/autogen/c_sw1d_q_in.pyx +383 -0
- hydpy/cythons/autogen/c_sw1d_q_out.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_q_out.pxd +224 -0
- hydpy/cythons/autogen/c_sw1d_q_out.pyx +383 -0
- hydpy/cythons/autogen/c_sw1d_storage.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_storage.pxd +193 -0
- hydpy/cythons/autogen/c_sw1d_storage.pyx +349 -0
- hydpy/cythons/autogen/c_sw1d_weir_out.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_weir_out.pxd +212 -0
- hydpy/cythons/autogen/c_sw1d_weir_out.pyx +404 -0
- hydpy/cythons/autogen/c_test.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_test.pxd +175 -0
- hydpy/cythons/autogen/c_test.pyx +348 -0
- hydpy/cythons/autogen/c_test_discontinous.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_test_discontinous.pxd +146 -0
- hydpy/cythons/autogen/c_test_discontinous.pyx +256 -0
- hydpy/cythons/autogen/c_test_stiff0d.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_test_stiff0d.pxd +146 -0
- hydpy/cythons/autogen/c_test_stiff0d.pyx +250 -0
- hydpy/cythons/autogen/c_test_stiff1d.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_test_stiff1d.pxd +145 -0
- hydpy/cythons/autogen/c_test_stiff1d.pyx +294 -0
- hydpy/cythons/autogen/c_whmod.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_whmod.pxd +482 -0
- hydpy/cythons/autogen/c_whmod.pyx +1156 -0
- hydpy/cythons/autogen/c_whmod_rural.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_whmod_rural.pxd +411 -0
- hydpy/cythons/autogen/c_whmod_rural.pyx +982 -0
- hydpy/cythons/autogen/c_whmod_urban.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_whmod_urban.pxd +482 -0
- hydpy/cythons/autogen/c_whmod_urban.pyx +1155 -0
- hydpy/cythons/autogen/c_wland.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wland.pxd +842 -0
- hydpy/cythons/autogen/c_wland.pyx +1890 -0
- hydpy/cythons/autogen/c_wland_gd.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wland_gd.pxd +829 -0
- hydpy/cythons/autogen/c_wland_gd.pyx +1847 -0
- hydpy/cythons/autogen/c_wland_wag.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wland_wag.pxd +810 -0
- hydpy/cythons/autogen/c_wland_wag.pyx +1780 -0
- hydpy/cythons/autogen/c_wq.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wq.pxd +275 -0
- hydpy/cythons/autogen/c_wq.pyx +652 -0
- hydpy/cythons/autogen/c_wq_trapeze.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wq_trapeze.pxd +170 -0
- hydpy/cythons/autogen/c_wq_trapeze.pyx +400 -0
- hydpy/cythons/autogen/c_wq_trapeze_strickler.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wq_trapeze_strickler.pxd +243 -0
- hydpy/cythons/autogen/c_wq_trapeze_strickler.pyx +578 -0
- hydpy/cythons/autogen/c_wq_walrus.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wq_walrus.pxd +61 -0
- hydpy/cythons/autogen/c_wq_walrus.pyx +82 -0
- hydpy/cythons/autogen/configutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/configutils.pxd +17 -0
- hydpy/cythons/autogen/configutils.pyx +119 -0
- hydpy/cythons/autogen/interfaceutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/interfaceutils.pxd +31 -0
- hydpy/cythons/autogen/interfaceutils.pyx +82 -0
- hydpy/cythons/autogen/interputils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/interputils.pxd +42 -0
- hydpy/cythons/autogen/interputils.pyx +118 -0
- hydpy/cythons/autogen/masterinterface.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/masterinterface.pxd +153 -0
- hydpy/cythons/autogen/masterinterface.pyx +222 -0
- hydpy/cythons/autogen/pointerutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/pointerutils.pxd +31 -0
- hydpy/cythons/autogen/pointerutils.pyx +650 -0
- hydpy/cythons/autogen/ppolyutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/ppolyutils.pxd +35 -0
- hydpy/cythons/autogen/ppolyutils.pyx +59 -0
- hydpy/cythons/autogen/quadutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/quadutils.pxd +26 -0
- hydpy/cythons/autogen/quadutils.pyx +973 -0
- hydpy/cythons/autogen/rootutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/rootutils.pxd +28 -0
- hydpy/cythons/autogen/rootutils.pyx +109 -0
- hydpy/cythons/autogen/sequenceutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/sequenceutils.pxd +45 -0
- hydpy/cythons/autogen/sequenceutils.pyx +101 -0
- hydpy/cythons/autogen/smoothutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/smoothutils.pxd +29 -0
- hydpy/cythons/autogen/smoothutils.pyx +833 -0
- hydpy/cythons/configutils.pxd +8 -0
- hydpy/cythons/configutils.pyi +5 -0
- hydpy/cythons/configutils.pyx +110 -0
- hydpy/cythons/interfaceutils.pxd +22 -0
- hydpy/cythons/interfaceutils.pyi +15 -0
- hydpy/cythons/interfaceutils.pyx +73 -0
- hydpy/cythons/interputils.pxd +33 -0
- hydpy/cythons/interputils.pyi +32 -0
- hydpy/cythons/interputils.pyx +109 -0
- hydpy/cythons/modelutils.py +2990 -0
- hydpy/cythons/pointerutils.pxd +22 -0
- hydpy/cythons/pointerutils.pyi +89 -0
- hydpy/cythons/pointerutils.pyx +641 -0
- hydpy/cythons/ppolyutils.pxd +26 -0
- hydpy/cythons/ppolyutils.pyi +21 -0
- hydpy/cythons/ppolyutils.pyx +50 -0
- hydpy/cythons/quadutils.pxd +17 -0
- hydpy/cythons/quadutils.pyi +13 -0
- hydpy/cythons/quadutils.pyx +964 -0
- hydpy/cythons/rootutils.pxd +19 -0
- hydpy/cythons/rootutils.pyi +21 -0
- hydpy/cythons/rootutils.pyx +100 -0
- hydpy/cythons/sequenceutils.pxd +36 -0
- hydpy/cythons/sequenceutils.pyi +7 -0
- hydpy/cythons/sequenceutils.pyx +92 -0
- hydpy/cythons/smoothutils.pxd +20 -0
- hydpy/cythons/smoothutils.pyi +15 -0
- hydpy/cythons/smoothutils.pyx +824 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_dill_assl.py +13 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_lahn_kalk.py +13 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_lahn_leun.py +14 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_lahn_marb.py +13 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/stream_dill_assl_lahn_leun.py +5 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/stream_lahn_leun_lahn_kalk.py +5 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/stream_lahn_marb_lahn_leun.py +5 -0
- hydpy/data/HydPy-H-Lahn/control/default/land.py +9 -0
- hydpy/data/HydPy-H-Lahn/control/default/land_dill_assl.py +57 -0
- hydpy/data/HydPy-H-Lahn/control/default/land_lahn_kalk.py +57 -0
- hydpy/data/HydPy-H-Lahn/control/default/land_lahn_leun.py +56 -0
- hydpy/data/HydPy-H-Lahn/control/default/land_lahn_marb.py +57 -0
- hydpy/data/HydPy-H-Lahn/control/default/stream_dill_assl_lahn_leun.py +7 -0
- hydpy/data/HydPy-H-Lahn/control/default/stream_lahn_leun_lahn_kalk.py +7 -0
- hydpy/data/HydPy-H-Lahn/control/default/stream_lahn_marb_lahn_leun.py +7 -0
- hydpy/data/HydPy-H-Lahn/multiple_runs.xml +309 -0
- hydpy/data/HydPy-H-Lahn/multiple_runs_alpha.xml +71 -0
- hydpy/data/HydPy-H-Lahn/network/default/headwaters.py +11 -0
- hydpy/data/HydPy-H-Lahn/network/default/nonheadwaters.py +11 -0
- hydpy/data/HydPy-H-Lahn/network/default/streams.py +8 -0
- hydpy/data/HydPy-H-Lahn/series/default/dill_assl_obs_q.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/evap_pet_hbv96_input_normalairtemperature.nc +0 -0
- hydpy/data/HydPy-H-Lahn/series/default/evap_pet_hbv96_input_normalevapotranspiration.nc +0 -0
- hydpy/data/HydPy-H-Lahn/series/default/hland_96_input_p.nc +0 -0
- hydpy/data/HydPy-H-Lahn/series/default/hland_96_input_t.nc +0 -0
- hydpy/data/HydPy-H-Lahn/series/default/lahn_kalk_obs_q.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/lahn_leun_obs_q.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/lahn_marb_obs_q.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_hland_96_input_p.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_hland_96_input_t.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_hland_96_input_p.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_hland_96_input_t.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_hland_96_input_p.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_hland_96_input_t.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_hland_96_input_p.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_hland_96_input_t.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/obs_q.nc +0 -0
- hydpy/data/HydPy-H-Lahn/single_run.xml +152 -0
- hydpy/data/HydPy-H-Lahn/single_run.xmlt +143 -0
- hydpy/data/__init__.py +17 -0
- hydpy/docs/__init__.py +0 -0
- hydpy/docs/autofigs/__init__.py +0 -0
- hydpy/docs/bib/__init__.py +0 -0
- hydpy/docs/bib/refs.bib +566 -0
- hydpy/docs/combine_docversions.py +133 -0
- hydpy/docs/draw_model_sketches.py +1301 -0
- hydpy/docs/enable_autodoc.py +7 -0
- hydpy/docs/figs/HydPy-G-GR4.png +0 -0
- hydpy/docs/figs/HydPy-G-GR5.png +0 -0
- hydpy/docs/figs/HydPy-G-GR6.png +0 -0
- hydpy/docs/figs/HydPy-H-HBV96-COSERO.png +0 -0
- hydpy/docs/figs/HydPy-H-HBV96-PREVAH.png +0 -0
- hydpy/docs/figs/HydPy-H-HBV96.png +0 -0
- hydpy/docs/figs/HydPy-H-Lahn.png +0 -0
- hydpy/docs/figs/HydPy-KinW-Williams.png +0 -0
- hydpy/docs/figs/HydPy-L-DD.png +0 -0
- hydpy/docs/figs/HydPy-W-Wag.png +0 -0
- hydpy/docs/figs/HydPy_Logo.png +0 -0
- hydpy/docs/figs/HydPy_Logo_Text.png +0 -0
- hydpy/docs/figs/IDLE-editor.png +0 -0
- hydpy/docs/figs/IDLE-shell.png +0 -0
- hydpy/docs/figs/LAWA_river-basin-bumbers.png +0 -0
- hydpy/docs/figs/__init__.py +0 -0
- hydpy/docs/html_/__init__.py +0 -0
- hydpy/docs/polish_html.py +57 -0
- hydpy/docs/prepare.py +224 -0
- hydpy/docs/publish_docs.py +53 -0
- hydpy/docs/rst/HydPy-ARMA.rst +27 -0
- hydpy/docs/rst/HydPy-Conv.rst +22 -0
- hydpy/docs/rst/HydPy-Dam.rst +79 -0
- hydpy/docs/rst/HydPy-Dummy.rst +21 -0
- hydpy/docs/rst/HydPy-Evap.rst +26 -0
- hydpy/docs/rst/HydPy-Exch.rst +36 -0
- hydpy/docs/rst/HydPy-G.rst +40 -0
- hydpy/docs/rst/HydPy-GA.rst +34 -0
- hydpy/docs/rst/HydPy-H.rst +24 -0
- hydpy/docs/rst/HydPy-KinW.rst +32 -0
- hydpy/docs/rst/HydPy-L.rst +42 -0
- hydpy/docs/rst/HydPy-Meteo.rst +28 -0
- hydpy/docs/rst/HydPy-Musk.rst +21 -0
- hydpy/docs/rst/HydPy-Rconc.rst +17 -0
- hydpy/docs/rst/HydPy-SW1D.rst +49 -0
- hydpy/docs/rst/HydPy-Test.rst +19 -0
- hydpy/docs/rst/HydPy-W.rst +20 -0
- hydpy/docs/rst/HydPy-WHMod.rst +19 -0
- hydpy/docs/rst/HydPy-WQ.rst +20 -0
- hydpy/docs/rst/__init__.py +0 -0
- hydpy/docs/rst/additional_repositories.rst +40 -0
- hydpy/docs/rst/auxiliaries.rst +31 -0
- hydpy/docs/rst/continuous_integration.rst +75 -0
- hydpy/docs/rst/core.rst +75 -0
- hydpy/docs/rst/cythons.rst +47 -0
- hydpy/docs/rst/definitions.rst +506 -0
- hydpy/docs/rst/developer_guide.rst +54 -0
- hydpy/docs/rst/example_projects.rst +40 -0
- hydpy/docs/rst/execution.rst +22 -0
- hydpy/docs/rst/framework_tools.rst +56 -0
- hydpy/docs/rst/how_to_read_the_reference_manual.rst +156 -0
- hydpy/docs/rst/hydpydependencies.rst +55 -0
- hydpy/docs/rst/index.rst +125 -0
- hydpy/docs/rst/installation.rst +155 -0
- hydpy/docs/rst/model_families.rst +79 -0
- hydpy/docs/rst/model_overview.rst +291 -0
- hydpy/docs/rst/modelimports.rst +10 -0
- hydpy/docs/rst/options.rst +119 -0
- hydpy/docs/rst/programming_style.rst +572 -0
- hydpy/docs/rst/project_structure.rst +520 -0
- hydpy/docs/rst/quickstart.rst +304 -0
- hydpy/docs/rst/reference_manual.rst +29 -0
- hydpy/docs/rst/required_tools.rst +50 -0
- hydpy/docs/rst/simulation.rst +514 -0
- hydpy/docs/rst/submodel_interfaces.rst +32 -0
- hydpy/docs/rst/tests_and_documentation.rst +85 -0
- hydpy/docs/rst/user_guide.rst +38 -0
- hydpy/docs/rst/version_control.rst +116 -0
- hydpy/docs/rst/zbibliography.rst +8 -0
- hydpy/docs/sphinx/__init__.py +0 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/changes/frameset.html +11 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/changes/rstsource.html +15 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/changes/versionchanges.html +33 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/defindex.html +35 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/domainindex.html +56 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/genindex-single.html +63 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/genindex-split.html +41 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/genindex.html +76 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/globaltoc.html +11 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/layout.html +221 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/localtoc.html +15 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/opensearch.xml +13 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/page.html +13 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/relations.html +23 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/search.html +65 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/searchbox.html +21 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/searchfield.html +23 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/sourcelink.html +18 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/basic.css_t +925 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/doctools.js +156 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/documentation_options.js_t +13 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/file.png +0 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/language_data.js_t +26 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/minus.png +0 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/plus.png +0 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/searchtools.js +574 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/sphinx_highlight.js +154 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/theme.conf +16 -0
- hydpy/docs/sphinx/_themes/classic_hydpy/layout.html +23 -0
- hydpy/docs/sphinx/_themes/classic_hydpy/static/classic.css_t +358 -0
- hydpy/docs/sphinx/_themes/classic_hydpy/static/sidebar.js_t +72 -0
- hydpy/docs/sphinx/_themes/classic_hydpy/theme.conf +32 -0
- hydpy/docs/sphinx/conf.py +398 -0
- hydpy/docs/sphinx/defaultlinks_extension.py +36 -0
- hydpy/docs/sphinx/integrationtest_extension.py +104 -0
- hydpy/docs/sphinx/projectstructure_extension.py +58 -0
- hydpy/docs/sphinx/submodelgraph_extension.py +53 -0
- hydpy/exe/__init__.py +0 -0
- hydpy/exe/commandtools.py +651 -0
- hydpy/exe/hyd.py +277 -0
- hydpy/exe/modelimports.py +41 -0
- hydpy/exe/replacetools.py +216 -0
- hydpy/exe/servertools.py +2348 -0
- hydpy/exe/xmltools.py +3280 -0
- hydpy/interfaces/__init__.py +0 -0
- hydpy/interfaces/aetinterfaces.py +94 -0
- hydpy/interfaces/dischargeinterfaces.py +45 -0
- hydpy/interfaces/petinterfaces.py +117 -0
- hydpy/interfaces/precipinterfaces.py +42 -0
- hydpy/interfaces/radiationinterfaces.py +79 -0
- hydpy/interfaces/rconcinterfaces.py +30 -0
- hydpy/interfaces/routinginterfaces.py +324 -0
- hydpy/interfaces/soilinterfaces.py +96 -0
- hydpy/interfaces/stateinterfaces.py +98 -0
- hydpy/interfaces/tempinterfaces.py +46 -0
- hydpy/models/__init__.py +0 -0
- hydpy/models/arma/__init__.py +14 -0
- hydpy/models/arma/arma_control.py +383 -0
- hydpy/models/arma/arma_derived.py +204 -0
- hydpy/models/arma/arma_fluxes.py +41 -0
- hydpy/models/arma/arma_inlets.py +11 -0
- hydpy/models/arma/arma_logs.py +19 -0
- hydpy/models/arma/arma_model.py +461 -0
- hydpy/models/arma/arma_outlets.py +11 -0
- hydpy/models/arma_rimorido.py +381 -0
- hydpy/models/conv/__init__.py +12 -0
- hydpy/models/conv/conv_control.py +303 -0
- hydpy/models/conv/conv_derived.py +271 -0
- hydpy/models/conv/conv_fluxes.py +54 -0
- hydpy/models/conv/conv_inlets.py +11 -0
- hydpy/models/conv/conv_model.py +687 -0
- hydpy/models/conv/conv_outlets.py +11 -0
- hydpy/models/conv_idw.py +120 -0
- hydpy/models/conv_idw_ed.py +184 -0
- hydpy/models/conv_nn.py +112 -0
- hydpy/models/dam/__init__.py +16 -0
- hydpy/models/dam/dam_aides.py +17 -0
- hydpy/models/dam/dam_control.py +346 -0
- hydpy/models/dam/dam_derived.py +559 -0
- hydpy/models/dam/dam_factors.py +46 -0
- hydpy/models/dam/dam_fluxes.py +179 -0
- hydpy/models/dam/dam_inlets.py +29 -0
- hydpy/models/dam/dam_logs.py +52 -0
- hydpy/models/dam/dam_model.py +5011 -0
- hydpy/models/dam/dam_outlets.py +23 -0
- hydpy/models/dam/dam_receivers.py +41 -0
- hydpy/models/dam/dam_senders.py +23 -0
- hydpy/models/dam/dam_solver.py +75 -0
- hydpy/models/dam/dam_states.py +11 -0
- hydpy/models/dam_llake.py +499 -0
- hydpy/models/dam_lreservoir.py +548 -0
- hydpy/models/dam_lretention.py +343 -0
- hydpy/models/dam_pump.py +278 -0
- hydpy/models/dam_pump_sluice.py +339 -0
- hydpy/models/dam_sluice.py +319 -0
- hydpy/models/dam_v001.py +1127 -0
- hydpy/models/dam_v002.py +381 -0
- hydpy/models/dam_v003.py +422 -0
- hydpy/models/dam_v004.py +665 -0
- hydpy/models/dam_v005.py +479 -0
- hydpy/models/dummy/__init__.py +15 -0
- hydpy/models/dummy/dummy_control.py +22 -0
- hydpy/models/dummy/dummy_fluxes.py +11 -0
- hydpy/models/dummy/dummy_inlets.py +11 -0
- hydpy/models/dummy/dummy_inputs.py +41 -0
- hydpy/models/dummy/dummy_model.py +196 -0
- hydpy/models/dummy/dummy_outlets.py +11 -0
- hydpy/models/dummy_interceptedwater.py +85 -0
- hydpy/models/dummy_node2node.py +83 -0
- hydpy/models/dummy_snowalbedo.py +84 -0
- hydpy/models/dummy_snowcover.py +84 -0
- hydpy/models/dummy_snowycanopy.py +86 -0
- hydpy/models/dummy_soilwater.py +85 -0
- hydpy/models/evap/__init__.py +13 -0
- hydpy/models/evap/evap_control.py +354 -0
- hydpy/models/evap/evap_derived.py +236 -0
- hydpy/models/evap/evap_factors.py +188 -0
- hydpy/models/evap/evap_fixed.py +68 -0
- hydpy/models/evap/evap_fluxes.py +150 -0
- hydpy/models/evap/evap_inputs.py +54 -0
- hydpy/models/evap/evap_logs.py +91 -0
- hydpy/models/evap/evap_masks.py +48 -0
- hydpy/models/evap/evap_model.py +9170 -0
- hydpy/models/evap/evap_parameters.py +149 -0
- hydpy/models/evap/evap_sequences.py +32 -0
- hydpy/models/evap/evap_states.py +18 -0
- hydpy/models/evap_aet_hbv96.py +372 -0
- hydpy/models/evap_aet_minhas.py +331 -0
- hydpy/models/evap_aet_morsim.py +627 -0
- hydpy/models/evap_pet_ambav1.py +483 -0
- hydpy/models/evap_pet_hbv96.py +147 -0
- hydpy/models/evap_pet_m.py +94 -0
- hydpy/models/evap_pet_mlc.py +107 -0
- hydpy/models/evap_ret_fao56.py +265 -0
- hydpy/models/evap_ret_io.py +74 -0
- hydpy/models/evap_ret_tw2002.py +165 -0
- hydpy/models/exch/__init__.py +14 -0
- hydpy/models/exch/exch_control.py +262 -0
- hydpy/models/exch/exch_derived.py +36 -0
- hydpy/models/exch/exch_factors.py +26 -0
- hydpy/models/exch/exch_fluxes.py +48 -0
- hydpy/models/exch/exch_inlets.py +11 -0
- hydpy/models/exch/exch_logs.py +12 -0
- hydpy/models/exch/exch_model.py +451 -0
- hydpy/models/exch/exch_outlets.py +17 -0
- hydpy/models/exch/exch_receivers.py +17 -0
- hydpy/models/exch_branch_hbv96.py +186 -0
- hydpy/models/exch_waterlevel.py +73 -0
- hydpy/models/exch_weir_hbv96.py +609 -0
- hydpy/models/ga/__init__.py +14 -0
- hydpy/models/ga/ga_aides.py +17 -0
- hydpy/models/ga/ga_control.py +208 -0
- hydpy/models/ga/ga_derived.py +77 -0
- hydpy/models/ga/ga_fluxes.py +83 -0
- hydpy/models/ga/ga_inputs.py +26 -0
- hydpy/models/ga/ga_logs.py +17 -0
- hydpy/models/ga/ga_model.py +2952 -0
- hydpy/models/ga/ga_states.py +87 -0
- hydpy/models/ga_garto.py +1001 -0
- hydpy/models/ga_garto_submodel1.py +79 -0
- hydpy/models/gland/__init__.py +14 -0
- hydpy/models/gland/gland_control.py +90 -0
- hydpy/models/gland/gland_derived.py +113 -0
- hydpy/models/gland/gland_fluxes.py +137 -0
- hydpy/models/gland/gland_inputs.py +12 -0
- hydpy/models/gland/gland_model.py +1439 -0
- hydpy/models/gland/gland_outlets.py +11 -0
- hydpy/models/gland/gland_states.py +90 -0
- hydpy/models/gland_gr4.py +501 -0
- hydpy/models/gland_gr5.py +463 -0
- hydpy/models/gland_gr6.py +487 -0
- hydpy/models/hland/__init__.py +20 -0
- hydpy/models/hland/hland_aides.py +19 -0
- hydpy/models/hland/hland_constants.py +37 -0
- hydpy/models/hland/hland_control.py +1530 -0
- hydpy/models/hland/hland_derived.py +683 -0
- hydpy/models/hland/hland_factors.py +57 -0
- hydpy/models/hland/hland_fixed.py +42 -0
- hydpy/models/hland/hland_fluxes.py +279 -0
- hydpy/models/hland/hland_inputs.py +19 -0
- hydpy/models/hland/hland_masks.py +107 -0
- hydpy/models/hland/hland_model.py +4664 -0
- hydpy/models/hland/hland_outlets.py +11 -0
- hydpy/models/hland/hland_parameters.py +227 -0
- hydpy/models/hland/hland_sequences.py +382 -0
- hydpy/models/hland/hland_states.py +236 -0
- hydpy/models/hland_96.py +1812 -0
- hydpy/models/hland_96c.py +1196 -0
- hydpy/models/hland_96p.py +1204 -0
- hydpy/models/kinw/__init__.py +18 -0
- hydpy/models/kinw/kinw_aides.py +306 -0
- hydpy/models/kinw/kinw_control.py +270 -0
- hydpy/models/kinw/kinw_derived.py +197 -0
- hydpy/models/kinw/kinw_fixed.py +33 -0
- hydpy/models/kinw/kinw_fluxes.py +37 -0
- hydpy/models/kinw/kinw_inlets.py +11 -0
- hydpy/models/kinw/kinw_model.py +3026 -0
- hydpy/models/kinw/kinw_outlets.py +11 -0
- hydpy/models/kinw/kinw_solver.py +45 -0
- hydpy/models/kinw/kinw_states.py +17 -0
- hydpy/models/kinw_williams.py +1299 -0
- hydpy/models/kinw_williams_ext.py +768 -0
- hydpy/models/lland/__init__.py +42 -0
- hydpy/models/lland/lland_aides.py +38 -0
- hydpy/models/lland/lland_constants.py +88 -0
- hydpy/models/lland/lland_control.py +1329 -0
- hydpy/models/lland/lland_derived.py +380 -0
- hydpy/models/lland/lland_factors.py +18 -0
- hydpy/models/lland/lland_fixed.py +128 -0
- hydpy/models/lland/lland_fluxes.py +626 -0
- hydpy/models/lland/lland_inlets.py +12 -0
- hydpy/models/lland/lland_inputs.py +33 -0
- hydpy/models/lland/lland_logs.py +17 -0
- hydpy/models/lland/lland_masks.py +212 -0
- hydpy/models/lland/lland_model.py +7690 -0
- hydpy/models/lland/lland_outlets.py +12 -0
- hydpy/models/lland/lland_parameters.py +195 -0
- hydpy/models/lland/lland_sequences.py +67 -0
- hydpy/models/lland/lland_states.py +280 -0
- hydpy/models/lland_dd.py +2270 -0
- hydpy/models/lland_knauf.py +2156 -0
- hydpy/models/lland_knauf_ic.py +1920 -0
- hydpy/models/meteo/__init__.py +12 -0
- hydpy/models/meteo/meteo_control.py +154 -0
- hydpy/models/meteo/meteo_derived.py +159 -0
- hydpy/models/meteo/meteo_factors.py +88 -0
- hydpy/models/meteo/meteo_fixed.py +19 -0
- hydpy/models/meteo/meteo_fluxes.py +46 -0
- hydpy/models/meteo/meteo_inputs.py +47 -0
- hydpy/models/meteo/meteo_logs.py +30 -0
- hydpy/models/meteo/meteo_model.py +2904 -0
- hydpy/models/meteo/meteo_parameters.py +14 -0
- hydpy/models/meteo/meteo_sequences.py +22 -0
- hydpy/models/meteo_clear_glob_io.py +77 -0
- hydpy/models/meteo_glob_fao56.py +217 -0
- hydpy/models/meteo_glob_io.py +68 -0
- hydpy/models/meteo_glob_morsim.py +444 -0
- hydpy/models/meteo_precip_io.py +76 -0
- hydpy/models/meteo_psun_sun_glob_io.py +83 -0
- hydpy/models/meteo_sun_fao56.py +188 -0
- hydpy/models/meteo_sun_morsim.py +466 -0
- hydpy/models/meteo_temp_io.py +76 -0
- hydpy/models/musk/__init__.py +15 -0
- hydpy/models/musk/musk_control.py +328 -0
- hydpy/models/musk/musk_derived.py +32 -0
- hydpy/models/musk/musk_factors.py +53 -0
- hydpy/models/musk/musk_fluxes.py +24 -0
- hydpy/models/musk/musk_inlets.py +11 -0
- hydpy/models/musk/musk_masks.py +15 -0
- hydpy/models/musk/musk_model.py +838 -0
- hydpy/models/musk/musk_outlets.py +11 -0
- hydpy/models/musk/musk_sequences.py +88 -0
- hydpy/models/musk/musk_solver.py +68 -0
- hydpy/models/musk/musk_states.py +64 -0
- hydpy/models/musk_classic.py +228 -0
- hydpy/models/musk_mct.py +1247 -0
- hydpy/models/rconc/__init__.py +12 -0
- hydpy/models/rconc/rconc_control.py +473 -0
- hydpy/models/rconc/rconc_derived.py +76 -0
- hydpy/models/rconc/rconc_fluxes.py +19 -0
- hydpy/models/rconc/rconc_logs.py +74 -0
- hydpy/models/rconc/rconc_model.py +260 -0
- hydpy/models/rconc/rconc_states.py +11 -0
- hydpy/models/rconc_nash.py +48 -0
- hydpy/models/rconc_uh.py +53 -0
- hydpy/models/sw1d/__init__.py +17 -0
- hydpy/models/sw1d/sw1d_control.py +356 -0
- hydpy/models/sw1d/sw1d_derived.py +85 -0
- hydpy/models/sw1d/sw1d_factors.py +78 -0
- hydpy/models/sw1d/sw1d_fixed.py +12 -0
- hydpy/models/sw1d/sw1d_fluxes.py +55 -0
- hydpy/models/sw1d/sw1d_inlets.py +17 -0
- hydpy/models/sw1d/sw1d_model.py +3385 -0
- hydpy/models/sw1d/sw1d_outlets.py +11 -0
- hydpy/models/sw1d/sw1d_receivers.py +11 -0
- hydpy/models/sw1d/sw1d_senders.py +11 -0
- hydpy/models/sw1d/sw1d_states.py +23 -0
- hydpy/models/sw1d_channel.py +2051 -0
- hydpy/models/sw1d_gate_out.py +599 -0
- hydpy/models/sw1d_lias.py +105 -0
- hydpy/models/sw1d_lias_sluice.py +531 -0
- hydpy/models/sw1d_network.py +1219 -0
- hydpy/models/sw1d_pump.py +448 -0
- hydpy/models/sw1d_q_in.py +79 -0
- hydpy/models/sw1d_q_out.py +81 -0
- hydpy/models/sw1d_storage.py +78 -0
- hydpy/models/sw1d_weir_out.py +75 -0
- hydpy/models/test/__init__.py +14 -0
- hydpy/models/test/test_control.py +28 -0
- hydpy/models/test/test_fluxes.py +17 -0
- hydpy/models/test/test_model.py +201 -0
- hydpy/models/test/test_solver.py +48 -0
- hydpy/models/test/test_states.py +17 -0
- hydpy/models/test_discontinous.py +46 -0
- hydpy/models/test_stiff0d.py +47 -0
- hydpy/models/test_stiff1d.py +42 -0
- hydpy/models/whmod/__init__.py +21 -0
- hydpy/models/whmod/whmod_constants.py +77 -0
- hydpy/models/whmod/whmod_control.py +333 -0
- hydpy/models/whmod/whmod_derived.py +210 -0
- hydpy/models/whmod/whmod_factors.py +9 -0
- hydpy/models/whmod/whmod_fluxes.py +105 -0
- hydpy/models/whmod/whmod_inputs.py +15 -0
- hydpy/models/whmod/whmod_masks.py +178 -0
- hydpy/models/whmod/whmod_model.py +2091 -0
- hydpy/models/whmod/whmod_parameters.py +155 -0
- hydpy/models/whmod/whmod_sequences.py +193 -0
- hydpy/models/whmod/whmod_states.py +73 -0
- hydpy/models/whmod_rural.py +794 -0
- hydpy/models/whmod_urban.py +1011 -0
- hydpy/models/wland/__init__.py +43 -0
- hydpy/models/wland/wland_aides.py +55 -0
- hydpy/models/wland/wland_constants.py +103 -0
- hydpy/models/wland/wland_control.py +508 -0
- hydpy/models/wland/wland_derived.py +330 -0
- hydpy/models/wland/wland_factors.py +11 -0
- hydpy/models/wland/wland_fixed.py +12 -0
- hydpy/models/wland/wland_fluxes.py +166 -0
- hydpy/models/wland/wland_inputs.py +33 -0
- hydpy/models/wland/wland_masks.py +54 -0
- hydpy/models/wland/wland_model.py +3755 -0
- hydpy/models/wland/wland_outlets.py +11 -0
- hydpy/models/wland/wland_parameters.py +214 -0
- hydpy/models/wland/wland_sequences.py +108 -0
- hydpy/models/wland/wland_solver.py +45 -0
- hydpy/models/wland/wland_states.py +56 -0
- hydpy/models/wland_gd.py +888 -0
- hydpy/models/wland_wag.py +1244 -0
- hydpy/models/wq/__init__.py +14 -0
- hydpy/models/wq/wq_control.py +117 -0
- hydpy/models/wq/wq_derived.py +182 -0
- hydpy/models/wq/wq_factors.py +79 -0
- hydpy/models/wq/wq_fluxes.py +17 -0
- hydpy/models/wq/wq_model.py +1889 -0
- hydpy/models/wq_trapeze.py +168 -0
- hydpy/models/wq_trapeze_strickler.py +101 -0
- hydpy/models/wq_walrus.py +57 -0
- hydpy/py.typed +0 -0
- hydpy/tests/.coveragerc +22 -0
- hydpy/tests/__init__.py +0 -0
- hydpy/tests/check_consistency.py +32 -0
- hydpy/tests/hydpydoctestcustomize.pth +1 -0
- hydpy/tests/hydpydoctestcustomize.py +15 -0
- hydpy/tests/iotesting/__init__.py +0 -0
- hydpy/tests/run_doctests.py +233 -0
- hydpy-6.2.dev1.data/scripts/hyd.py +277 -0
- hydpy-6.2.dev1.dist-info/LICENSE +165 -0
- hydpy-6.2.dev1.dist-info/METADATA +163 -0
- hydpy-6.2.dev1.dist-info/RECORD +890 -0
- hydpy-6.2.dev1.dist-info/WHEEL +5 -0
- hydpy-6.2.dev1.dist-info/licenses_hydpy_installer.txt +42 -0
- 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
|