flextool 4.1.0__tar.gz → 4.1.1__tar.gz

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 (409) hide show
  1. {flextool-4.1.0 → flextool-4.1.1}/PKG-INFO +1 -1
  2. flextool-4.1.1/flextool/engine_polars/_constants.py +16 -0
  3. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_derived_params.py +3 -2
  4. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_inflow_scaling.py +44 -6
  5. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_period_calc.py +6 -4
  6. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_native_run_model.py +4 -2
  7. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_per_solve_sets.py +4 -2
  8. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_timeline.py +71 -0
  9. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/out_node.py +16 -6
  10. {flextool-4.1.0 → flextool-4.1.1}/flextool.egg-info/PKG-INFO +1 -1
  11. {flextool-4.1.0 → flextool-4.1.1}/flextool.egg-info/SOURCES.txt +1 -0
  12. {flextool-4.1.0 → flextool-4.1.1}/pyproject.toml +1 -1
  13. {flextool-4.1.0 → flextool-4.1.1}/LICENSE.txt +0 -0
  14. {flextool-4.1.0 → flextool-4.1.1}/README.md +0 -0
  15. {flextool-4.1.0 → flextool-4.1.1}/flextool/__init__.py +0 -0
  16. {flextool-4.1.0 → flextool-4.1.1}/flextool/_mem_sampler.py +0 -0
  17. {flextool-4.1.0 → flextool-4.1.1}/flextool/_resources.py +0 -0
  18. {flextool-4.1.0 → flextool-4.1.1}/flextool/calibrate/__init__.py +0 -0
  19. {flextool-4.1.0 → flextool-4.1.1}/flextool/calibrate/__main__.py +0 -0
  20. {flextool-4.1.0 → flextool-4.1.1}/flextool/calibrate/_cli.py +0 -0
  21. {flextool-4.1.0 → flextool-4.1.1}/flextool/calibrate/_db_alt.py +0 -0
  22. {flextool-4.1.0 → flextool-4.1.1}/flextool/calibrate/_final_outputs.py +0 -0
  23. {flextool-4.1.0 → flextool-4.1.1}/flextool/calibrate/_guard.py +0 -0
  24. {flextool-4.1.0 → flextool-4.1.1}/flextool/calibrate/_loop.py +0 -0
  25. {flextool-4.1.0 → flextool-4.1.1}/flextool/calibrate/_readers.py +0 -0
  26. {flextool-4.1.0 → flextool-4.1.1}/flextool/calibrate/_report.py +0 -0
  27. {flextool-4.1.0 → flextool-4.1.1}/flextool/calibrate/_sizing.py +0 -0
  28. {flextool-4.1.0 → flextool-4.1.1}/flextool/calibrate/_solve.py +0 -0
  29. {flextool-4.1.0 → flextool-4.1.1}/flextool/calibrate/_solve_status.py +0 -0
  30. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/__init__.py +0 -0
  31. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/_console.py +0 -0
  32. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/_timing.py +0 -0
  33. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/cmd_execute_flextool_workflow.py +0 -0
  34. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/cmd_export_to_tabular.py +0 -0
  35. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/cmd_import_sensitivities.py +0 -0
  36. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/cmd_migrate_database.py +0 -0
  37. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/cmd_open_results_db.py +0 -0
  38. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/cmd_read_matpower.py +0 -0
  39. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/cmd_read_old_flextool.py +0 -0
  40. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/cmd_read_self_describing_tabular_input.py +0 -0
  41. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/cmd_read_tabular_input.py +0 -0
  42. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/cmd_run_flextool.py +0 -0
  43. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/cmd_scenario_results.py +0 -0
  44. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/cmd_solve_mps.py +0 -0
  45. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/cmd_update_flextool.py +0 -0
  46. {flextool-4.1.0 → flextool-4.1.1}/flextool/cli/cmd_write_outputs.py +0 -0
  47. {flextool-4.1.0 → flextool-4.1.1}/flextool/common_utils/__init__.py +0 -0
  48. {flextool-4.1.0 → flextool-4.1.1}/flextool/common_utils/plot_mem_shape.py +0 -0
  49. {flextool-4.1.0 → flextool-4.1.1}/flextool/common_utils/precision.py +0 -0
  50. {flextool-4.1.0 → flextool-4.1.1}/flextool/decomposition/__init__.py +0 -0
  51. {flextool-4.1.0 → flextool-4.1.1}/flextool/decomposition/region_decomposition.py +0 -0
  52. {flextool-4.1.0 → flextool-4.1.1}/flextool/decomposition/region_filter.py +0 -0
  53. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/__init__.py +0 -0
  54. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_axis_enums.py +0 -0
  55. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_benders.py +0 -0
  56. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_block_layout.py +0 -0
  57. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_blocks.py +0 -0
  58. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_commodity_ladder.py +0 -0
  59. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_cumulative_invest.py +0 -0
  60. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_db_loader.py +0 -0
  61. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_db_reader.py +0 -0
  62. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_dc_power_flow.py +0 -0
  63. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_delay.py +0 -0
  64. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_derived_arithmetic.py +0 -0
  65. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_derived_block.py +0 -0
  66. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_derived_branch.py +0 -0
  67. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_derived_existing.py +0 -0
  68. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_derived_npv.py +0 -0
  69. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_derived_profile.py +0 -0
  70. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_derived_walks.py +0 -0
  71. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_determinism.py +0 -0
  72. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_direct_params.py +0 -0
  73. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_dump_csvs.py +0 -0
  74. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_arc_unions.py +0 -0
  75. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_calc_params.py +0 -0
  76. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_chain_params.py +0 -0
  77. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_co2_accumulators.py +0 -0
  78. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_dispatchers.py +0 -0
  79. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_energy_margin.py +0 -0
  80. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_energy_margin_adder.py +0 -0
  81. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_entity_annual.py +0 -0
  82. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_leaf_sets.py +0 -0
  83. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_lp_scaling.py +0 -0
  84. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_mid_sets.py +0 -0
  85. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_pdt_params.py +0 -0
  86. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_per_solve.py +0 -0
  87. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_period_params.py +0 -0
  88. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_provider_io.py +0 -0
  89. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_reserve.py +0 -0
  90. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_solve_time.py +0 -0
  91. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_emit_solve_writers.py +0 -0
  92. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_flex_data_accumulator.py +0 -0
  93. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_flex_data_provider.py +0 -0
  94. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_group_slack.py +0 -0
  95. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_inmemory_reader.py +0 -0
  96. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_input_source.py +0 -0
  97. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_invest_seeds.py +0 -0
  98. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_native_input_writer.py +0 -0
  99. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_orchestration.py +0 -0
  100. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_output_writer.py +0 -0
  101. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_param_shapes.py +0 -0
  102. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_parquet_bundle.py +0 -0
  103. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_pdt_join.py +0 -0
  104. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_pdt_lookup.py +0 -0
  105. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_projection_params.py +0 -0
  106. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_provider_keys.py +0 -0
  107. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_provider_translators.py +0 -0
  108. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_recursive_solve.py +0 -0
  109. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_region_filter.py +0 -0
  110. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_reserve.py +0 -0
  111. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_solve_acceptance.py +0 -0
  112. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_solve_config.py +0 -0
  113. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_solve_context.py +0 -0
  114. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_solve_handoff.py +0 -0
  115. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_solve_state.py +0 -0
  116. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_solver_base.py +0 -0
  117. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_solver_dispatch.py +0 -0
  118. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_spinedb_reader.py +0 -0
  119. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_stochastic.py +0 -0
  120. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_stochastic_detect.py +0 -0
  121. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_subprocess_solve.py +0 -0
  122. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_vectorize.py +0 -0
  123. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/_warm.py +0 -0
  124. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/autoscale/__init__.py +0 -0
  125. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/autoscale/_config.py +0 -0
  126. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/autoscale/_layer2.py +0 -0
  127. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/autoscale/_layer2_types.py +0 -0
  128. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/autoscale/_quantity_types.py +0 -0
  129. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/autoscale/_report.py +0 -0
  130. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/chain.py +0 -0
  131. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/input.py +0 -0
  132. {flextool-4.1.0 → flextool-4.1.1}/flextool/engine_polars/model.py +0 -0
  133. {flextool-4.1.0 → flextool-4.1.1}/flextool/env_check.py +0 -0
  134. {flextool-4.1.0 → flextool-4.1.1}/flextool/export_to_tabular/__init__.py +0 -0
  135. {flextool-4.1.0 → flextool-4.1.1}/flextool/export_to_tabular/db_reader.py +0 -0
  136. {flextool-4.1.0 → flextool-4.1.1}/flextool/export_to_tabular/excel_writer.py +0 -0
  137. {flextool-4.1.0 → flextool-4.1.1}/flextool/export_to_tabular/export_settings.yaml +0 -0
  138. {flextool-4.1.0 → flextool-4.1.1}/flextool/export_to_tabular/export_to_excel.py +0 -0
  139. {flextool-4.1.0 → flextool-4.1.1}/flextool/export_to_tabular/formatting.py +0 -0
  140. {flextool-4.1.0 → flextool-4.1.1}/flextool/export_to_tabular/sheet_config.py +0 -0
  141. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/__init__.py +0 -0
  142. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/__main__.py +0 -0
  143. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/calibrate_commands.py +0 -0
  144. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/calibrate_jobs.py +0 -0
  145. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/check_tree.py +0 -0
  146. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/cli_format.py +0 -0
  147. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/config_parser.py +0 -0
  148. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/data_models.py +0 -0
  149. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/db_editor_integration.py +0 -0
  150. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/db_version_check.py +0 -0
  151. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/dialogs/__init__.py +0 -0
  152. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/dialogs/add_dialog.py +0 -0
  153. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/dialogs/calibrate_dialog.py +0 -0
  154. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/dialogs/file_picker.py +0 -0
  155. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/dialogs/group_picker.py +0 -0
  156. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/dialogs/migration_consent_dialog.py +0 -0
  157. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/dialogs/migration_progress_dialog.py +0 -0
  158. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/dialogs/plot_dialog.py +0 -0
  159. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/dialogs/plot_settings_picker.py +0 -0
  160. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/dialogs/project_dialog.py +0 -0
  161. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/dialogs/update_dialog.py +0 -0
  162. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/downsampling.py +0 -0
  163. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/error_handling.py +0 -0
  164. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/execution_manager.py +0 -0
  165. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/execution_window.py +0 -0
  166. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/hover_tooltip.py +0 -0
  167. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/input_sources.py +0 -0
  168. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/main_window.py +0 -0
  169. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/network_graph.py +0 -0
  170. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/output_actions.py +0 -0
  171. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/output_log_window.py +0 -0
  172. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/platform_utils.py +0 -0
  173. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/plot_cache.py +0 -0
  174. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/plot_canvas.py +0 -0
  175. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/plot_config_reader.py +0 -0
  176. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/project_utils.py +0 -0
  177. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/result_viewer.py +0 -0
  178. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/scenario_key.py +0 -0
  179. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/scenario_lists.py +0 -0
  180. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/settings_io.py +0 -0
  181. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/solve_reader.py +0 -0
  182. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/tree_reorder.py +0 -0
  183. {flextool-4.1.0 → flextool-4.1.1}/flextool/gui/ui_metrics.py +0 -0
  184. {flextool-4.1.0 → flextool-4.1.1}/flextool/input_derivation/__init__.py +0 -0
  185. {flextool-4.1.0 → flextool-4.1.1}/flextool/input_derivation/_commodity_ladder.py +0 -0
  186. {flextool-4.1.0 → flextool-4.1.1}/flextool/input_derivation/_commodity_ladder_sets.py +0 -0
  187. {flextool-4.1.0 → flextool-4.1.1}/flextool/input_derivation/_dc_power_flow.py +0 -0
  188. {flextool-4.1.0 → flextool-4.1.1}/flextool/input_derivation/_method_constants.py +0 -0
  189. {flextool-4.1.0 → flextool-4.1.1}/flextool/input_derivation/_process_method.py +0 -0
  190. {flextool-4.1.0 → flextool-4.1.1}/flextool/input_derivation/_specs.py +0 -0
  191. {flextool-4.1.0 → flextool-4.1.1}/flextool/input_derivation/_validators.py +0 -0
  192. {flextool-4.1.0 → flextool-4.1.1}/flextool/lean_parquet.py +0 -0
  193. {flextool-4.1.0 → flextool-4.1.1}/flextool/model_builder/__init__.py +0 -0
  194. {flextool-4.1.0 → flextool-4.1.1}/flextool/model_builder/build_model.py +0 -0
  195. {flextool-4.1.0 → flextool-4.1.1}/flextool/model_builder/encoding.py +0 -0
  196. {flextool-4.1.0 → flextool-4.1.1}/flextool/model_builder/names.py +0 -0
  197. {flextool-4.1.0 → flextool-4.1.1}/flextool/model_builder/profiles.py +0 -0
  198. {flextool-4.1.0 → flextool-4.1.1}/flextool/plot_outputs/__init__.py +0 -0
  199. {flextool-4.1.0 → flextool-4.1.1}/flextool/plot_outputs/axis_helpers.py +0 -0
  200. {flextool-4.1.0 → flextool-4.1.1}/flextool/plot_outputs/color_template.py +0 -0
  201. {flextool-4.1.0 → flextool-4.1.1}/flextool/plot_outputs/config.py +0 -0
  202. {flextool-4.1.0 → flextool-4.1.1}/flextool/plot_outputs/format_helpers.py +0 -0
  203. {flextool-4.1.0 → flextool-4.1.1}/flextool/plot_outputs/legend_helpers.py +0 -0
  204. {flextool-4.1.0 → flextool-4.1.1}/flextool/plot_outputs/orchestrator.py +0 -0
  205. {flextool-4.1.0 → flextool-4.1.1}/flextool/plot_outputs/perf.py +0 -0
  206. {flextool-4.1.0 → flextool-4.1.1}/flextool/plot_outputs/plan.py +0 -0
  207. {flextool-4.1.0 → flextool-4.1.1}/flextool/plot_outputs/plot_bars.py +0 -0
  208. {flextool-4.1.0 → flextool-4.1.1}/flextool/plot_outputs/plot_bars_detail.py +0 -0
  209. {flextool-4.1.0 → flextool-4.1.1}/flextool/plot_outputs/plot_lines.py +0 -0
  210. {flextool-4.1.0 → flextool-4.1.1}/flextool/plot_outputs/shared_manifest.py +0 -0
  211. {flextool-4.1.0 → flextool-4.1.1}/flextool/plot_outputs/subplot_helpers.py +0 -0
  212. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_inputs/__init__.py +0 -0
  213. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_inputs/import_old_excel_input.json +0 -0
  214. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_inputs/read_matpower.py +0 -0
  215. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_inputs/read_old_flextool.py +0 -0
  216. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_inputs/read_self_describing_excel.py +0 -0
  217. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_inputs/read_tabular_with_specification.py +0 -0
  218. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_inputs/write_old_flextool_to_db.py +0 -0
  219. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_inputs/write_self_describing_to_db.py +0 -0
  220. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_inputs/write_to_input_db.py +0 -0
  221. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/__init__.py +0 -0
  222. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/_annualize.py +0 -0
  223. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/_branch_weight.py +0 -0
  224. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/_inmemory_helpers.py +0 -0
  225. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/_output_meta.py +0 -0
  226. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/calc_capacity_flows.py +0 -0
  227. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/calc_connections.py +0 -0
  228. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/calc_costs.py +0 -0
  229. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/calc_group_flows.py +0 -0
  230. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/calc_slacks.py +0 -0
  231. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/calc_storage_vre.py +0 -0
  232. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/drop_levels.py +0 -0
  233. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/handoff_writers.py +0 -0
  234. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/out_ancillary.py +0 -0
  235. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/out_capacity.py +0 -0
  236. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/out_costs.py +0 -0
  237. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/out_flowgroup.py +0 -0
  238. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/out_flows.py +0 -0
  239. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/out_group.py +0 -0
  240. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/persist_realized_slice.py +0 -0
  241. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/process_results.py +0 -0
  242. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/read_highs_solution.py +0 -0
  243. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/read_parameters.py +0 -0
  244. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/read_sets.py +0 -0
  245. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/read_variables.py +0 -0
  246. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/solve_order.py +0 -0
  247. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/spinedb_replay.py +0 -0
  248. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/union_realized_slice.py +0 -0
  249. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/write_outputs.py +0 -0
  250. {flextool-4.1.0 → flextool-4.1.1}/flextool/process_outputs/write_spinedb.py +0 -0
  251. {flextool-4.1.0 → flextool-4.1.1}/flextool/representative_periods/__init__.py +0 -0
  252. {flextool-4.1.0 → flextool-4.1.1}/flextool/representative_periods/clustering.py +0 -0
  253. {flextool-4.1.0 → flextool-4.1.1}/flextool/representative_periods/force_include.py +0 -0
  254. {flextool-4.1.0 → flextool-4.1.1}/flextool/representative_periods/netload.py +0 -0
  255. {flextool-4.1.0 → flextool-4.1.1}/flextool/representative_periods/netload_inputs.py +0 -0
  256. {flextool-4.1.0 → flextool-4.1.1}/flextool/representative_periods/netload_iterate.py +0 -0
  257. {flextool-4.1.0 → flextool-4.1.1}/flextool/representative_periods/preprocess.py +0 -0
  258. {flextool-4.1.0 → flextool-4.1.1}/flextool/representative_periods/scenario_stack.py +0 -0
  259. {flextool-4.1.0 → flextool-4.1.1}/flextool/representative_periods/weights.py +0 -0
  260. {flextool-4.1.0 → flextool-4.1.1}/flextool/scenario_comparison/__init__.py +0 -0
  261. {flextool-4.1.0 → flextool-4.1.1}/flextool/scenario_comparison/config_builder.py +0 -0
  262. {flextool-4.1.0 → flextool-4.1.1}/flextool/scenario_comparison/constants.py +0 -0
  263. {flextool-4.1.0 → flextool-4.1.1}/flextool/scenario_comparison/data_models.py +0 -0
  264. {flextool-4.1.0 → flextool-4.1.1}/flextool/scenario_comparison/db_reader.py +0 -0
  265. {flextool-4.1.0 → flextool-4.1.1}/flextool/scenario_comparison/dispatch_data.py +0 -0
  266. {flextool-4.1.0 → flextool-4.1.1}/flextool/scenario_comparison/dispatch_mappings.py +0 -0
  267. {flextool-4.1.0 → flextool-4.1.1}/flextool/scenario_comparison/dispatch_plots.py +0 -0
  268. {flextool-4.1.0 → flextool-4.1.1}/flextool/scenario_comparison/input_entity_colors.py +0 -0
  269. {flextool-4.1.0 → flextool-4.1.1}/flextool/scenario_comparison/orchestrator.py +0 -0
  270. {flextool-4.1.0 → flextool-4.1.1}/flextool/scenario_comparison/plan_union.py +0 -0
  271. {flextool-4.1.0 → flextool-4.1.1}/flextool/scenario_comparison/plot_settings_seed.py +0 -0
  272. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/AXIS_CONTRACT.md +0 -0
  273. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_aggregate_output.json +0 -0
  274. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_connections.json +0 -0
  275. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_demand.json +0 -0
  276. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_hydro_reservoir.json +0 -0
  277. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_hydro_reservoir_with_pump.json +0 -0
  278. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_non_sync_and_curtailment.json +0 -0
  279. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_ramp_and_start_up.json +0 -0
  280. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_stochastics.json +0 -0
  281. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/canonical_databases/templates_examples.json +0 -0
  282. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/canonical_databases/templates_time_settings_only.json +0 -0
  283. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/comparison_settings_template.json +0 -0
  284. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/default_plot_settings.yaml +0 -0
  285. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/default_plots.yaml +0 -0
  286. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/flextool_axis_contract.json +0 -0
  287. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/flextool_axis_contract.schema.json +0 -0
  288. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/old_flextool_import_template.json +0 -0
  289. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/output_info_template.json +0 -0
  290. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/output_settings_template.json +0 -0
  291. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_constant_default.json +0 -0
  292. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_default_optional_output.json +0 -0
  293. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_default_value.json +0 -0
  294. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_drop_down.json +0 -0
  295. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_lifetime_method.json +0 -0
  296. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_optional_outputs.json +0 -0
  297. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_output_node_flows.json +0 -0
  298. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_results_master.json +0 -0
  299. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_rolling_start_remove.json +0 -0
  300. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_rolling_window.json +0 -0
  301. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_storage_binding_defaults.json +0 -0
  302. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_v2.json +0 -0
  303. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_v25.json +0 -0
  304. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/spinedb_results_schema.json +0 -0
  305. {flextool-4.1.0 → flextool-4.1.1}/flextool/schemas/spinedb_schema.json +0 -0
  306. {flextool-4.1.0 → flextool-4.1.1}/flextool/solver_config/copt.opt.template +0 -0
  307. {flextool-4.1.0 → flextool-4.1.1}/flextool/solver_config/cplex.opt.template +0 -0
  308. {flextool-4.1.0 → flextool-4.1.1}/flextool/solver_config/gurobi.opt.template +0 -0
  309. {flextool-4.1.0 → flextool-4.1.1}/flextool/solver_config/highs.opt.template +0 -0
  310. {flextool-4.1.0 → flextool-4.1.1}/flextool/solver_config/xpress.opt.template +0 -0
  311. {flextool-4.1.0 → flextool-4.1.1}/flextool/spinedb_backend/__init__.py +0 -0
  312. {flextool-4.1.0 → flextool-4.1.1}/flextool/spinedb_backend/_axis_enums.py +0 -0
  313. {flextool-4.1.0 → flextool-4.1.1}/flextool/spinedb_backend/_backend.py +0 -0
  314. {flextool-4.1.0 → flextool-4.1.1}/flextool/update_flextool/__init__.py +0 -0
  315. {flextool-4.1.0 → flextool-4.1.1}/flextool/update_flextool/canonical_databases.py +0 -0
  316. {flextool-4.1.0 → flextool-4.1.1}/flextool/update_flextool/db_migration.py +0 -0
  317. {flextool-4.1.0 → flextool-4.1.1}/flextool/update_flextool/ensure_settings_db.py +0 -0
  318. {flextool-4.1.0 → flextool-4.1.1}/flextool/update_flextool/export_database.py +0 -0
  319. {flextool-4.1.0 → flextool-4.1.1}/flextool/update_flextool/extend_tests_fixture.py +0 -0
  320. {flextool-4.1.0 → flextool-4.1.1}/flextool/update_flextool/generate_canonical.py +0 -0
  321. {flextool-4.1.0 → flextool-4.1.1}/flextool/update_flextool/initialize_database.py +0 -0
  322. {flextool-4.1.0 → flextool-4.1.1}/flextool/update_flextool/install_info.py +0 -0
  323. {flextool-4.1.0 → flextool-4.1.1}/flextool/update_flextool/self_update.py +0 -0
  324. {flextool-4.1.0 → flextool-4.1.1}/flextool/update_flextool/sync_master_json_template.py +0 -0
  325. {flextool-4.1.0 → flextool-4.1.1}/flextool/update_flextool/test_fixtures.py +0 -0
  326. {flextool-4.1.0 → flextool-4.1.1}/flextool.egg-info/dependency_links.txt +0 -0
  327. {flextool-4.1.0 → flextool-4.1.1}/flextool.egg-info/entry_points.txt +0 -0
  328. {flextool-4.1.0 → flextool-4.1.1}/flextool.egg-info/requires.txt +0 -0
  329. {flextool-4.1.0 → flextool-4.1.1}/flextool.egg-info/top_level.txt +0 -0
  330. {flextool-4.1.0 → flextool-4.1.1}/setup.cfg +0 -0
  331. {flextool-4.1.0 → flextool-4.1.1}/tests/test_bar_layout.py +0 -0
  332. {flextool-4.1.0 → flextool-4.1.1}/tests/test_bar_sub_pixel_labels.py +0 -0
  333. {flextool-4.1.0 → flextool-4.1.1}/tests/test_blocks.py +0 -0
  334. {flextool-4.1.0 → flextool-4.1.1}/tests/test_branch_weights.py +0 -0
  335. {flextool-4.1.0 → flextool-4.1.1}/tests/test_color_template.py +0 -0
  336. {flextool-4.1.0 → flextool-4.1.1}/tests/test_commodity_ladder_rolling.py +0 -0
  337. {flextool-4.1.0 → flextool-4.1.1}/tests/test_comparison_excel.py +0 -0
  338. {flextool-4.1.0 → flextool-4.1.1}/tests/test_comparison_project_root.py +0 -0
  339. {flextool-4.1.0 → flextool-4.1.1}/tests/test_complete_period_share_reduction.py +0 -0
  340. {flextool-4.1.0 → flextool-4.1.1}/tests/test_connection_node_warnings.py +0 -0
  341. {flextool-4.1.0 → flextool-4.1.1}/tests/test_console_run_tool.py +0 -0
  342. {flextool-4.1.0 → flextool-4.1.1}/tests/test_cost_aggregation_semantics.py +0 -0
  343. {flextool-4.1.0 → flextool-4.1.1}/tests/test_cost_breakdown_by_entity.py +0 -0
  344. {flextool-4.1.0 → flextool-4.1.1}/tests/test_csv_dump_roundtrip.py +0 -0
  345. {flextool-4.1.0 → flextool-4.1.1}/tests/test_dc_power_flow.py +0 -0
  346. {flextool-4.1.0 → flextool-4.1.1}/tests/test_dispatch_consumer_and_connection_signs.py +0 -0
  347. {flextool-4.1.0 → flextool-4.1.1}/tests/test_dispatch_node_debug_and_tree.py +0 -0
  348. {flextool-4.1.0 → flextool-4.1.1}/tests/test_dispatch_order_specials.py +0 -0
  349. {flextool-4.1.0 → flextool-4.1.1}/tests/test_dispatch_scenario_tag.py +0 -0
  350. {flextool-4.1.0 → flextool-4.1.1}/tests/test_ensure_settings_db.py +0 -0
  351. {flextool-4.1.0 → flextool-4.1.1}/tests/test_entity_unitsize_invariant.py +0 -0
  352. {flextool-4.1.0 → flextool-4.1.1}/tests/test_entity_universe_carrier.py +0 -0
  353. {flextool-4.1.0 → flextool-4.1.1}/tests/test_env_check.py +0 -0
  354. {flextool-4.1.0 → flextool-4.1.1}/tests/test_export_to_tabular.py +0 -0
  355. {flextool-4.1.0 → flextool-4.1.1}/tests/test_extend_tests_fixture.py +0 -0
  356. {flextool-4.1.0 → flextool-4.1.1}/tests/test_flowgroup_indicators.py +0 -0
  357. {flextool-4.1.0 → flextool-4.1.1}/tests/test_force_include.py +0 -0
  358. {flextool-4.1.0 → flextool-4.1.1}/tests/test_group_output_warnings.py +0 -0
  359. {flextool-4.1.0 → flextool-4.1.1}/tests/test_handoff_writers.py +0 -0
  360. {flextool-4.1.0 → flextool-4.1.1}/tests/test_input_entity_colors.py +0 -0
  361. {flextool-4.1.0 → flextool-4.1.1}/tests/test_lh2_three_region.py +0 -0
  362. {flextool-4.1.0 → flextool-4.1.1}/tests/test_min_load_rolling.py +0 -0
  363. {flextool-4.1.0 → flextool-4.1.1}/tests/test_non_anticipativity.py +0 -0
  364. {flextool-4.1.0 → flextool-4.1.1}/tests/test_old_flextool_importer_schema_drift.py +0 -0
  365. {flextool-4.1.0 → flextool-4.1.1}/tests/test_open_results_db.py +0 -0
  366. {flextool-4.1.0 → flextool-4.1.1}/tests/test_output_column_metadata.py +0 -0
  367. {flextool-4.1.0 → flextool-4.1.1}/tests/test_output_metadata_renderers.py +0 -0
  368. {flextool-4.1.0 → flextool-4.1.1}/tests/test_parameter_group_coverage.py +0 -0
  369. {flextool-4.1.0 → flextool-4.1.1}/tests/test_plan_union.py +0 -0
  370. {flextool-4.1.0 → flextool-4.1.1}/tests/test_plot_draw_order.py +0 -0
  371. {flextool-4.1.0 → flextool-4.1.1}/tests/test_plot_pipeline.py +0 -0
  372. {flextool-4.1.0 → flextool-4.1.1}/tests/test_plot_plan_chunk_reconstruction.py +0 -0
  373. {flextool-4.1.0 → flextool-4.1.1}/tests/test_plot_plan_time_labels_roundtrip.py +0 -0
  374. {flextool-4.1.0 → flextool-4.1.1}/tests/test_plot_settings_seed.py +0 -0
  375. {flextool-4.1.0 → flextool-4.1.1}/tests/test_precision.py +0 -0
  376. {flextool-4.1.0 → flextool-4.1.1}/tests/test_read_highs_solution.py +0 -0
  377. {flextool-4.1.0 → flextool-4.1.1}/tests/test_recourse_cost_reconciliation.py +0 -0
  378. {flextool-4.1.0 → flextool-4.1.1}/tests/test_regional_filter.py +0 -0
  379. {flextool-4.1.0 → flextool-4.1.1}/tests/test_representative_periods.py +0 -0
  380. {flextool-4.1.0 → flextool-4.1.1}/tests/test_rolling_online_carry.py +0 -0
  381. {flextool-4.1.0 → flextool-4.1.1}/tests/test_rolling_online_mintime_carry.py +0 -0
  382. {flextool-4.1.0 → flextool-4.1.1}/tests/test_rolling_online_minuptime.py +0 -0
  383. {flextool-4.1.0 → flextool-4.1.1}/tests/test_rp_alternative_name.py +0 -0
  384. {flextool-4.1.0 → flextool-4.1.1}/tests/test_rp_force_include_wiring.py +0 -0
  385. {flextool-4.1.0 → flextool-4.1.1}/tests/test_rp_solves_filter.py +0 -0
  386. {flextool-4.1.0 → flextool-4.1.1}/tests/test_scenario_colors.py +0 -0
  387. {flextool-4.1.0 → flextool-4.1.1}/tests/test_scenario_stack.py +0 -0
  388. {flextool-4.1.0 → flextool-4.1.1}/tests/test_scenarios.py +0 -0
  389. {flextool-4.1.0 → flextool-4.1.1}/tests/test_self_describing_reader.py +0 -0
  390. {flextool-4.1.0 → flextool-4.1.1}/tests/test_shared_axis_manifest.py +0 -0
  391. {flextool-4.1.0 → flextool-4.1.1}/tests/test_simple_bar_entity_color.py +0 -0
  392. {flextool-4.1.0 → flextool-4.1.1}/tests/test_solve_config.py +0 -0
  393. {flextool-4.1.0 → flextool-4.1.1}/tests/test_solve_reader.py +0 -0
  394. {flextool-4.1.0 → flextool-4.1.1}/tests/test_synthesize_invest_dual.py +0 -0
  395. {flextool-4.1.0 → flextool-4.1.1}/tests/test_timings_csv.py +0 -0
  396. {flextool-4.1.0 → flextool-4.1.1}/tests/test_unidirectional_connection.py +0 -0
  397. {flextool-4.1.0 → flextool-4.1.1}/tests/test_unit_online_dt_columns.py +0 -0
  398. {flextool-4.1.0 → flextool-4.1.1}/tests/test_v52_migration.py +0 -0
  399. {flextool-4.1.0 → flextool-4.1.1}/tests/test_v63_migration.py +0 -0
  400. {flextool-4.1.0 → flextool-4.1.1}/tests/test_v64_migration.py +0 -0
  401. {flextool-4.1.0 → flextool-4.1.1}/tests/test_v65_migration.py +0 -0
  402. {flextool-4.1.0 → flextool-4.1.1}/tests/test_v66_migration.py +0 -0
  403. {flextool-4.1.0 → flextool-4.1.1}/tests/test_v67_migration.py +0 -0
  404. {flextool-4.1.0 → flextool-4.1.1}/tests/test_v68_migration.py +0 -0
  405. {flextool-4.1.0 → flextool-4.1.1}/tests/test_v69_migration.py +0 -0
  406. {flextool-4.1.0 → flextool-4.1.1}/tests/test_v70_migration.py +0 -0
  407. {flextool-4.1.0 → flextool-4.1.1}/tests/test_workdir_empty_default.py +0 -0
  408. {flextool-4.1.0 → flextool-4.1.1}/tests/test_xlsx_workflow.py +0 -0
  409. {flextool-4.1.0 → flextool-4.1.1}/tests/test_years_represented.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flextool
