flextool 4.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. flextool/__init__.py +41 -0
  2. flextool/_mem_sampler.py +193 -0
  3. flextool/_resources.py +43 -0
  4. flextool/calibrate/__init__.py +51 -0
  5. flextool/calibrate/__main__.py +11 -0
  6. flextool/calibrate/_cli.py +316 -0
  7. flextool/calibrate/_db_alt.py +166 -0
  8. flextool/calibrate/_final_outputs.py +110 -0
  9. flextool/calibrate/_guard.py +151 -0
  10. flextool/calibrate/_loop.py +558 -0
  11. flextool/calibrate/_readers.py +223 -0
  12. flextool/calibrate/_report.py +263 -0
  13. flextool/calibrate/_sizing.py +699 -0
  14. flextool/calibrate/_solve.py +134 -0
  15. flextool/calibrate/_solve_status.py +495 -0
  16. flextool/cli/__init__.py +9 -0
  17. flextool/cli/_console.py +51 -0
  18. flextool/cli/_timing.py +147 -0
  19. flextool/cli/cmd_execute_flextool_workflow.py +187 -0
  20. flextool/cli/cmd_export_to_tabular.py +56 -0
  21. flextool/cli/cmd_import_sensitivities.py +75 -0
  22. flextool/cli/cmd_migrate_database.py +13 -0
  23. flextool/cli/cmd_open_results_db.py +269 -0
  24. flextool/cli/cmd_read_matpower.py +66 -0
  25. flextool/cli/cmd_read_old_flextool.py +63 -0
  26. flextool/cli/cmd_read_self_describing_tabular_input.py +50 -0
  27. flextool/cli/cmd_read_tabular_input.py +81 -0
  28. flextool/cli/cmd_run_flextool.py +1095 -0
  29. flextool/cli/cmd_scenario_results.py +284 -0
  30. flextool/cli/cmd_solve_mps.py +169 -0
  31. flextool/cli/cmd_update_flextool.py +17 -0
  32. flextool/cli/cmd_write_outputs.py +125 -0
  33. flextool/common_utils/__init__.py +1 -0
  34. flextool/common_utils/plot_mem_shape.py +77 -0
  35. flextool/common_utils/precision.py +451 -0
  36. flextool/decomposition/__init__.py +0 -0
  37. flextool/decomposition/region_decomposition.py +128 -0
  38. flextool/decomposition/region_filter.py +1261 -0
  39. flextool/engine_polars/__init__.py +110 -0
  40. flextool/engine_polars/_axis_enums.py +742 -0
  41. flextool/engine_polars/_benders.py +3462 -0
  42. flextool/engine_polars/_block_layout.py +1479 -0
  43. flextool/engine_polars/_blocks.py +1515 -0
  44. flextool/engine_polars/_commodity_ladder.py +660 -0
  45. flextool/engine_polars/_cumulative_invest.py +1165 -0
  46. flextool/engine_polars/_db_loader.py +153 -0
  47. flextool/engine_polars/_db_reader.py +127 -0
  48. flextool/engine_polars/_dc_power_flow.py +445 -0
  49. flextool/engine_polars/_delay.py +442 -0
  50. flextool/engine_polars/_derived_arithmetic.py +432 -0
  51. flextool/engine_polars/_derived_block.py +990 -0
  52. flextool/engine_polars/_derived_branch.py +769 -0
  53. flextool/engine_polars/_derived_existing.py +1353 -0
  54. flextool/engine_polars/_derived_npv.py +1297 -0
  55. flextool/engine_polars/_derived_params.py +9850 -0
  56. flextool/engine_polars/_derived_profile.py +881 -0
  57. flextool/engine_polars/_derived_walks.py +276 -0
  58. flextool/engine_polars/_determinism.py +70 -0
  59. flextool/engine_polars/_direct_params.py +2186 -0
  60. flextool/engine_polars/_dump_csvs.py +1009 -0
  61. flextool/engine_polars/_emit_arc_unions.py +1631 -0
  62. flextool/engine_polars/_emit_calc_params.py +729 -0
  63. flextool/engine_polars/_emit_chain_params.py +709 -0
  64. flextool/engine_polars/_emit_co2_accumulators.py +400 -0
  65. flextool/engine_polars/_emit_dispatchers.py +690 -0
  66. flextool/engine_polars/_emit_energy_margin.py +125 -0
  67. flextool/engine_polars/_emit_energy_margin_adder.py +290 -0
  68. flextool/engine_polars/_emit_entity_annual.py +428 -0
  69. flextool/engine_polars/_emit_inflow_scaling.py +1420 -0
  70. flextool/engine_polars/_emit_leaf_sets.py +550 -0
  71. flextool/engine_polars/_emit_lp_scaling.py +665 -0
  72. flextool/engine_polars/_emit_mid_sets.py +859 -0
  73. flextool/engine_polars/_emit_pdt_params.py +759 -0
  74. flextool/engine_polars/_emit_per_solve.py +774 -0
  75. flextool/engine_polars/_emit_period_calc.py +504 -0
  76. flextool/engine_polars/_emit_period_params.py +2398 -0
  77. flextool/engine_polars/_emit_provider_io.py +141 -0
  78. flextool/engine_polars/_emit_reserve.py +574 -0
  79. flextool/engine_polars/_emit_solve_time.py +311 -0
  80. flextool/engine_polars/_emit_solve_writers.py +1249 -0
  81. flextool/engine_polars/_flex_data_accumulator.py +388 -0
  82. flextool/engine_polars/_flex_data_provider.py +478 -0
  83. flextool/engine_polars/_group_slack.py +1253 -0
  84. flextool/engine_polars/_inmemory_reader.py +140 -0
  85. flextool/engine_polars/_input_source.py +336 -0
  86. flextool/engine_polars/_invest_seeds.py +191 -0
  87. flextool/engine_polars/_native_input_writer.py +100 -0
  88. flextool/engine_polars/_native_run_model.py +1348 -0
  89. flextool/engine_polars/_orchestration.py +4314 -0
  90. flextool/engine_polars/_output_writer.py +439 -0
  91. flextool/engine_polars/_param_shapes.py +1595 -0
  92. flextool/engine_polars/_parquet_bundle.py +723 -0
  93. flextool/engine_polars/_pdt_join.py +167 -0
  94. flextool/engine_polars/_pdt_lookup.py +547 -0
  95. flextool/engine_polars/_per_solve_sets.py +335 -0
  96. flextool/engine_polars/_projection_params.py +2056 -0
  97. flextool/engine_polars/_provider_keys.py +173 -0
  98. flextool/engine_polars/_provider_translators.py +225 -0
  99. flextool/engine_polars/_recursive_solve.py +703 -0
  100. flextool/engine_polars/_region_filter.py +2508 -0
  101. flextool/engine_polars/_reserve.py +649 -0
  102. flextool/engine_polars/_solve_acceptance.py +331 -0
  103. flextool/engine_polars/_solve_config.py +1001 -0
  104. flextool/engine_polars/_solve_context.py +885 -0
  105. flextool/engine_polars/_solve_handoff.py +164 -0
  106. flextool/engine_polars/_solve_state.py +232 -0
  107. flextool/engine_polars/_solver_base.py +36 -0
  108. flextool/engine_polars/_solver_dispatch.py +511 -0
  109. flextool/engine_polars/_spinedb_reader.py +1165 -0
  110. flextool/engine_polars/_stochastic.py +593 -0
  111. flextool/engine_polars/_subprocess_solve.py +1838 -0
  112. flextool/engine_polars/_timeline.py +1416 -0
  113. flextool/engine_polars/_vectorize.py +438 -0
  114. flextool/engine_polars/_warm.py +858 -0
  115. flextool/engine_polars/autoscale/__init__.py +107 -0
  116. flextool/engine_polars/autoscale/_config.py +218 -0
  117. flextool/engine_polars/autoscale/_layer2.py +1253 -0
  118. flextool/engine_polars/autoscale/_layer2_types.py +584 -0
  119. flextool/engine_polars/autoscale/_quantity_types.py +621 -0
  120. flextool/engine_polars/autoscale/_report.py +336 -0
  121. flextool/engine_polars/chain.py +259 -0
  122. flextool/engine_polars/input.py +6638 -0
  123. flextool/engine_polars/model.py +4754 -0
  124. flextool/env_check.py +388 -0
  125. flextool/export_to_tabular/__init__.py +5 -0
  126. flextool/export_to_tabular/db_reader.py +224 -0
  127. flextool/export_to_tabular/excel_writer.py +3559 -0
  128. flextool/export_to_tabular/export_settings.yaml +377 -0
  129. flextool/export_to_tabular/export_to_excel.py +227 -0
  130. flextool/export_to_tabular/formatting.py +543 -0
  131. flextool/export_to_tabular/sheet_config.py +876 -0
  132. flextool/gui/__init__.py +0 -0
  133. flextool/gui/__main__.py +118 -0
  134. flextool/gui/calibrate_commands.py +184 -0
  135. flextool/gui/calibrate_jobs.py +424 -0
  136. flextool/gui/check_tree.py +142 -0
  137. flextool/gui/cli_format.py +83 -0
  138. flextool/gui/config_parser.py +68 -0
  139. flextool/gui/data_models.py +362 -0
  140. flextool/gui/db_editor_integration.py +202 -0
  141. flextool/gui/db_version_check.py +269 -0
  142. flextool/gui/dialogs/__init__.py +0 -0
  143. flextool/gui/dialogs/add_dialog.py +1098 -0
  144. flextool/gui/dialogs/calibrate_dialog.py +1259 -0
  145. flextool/gui/dialogs/file_picker.py +473 -0
  146. flextool/gui/dialogs/group_picker.py +299 -0
  147. flextool/gui/dialogs/migration_consent_dialog.py +106 -0
  148. flextool/gui/dialogs/migration_progress_dialog.py +237 -0
  149. flextool/gui/dialogs/plot_dialog.py +459 -0
  150. flextool/gui/dialogs/plot_settings_picker.py +2184 -0
  151. flextool/gui/dialogs/project_dialog.py +426 -0
  152. flextool/gui/dialogs/update_dialog.py +212 -0
  153. flextool/gui/downsampling.py +88 -0
  154. flextool/gui/error_handling.py +50 -0
  155. flextool/gui/execution_manager.py +1715 -0
  156. flextool/gui/execution_window.py +1377 -0
  157. flextool/gui/hover_tooltip.py +111 -0
  158. flextool/gui/input_sources.py +730 -0
  159. flextool/gui/main_window.py +6181 -0
  160. flextool/gui/network_graph.py +215 -0
  161. flextool/gui/output_actions.py +393 -0
  162. flextool/gui/output_log_window.py +159 -0
  163. flextool/gui/platform_utils.py +421 -0
  164. flextool/gui/plot_cache.py +88 -0
  165. flextool/gui/plot_canvas.py +543 -0
  166. flextool/gui/plot_config_reader.py +272 -0
  167. flextool/gui/project_utils.py +100 -0
  168. flextool/gui/result_viewer.py +4394 -0
  169. flextool/gui/scenario_key.py +162 -0
  170. flextool/gui/scenario_lists.py +516 -0
  171. flextool/gui/settings_io.py +360 -0
  172. flextool/gui/solve_reader.py +103 -0
  173. flextool/gui/tree_reorder.py +88 -0
  174. flextool/gui/ui_metrics.py +420 -0
  175. flextool/input_derivation/__init__.py +281 -0
  176. flextool/input_derivation/_commodity_ladder.py +375 -0
  177. flextool/input_derivation/_commodity_ladder_sets.py +70 -0
  178. flextool/input_derivation/_dc_power_flow.py +377 -0
  179. flextool/input_derivation/_method_constants.py +77 -0
  180. flextool/input_derivation/_process_method.py +258 -0
  181. flextool/input_derivation/_specs.py +1026 -0
  182. flextool/input_derivation/_validators.py +321 -0
  183. flextool/lean_parquet.py +159 -0
  184. flextool/model_builder/__init__.py +5 -0
  185. flextool/model_builder/build_model.py +589 -0
  186. flextool/model_builder/encoding.py +67 -0
  187. flextool/model_builder/names.py +34 -0
  188. flextool/model_builder/profiles.py +129 -0
  189. flextool/plot_outputs/__init__.py +14 -0
  190. flextool/plot_outputs/axis_helpers.py +355 -0
  191. flextool/plot_outputs/color_template.py +888 -0
  192. flextool/plot_outputs/config.py +171 -0
  193. flextool/plot_outputs/format_helpers.py +345 -0
  194. flextool/plot_outputs/legend_helpers.py +143 -0
  195. flextool/plot_outputs/orchestrator.py +1141 -0
  196. flextool/plot_outputs/perf.py +37 -0
  197. flextool/plot_outputs/plan.py +1787 -0
  198. flextool/plot_outputs/plot_bars.py +1510 -0
  199. flextool/plot_outputs/plot_bars_detail.py +753 -0
  200. flextool/plot_outputs/plot_lines.py +951 -0
  201. flextool/plot_outputs/shared_manifest.py +564 -0
  202. flextool/plot_outputs/subplot_helpers.py +137 -0
  203. flextool/process_inputs/__init__.py +188 -0
  204. flextool/process_inputs/import_old_excel_input.json +4159 -0
  205. flextool/process_inputs/read_matpower.py +451 -0
  206. flextool/process_inputs/read_old_flextool.py +1288 -0
  207. flextool/process_inputs/read_self_describing_excel.py +1423 -0
  208. flextool/process_inputs/read_tabular_with_specification.py +1114 -0
  209. flextool/process_inputs/write_old_flextool_to_db.py +3077 -0
  210. flextool/process_inputs/write_self_describing_to_db.py +977 -0
  211. flextool/process_inputs/write_to_input_db.py +269 -0
  212. flextool/process_outputs/__init__.py +7 -0
  213. flextool/process_outputs/_annualize.py +55 -0
  214. flextool/process_outputs/_inmemory_helpers.py +292 -0
  215. flextool/process_outputs/_output_meta.py +672 -0
  216. flextool/process_outputs/calc_capacity_flows.py +107 -0
  217. flextool/process_outputs/calc_connections.py +136 -0
  218. flextool/process_outputs/calc_costs.py +260 -0
  219. flextool/process_outputs/calc_group_flows.py +192 -0
  220. flextool/process_outputs/calc_slacks.py +103 -0
  221. flextool/process_outputs/calc_storage_vre.py +160 -0
  222. flextool/process_outputs/drop_levels.py +208 -0
  223. flextool/process_outputs/handoff_writers.py +1315 -0
  224. flextool/process_outputs/out_ancillary.py +544 -0
  225. flextool/process_outputs/out_capacity.py +179 -0
  226. flextool/process_outputs/out_costs.py +334 -0
  227. flextool/process_outputs/out_flowgroup.py +189 -0
  228. flextool/process_outputs/out_flows.py +301 -0
  229. flextool/process_outputs/out_group.py +475 -0
  230. flextool/process_outputs/out_node.py +190 -0
  231. flextool/process_outputs/persist_realized_slice.py +601 -0
  232. flextool/process_outputs/process_results.py +24 -0
  233. flextool/process_outputs/read_highs_solution.py +2256 -0
  234. flextool/process_outputs/read_parameters.py +1799 -0
  235. flextool/process_outputs/read_sets.py +1095 -0
  236. flextool/process_outputs/read_variables.py +553 -0
  237. flextool/process_outputs/solve_order.py +81 -0
  238. flextool/process_outputs/spinedb_replay.py +412 -0
  239. flextool/process_outputs/union_realized_slice.py +224 -0
  240. flextool/process_outputs/write_outputs.py +1286 -0
  241. flextool/process_outputs/write_spinedb.py +1267 -0
  242. flextool/representative_periods/__init__.py +5 -0
  243. flextool/representative_periods/clustering.py +165 -0
  244. flextool/representative_periods/force_include.py +563 -0
  245. flextool/representative_periods/netload.py +365 -0
  246. flextool/representative_periods/netload_inputs.py +345 -0
  247. flextool/representative_periods/netload_iterate.py +722 -0
  248. flextool/representative_periods/preprocess.py +948 -0
  249. flextool/representative_periods/scenario_stack.py +195 -0
  250. flextool/representative_periods/weights.py +124 -0
  251. flextool/scenario_comparison/__init__.py +13 -0
  252. flextool/scenario_comparison/config_builder.py +158 -0
  253. flextool/scenario_comparison/constants.py +20 -0
  254. flextool/scenario_comparison/data_models.py +222 -0
  255. flextool/scenario_comparison/db_reader.py +399 -0
  256. flextool/scenario_comparison/dispatch_data.py +1002 -0
  257. flextool/scenario_comparison/dispatch_mappings.py +205 -0
  258. flextool/scenario_comparison/dispatch_plots.py +691 -0
  259. flextool/scenario_comparison/input_entity_colors.py +319 -0
  260. flextool/scenario_comparison/orchestrator.py +453 -0
  261. flextool/scenario_comparison/plan_union.py +244 -0
  262. flextool/scenario_comparison/plot_settings_seed.py +205 -0
  263. flextool/schemas/AXIS_CONTRACT.md +71 -0
  264. flextool/schemas/canonical_databases/howto_aggregate_output.json +6225 -0
  265. flextool/schemas/canonical_databases/howto_connections.json +5606 -0
  266. flextool/schemas/canonical_databases/howto_demand.json +5518 -0
  267. flextool/schemas/canonical_databases/howto_hydro_reservoir.json +6239 -0
  268. flextool/schemas/canonical_databases/howto_hydro_reservoir_with_pump.json +5933 -0
  269. flextool/schemas/canonical_databases/howto_non_sync_and_curtailment.json +5794 -0
  270. flextool/schemas/canonical_databases/howto_ramp_and_start_up.json +5707 -0
  271. flextool/schemas/canonical_databases/howto_stochastics.json +6032 -0
  272. flextool/schemas/canonical_databases/templates_examples.json +13532 -0
  273. flextool/schemas/canonical_databases/templates_time_settings_only.json +5340 -0
  274. flextool/schemas/comparison_settings_template.json +197 -0
  275. flextool/schemas/default_plot_settings.yaml +260 -0
  276. flextool/schemas/default_plots.yaml +2293 -0
  277. flextool/schemas/flextool_axis_contract.json +303 -0
  278. flextool/schemas/flextool_axis_contract.schema.json +247 -0
  279. flextool/schemas/old_flextool_import_template.json +4443 -0
  280. flextool/schemas/output_info_template.json +48 -0
  281. flextool/schemas/output_settings_template.json +256 -0
  282. flextool/schemas/pre_v26/flextool_template_constant_default.json +2105 -0
  283. flextool/schemas/pre_v26/flextool_template_default_optional_output.json +2152 -0
  284. flextool/schemas/pre_v26/flextool_template_default_value.json +2094 -0
  285. flextool/schemas/pre_v26/flextool_template_drop_down.json +2080 -0
  286. flextool/schemas/pre_v26/flextool_template_lifetime_method.json +1990 -0
  287. flextool/schemas/pre_v26/flextool_template_optional_outputs.json +2094 -0
  288. flextool/schemas/pre_v26/flextool_template_output_node_flows.json +2105 -0
  289. flextool/schemas/pre_v26/flextool_template_results_master.json +493 -0
  290. flextool/schemas/pre_v26/flextool_template_rolling_start_remove.json +2087 -0
  291. flextool/schemas/pre_v26/flextool_template_rolling_window.json +2059 -0
  292. flextool/schemas/pre_v26/flextool_template_storage_binding_defaults.json +46 -0
  293. flextool/schemas/pre_v26/flextool_template_v2.json +1990 -0
  294. flextool/schemas/pre_v26/flextool_template_v25.json +3864 -0
  295. flextool/schemas/spinedb_results_schema.json +581 -0
  296. flextool/schemas/spinedb_schema.json +4636 -0
  297. flextool/solver_config/copt.opt.template +18 -0
  298. flextool/solver_config/cplex.opt.template +25 -0
  299. flextool/solver_config/gurobi.opt.template +18 -0
  300. flextool/solver_config/highs.opt.template +18 -0
  301. flextool/solver_config/xpress.opt.template +26 -0
  302. flextool/spinedb_backend/__init__.py +26 -0
  303. flextool/spinedb_backend/_axis_enums.py +1119 -0
  304. flextool/spinedb_backend/_backend.py +1139 -0
  305. flextool/update_flextool/__init__.py +12 -0
  306. flextool/update_flextool/canonical_databases.py +251 -0
  307. flextool/update_flextool/db_migration.py +7108 -0
  308. flextool/update_flextool/ensure_settings_db.py +138 -0
  309. flextool/update_flextool/export_database.py +103 -0
  310. flextool/update_flextool/extend_tests_fixture.py +772 -0
  311. flextool/update_flextool/generate_canonical.py +274 -0
  312. flextool/update_flextool/initialize_database.py +42 -0
  313. flextool/update_flextool/install_info.py +225 -0
  314. flextool/update_flextool/self_update.py +464 -0
  315. flextool/update_flextool/sync_master_json_template.py +125 -0
  316. flextool/update_flextool/test_fixtures.py +187 -0
  317. flextool-4.0.0.dist-info/METADATA +217 -0
  318. flextool-4.0.0.dist-info/RECORD +322 -0
  319. flextool-4.0.0.dist-info/WHEEL +5 -0
  320. flextool-4.0.0.dist-info/entry_points.txt +17 -0
  321. flextool-4.0.0.dist-info/licenses/LICENSE.txt +19 -0
  322. flextool-4.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1026 @@
1
+ """Specification tables + validators for the SpineDB → Provider pipeline.
2
+
3
+ This module holds the canonical EAV → tabular materialiser
4
+ specifications (``_ENTITY_SPECS``, ``_PARAMETER_SPECS``,
5
+ ``_DEFAULT_VALUES_SPECS``), the ``METHODS_MAPPING`` lookup, plus a
6
+ handful of validators that gate :func:`flextool.input_derivation.run`.
7
+
8
+ Related modules:
9
+
10
+ * :mod:`flextool.input_derivation` — the run-time entry point;
11
+ * this module — declarative specs + validators;
12
+ * :mod:`flextool.spinedb_backend` — the EAV → polars materialisers
13
+ (``SpineDBBackend.entities`` / ``parameter_values`` /
14
+ ``parameter_defaults``);
15
+ * :mod:`flextool.engine_polars._emit_*` — the native polars writers
16
+ that consume the materialised frames and emit derived ``solve_data/``
17
+ frames.
18
+ """
19
+ from __future__ import annotations
20
+
21
+ from typing import NamedTuple
22
+
23
+
24
+ # ---------------------------------------------------------------------------
25
+ # Spec definitions: each entry maps 1-to-1 to a former call in write_input().
26
+ # ---------------------------------------------------------------------------
27
+
28
+ class EntitySpec(NamedTuple):
29
+ """Spec for a write_entity() call."""
30
+ classes: list[str]
31
+ header: str
32
+ filename: str
33
+ entity_dimens: list[list[int]] | None = None
34
+
35
+
36
+ _ENTITY_SPECS: list[EntitySpec] = [
37
+ EntitySpec(["commodity"], "commodity", "input/commodity.csv"),
38
+ EntitySpec(["commodity__node"], "commodity,node", "input/commodity__node.csv"),
39
+ EntitySpec(["node", "unit", "connection"], "entity", "input/entity.csv"),
40
+ EntitySpec(["group"], "group", "input/group.csv"),
41
+ EntitySpec(["group__node"], "group,node", "input/group__node.csv"),
42
+ EntitySpec(["group__unit", "group__connection"], "group,process", "input/group__process.csv"),
43
+ EntitySpec(["flowGroup__unit__node", "flowGroup__connection__node"], "flowGroup,process,node",
44
+ "input/flowGroup__process__node.csv"),
45
+ EntitySpec(["node"], "node", "input/node.csv"),
46
+ EntitySpec(["unit", "connection"], "process", "input/process.csv"),
47
+ EntitySpec(["connection"], "process_connection", "input/process_connection.csv"),
48
+ EntitySpec(["unit"], "process_unit", "input/process_unit.csv"),
49
+ EntitySpec(["reserve__upDown__unit__node", "reserve__upDown__connection__node"],
50
+ "process,reserve,upDown,node", "input/process__reserve__upDown__node.csv",
51
+ entity_dimens=[[2, 0, 1, 3], [2, 0, 1, 3]]),
52
+ EntitySpec(["profile"], "profile", "input/profile.csv"),
53
+ EntitySpec(["unit__inputNode", "connection__node__node"], "process,source",
54
+ "input/process__source.csv", entity_dimens=[[0, 1], [0, 1]]),
55
+ EntitySpec(["unit__outputNode", "connection__node__node"], "process,sink",
56
+ "input/process__sink.csv", entity_dimens=[[0, 1], [0, 2]]),
57
+ ]
58
+
59
+
60
+ _PARAMETER_SPECS: list[dict] = [
61
+ # --- commodity ---
62
+ {
63
+ "cl_pars": [("commodity", "price")],
64
+ "header": "commodity,commodityParam,time,pt_commodity",
65
+ "filename": "input/pdt_commodity.csv",
66
+ "filter_in_type": ["1d_map"],
67
+ "param_print": True,
68
+ },
69
+ {
70
+ "cl_pars": [("commodity", "price"), ("commodity", "co2_content")],
71
+ "header": "commodity,commodityParam,p_commodity",
72
+ "filename": "input/p_commodity.csv",
73
+ "filter_in_type": ["float", "str"],
74
+ "param_print": True,
75
+ },
76
+ {
77
+ "cl_pars": [("commodity", "price_method")],
78
+ "header": "commodity,p_commodity_price_method",
79
+ "filename": "input/p_commodity_price_method.csv",
80
+ },
81
+ {
82
+ "cl_pars": [("commodity", "unitsize")],
83
+ "header": "commodity,p_commodity_unitsize",
84
+ "filename": "input/p_commodity_unitsize.csv",
85
+ },
86
+ # --- constraint ---
87
+ {
88
+ "cl_pars": [("constraint", "sense")],
89
+ "header": "constraint,sense",
90
+ "filename": "input/constraint__sense.csv",
91
+ },
92
+ {
93
+ "cl_pars": [("constraint", "constant")],
94
+ "header": "constraint,p_constraint_constant",
95
+ "filename": "input/p_constraint_constant.csv",
96
+ },
97
+ # --- entity invest/lifetime methods ---
98
+ {
99
+ "cl_pars": [("node", "invest_method"), ("unit", "invest_method"), ("connection", "invest_method")],
100
+ "header": "entity,invest_method",
101
+ "filename": "input/entity__invest_method.csv",
102
+ },
103
+ {
104
+ "cl_pars": [("node", "lifetime_method"), ("unit", "lifetime_method"),
105
+ ("connection", "lifetime_method")],
106
+ "header": "entity,lifetime_method",
107
+ "filename": "input/entity__lifetime_method.csv",
108
+ },
109
+ # --- group parameters ---
110
+ {
111
+ "cl_pars": [("group", "co2_method")],
112
+ "header": "group,co2_method",
113
+ "filename": "input/group__co2_method.csv",
114
+ },
115
+ {
116
+ "cl_pars": [("group", "invest_method")],
117
+ "header": "group,invest_method",
118
+ "filename": "input/group__invest_method.csv",
119
+ },
120
+ {
121
+ "cl_pars": [("group", "loss_share_type")],
122
+ "header": "group,loss_share_type",
123
+ "filename": "input/group__loss_share_type.csv",
124
+ },
125
+ {
126
+ "cl_pars": [("group", "capacity_margin_method")],
127
+ "header": "groupCapacityMargin",
128
+ "filename": "input/groupCapacityMargin.csv",
129
+ "filter_in_value": "manual",
130
+ "no_value": True,
131
+ },
132
+ {
133
+ "cl_pars": [("group", "include_stochastics")],
134
+ "header": "group",
135
+ "filename": "input/groupIncludeStochastics.csv",
136
+ "filter_in_value": "yes",
137
+ "no_value": True,
138
+ },
139
+ {
140
+ "cl_pars": [("group", "has_inertia")],
141
+ "header": "groupInertia",
142
+ "filename": "input/groupInertia.csv",
143
+ "filter_in_value": "yes",
144
+ "no_value": True,
145
+ },
146
+ {
147
+ "cl_pars": [("group", "print_dispatch")],
148
+ "header": "nodeGroupDispatch",
149
+ "filename": "input/nodeGroupDispatch.csv",
150
+ "filter_in_value": "yes",
151
+ "no_value": True,
152
+ },
153
+ {
154
+ "cl_pars": [("flowGroup", "flow_aggregator")],
155
+ "header": "flowAggregator",
156
+ "filename": "input/flowAggregator.csv",
157
+ "filter_in_value": {"dispatch_plots_only", "both"},
158
+ "no_value": True,
159
+ },
160
+ # --- model parameters ---
161
+ {
162
+ "cl_pars": [("model", "solves")],
163
+ "header": "model,solve",
164
+ "filename": "input/model__solve.csv",
165
+ },
166
+ {
167
+ "cl_pars": [("model", "periods_available")],
168
+ "header": "model,period_from_model",
169
+ "filename": "input/periods_available.csv",
170
+ },
171
+ # --- node parameters ---
172
+ {
173
+ "cl_pars": [("node", "constraint_invested_capacity_coeff")],
174
+ "header": "node,constraint,p_node_constraint_invested_capacity_coeff",
175
+ "filename": "input/p_node_constraint_invested_capacity_coeff.csv",
176
+ },
177
+ {
178
+ "cl_pars": [("node", "constraint_cumulative_pre_built_capacity_coeff")],
179
+ "header": "node,constraint,p_node_constraint_prebuilt_capacity_coeff",
180
+ "filename": "input/p_node_constraint_cumulative_pre_built_capacity_coeff.csv",
181
+ },
182
+ {
183
+ "cl_pars": [("node", "constraint_state_coeff")],
184
+ "header": "node,constraint,p_node_constraint_state_coeff",
185
+ "filename": "input/p_node_constraint_state_coeff.csv",
186
+ },
187
+ {
188
+ "cl_pars": [("node", "node_type")],
189
+ "header": "node,p_node_type",
190
+ "filename": "input/p_node_type.csv",
191
+ },
192
+ {
193
+ "cl_pars": [("node", "inflow_method")],
194
+ "header": "node,inflow_method",
195
+ "filename": "input/node__inflow_method.csv",
196
+ },
197
+ {
198
+ "cl_pars": [("node", "energy_margin_method")],
199
+ "header": "node,energy_margin_method",
200
+ "filename": "input/node__energy_margin_method.csv",
201
+ },
202
+ {
203
+ # Scalar-float only: a period-map energy_margin_multiplier is a
204
+ # documented FUTURE extension (route through _param_shapes) and must
205
+ # NOT be silently mis-ingested by this scalar spec.
206
+ "cl_pars": [("node", "energy_margin_multiplier")],
207
+ "header": "node,energy_margin_multiplier",
208
+ "filename": "input/energy_margin_multiplier.csv",
209
+ "filter_in_type": ["float"],
210
+ },
211
+ {
212
+ # Additive energy margin [MWh] — SCALAR (constant) only. The
213
+ # ``["float"]`` filter is load-bearing: without it a period /
214
+ # period-time Map written to this param would be silently mangled
215
+ # here (``_rows_to_frame`` truncates the flattened map row to this
216
+ # 2-col header, dropping the time axis and value). Map-shaped
217
+ # adders ingest through the ``pd_``/``pdt_`` specs below; the
218
+ # emitter (_emit_energy_margin_adder) reads all three files and
219
+ # broadcasts each authored shape over the invest (d, t) grid via
220
+ # _param_shapes' promote_param_to_dt. A node has a scalar OR a
221
+ # map adder, never both.
222
+ "cl_pars": [("node", "energy_margin_adder")],
223
+ "header": "node,energy_margin_adder",
224
+ "filename": "input/energy_margin_adder.csv",
225
+ "filter_in_type": ["float"],
226
+ },
227
+ {
228
+ # Additive energy margin [MWh] — period Map (1d). Places a
229
+ # per-period constant demand adder; the emitter broadcasts each
230
+ # period's value over that period's (d, t) cells.
231
+ "cl_pars": [("node", "energy_margin_adder")],
232
+ "header": "node,period,energy_margin_adder",
233
+ "filename": "input/pd_energy_margin_adder.csv",
234
+ "filter_in_type": ["1d_map"],
235
+ },
236
+ {
237
+ # Additive energy margin [MWh] — period-time Map (2d). Places a
238
+ # per-(period, time) demand adder — the timed-sizing shape the
239
+ # calibrator relies on. ``convert_map_to_table`` emits the outer
240
+ # (period) index, then the inner (time) index, then the value, so
241
+ # the flattened row is [node, period, time, value] — matching this
242
+ # 4-col header exactly.
243
+ "cl_pars": [("node", "energy_margin_adder")],
244
+ "header": "node,period,time,energy_margin_adder",
245
+ "filename": "input/pdt_energy_margin_adder.csv",
246
+ "filter_in_type": ["2d_map"],
247
+ },
248
+ {
249
+ "cl_pars": [("node__profile", "profile_method")],
250
+ "header": "node,profile,profile_method",
251
+ "filename": "input/node__profile__profile_method.csv",
252
+ },
253
+ {
254
+ "cl_pars": [("node", "storage_binding_method")],
255
+ "header": "node,storage_binding_method",
256
+ "filename": "input/node__storage_binding_method.csv",
257
+ },
258
+ {
259
+ "cl_pars": [("node", "storage_nested_fix_method")],
260
+ "header": "node,storage_nested_fix_method",
261
+ "filename": "input/node__storage_nested_fix_method.csv",
262
+ },
263
+ {
264
+ "cl_pars": [("node", "storage_solve_horizon_method")],
265
+ "header": "node,storage_solve_horizon_method",
266
+ "filename": "input/node__storage_solve_horizon_method.csv",
267
+ },
268
+ {
269
+ "cl_pars": [("node", "storage_start_end_method")],
270
+ "header": "node,storage_start_end_method",
271
+ "filename": "input/node__storage_start_end_method.csv",
272
+ },
273
+ {
274
+ "cl_pars": [("node", "penalty_method")],
275
+ "header": "node,penalty_method",
276
+ "filename": "input/node__penalty_method.csv",
277
+ },
278
+ {
279
+ "cl_pars": [("node", "penalty_down"), ("node", "self_discharge_loss"), ("node", "availability"),
280
+ ("node", "storage_state_reference_value")],
281
+ "header": "node,nodeParam,time,pt_node",
282
+ "filename": "input/pt_node.csv",
283
+ "filter_in_type": ["1d_map", "array", "time_series"],
284
+ "filter_out_index": "period",
285
+ "param_print": True,
286
+ },
287
+ {
288
+ "cl_pars": [("node", "penalty_down"), ("node", "self_discharge_loss"), ("node", "availability"),
289
+ ("node", "storage_state_reference_value")],
290
+ "header": "node,nodeParam,branch,time_start,time,pt_node",
291
+ "filename": "input/pbt_node.csv",
292
+ "filter_in_type": ["3d_map"],
293
+ "param_print": True,
294
+ },
295
+ {
296
+ "cl_pars": [("node", "inflow")],
297
+ "header": "node,time,pt_node_inflow",
298
+ "filename": "input/pt_node_inflow.csv",
299
+ "filter_in_type": ["1d_map", "array", "time_series"],
300
+ "filter_out_index": "period",
301
+ },
302
+ {
303
+ "cl_pars": [("node", "inflow")],
304
+ "header": "node,branch,time_start,time,pbt_node_inflow",
305
+ "filename": "input/pbt_node_inflow.csv",
306
+ "filter_in_type": ["3d_map"],
307
+ },
308
+ {
309
+ "cl_pars": [("node", "annual_flow"),
310
+ ("node", "peak_inflow"),
311
+ ("node", "invest_forced"),
312
+ ("node", "invest_max_period"),
313
+ ("node", "invest_min_period"),
314
+ ("node", "retire_forced"),
315
+ ("node", "retire_max_period"),
316
+ ("node", "retire_min_period"),
317
+ ("node", "invest_cost"),
318
+ ("node", "salvage_value"),
319
+ ("node", "discount_rate"),
320
+ ("node", "lifetime"),
321
+ ("node", "fixed_cost"),
322
+ ("node", "storage_state_reference_price"),
323
+ ("node", "availability"),
324
+ ("node", "penalty_up"),
325
+ ("node", "penalty_down"),
326
+ ("node", "cumulative_max_capacity"),
327
+ ("node", "cumulative_min_capacity"),
328
+ ("node", "self_discharge_loss"),
329
+ ("node", "existing"),
330
+ ("node", "storage_state_reference_value")],
331
+ "header": "node,nodeParam,period,pd_node",
332
+ "filename": "input/pd_node.csv",
333
+ "filter_in_type": ["1d_map"],
334
+ "filter_out_index": "time",
335
+ "param_print": True,
336
+ },
337
+ # --- process parameters ---
338
+ {
339
+ "cl_pars": [("unit__outputNode", "conversion_flow_coeff")],
340
+ "header": "process,sink,p_process_sink_conversion_flow_coeff",
341
+ "filename": "input/p_process_sink_conversion_flow_coeff.csv",
342
+ "filter_in_type": ["float", "str", "bool"],
343
+ },
344
+ {
345
+ "cl_pars": [("unit__inputNode", "conversion_flow_coeff")],
346
+ "header": "process,source,p_process_source_conversion_flow_coeff",
347
+ "filename": "input/p_process_source_conversion_flow_coeff.csv",
348
+ "filter_in_type": ["float", "str", "bool"],
349
+ },
350
+ {
351
+ "cl_pars": [("unit__outputNode", "capacity_max_coeff")],
352
+ "header": "process,sink,p_process_sink_capacity_max_coeff",
353
+ "filename": "input/p_process_sink_capacity_max_coeff.csv",
354
+ "filter_in_type": ["float", "str", "bool"],
355
+ },
356
+ {
357
+ "cl_pars": [("unit__outputNode", "capacity_min_coeff")],
358
+ "header": "process,sink,p_process_sink_capacity_min_coeff",
359
+ "filename": "input/p_process_sink_capacity_min_coeff.csv",
360
+ "filter_in_type": ["float", "str", "bool"],
361
+ },
362
+ {
363
+ "cl_pars": [("unit__inputNode", "capacity_max_coeff")],
364
+ "header": "process,source,p_process_source_capacity_max_coeff",
365
+ "filename": "input/p_process_source_capacity_max_coeff.csv",
366
+ "filter_in_type": ["float", "str", "bool"],
367
+ },
368
+ {
369
+ "cl_pars": [("unit__inputNode", "capacity_min_coeff")],
370
+ "header": "process,source,p_process_source_capacity_min_coeff",
371
+ "filename": "input/p_process_source_capacity_min_coeff.csv",
372
+ "filter_in_type": ["float", "str", "bool"],
373
+ },
374
+ {
375
+ "cl_pars": [("connection", "is_DC")],
376
+ "header": "process",
377
+ "filename": "input/process_nonSync_connection.csv",
378
+ "filter_in_value": "yes",
379
+ "no_value": True,
380
+ },
381
+ {
382
+ "cl_pars": [("unit__outputNode", "other_operational_cost")],
383
+ "header": "process,sink,sourceSinkTimeParam,time,pt_process_sink",
384
+ "filename": "input/pt_process_sink.csv",
385
+ "filter_in_type": ["1d_map"],
386
+ "filter_out_index": "period",
387
+ "param_print": True,
388
+ },
389
+ {
390
+ "cl_pars": [("unit__outputNode", "other_operational_cost")],
391
+ "header": "process,sink,sourceSinkPeriodParam,period,pd_process_sink",
392
+ "filename": "input/pd_process_sink.csv",
393
+ "filter_in_type": ["1d_map"],
394
+ "filter_out_index": "time",
395
+ "param_print": True,
396
+ },
397
+ {
398
+ "cl_pars": [("unit__outputNode", "other_operational_cost")],
399
+ "header": "process,sink,sourceSinkTimeParam,branch,time_start,time,pbt_process_sink",
400
+ "filename": "input/pbt_process_sink.csv",
401
+ "filter_in_type": ["3d_map"],
402
+ "param_print": True,
403
+ },
404
+ {
405
+ "cl_pars": [("unit__inputNode", "other_operational_cost")],
406
+ "header": "process,source,sourceSinkTimeParam,time,pt_process_source",
407
+ "filename": "input/pt_process_source.csv",
408
+ "filter_in_type": ["1d_map"],
409
+ "filter_out_index": "period",
410
+ "param_print": True,
411
+ },
412
+ {
413
+ "cl_pars": [("unit__inputNode", "other_operational_cost")],
414
+ "header": "process,source,sourceSinkPeriodParam,period,pd_process_source",
415
+ "filename": "input/pd_process_source.csv",
416
+ "filter_in_type": ["1d_map"],
417
+ "filter_out_index": "time",
418
+ "param_print": True,
419
+ },
420
+ {
421
+ "cl_pars": [("unit__inputNode", "other_operational_cost")],
422
+ "header": "process,source,sourceSinkTimeParam,branch,time_start,time,pbt_process_source",
423
+ "filename": "input/pbt_process_source.csv",
424
+ "filter_in_type": ["3d_map"],
425
+ "param_print": True,
426
+ },
427
+ {
428
+ "cl_pars": [("connection__profile", "profile_method")],
429
+ "header": "process,profile,profile_method",
430
+ "filename": "input/process__profile__profile_method.csv",
431
+ },
432
+ {
433
+ "cl_pars": [("unit__outputNode", "ramp_method"), ("unit__inputNode", "ramp_method")],
434
+ "header": "process,node,ramp_method",
435
+ "filename": "input/process__node__ramp_method.csv",
436
+ },
437
+ {
438
+ "cl_pars": [("unit", "startup_method"), ("connection", "startup_method")],
439
+ "header": "process,startup_method",
440
+ "filename": "input/process__startup_method.csv",
441
+ },
442
+ {
443
+ "cl_pars": [("unit", "conversion_method"), ("connection", "transfer_method")],
444
+ "header": "process,ct_method",
445
+ "filename": "input/process__ct_method.csv",
446
+ },
447
+ # --- profile ---
448
+ {
449
+ "cl_pars": [("profile", "profile")],
450
+ "header": "profile,time,pt_profile",
451
+ "filename": "input/pt_profile.csv",
452
+ "filter_in_type": ["1d_map"],
453
+ "filter_out_index": "period",
454
+ },
455
+ {
456
+ "cl_pars": [("profile", "profile")],
457
+ "header": "profile,branch,time_start,time,pbt_profile",
458
+ "filename": "input/pbt_profile.csv",
459
+ "filter_in_type": ["3d_map"],
460
+ },
461
+ {
462
+ "cl_pars": [("profile", "profile")],
463
+ "header": "profile,period,pd_profile",
464
+ "filename": "input/pd_profile.csv",
465
+ "filter_in_type": ["1d_map"],
466
+ "filter_out_index": "time",
467
+ },
468
+ {
469
+ "cl_pars": [("profile", "profile")],
470
+ "header": "profile,p_profile",
471
+ "filename": "input/p_profile.csv",
472
+ "filter_in_type": ["float", "str", "bool"],
473
+ },
474
+ # --- reserve ---
475
+ {
476
+ "cl_pars": [("reserve__upDown__group", "increase_reserve_ratio"),
477
+ ("reserve__upDown__group", "penalty_reserve"),
478
+ ("reserve__upDown__group", "reservation")],
479
+ "header": "reserve,upDown,group,reserveParam,p_reserve_upDown_group",
480
+ "filename": "input/p_reserve__upDown__group.csv",
481
+ "filter_in_type": ["float", "str", "bool"],
482
+ "param_print": True,
483
+ },
484
+ {
485
+ "cl_pars": [("reserve__upDown__group", "reservation")],
486
+ "header": "reserve,upDown,group,reserveParam,time,pt_reserve_upDown_group",
487
+ "filename": "input/pt_reserve__upDown__group.csv",
488
+ "filter_in_type": ["1d_map"],
489
+ "filter_out_index": "period",
490
+ "param_print": True,
491
+ },
492
+ {
493
+ "cl_pars": [("reserve__upDown__group", "reservation")],
494
+ "header": "reserve,upDown,group,reserveParam,branch,time_start,time,pbt_reserve_upDown_group",
495
+ "filename": "input/pbt_reserve__upDown__group.csv",
496
+ "filter_in_type": ["3d_map"],
497
+ "param_print": True,
498
+ },
499
+ {
500
+ "cl_pars": [("reserve__upDown__group", "reserve_method")],
501
+ "header": "reserve,upDown,group,method",
502
+ "filename": "input/reserve__upDown__group__method.csv",
503
+ },
504
+ # --- solve ---
505
+ {
506
+ "cl_pars": [("solve", "solver")],
507
+ "header": "solve,solver",
508
+ "filename": "input/solver.csv",
509
+ },
510
+ {
511
+ "cl_pars": [("solve", "timeline_hole_multiplier")],
512
+ "header": "solve,p_hole_multiplier",
513
+ "filename": "input/solve_hole_multiplier.csv",
514
+ },
515
+ {
516
+ "cl_pars": [("solve", "solver_precommand")],
517
+ "header": "solve,solver_precommand",
518
+ "filename": "input/solver_precommand.csv",
519
+ },
520
+ {
521
+ "cl_pars": [("solve", "solver_arguments")],
522
+ "header": "solve,arguments",
523
+ "filename": "input/solver_arguments.csv",
524
+ },
525
+ {
526
+ "cl_pars": [("solve", "solve_mode")],
527
+ "header": "param,solve,value",
528
+ "filename": "input/solve_mode.csv",
529
+ "param_print": True,
530
+ "param_loc": 0,
531
+ },
532
+ {
533
+ "cl_pars": [("solve", "contains_solves")],
534
+ "header": "solve,include_solve",
535
+ "filename": "input/solve__contains_solve.csv",
536
+ },
537
+ {
538
+ "cl_pars": [("solve", "realized_periods")],
539
+ "header": "solve,roll,period",
540
+ "filename": "input/solve__realized_period_2d_map.csv",
541
+ "filter_in_type": ["2d_map"],
542
+ "no_value": True,
543
+ },
544
+ {
545
+ "cl_pars": [("solve", "fix_storage_periods")],
546
+ "header": "solve,roll,period",
547
+ "filename": "input/solve__fix_storage_period_2d_map.csv",
548
+ "filter_in_type": ["2d_map"],
549
+ "no_value": True,
550
+ },
551
+ {
552
+ "cl_pars": [("solve", "invest_periods")],
553
+ "header": "solve,roll,period",
554
+ "filename": "input/solve__invest_period_2d_map.csv",
555
+ "filter_in_type": ["2d_map"],
556
+ "no_value": True,
557
+ },
558
+ {
559
+ "cl_pars": [("solve", "realized_periods")],
560
+ "header": "solve,period",
561
+ "filename": "input/solve__realized_period.csv",
562
+ "filter_in_type": ["array", "1d_map"],
563
+ },
564
+ {
565
+ "cl_pars": [("solve", "realized_invest_periods")],
566
+ "header": "solve,invest_realized_period",
567
+ "filename": "input/solve__realized_invest_period.csv",
568
+ "filter_in_type": ["array", "1d_map"],
569
+ },
570
+ {
571
+ "cl_pars": [("solve", "realized_invest_periods")],
572
+ "header": "solve,roll,period",
573
+ "filename": "input/solve__realized_invest_period_2d_map.csv",
574
+ "filter_in_type": ["2d_map"],
575
+ "no_value": True,
576
+ },
577
+ {
578
+ "cl_pars": [("solve", "fix_storage_periods")],
579
+ "header": "solve,period",
580
+ "filename": "input/solve__fix_storage_period.csv",
581
+ "filter_in_type": ["array", "1d_map"],
582
+ },
583
+ {
584
+ "cl_pars": [("solve", "invest_periods")],
585
+ "header": "solve,period",
586
+ "filename": "input/solve__invest_period.csv",
587
+ "filter_in_type": ["array", "1d_map"],
588
+ },
589
+ # --- timeline ---
590
+ {
591
+ "cl_pars": [("timeline", "timestep_duration")],
592
+ "header": "timeline,timestep,duration",
593
+ "filename": "input/timeline.csv",
594
+ },
595
+ # --- process time-series / period / branch ---
596
+ {
597
+ "cl_pars": [("unit", "efficiency"),
598
+ ("unit", "efficiency_at_min_load"),
599
+ ("unit", "min_load"),
600
+ ("unit", "availability"),
601
+ ("connection", "efficiency"),
602
+ ("connection", "efficiency_at_min_load"),
603
+ ("connection", "min_load"),
604
+ ("connection", "other_operational_cost"),
605
+ ("connection", "availability")],
606
+ "header": "process,processParam,time,pt_process",
607
+ "filename": "input/pt_process.csv",
608
+ "filter_in_type": ["1d_map"],
609
+ "filter_out_index": "period",
610
+ "param_print": True,
611
+ },
612
+ {
613
+ "cl_pars": [("unit__outputNode", "is_non_synchronous")],
614
+ "header": "process,sink",
615
+ "filename": "input/process__sink_nonSync_unit.csv",
616
+ "filter_in_value": "yes",
617
+ "no_value": True,
618
+ },
619
+ {
620
+ "cl_pars": [("unit__node__profile", "profile_method")],
621
+ "header": "process,node,profile,profile_method",
622
+ "filename": "input/process__node__profile__profile_method.csv",
623
+ },
624
+ {
625
+ "cl_pars": [("unit__inputNode", "inertia_constant"),
626
+ ("unit__inputNode", "other_operational_cost"),
627
+ ("unit__inputNode", "ramp_cost"),
628
+ ("unit__inputNode", "ramp_speed_down"),
629
+ ("unit__inputNode", "ramp_speed_up")],
630
+ "header": "process,source,sourceSinkParam,p_process_source",
631
+ "filename": "input/p_process_source.csv",
632
+ "filter_in_type": ["float"],
633
+ "param_print": True,
634
+ },
635
+ {
636
+ "cl_pars": [("unit__outputNode", "inertia_constant"),
637
+ ("unit__outputNode", "other_operational_cost"),
638
+ ("unit__outputNode", "ramp_cost"),
639
+ ("unit__outputNode", "ramp_speed_down"),
640
+ ("unit__outputNode", "ramp_speed_up")],
641
+ "header": "process,sink,sourceSinkParam,p_process_sink",
642
+ "filename": "input/p_process_sink.csv",
643
+ "filter_in_type": ["float"],
644
+ "param_print": True,
645
+ },
646
+ {
647
+ "cl_pars": [("reserve__upDown__unit__node", "increase_reserve_ratio"),
648
+ ("reserve__upDown__unit__node", "large_failure_ratio"),
649
+ ("reserve__upDown__unit__node", "max_share"),
650
+ ("reserve__upDown__unit__node", "reliability"),
651
+ ("reserve__upDown__connection__node", "increase_reserve_ratio"),
652
+ ("reserve__upDown__connection__node", "large_failure_ratio"),
653
+ ("reserve__upDown__connection__node", "max_share"),
654
+ ("reserve__upDown__connection__node", "reliability")],
655
+ "header": "process,reserve,upDown,node,reserveParam,p_process_reserve_upDown_node",
656
+ "filename": "input/p_process__reserve__upDown__node.csv",
657
+ "filter_in_type": ["float", "str", "bool"],
658
+ "param_print": True,
659
+ "dimens": [1, 2, 0, 3],
660
+ },
661
+ {
662
+ "cl_pars": [("unit__outputNode", "constraint_flow_coeff"),
663
+ ("unit__inputNode", "constraint_flow_coeff"),
664
+ ("connection__node", "constraint_flow_coeff")],
665
+ "header": "process,node,constraint,p_process_node_constraint_flow_coeff",
666
+ "filename": "input/p_process_node_constraint_flow_coeff.csv",
667
+ "filter_in_type": ["1d_map"],
668
+ },
669
+ {
670
+ "cl_pars": [("unit", "constraint_invested_capacity_coeff"),
671
+ ("connection", "constraint_invested_capacity_coeff")],
672
+ "header": "process,constraint,p_process_constraint_invested_capacity_coeff",
673
+ "filename": "input/p_process_constraint_invested_capacity_coeff.csv",
674
+ "filter_in_type": ["1d_map"],
675
+ },
676
+ {
677
+ "cl_pars": [("unit", "constraint_cumulative_pre_built_capacity_coeff"),
678
+ ("connection", "constraint_cumulative_pre_built_capacity_coeff")],
679
+ "header": "process,constraint,p_process_constraint_prebuilt_capacity_coeff",
680
+ "filename": "input/p_process_constraint_cumulative_pre_built_capacity_coeff.csv",
681
+ "filter_in_type": ["1d_map"],
682
+ },
683
+ {
684
+ "cl_pars": [("unit", "delay"), ("connection", "delay")],
685
+ "header": "process,delay_duration,p_process_delay_weighted",
686
+ "filename": "input/p_process_delay_weighted.csv",
687
+ "filter_in_type": ["1d_map"],
688
+ },
689
+ {
690
+ "cl_pars": [("unit", "delay"), ("connection", "delay")],
691
+ "header": "process,delay_duration",
692
+ "filename": "input/process_delay_single.csv",
693
+ "filter_in_type": ["str", "float"],
694
+ },
695
+ # --- p_process (scalars) ---
696
+ {
697
+ "cl_pars": [("unit", "availability"),
698
+ ("unit", "cumulative_max_capacity"),
699
+ ("unit", "cumulative_min_capacity"),
700
+ ("unit", "efficiency"),
701
+ ("unit", "efficiency_at_min_load"),
702
+ ("unit", "existing"),
703
+ ("unit", "fixed_cost"),
704
+ ("unit", "discount_rate"),
705
+ ("unit", "invest_cost"),
706
+ ("unit", "invest_max_total"),
707
+ ("unit", "invest_min_total"),
708
+ ("unit", "lifetime"),
709
+ ("unit", "min_downtime"),
710
+ ("unit", "min_load"),
711
+ ("unit", "min_uptime"),
712
+ ("unit", "retire_max_total"),
713
+ ("unit", "retire_min_total"),
714
+ ("unit", "salvage_value"),
715
+ ("unit", "startup_cost"),
716
+ ("unit", "virtual_unitsize"),
717
+ ("connection", "availability"),
718
+ ("connection", "cumulative_max_capacity"),
719
+ ("connection", "cumulative_min_capacity"),
720
+ ("connection", "efficiency"),
721
+ ("connection", "existing"),
722
+ ("connection", "fixed_cost"),
723
+ ("connection", "discount_rate"),
724
+ ("connection", "invest_cost"),
725
+ ("connection", "invest_max_total"),
726
+ ("connection", "invest_min_total"),
727
+ ("connection", "lifetime"),
728
+ ("connection", "other_operational_cost"),
729
+ ("connection", "retire_max_total"),
730
+ ("connection", "retire_min_total"),
731
+ ("connection", "salvage_value"),
732
+ ("connection", "startup_cost"),
733
+ ("connection", "virtual_unitsize")],
734
+ "header": "process,processParam,p_process",
735
+ "filename": "input/p_process.csv",
736
+ "filter_in_type": ["float", "str", "bool"],
737
+ "param_print": True,
738
+ },
739
+ # --- p_node (scalars) ---
740
+ {
741
+ "cl_pars": [("node", "annual_flow"),
742
+ ("node", "availability"),
743
+ ("node", "cumulative_max_capacity"),
744
+ ("node", "cumulative_min_capacity"),
745
+ ("node", "existing"),
746
+ ("node", "fixed_cost"),
747
+ ("node", "inflow"),
748
+ ("node", "discount_rate"),
749
+ ("node", "invest_cost"),
750
+ ("node", "invest_forced"),
751
+ ("node", "invest_max_total"),
752
+ ("node", "invest_min_total"),
753
+ ("node", "lifetime"),
754
+ ("node", "peak_inflow"),
755
+ ("node", "penalty_down"),
756
+ ("node", "penalty_up"),
757
+ ("node", "retire_max_total"),
758
+ ("node", "retire_min_total"),
759
+ ("node", "salvage_value"),
760
+ ("node", "self_discharge_loss"),
761
+ ("node", "storage_state_end"),
762
+ ("node", "storage_state_reference_price"),
763
+ ("node", "storage_state_reference_value"),
764
+ ("node", "storage_state_start"),
765
+ ("node", "virtual_unitsize")],
766
+ "header": "node,nodeParam,p_node",
767
+ "filename": "input/p_node.csv",
768
+ "filter_in_type": ["float", "str", "bool"],
769
+ "param_print": True,
770
+ },
771
+ # --- group__process ---
772
+ {
773
+ "cl_pars": [("group__unit", "groupParam"), ("group__connection", "groupParam")],
774
+ "header": "group,process,groupParam,p_group_process_s",
775
+ "filename": "input/p_group__process.csv",
776
+ "param_print": True,
777
+ },
778
+ # --- p_group (scalars) ---
779
+ {
780
+ "cl_pars": [("group", "groupParam"),
781
+ ("group", "capacity_margin"),
782
+ ("group", "co2_max_total"),
783
+ ("group", "co2_price"),
784
+ ("group", "inertia_limit"),
785
+ ("group", "invest_max_total"),
786
+ ("group", "invest_min_total"),
787
+ ("group", "invest_max_cumulative"),
788
+ ("group", "invest_min_cumulative"),
789
+ ("group", "non_synchronous_limit"),
790
+ ("group", "penalty_capacity_margin"),
791
+ ("group", "penalty_inertia"),
792
+ ("group", "penalty_non_synchronous"),
793
+ # Agent 1.9: v51 group-level new_stepduration is
794
+ # numeric so it flows through the normal p_group
795
+ # numeric channel. The companion
796
+ # ``decomposition_method`` is a *string* enum and
797
+ # would break ``p_group``'s numeric type — it lives
798
+ # in its own ``input/p_group_decomposition.csv``
799
+ # written below (consumed only by ``blocks.py``).
800
+ ("group", "new_stepduration")],
801
+ "header": "group,groupParam,p_group",
802
+ "filename": "input/p_group.csv",
803
+ "filter_in_type": ["float", "str", "bool"],
804
+ "param_print": True,
805
+ },
806
+ # Agent 1.9: separate file for the (string) decomposition_method
807
+ # so the numeric p_group channel stays clean. ``blocks.py``
808
+ # falls back to this file when the row isn't found in
809
+ # ``p_group.csv``.
810
+ {
811
+ "cl_pars": [("group", "decomposition_method")],
812
+ "header": "group,groupParam,p_group",
813
+ "filename": "input/p_group_decomposition.csv",
814
+ "filter_in_type": ["str"],
815
+ "param_print": True,
816
+ },
817
+ # --- p_flowgroup (scalars) ---
818
+ # v58 split: the 4 numeric flow-limit params live on the dedicated
819
+ # ``flowGroup`` class (see specs/nodegroup_flowgroup_db_split.md §5.1).
820
+ {
821
+ "cl_pars": [("flowGroup", "groupParam"),
822
+ ("flowGroup", "max_cumulative_flow"),
823
+ ("flowGroup", "max_instant_flow"),
824
+ ("flowGroup", "min_cumulative_flow"),
825
+ ("flowGroup", "min_instant_flow")],
826
+ "header": "flowGroup,groupParam,p_flowgroup",
827
+ "filename": "input/p_flowgroup.csv",
828
+ "filter_in_type": ["float", "str", "bool"],
829
+ "param_print": True,
830
+ },
831
+ # --- pd_process (period maps) ---
832
+ {
833
+ "cl_pars": [("unit", "invest_forced"),
834
+ ("unit", "invest_max_period"),
835
+ ("unit", "invest_min_period"),
836
+ ("unit", "retire_forced"),
837
+ ("unit", "retire_max_period"),
838
+ ("unit", "retire_min_period"),
839
+ ("unit", "invest_cost"),
840
+ ("unit", "salvage_value"),
841
+ ("unit", "discount_rate"),
842
+ ("unit", "lifetime"),
843
+ ("unit", "fixed_cost"),
844
+ ("unit", "existing"),
845
+ ("unit", "cumulative_max_capacity"),
846
+ ("unit", "cumulative_min_capacity"),
847
+ ("connection", "invest_forced"),
848
+ ("connection", "invest_max_period"),
849
+ ("connection", "invest_min_period"),
850
+ ("connection", "retire_forced"),
851
+ ("connection", "retire_max_period"),
852
+ ("connection", "retire_min_period"),
853
+ ("connection", "invest_cost"),
854
+ ("connection", "salvage_value"),
855
+ ("connection", "discount_rate"),
856
+ ("connection", "lifetime"),
857
+ ("connection", "fixed_cost"),
858
+ ("connection", "other_operational_cost"),
859
+ ("connection", "existing"),
860
+ ("connection", "cumulative_max_capacity"),
861
+ ("connection", "cumulative_min_capacity")],
862
+ "header": "process,processParam,period,pd_process",
863
+ "filename": "input/pd_process.csv",
864
+ "filter_in_type": ["1d_map"],
865
+ "filter_out_index": "time",
866
+ "param_print": True,
867
+ },
868
+ # --- model inflation ---
869
+ {
870
+ "cl_pars": [("model", "inflation_rate")],
871
+ "header": "model,p_inflation_rate",
872
+ "filename": "input/p_inflation_rate.csv",
873
+ },
874
+ {
875
+ "cl_pars": [("model", "inflation_offset_operations")],
876
+ "header": "model,p_inflation_offset_operations",
877
+ "filename": "input/p_inflation_offset_operations.csv",
878
+ },
879
+ {
880
+ "cl_pars": [("model", "inflation_offset_investment")],
881
+ "header": "model,p_inflation_offset_investment",
882
+ "filename": "input/p_inflation_offset_investment.csv",
883
+ },
884
+ {
885
+ "cl_pars": [("model", "max_flow_for_unconstrained_variables")],
886
+ "header": "model,p_max_flow_for_unconstrained_variables",
887
+ "filename": "input/p_max_flow_for_unconstrained_variables.csv",
888
+ },
889
+ {
890
+ "cl_pars": [("model", "small_number_threshold")],
891
+ "header": "model,p_small_number_threshold",
892
+ "filename": "input/p_small_number_threshold.csv",
893
+ },
894
+ # --- pdt_group (time maps) ---
895
+ {
896
+ "cl_pars": [("group", "co2_max_period"),
897
+ ("group", "co2_price"),
898
+ ("group", "inertia_limit"),
899
+ ("group", "invest_max_period"),
900
+ ("group", "invest_min_period"),
901
+ ("group", "invest_min_total"),
902
+ ("group", "non_synchronous_limit"),
903
+ ("group", "penalty_capacity_margin"),
904
+ ("group", "penalty_inertia"),
905
+ ("group", "penalty_non_synchronous")],
906
+ "header": "group,groupParam,time,pt_group",
907
+ "filename": "input/pdt_group.csv",
908
+ "filter_in_type": ["1d_map"],
909
+ "param_print": True,
910
+ },
911
+ # --- pdt_flowgroup (time maps) ---
912
+ # v58 split: time-varying flow-limit params on ``flowGroup``.
913
+ {
914
+ "cl_pars": [("flowGroup", "max_cumulative_flow"),
915
+ ("flowGroup", "max_instant_flow"),
916
+ ("flowGroup", "min_cumulative_flow"),
917
+ ("flowGroup", "min_instant_flow")],
918
+ "header": "flowGroup,groupParam,time,pt_flowgroup",
919
+ "filename": "input/pdt_flowgroup.csv",
920
+ "filter_in_type": ["1d_map"],
921
+ "param_print": True,
922
+ },
923
+ # --- pbt_process (branch maps) ---
924
+ {
925
+ "cl_pars": [("unit", "efficiency"),
926
+ ("unit", "efficiency_at_min_load"),
927
+ ("unit", "min_load"),
928
+ ("unit", "availability"),
929
+ ("connection", "efficiency"),
930
+ ("connection", "efficiency_at_min_load"),
931
+ ("connection", "min_load"),
932
+ ("connection", "other_operational_cost"),
933
+ ("connection", "availability")],
934
+ "header": "process,processParam,branch,time_start,time,pbt_process",
935
+ "filename": "input/pbt_process.csv",
936
+ "filter_in_type": ["3d_map"],
937
+ "param_print": True,
938
+ },
939
+ # --- optional outputs ---
940
+ {
941
+ "cl_pars": [("model", "output_horizon")],
942
+ "header": "output,value",
943
+ "filename": "input/optional_outputs.csv",
944
+ "param_print": True,
945
+ "no_entity": True,
946
+ },
947
+ {
948
+ "cl_pars": [("group", "print_indicators")],
949
+ "header": "nodeGroupIndicators",
950
+ "filename": "input/nodeGroupIndicators.csv",
951
+ "filter_in_value": "yes",
952
+ "no_value": True,
953
+ },
954
+ {
955
+ "cl_pars": [("flowGroup", "flow_aggregator")],
956
+ "header": "flowGroupIndicators",
957
+ "filename": "input/flowGroupIndicators.csv",
958
+ "filter_in_value": {"standalone_aggregator_only", "both"},
959
+ "no_value": True,
960
+ },
961
+ {
962
+ "cl_pars": [("group", "has_non_synchronous")],
963
+ "header": "groupNonSync",
964
+ "filename": "input/groupNonSync.csv",
965
+ "filter_in_value": "yes",
966
+ "no_value": True,
967
+ },
968
+ ]
969
+
970
+
971
+ _DEFAULT_VALUES_SPECS: list[dict] = [
972
+ {
973
+ "cl_pars": [("node", "penalty_up"), ("node", "penalty_down")],
974
+ "header": "class,paramName,default_value",
975
+ "filename": "input/default_values.csv",
976
+ "filter_in_type": ["float", "str", "bool"],
977
+ },
978
+ {
979
+ "cl_pars": [("model", "version")],
980
+ "header": "version",
981
+ "filename": "input/db_version.csv",
982
+ "filter_in_type": ["float", "str", "bool"],
983
+ "only_value": True,
984
+ },
985
+ ]
986
+
987
+
988
+ # ---------------------------------------------------------------------------
989
+ # Methods mapping — must stay in sync with flextool_base.dat ``set methods``
990
+ # ---------------------------------------------------------------------------
991
+
992
+ # (ct_method, startup_method, fork_method) -> method
993
+ METHODS_MAPPING: dict[tuple[str, str, str], str] = {
994
+ ("constant_efficiency", "no_startup", "fork_no"): "method_1way_1var_off",
995
+ ("constant_efficiency", "no_startup", "fork_yes"): "method_1way_nvar_off",
996
+ ("constant_efficiency", "linear", "fork_no"): "method_1way_1var_LP",
997
+ ("constant_efficiency", "linear", "fork_yes"): "method_1way_nvar_LP",
998
+ ("constant_efficiency", "binary", "fork_no"): "method_1way_1var_MIP",
999
+ ("constant_efficiency", "binary", "fork_yes"): "method_1way_nvar_MIP",
1000
+ ("no_losses_no_variable_cost", "no_startup", "fork_no"): "method_2way_1var_off",
1001
+ ("no_losses_no_variable_cost", "no_startup", "fork_yes"): "method_2way_nvar_off",
1002
+ ("variable_cost_only", "no_startup", "fork_no"): "method_2way_2var_off",
1003
+ ("variable_cost_only", "no_startup", "fork_yes"): "method_2way_nvar_off",
1004
+ ("regular", "no_startup", "fork_no"): "method_2way_2var_exclude",
1005
+ ("regular", "no_startup", "fork_yes"): "not_applicable",
1006
+ ("exact", "no_startup", "fork_no"): "method_2way_2var_MIP_exclude",
1007
+ ("exact", "no_startup", "fork_yes"): "not_applicable",
1008
+ ("min_load_efficiency", "no_startup", "fork_no"): "not_applicable",
1009
+ ("min_load_efficiency", "no_startup", "fork_yes"): "not_applicable",
1010
+ ("min_load_efficiency", "linear", "fork_no"): "method_1way_1var_LP",
1011
+ ("min_load_efficiency", "linear", "fork_yes"): "method_1way_nvar_LP",
1012
+ ("min_load_efficiency", "binary", "fork_no"): "method_1way_1var_MIP",
1013
+ ("min_load_efficiency", "binary", "fork_yes"): "method_1way_nvar_MIP",
1014
+ ("none", "no_startup", "fork_no"): "method_1way_1var_off",
1015
+ ("none", "no_startup", "fork_yes"): "method_1way_nvar_off",
1016
+ ("none", "linear", "fork_no"): "method_1way_1var_LP",
1017
+ ("none", "linear", "fork_yes"): "method_1way_nvar_LP",
1018
+ ("none", "binary", "fork_no"): "method_1way_1var_MIP",
1019
+ ("none", "binary", "fork_yes"): "method_1way_nvar_MIP",
1020
+ ("unidirectional", "no_startup", "fork_no"): "method_1way_1var_off",
1021
+ ("unidirectional", "no_startup", "fork_yes"): "method_1way_nvar_off",
1022
+ ("unidirectional", "linear", "fork_no"): "method_1way_1var_LP",
1023
+ ("unidirectional", "linear", "fork_yes"): "method_1way_nvar_LP",
1024
+ ("unidirectional", "binary", "fork_no"): "method_1way_1var_MIP",
1025
+ ("unidirectional", "binary", "fork_yes"): "method_1way_nvar_MIP",
1026
+ }