3
- Version: 4.1.0
3
+ Version: 4.1.1
4
4
  Summary: IRENA FlexTool is an energy and power systems model for understanding the role of variable power generation in future energy systems.
5
5
  Author: IRENA FlexTool contributors
6
6
  License: © International Renewable Energy Agency 2018-2022
@@ -0,0 +1,16 @@
1
+ """Shared numeric constants for the polars engine.
2
+
3
+ FlexTool timelines use arbitrary indices (not datetime), so "a year" has
4
+ no calendar definition the engine can read off the timestamps.
5
+ ``HOURS_PER_YEAR`` is the single canonical hours->years unit used for
6
+ *every* period-share / annualisation conversion in the engine
7
+ (``period_share_of_year``, ``timeline_duration_in_years``, the
8
+ ``scale_to_annual_flow`` denominator, peak annualisation, ...). Keeping
9
+ it in one place means the serve/report/cost annualisations stay mutually
10
+ consistent, and a future per-period override only has to replace one
11
+ symbol rather than ~two dozen scattered literals.
12
+ """
13
+ from __future__ import annotations
14
+
15
+ # Hours in a reference year (365 * 24). See module docstring.
16
+ HOURS_PER_YEAR = 8760.0
@@ -54,6 +54,7 @@ from ._axis_enums import (
54
54
  rename_to_axis,
55
55
  schema_dtype,
56
56
  )
57
+ from ._constants import HOURS_PER_YEAR
57
58
  from ._emit_provider_io import _provider_key
58
59
  from ._solve_state import CommissioningLagError, LineageFilterError
59
60
  from ._param_shapes import (
@@ -826,7 +827,7 @@ def p_period_share_from_source(
826
827
  sd = step_dur.frame
827
828
  out = (sd.lazy()
828
829
  .group_by("d")
829
- .agg((pl.col("value").cast(pl.Float64).sum() / 8760.0)
830
+ .agg((pl.col("value").cast(pl.Float64).sum() / HOURS_PER_YEAR)
830
831
  .alias("value"))
831
832
  .sort("d")
832
833
  .collect())
@@ -10228,7 +10229,7 @@ def p_f_d_k_from_source(
10228
10229
  out_lf = (out_lf
10229
10230
  .with_columns(pl.col("sum_step").fill_null(0.0))
10230
10231
  .with_columns(value=(pl.col("cum") + pl.col("sum_step"))
10231
- / (pl.col("share") * 8760.0))
10232
+ / (pl.col("share") * HOURS_PER_YEAR))
10232
10233
  .select("d", "value"))
10233
10234
  out = out_lf.collect()
10234
10235
  if out.height == 0:
@@ -56,6 +56,7 @@ from pathlib import Path
56
56
 
57
57
  import polars as pl
58
58
 
59
+ from flextool.engine_polars._constants import HOURS_PER_YEAR
59
60
  from flextool.engine_polars._emit_provider_io import (
60
61
  _emit,
61
62
  _provider_key,
@@ -289,6 +290,14 @@ def _compute_inflow_scaling_frames(
289
290
  solve_data_dir / "p_timeline_duration_in_years.csv",
290
291
  provider=provider,
291
292
  )
293
+ # Full-timeline annualised inflow energy per node — the
294
+ # timeset-independent ``scale_to_annual_flow`` denominator. Emitted
295
+ # by ``create_averaged_timeseries`` only for coarsened
296
+ # (``new_stepduration``) solves; absent → legacy per-solve formula.
297
+ ftf = _read_keyed_float(
298
+ solve_data_dir / "node_full_timeline_flow.csv",
299
+ provider=provider,
300
+ )
292
301
 
293
302
  # Representative weight w[(d, t)] = p_timestep_weight[d, t] (the param
294
303
  # the cost objective already uses). Sourced from the per-solve
@@ -420,12 +429,20 @@ def _compute_inflow_scaling_frames(
420
429
  # ── period_flow_annual_multiplier ─────────────────────────────────
421
430
  # value = complete_period_share_of_year[d] / period_share_of_annual_flow[n, d].
422
431
  # Domain: (n, d) where scale_to_annual_flow AND pdNode annual_flow.
432
+ # When a full-timeline energy exists for the node (coarsened solve),
433
+ # use the timeset-independent denominator
434
+ # value = annual_flow[n, d] / abs(full_timeline_flow[n]) instead.
423
435
  rows_pfam: list[tuple[str, str, float]] = []
424
436
  for n in nodes:
425
437
  if not _has_method(n, "scale_to_annual_flow"):
426
438
  continue
439
+ ft = ftf.get(n, 0.0)
427
440
  for d in period_in_use:
428
- if pdNode.get((n, "annual_flow", d), 0.0) == 0.0:
441
+ af = pdNode.get((n, "annual_flow", d), 0.0)
442
+ if af == 0.0:
443
+ continue
444
+ if ft != 0.0:
445
+ rows_pfam.append((n, d, af / abs(ft)))
429
446
  continue
430
447
  denom = psaf.get((n, d), 0.0)
431
448
  if denom == 0.0:
@@ -549,7 +566,7 @@ def _compute_inflow_scaling_frames(
549
566
  # ── new_peak_inflow_sum, new_old_multiplier/slope/section ─────────
550
567
  # Same domain as rows_nps; values derived from peak / npop / npopis.
551
568
  npis_dict = {
552
- (n, d): pdNode.get((n, "peak_inflow", d), 0.0) * 8760.0
569
+ (n, d): pdNode.get((n, "peak_inflow", d), 0.0) * HOURS_PER_YEAR
553
570
  for n, d, _ in rows_nps
554
571
  }
555
572
  rows_npis = [(n, d, npis_dict.get((n, d), 0.0)) for n, d, _ in rows_nps]
@@ -696,6 +713,13 @@ def _compute_inflow_scaling_frames_vectorized(
696
713
  solve_data_dir / "p_timeline_duration_in_years.csv",
697
714
  provider=provider,
698
715
  )
716
+ # Full-timeline annualised inflow energy per node — the
717
+ # timeset-independent ``scale_to_annual_flow`` denominator (see the
718
+ # legacy oracle for the full rationale). Absent → legacy formula.
719
+ ftf = _read_keyed_float(
720
+ solve_data_dir / "node_full_timeline_flow.csv",
721
+ provider=provider,
722
+ )
699
723
 
700
724
  # Representative weight w[(d, t)] = p_timestep_weight[d, t] (see the
701
725
  # legacy reader block for the full rationale). DEFAULT 1.0 for any
@@ -1032,19 +1056,33 @@ def _compute_inflow_scaling_frames_vectorized(
1032
1056
  {"period": list(cpsoy.keys()), "v_cpsoy": list(cpsoy.values())},
1033
1057
  schema={"period": pl.Utf8, "v_cpsoy": pl.Float64},
1034
1058
  )
1059
+ # Full-timeline energy lookup: when present (coarsened solve) its
1060
+ # branch overrides the legacy cpsoy/psaf denominator with the
1061
+ # timeset-independent ``af / abs(full_timeline_flow)``.
1062
+ ftf_lk = pl.DataFrame(
1063
+ {"node": list(ftf.keys()), "v_ftf": list(ftf.values())},
1064
+ schema={"node": pl.Utf8, "v_ftf": pl.Float64},
1065
+ )
1035
1066
  pfam_df = (
1036
1067
  annual_flow_only_eo
1037
1068
  .join(period_po, how="cross")
1038
1069
  # (a) af==0/miss → DROP.
1039
1070
  .join(af_lk, on=["node", "period"], how="left")
1040
1071
  .filter(pl.col("v_af").fill_null(0.0) != 0.0)
1041
- # (b) psaf miss OR exact-0 → DROP.
1042
1072
  .join(psaf_lk, on=["node", "period"], how="left")
1043
- .filter(pl.col("v_psaf").fill_null(0.0) != 0.0)
1044
1073
  # (c) cpsoy numerator → survive-with-0.
1045
1074
  .join(cpsoy_lk, on="period", how="left")
1075
+ .join(ftf_lk, on="node", how="left")
1076
+ # (b) Full-timeline branch (v_ftf != 0) survives regardless of
1077
+ # psaf; legacy branch keeps the psaf miss-OR-exact-0 → DROP gate.
1078
+ .filter(
1079
+ (pl.col("v_ftf").fill_null(0.0) != 0.0)
1080
+ | (pl.col("v_psaf").fill_null(0.0) != 0.0))
1046
1081
  .with_columns(
1047
- (pl.col("v_cpsoy").fill_null(0.0) / pl.col("v_psaf"))
1082
+ pl.when(pl.col("v_ftf").fill_null(0.0) != 0.0)
1083
+ .then(pl.col("v_af") / pl.col("v_ftf").abs())
1084
+ .otherwise(
1085
+ pl.col("v_cpsoy").fill_null(0.0) / pl.col("v_psaf"))
1048
1086
  .alias("value_f"),
1049
1087
  )
1050
1088
  )
@@ -1169,7 +1207,7 @@ def _compute_inflow_scaling_frames_vectorized(
1169
1207
  )
1170
1208
  .with_columns(
1171
1209
  # npis = peak * 8760.0 (constraint 3).
1172
- (pl.col("v_peak") * 8760.0).alias("v_npis"),
1210
+ (pl.col("v_peak") * HOURS_PER_YEAR).alias("v_npis"),
1173
1211
  # npop = 0.0 if old_peak == 0.0 else peak / old_peak. FILL,
1174
1212
  # not drop (constraint 1); exact ``== 0.0`` guard (constraint 4).
1175
1213
  pl.when(pl.col("old_peak") == 0.0)
@@ -45,6 +45,7 @@ from pathlib import Path
45
45
 
46
46
  import polars as pl
47
47
 
48
+ from flextool.engine_polars._constants import HOURS_PER_YEAR
48
49
  from flextool.engine_polars._emit_provider_io import _emit
49
50
 
50
51
 
@@ -241,7 +242,8 @@ def emit_period_calculated_params(
241
242
  for (d2, _t), v in complete_step_duration.items():
242
243
  sum_complete_by_d2[d2] = sum_complete_by_d2.get(d2, 0.0) + v
243
244
 
244
- p_tdy = [(tl, sum_timeline_dur.get(tl, 0.0) / 8760.0) for tl in timelines]
245
+ p_tdy = [(tl, sum_timeline_dur.get(tl, 0.0) / HOURS_PER_YEAR)
246
+ for tl in timelines]
245
247
  _emit_keyed(provider, "solve_data/p_timeline_duration_in_years.csv",
246
248
  ("timeline", "value"), p_tdy)
247
249
 
@@ -251,7 +253,7 @@ def emit_period_calculated_params(
251
253
  _emit_keyed(provider, "solve_data/hours_in_period.csv",
252
254
  ("period", "value"), hours_in_period)
253
255
 
254
- period_share = [(d, h / 8760.0) for d, h in hours_in_period]
256
+ period_share = [(d, h / HOURS_PER_YEAR) for d, h in hours_in_period]
255
257
  _emit_keyed(provider, "solve_data/period_share_of_year.csv",
256
258
  ("period", "value"), period_share)
257
259
 
@@ -274,7 +276,7 @@ def emit_period_calculated_params(
274
276
  _emit_keyed(provider, "solve_data/complete_hours_in_period.csv",
275
277
  ("period", "value"), complete_hours)
276
278
 
277
- complete_share = [(d, h / 8760.0) for d, h in complete_hours]
279
+ complete_share = [(d, h / HOURS_PER_YEAR) for d, h in complete_hours]
278
280
  _emit_keyed(provider, "solve_data/complete_period_share_of_year_calc.csv",
279
281
  ("period", "value"), complete_share)
280
282
 
@@ -399,7 +401,7 @@ def emit_period_calculated_params(
399
401
  f_d_k_rows: list[tuple[str, float]] = []
400
402
  for d in period_in_use:
401
403
  num = p_ladder_cum.get(d, 0.0) + sum_step_dur_by_period.get(d, 0.0)
402
- denom = complete_share_lookup.get(d, 0.0) * 8760.0
404
+ denom = complete_share_lookup.get(d, 0.0) * HOURS_PER_YEAR
403
405
  f_d_k_rows.append((d, num / denom))
404
406
  _emit_keyed(provider, "solve_data/f_d_k.csv",
405
407
  ("period", "value"), f_d_k_rows)
@@ -991,8 +991,10 @@ def native_run_model(state, solver) -> int:
991
991
  # sub-solve Provider too — this iter's readers must find
992
992
  # them without waiting for the next seed pass.
993
993
  for _key, _frame in cascade_input_provider.items():
994
- if _key.startswith("solve_data/pt_") or _key.startswith(
995
- "solve_data/pbt_",
994
+ if (
995
+ _key.startswith("solve_data/pt_")
996
+ or _key.startswith("solve_data/pbt_")
997
+ or _key.endswith("node_full_timeline_flow")
996
998
  ):
997
999
  sub_solve_provider.put(_key, _frame)
998
1000
  previous_complete_solve = complete_solve[solve]
@@ -49,6 +49,7 @@ from typing import TYPE_CHECKING
49
49
  import polars as pl
50
50
 
51
51
  from ._axis_enums import alias_to_axis
52
+ from ._constants import HOURS_PER_YEAR
52
53
 
53
54
  if TYPE_CHECKING:
54
55
  from flextool.engine_polars._input_source import InputSource
@@ -304,7 +305,7 @@ def derive_per_solve_aggregates(
304
305
  # ── p_timeline_duration_in_years[timeline] ───────────────────────
305
306
  # = sum_t step_duration[timeline, t] / 8760
306
307
  p_tdy = (tl_lf.group_by("timeline")
307
- .agg((pl.col("step_duration").sum() / 8760.0)
308
+ .agg((pl.col("step_duration").sum() / HOURS_PER_YEAR)
308
309
  .alias("value"))
309
310
  .sort("timeline")
310
311
  .collect())
@@ -321,7 +322,8 @@ def derive_per_solve_aggregates(
321
322
  # PerSolveAggregates dataclass already exposes the per-(d, d) frame
322
323
  # which downstream branch-aware helpers can fold themselves.
323
324
  cpsoy = (expanded_lf
324
- .group_by("d").agg((pl.col("step_duration").sum() / 8760.0)
325
+ .group_by("d").agg((pl.col("step_duration").sum()
326
+ / HOURS_PER_YEAR)
325
327
  .alias("value"))
326
328
  .sort("d")
327
329
  .collect())
@@ -50,6 +50,7 @@ from typing import TYPE_CHECKING, Any
50
50
  import polars as pl
51
51
  import spinedb_api as api
52
52
 
53
+ from flextool.engine_polars._constants import HOURS_PER_YEAR
53
54
  from flextool.engine_polars._solve_config import (
54
55
  DictMode,
55
56
  get_single_entities,
@@ -828,6 +829,76 @@ class TimelineConfig:
828
829
  _build_frame_with_headers(headers, out_rows),
829
830
  )
830
831
 
832
+ # ── Full-timeline inflow energy (timeset-independent scaling) ──
833
+ # ``scale_to_annual_flow`` normalises each node's inflow to its
834
+ # ``annual_flow`` using the ORIGINAL unmodified timeline
835
+ # (pre-``new_stepduration``). A shared timeset makes
836
+ # ``create_timeline_from_timestep_duration`` accumulate every
837
+ # solve's periods into a single coarsened timeline; summing over
838
+ # that leaks later solves' inflow into this solve's scaling.
839
+ # Instead sum the raw inflow over the WHOLE original timeline and
840
+ # annualise it with its ``timeline_duration_in_years`` (= total
841
+ # hours / HOURS_PER_YEAR), exactly as the sibling
842
+ # ``scale_in_proportion`` method annualises. No "find one year"
843
+ # windowing is needed: a sub-year timeline scales up (duration <
844
+ # 1), a multi-year timeline averages over its years (duration >
845
+ # 1), and a one-year timeline is unchanged (duration == 1).
846
+ new_tl = timelines_list[0] if timelines_list else None
847
+ # Walk back to the truly unmodified (pre-coarsening) timeline.
848
+ base_tl = new_tl
849
+ seen_tl: set[str] = set()
850
+ while base_tl in self.original_timeline and base_tl not in seen_tl:
851
+ seen_tl.add(base_tl)
852
+ base_tl = self.original_timeline[base_tl]
853
+ base_steps = self.timelines.get(base_tl, [])
854
+ all_step_names: set[str] = {step[0] for step in base_steps}
855
+ total_hours = sum(float(step[1]) for step in base_steps)
856
+ duration_in_years = total_hours / HOURS_PER_YEAR
857
+ if duration_in_years:
858
+ inflow_path = wf / "input" / "pt_node_inflow.csv"
859
+ inflow_frame = _provider_get_or_read(
860
+ provider, _provider_key(inflow_path), inflow_path,
861
+ )
862
+ ts_sum: dict[str, float] = {}
863
+ if inflow_frame is not None and inflow_frame.height > 0:
864
+ cols = inflow_frame.columns
865
+ grouped = (
866
+ inflow_frame
867
+ .filter(pl.col(cols[1]).is_in(all_step_names))
868
+ .select(
869
+ pl.col(cols[0]).alias("node"),
870
+ pl.col(cols[-1]).cast(pl.Float64, strict=False)
871
+ .alias("v"),
872
+ )
873
+ .group_by("node")
874
+ .agg(pl.col("v").sum().alias("v"))
875
+ )
876
+ for n_name, v in grouped.iter_rows():
877
+ if n_name:
878
+ ts_sum[str(n_name)] = (
879
+ float(v) if v is not None else 0.0
880
+ )
881
+ const_for_node: dict[str, float] = {}
882
+ for node__value in node__inflow:
883
+ try:
884
+ const_for_node[node__value[0]] = float(node__value[1])
885
+ except (ValueError, TypeError):
886
+ continue
887
+ flow_rows: list[list] = []
888
+ for n_name in dict.fromkeys(
889
+ list(ts_sum) + list(const_for_node)
890
+ ):
891
+ energy = (
892
+ ts_sum.get(n_name, 0.0)
893
+ + const_for_node.get(n_name, 0.0) * total_hours
894
+ )
895
+ flow_rows.append([n_name, energy / duration_in_years])
896
+ flow_path = wf / "solve_data" / "node_full_timeline_flow.csv"
897
+ provider.put(
898
+ _provider_key(flow_path),
899
+ _build_frame_with_headers(["node", "value"], flow_rows),
900
+ )
901
+
831
902
 
832
903
  # ---------------------------------------------------------------------------
833
904
  # Helpers (private)
@@ -108,21 +108,31 @@ def node_summary(par, s, v, r, debug):
108
108
  & node_dt.columns.get_level_values('category').isin(['Excess load'])]
109
109
  node_dt[downward_slack_cols] = downward_slack_data[downward_slack_cols.get_level_values('node')]
110
110
 
111
- # Inflow
111
+ # Inflow — par.node_inflow is energy per step (MWh/step). Divide it by
112
+ # step_duration in place so the Inflow column becomes a MW rate like every
113
+ # other node__dt category (identity at step_duration == 1). Dividing
114
+ # node_dt's own inflow columns reuses the exact (period, time) index the
115
+ # flow path already aligns against, so a stray/misaligned row cannot turn
116
+ # into NaN and get silently zeroed by the fillna(0.0) below.
112
117
  inflow_cols = node_dt.columns[
113
118
  node_dt.columns.get_level_values('node').isin(par.node_inflow.columns.intersection(nodes))
114
119
  & node_dt.columns.get_level_values('category').isin(['Inflow'])]
115
120
  node_dt[inflow_cols] = par.node_inflow[inflow_cols.get_level_values('node')]
121
+ node_dt[inflow_cols] = node_dt[inflow_cols].div(par.step_duration, axis=0)
116
122
 
117
123
  # Fill any remaining NaN values with 0
118
124
  node_dt = node_dt.fillna(0.0)
119
125
 
120
126
  results.append((node_dt, 'node_dt_ep'))
121
127
 
122
- # 2. Period-level node summary. Most categories (flows, slacks, self
123
- # discharge) are MW — multiply by step_duration to get MWh per step.
124
- # Inflow is already MWh/step (par.node_inflow is energy per step, see
125
- # mod comment at flextool.mod:2319), so compute it separately.
128
+ # 2. Period-level node summary. Every node__dt category is now a MW rate
129
+ # (Inflow was divided by step_duration at the inflow block above), so the
130
+ # table is internally consistent and each (d, t) row balances. The period
131
+ # path therefore multiplies all categories — inflow included — by
132
+ # step_duration uniformly to get MWh per step. (Algebra: the pre-fix
133
+ # inflow period sum was Σ_t inflow_MWh_step·weight / share; after the fix
134
+ # it is Σ_t (inflow_MWh_step / sd)·sd·weight / share — identical, so
135
+ # node__d is unchanged.)
126
136
  energy_categories = [c for c in categories if c != 'Inflow']
127
137
  energy_cols = node_dt.columns[node_dt.columns.get_level_values('category').isin(energy_categories)]
128
138
  inflow_cols = node_dt.columns[node_dt.columns.get_level_values('category') == 'Inflow']
@@ -135,7 +145,7 @@ def node_summary(par, s, v, r, debug):
135
145
  par.complete_period_share_of_year, par.step_duration, div_level=1)
136
146
  node_d_inflow = annualize_dt_to_d(
137
147
  node_dt[inflow_cols], par.timestep_weight,
138
- par.complete_period_share_of_year, div_level=1)
148
+ par.complete_period_share_of_year, par.step_duration, div_level=1)
139
149
  node_d = pd.concat([node_d_energy, node_d_inflow], axis=1).reindex(columns=node_dt.columns)
140
150
 
141
151
  results.append((node_d, 'node_d_ep'))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flextool
3
- Version: 4.1.0
3
+ Version: 4.1.1
4
4
  Summary: IRENA FlexTool is an energy and power systems model for understanding the role of variable power generation in future energy systems.
5
5
  Author: IRENA FlexTool contributors
6
6
  License: © International Renewable Energy Agency 2018-2022
@@ -53,6 +53,7 @@ flextool/engine_polars/_benders.py
53
53
  flextool/engine_polars/_block_layout.py
54
54
  flextool/engine_polars/_blocks.py
55
55
  flextool/engine_polars/_commodity_ladder.py
56
+ flextool/engine_polars/_constants.py
56
57
  flextool/engine_polars/_cumulative_invest.py
57
58
  flextool/engine_polars/_db_loader.py
58
59
  flextool/engine_polars/_db_reader.py
@@ -3,7 +3,7 @@ build-backend = "setuptools.build_meta"
3
3
 
4
4
  [project]
5
5
  name = "flextool"
6
- version = "4.1.0"
6
+ version = "4.1.1"
7
7
  description = "IRENA FlexTool is an energy and power systems model for understanding the role of variable power generation in future energy systems."
8
8
  readme = "README.md"
9
9
  license = { file = "LICENSE.txt" }
File without changes
File without changes
File without changes