flextool 4.0.4__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.
- {flextool-4.0.4 → flextool-4.1.1}/PKG-INFO +6 -6
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/cmd_open_results_db.py +4 -9
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_axis_enums.py +3 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_benders.py +16 -0
- flextool-4.1.1/flextool/engine_polars/_constants.py +16 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_cumulative_invest.py +75 -20
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_delay.py +118 -8
- flextool-4.1.1/flextool/engine_polars/_derived_branch.py +1804 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_derived_existing.py +342 -11
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_derived_npv.py +120 -23
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_derived_params.py +1214 -154
- flextool-4.1.1/flextool/engine_polars/_derived_walks.py +487 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_direct_params.py +132 -65
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_dump_csvs.py +10 -3
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_arc_unions.py +67 -31
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_chain_params.py +28 -2
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_inflow_scaling.py +44 -6
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_mid_sets.py +6 -3
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_per_solve.py +71 -8
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_period_calc.py +30 -4
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_solve_time.py +14 -1
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_solve_writers.py +16 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_flex_data_accumulator.py +1 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_inmemory_reader.py +37 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_input_source.py +22 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_native_run_model.py +197 -6
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_orchestration.py +340 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_output_writer.py +5 -2
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_param_shapes.py +225 -14
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_pdt_join.py +25 -6
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_per_solve_sets.py +4 -2
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_projection_params.py +5 -4
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_provider_keys.py +8 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_provider_translators.py +35 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_recursive_solve.py +74 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_region_filter.py +6 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_reserve.py +437 -13
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_solve_config.py +309 -6
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_solve_handoff.py +54 -1
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_solve_state.py +41 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_solver_dispatch.py +52 -2
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_spinedb_reader.py +531 -21
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_stochastic.py +240 -32
- flextool-4.1.1/flextool/engine_polars/_stochastic_detect.py +85 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_timeline.py +142 -15
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_warm.py +26 -4
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/autoscale/_layer2.py +26 -9
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/autoscale/_layer2_types.py +57 -1
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/autoscale/_quantity_types.py +30 -4
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/input.py +678 -14
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/model.py +1933 -394
- {flextool-4.0.4 → flextool-4.1.1}/flextool/export_to_tabular/export_settings.yaml +9 -2
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/db_editor_integration.py +30 -17
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/main_window.py +14 -11
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/platform_utils.py +40 -12
- {flextool-4.0.4 → flextool-4.1.1}/flextool/input_derivation/__init__.py +8 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/input_derivation/_process_method.py +4 -1
- {flextool-4.0.4 → flextool-4.1.1}/flextool/input_derivation/_specs.py +10 -8
- {flextool-4.0.4 → flextool-4.1.1}/flextool/input_derivation/_validators.py +259 -0
- flextool-4.1.1/flextool/process_outputs/_branch_weight.py +48 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/calc_costs.py +50 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/calc_slacks.py +27 -3
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/drop_levels.py +7 -1
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/out_node.py +16 -6
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/read_highs_solution.py +82 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/read_parameters.py +38 -4
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_aggregate_output.json +235 -28
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_connections.json +235 -28
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_demand.json +235 -28
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_hydro_reservoir.json +235 -28
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_hydro_reservoir_with_pump.json +242 -48
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_non_sync_and_curtailment.json +235 -28
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_ramp_and_start_up.json +235 -28
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/canonical_databases/howto_stochastics.json +236 -29
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/canonical_databases/templates_examples.json +242 -35
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/canonical_databases/templates_time_settings_only.json +235 -28
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/flextool_axis_contract.json +1 -2
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/spinedb_schema.json +213 -33
- {flextool-4.0.4 → flextool-4.1.1}/flextool/solver_config/highs.opt.template +0 -3
- {flextool-4.0.4 → flextool-4.1.1}/flextool/update_flextool/__init__.py +1 -1
- {flextool-4.0.4 → flextool-4.1.1}/flextool/update_flextool/db_migration.py +813 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool.egg-info/PKG-INFO +6 -6
- {flextool-4.0.4 → flextool-4.1.1}/flextool.egg-info/SOURCES.txt +8 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool.egg-info/requires.txt +5 -5
- {flextool-4.0.4 → flextool-4.1.1}/pyproject.toml +26 -11
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_branch_weights.py +64 -37
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_cost_aggregation_semantics.py +59 -47
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_handoff_writers.py +19 -6
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_min_load_rolling.py +19 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_non_anticipativity.py +46 -38
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_parameter_group_coverage.py +6 -13
- flextool-4.1.1/tests/test_recourse_cost_reconciliation.py +111 -0
- flextool-4.1.1/tests/test_rolling_online_carry.py +247 -0
- flextool-4.1.1/tests/test_rolling_online_mintime_carry.py +353 -0
- flextool-4.1.1/tests/test_rolling_online_minuptime.py +204 -0
- flextool-4.1.1/tests/test_v70_migration.py +392 -0
- flextool-4.0.4/flextool/engine_polars/_derived_branch.py +0 -769
- flextool-4.0.4/flextool/engine_polars/_derived_walks.py +0 -276
- {flextool-4.0.4 → flextool-4.1.1}/LICENSE.txt +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/README.md +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/_mem_sampler.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/_resources.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/calibrate/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/calibrate/__main__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/calibrate/_cli.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/calibrate/_db_alt.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/calibrate/_final_outputs.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/calibrate/_guard.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/calibrate/_loop.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/calibrate/_readers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/calibrate/_report.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/calibrate/_sizing.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/calibrate/_solve.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/calibrate/_solve_status.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/_console.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/_timing.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/cmd_execute_flextool_workflow.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/cmd_export_to_tabular.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/cmd_import_sensitivities.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/cmd_migrate_database.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/cmd_read_matpower.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/cmd_read_old_flextool.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/cmd_read_self_describing_tabular_input.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/cmd_read_tabular_input.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/cmd_run_flextool.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/cmd_scenario_results.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/cmd_solve_mps.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/cmd_update_flextool.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/cli/cmd_write_outputs.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/common_utils/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/common_utils/plot_mem_shape.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/common_utils/precision.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/decomposition/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/decomposition/region_decomposition.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/decomposition/region_filter.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_block_layout.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_blocks.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_commodity_ladder.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_db_loader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_db_reader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_dc_power_flow.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_derived_arithmetic.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_derived_block.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_derived_profile.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_determinism.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_calc_params.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_co2_accumulators.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_dispatchers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_energy_margin.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_energy_margin_adder.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_entity_annual.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_leaf_sets.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_lp_scaling.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_pdt_params.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_period_params.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_provider_io.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_emit_reserve.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_flex_data_provider.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_group_slack.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_invest_seeds.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_native_input_writer.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_parquet_bundle.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_pdt_lookup.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_solve_acceptance.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_solve_context.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_solver_base.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_subprocess_solve.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/_vectorize.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/autoscale/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/autoscale/_config.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/autoscale/_report.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/engine_polars/chain.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/env_check.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/export_to_tabular/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/export_to_tabular/db_reader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/export_to_tabular/excel_writer.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/export_to_tabular/export_to_excel.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/export_to_tabular/formatting.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/export_to_tabular/sheet_config.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/__main__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/calibrate_commands.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/calibrate_jobs.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/check_tree.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/cli_format.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/config_parser.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/data_models.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/db_version_check.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/dialogs/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/dialogs/add_dialog.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/dialogs/calibrate_dialog.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/dialogs/file_picker.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/dialogs/group_picker.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/dialogs/migration_consent_dialog.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/dialogs/migration_progress_dialog.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/dialogs/plot_dialog.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/dialogs/plot_settings_picker.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/dialogs/project_dialog.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/dialogs/update_dialog.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/downsampling.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/error_handling.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/execution_manager.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/execution_window.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/hover_tooltip.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/input_sources.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/network_graph.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/output_actions.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/output_log_window.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/plot_cache.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/plot_canvas.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/plot_config_reader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/project_utils.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/result_viewer.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/scenario_key.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/scenario_lists.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/settings_io.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/solve_reader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/tree_reorder.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/gui/ui_metrics.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/input_derivation/_commodity_ladder.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/input_derivation/_commodity_ladder_sets.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/input_derivation/_dc_power_flow.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/input_derivation/_method_constants.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/lean_parquet.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/model_builder/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/model_builder/build_model.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/model_builder/encoding.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/model_builder/names.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/model_builder/profiles.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/plot_outputs/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/plot_outputs/axis_helpers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/plot_outputs/color_template.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/plot_outputs/config.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/plot_outputs/format_helpers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/plot_outputs/legend_helpers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/plot_outputs/orchestrator.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/plot_outputs/perf.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/plot_outputs/plan.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/plot_outputs/plot_bars.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/plot_outputs/plot_bars_detail.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/plot_outputs/plot_lines.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/plot_outputs/shared_manifest.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/plot_outputs/subplot_helpers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_inputs/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_inputs/import_old_excel_input.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_inputs/read_matpower.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_inputs/read_old_flextool.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_inputs/read_self_describing_excel.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_inputs/read_tabular_with_specification.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_inputs/write_old_flextool_to_db.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_inputs/write_self_describing_to_db.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_inputs/write_to_input_db.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/_annualize.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/_inmemory_helpers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/_output_meta.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/calc_capacity_flows.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/calc_connections.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/calc_group_flows.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/calc_storage_vre.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/handoff_writers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/out_ancillary.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/out_capacity.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/out_costs.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/out_flowgroup.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/out_flows.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/out_group.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/persist_realized_slice.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/process_results.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/read_sets.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/read_variables.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/solve_order.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/spinedb_replay.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/union_realized_slice.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/write_outputs.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/process_outputs/write_spinedb.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/representative_periods/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/representative_periods/clustering.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/representative_periods/force_include.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/representative_periods/netload.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/representative_periods/netload_inputs.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/representative_periods/netload_iterate.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/representative_periods/preprocess.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/representative_periods/scenario_stack.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/representative_periods/weights.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/scenario_comparison/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/scenario_comparison/config_builder.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/scenario_comparison/constants.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/scenario_comparison/data_models.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/scenario_comparison/db_reader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/scenario_comparison/dispatch_data.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/scenario_comparison/dispatch_mappings.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/scenario_comparison/dispatch_plots.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/scenario_comparison/input_entity_colors.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/scenario_comparison/orchestrator.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/scenario_comparison/plan_union.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/scenario_comparison/plot_settings_seed.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/AXIS_CONTRACT.md +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/comparison_settings_template.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/default_plot_settings.yaml +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/default_plots.yaml +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/flextool_axis_contract.schema.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/old_flextool_import_template.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/output_info_template.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/output_settings_template.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_constant_default.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_default_optional_output.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_default_value.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_drop_down.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_lifetime_method.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_optional_outputs.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_output_node_flows.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_results_master.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_rolling_start_remove.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_rolling_window.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_storage_binding_defaults.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_v2.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/pre_v26/flextool_template_v25.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/schemas/spinedb_results_schema.json +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/solver_config/copt.opt.template +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/solver_config/cplex.opt.template +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/solver_config/gurobi.opt.template +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/solver_config/xpress.opt.template +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/spinedb_backend/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/spinedb_backend/_axis_enums.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/spinedb_backend/_backend.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/update_flextool/canonical_databases.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/update_flextool/ensure_settings_db.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/update_flextool/export_database.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/update_flextool/extend_tests_fixture.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/update_flextool/generate_canonical.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/update_flextool/initialize_database.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/update_flextool/install_info.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/update_flextool/self_update.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/update_flextool/sync_master_json_template.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool/update_flextool/test_fixtures.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool.egg-info/dependency_links.txt +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool.egg-info/entry_points.txt +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/flextool.egg-info/top_level.txt +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/setup.cfg +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_bar_layout.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_bar_sub_pixel_labels.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_blocks.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_color_template.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_commodity_ladder_rolling.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_comparison_excel.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_comparison_project_root.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_complete_period_share_reduction.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_connection_node_warnings.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_console_run_tool.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_cost_breakdown_by_entity.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_csv_dump_roundtrip.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_dc_power_flow.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_dispatch_consumer_and_connection_signs.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_dispatch_node_debug_and_tree.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_dispatch_order_specials.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_dispatch_scenario_tag.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_ensure_settings_db.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_entity_unitsize_invariant.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_entity_universe_carrier.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_env_check.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_export_to_tabular.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_extend_tests_fixture.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_flowgroup_indicators.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_force_include.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_group_output_warnings.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_input_entity_colors.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_lh2_three_region.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_old_flextool_importer_schema_drift.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_open_results_db.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_output_column_metadata.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_output_metadata_renderers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_plan_union.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_plot_draw_order.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_plot_pipeline.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_plot_plan_chunk_reconstruction.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_plot_plan_time_labels_roundtrip.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_plot_settings_seed.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_precision.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_read_highs_solution.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_regional_filter.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_representative_periods.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_rp_alternative_name.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_rp_force_include_wiring.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_rp_solves_filter.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_scenario_colors.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_scenario_stack.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_scenarios.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_self_describing_reader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_shared_axis_manifest.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_simple_bar_entity_color.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_solve_config.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_solve_reader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_synthesize_invest_dual.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_timings_csv.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_unidirectional_connection.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_unit_online_dt_columns.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_v52_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_v63_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_v64_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_v65_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_v66_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_v67_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_v68_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_v69_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_workdir_empty_default.py +0 -0
- {flextool-4.0.4 → flextool-4.1.1}/tests/test_xlsx_workflow.py +0 -0
- {flextool-4.0.4 → 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.
|
|
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
|
|
@@ -38,11 +38,11 @@ Classifier: Topic :: Scientific/Engineering
|
|
|
38
38
|
Requires-Python: >=3.11
|
|
39
39
|
Description-Content-Type: text/markdown
|
|
40
40
|
License-File: LICENSE.txt
|
|
41
|
-
Requires-Dist: polar-high>=3.
|
|
42
|
-
Requires-Dist: highspy
|
|
43
|
-
Requires-Dist: polars
|
|
44
|
-
Requires-Dist: pandas
|
|
45
|
-
Requires-Dist: spinedb-api
|
|
41
|
+
Requires-Dist: polar-high>=3.8.0
|
|
42
|
+
Requires-Dist: highspy<1.15,>=1.14.0
|
|
43
|
+
Requires-Dist: polars<3,>=1.40
|
|
44
|
+
Requires-Dist: pandas<4,>=2.2.3
|
|
45
|
+
Requires-Dist: spinedb-api<0.37,>=0.36.5
|
|
46
46
|
Requires-Dist: openpyxl
|
|
47
47
|
Requires-Dist: odfpy
|
|
48
48
|
Requires-Dist: python-calamine
|
|
@@ -33,6 +33,7 @@ from pathlib import Path
|
|
|
33
33
|
|
|
34
34
|
from flextool.cli._console import run_tool
|
|
35
35
|
from flextool.cli.cmd_run_flextool import resolve_output_path
|
|
36
|
+
from flextool.gui.platform_utils import spine_db_editor_argv
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
def resolve_results_db_path(project_folder_file, output_location=None):
|
|
@@ -100,16 +101,10 @@ def _build_launch_argv(db_urls):
|
|
|
100
101
|
``db_urls`` may be a single URL string or a list of URLs (each becomes a
|
|
101
102
|
tab). The supported standalone entry point is
|
|
102
103
|
``spinetoolbox.spine_db_editor.main:main``, whose ``main()`` reads
|
|
103
|
-
positional ``url`` args.
|
|
104
|
+
positional ``url`` args. Shared with the GUI launchers
|
|
105
|
+
(:func:`flextool.gui.platform_utils.spine_db_editor_argv`).
|
|
104
106
|
"""
|
|
105
|
-
|
|
106
|
-
db_urls = [db_urls]
|
|
107
|
-
return [
|
|
108
|
-
sys.executable,
|
|
109
|
-
"-m",
|
|
110
|
-
"spinetoolbox.spine_db_editor.main",
|
|
111
|
-
*db_urls,
|
|
112
|
-
]
|
|
107
|
+
return spine_db_editor_argv(db_urls)
|
|
113
108
|
|
|
114
109
|
|
|
115
110
|
def launch_db_editor(db_urls, _popen=subprocess.Popen):
|
|
@@ -105,6 +105,9 @@ _AXIS_SYNONYMS: dict[str, str] = {
|
|
|
105
105
|
"b_f": "block",
|
|
106
106
|
# Period history column — holds period tokens (subset of d).
|
|
107
107
|
"d_h": "d",
|
|
108
|
+
# Scenario-lineage pair column (``dd_same_scenario``, recourse plan
|
|
109
|
+
# §6b Slice A) — holds period tokens (subset of d).
|
|
110
|
+
"d_other": "d",
|
|
108
111
|
# ``d_first`` — column holding period tokens of "first" periods
|
|
109
112
|
# (e.g. in ``_lifetime_expired_pairs_lf`` cascade). Subset of d.
|
|
110
113
|
"d_first": "d",
|
|
@@ -114,6 +114,10 @@ from flextool.engine_polars.autoscale import (
|
|
|
114
114
|
unscale_solution,
|
|
115
115
|
)
|
|
116
116
|
from flextool.engine_polars._region_filter import HalfFlow, RegionSplit
|
|
117
|
+
from flextool.engine_polars._solve_state import FlexToolConfigError
|
|
118
|
+
from flextool.engine_polars._stochastic_detect import (
|
|
119
|
+
is_genuinely_stochastic as _is_genuinely_stochastic,
|
|
120
|
+
)
|
|
117
121
|
from flextool.engine_polars.input import FlexData
|
|
118
122
|
|
|
119
123
|
_logger = logging.getLogger(__name__)
|
|
@@ -2043,6 +2047,18 @@ def solve_benders(
|
|
|
2043
2047
|
-------
|
|
2044
2048
|
BendersResult
|
|
2045
2049
|
"""
|
|
2050
|
+
# Slice C Guard 2 (defensive): a caller reaching solve_benders while
|
|
2051
|
+
# bypassing _run_benders_solve (the primary guard site) still fails
|
|
2052
|
+
# loudly on a stochastic model. Same shared detector on the master
|
|
2053
|
+
# ``data``. Benders x stochastics is not supported (recourse plan §4).
|
|
2054
|
+
if _is_genuinely_stochastic(data):
|
|
2055
|
+
raise FlexToolConfigError(
|
|
2056
|
+
"solve_benders called on a stochastic model "
|
|
2057
|
+
"(period__branch has non-realized branch periods with active "
|
|
2058
|
+
"time); Benders x stochastics is not supported "
|
|
2059
|
+
"(recourse plan §4)."
|
|
2060
|
+
)
|
|
2061
|
+
|
|
2046
2062
|
if build_problem is None:
|
|
2047
2063
|
def build_problem(pb, d):
|
|
2048
2064
|
_build_flextool(pb, d, scale_the_objective=scale_the_objective)
|
|
@@ -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
|
|
@@ -722,6 +722,57 @@ def _emit_group_invest_period(m, d, vars: dict,
|
|
|
722
722
|
# ---------------------------------------------------------------------------
|
|
723
723
|
# Group invest / divest — total scope
|
|
724
724
|
|
|
725
|
+
def _emit_group_total_divest_cap(
|
|
726
|
+
m, *, legacy_name: str, path_name: str, outer: pl.DataFrame,
|
|
727
|
+
ge: pl.DataFrame, axis: str, var, unitsize, cap_param,
|
|
728
|
+
sense: str, d_leaf,
|
|
729
|
+
) -> None:
|
|
730
|
+
"""Per-path divest-group total cap (design §7.2 (G) item 4).
|
|
731
|
+
|
|
732
|
+
The divest group total sums ``v_divest * unitsize`` over ALL ``d``
|
|
733
|
+
(``edd_set`` is None on the divest side) grouped by ``g`` — under
|
|
734
|
+
recourse that cross-scenario double-counts one cap. When more than
|
|
735
|
+
one scenario leaf covers the divest periods (recourse, sense
|
|
736
|
+
``"<="``), emit ``path_name`` indexed by ``(g, leaf)`` with the
|
|
737
|
+
inner sum masked to each leaf's periods. Single leaf — deterministic
|
|
738
|
+
/ flag-off — or the ``">="`` floor keeps the legacy ``over=g`` shape
|
|
739
|
+
and NAME (byte-parity; the design registers only the ``max`` path
|
|
740
|
+
cap).
|
|
741
|
+
"""
|
|
742
|
+
dl = None
|
|
743
|
+
if (sense == "<=" and d_leaf is not None
|
|
744
|
+
and getattr(d_leaf, "height", 0) > 0):
|
|
745
|
+
inv_periods = var.frame.select("d").unique()
|
|
746
|
+
_d_dt = var.frame.schema["d"]
|
|
747
|
+
dlx = d_leaf
|
|
748
|
+
if dlx.schema["d"] != _d_dt:
|
|
749
|
+
dlx = dlx.with_columns(pl.col("d").cast(_d_dt, strict=False))
|
|
750
|
+
dl = dlx.join(inv_periods, on="d", how="semi")
|
|
751
|
+
n_leaves = (dl["leaf"].n_unique()
|
|
752
|
+
if dl is not None and dl.height > 0 else 1)
|
|
753
|
+
if n_leaves <= 1:
|
|
754
|
+
m.add_cstr(
|
|
755
|
+
legacy_name,
|
|
756
|
+
over = outer,
|
|
757
|
+
sense = sense,
|
|
758
|
+
lhs_terms = {"divest_grp": Sum(Where(var * unitsize, ge),
|
|
759
|
+
over=(axis, "d"))},
|
|
760
|
+
rhs_terms = {"cap": cap_param},
|
|
761
|
+
)
|
|
762
|
+
return
|
|
763
|
+
mask = ge.join(dl, how="cross")
|
|
764
|
+
over_path = outer.join(dl.select("leaf").unique().sort("leaf"),
|
|
765
|
+
how="cross")
|
|
766
|
+
m.add_cstr(
|
|
767
|
+
path_name,
|
|
768
|
+
over = over_path,
|
|
769
|
+
sense = sense,
|
|
770
|
+
lhs_terms = {"divest_grp": Sum(Where(var * unitsize, mask),
|
|
771
|
+
over=(axis, "d"))},
|
|
772
|
+
rhs_terms = {"cap": cap_param},
|
|
773
|
+
)
|
|
774
|
+
|
|
775
|
+
|
|
725
776
|
def _emit_group_invest_total(m, d, vars: dict,
|
|
726
777
|
kind: str, sense: str) -> None:
|
|
727
778
|
"""Mod:
|
|
@@ -852,16 +903,18 @@ def _emit_group_invest_total(m, d, vars: dict,
|
|
|
852
903
|
pl.col("p").is_in(v_p.frame["p"].unique())) \
|
|
853
904
|
.filter(pl.col("g").is_in(g_set["g"].unique()))
|
|
854
905
|
if ge_p.height > 0:
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
906
|
+
_emit_group_total_divest_cap(
|
|
907
|
+
m,
|
|
908
|
+
legacy_name = f"{name}_p",
|
|
909
|
+
path_name = f"{name}_path_p",
|
|
910
|
+
outer = outer,
|
|
911
|
+
ge = ge_p,
|
|
912
|
+
axis = "p",
|
|
913
|
+
var = v_p,
|
|
914
|
+
unitsize = d.p_unitsize,
|
|
915
|
+
cap_param = cap_param,
|
|
916
|
+
sense = sense,
|
|
917
|
+
d_leaf = getattr(d, "d_leaf", None),
|
|
865
918
|
)
|
|
866
919
|
# Node branch
|
|
867
920
|
if v_n is not None and d.p_state_unitsize is not None:
|
|
@@ -876,16 +929,18 @@ def _emit_group_invest_total(m, d, vars: dict,
|
|
|
876
929
|
pl.col("n").is_in(v_n.frame["n"].unique())) \
|
|
877
930
|
.filter(pl.col("g").is_in(g_set["g"].unique()))
|
|
878
931
|
if ge_n.height > 0:
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
932
|
+
_emit_group_total_divest_cap(
|
|
933
|
+
m,
|
|
934
|
+
legacy_name = f"{name}_n",
|
|
935
|
+
path_name = f"{name}_path_n",
|
|
936
|
+
outer = outer,
|
|
937
|
+
ge = ge_n,
|
|
938
|
+
axis = "n",
|
|
939
|
+
var = v_n,
|
|
940
|
+
unitsize = us_n,
|
|
941
|
+
cap_param = cap_param,
|
|
942
|
+
sense = sense,
|
|
943
|
+
d_leaf = getattr(d, "d_leaf", None),
|
|
889
944
|
)
|
|
890
945
|
|
|
891
946
|
|
|
@@ -98,6 +98,7 @@ from polar_high import Sum, Where, Param
|
|
|
98
98
|
# Engine imports kept light — we don't introduce new variable types.
|
|
99
99
|
|
|
100
100
|
from ._axis_enums import cast_dim
|
|
101
|
+
from ._derived_params import process_delayed__duration_from_weight
|
|
101
102
|
from ._emit_provider_io import _provider_key
|
|
102
103
|
|
|
103
104
|
|
|
@@ -176,11 +177,10 @@ def load_data(inp_dir: str | Path, sd_dir: str | Path, *,
|
|
|
176
177
|
|
|
177
178
|
pd_df = pd_df.rename({"process": "p"}) if "process" in pd_df.columns else pd_df
|
|
178
179
|
|
|
179
|
-
#
|
|
180
|
-
#
|
|
181
|
-
# ``
|
|
182
|
-
#
|
|
183
|
-
pdd_df = None
|
|
180
|
+
# ``process_delayed__duration`` is derived from the delay-weight
|
|
181
|
+
# keys below (``_derived_params.process_delayed__duration_from_weight``,
|
|
182
|
+
# the same producer the DB path uses), so its ``td`` labels match
|
|
183
|
+
# ``dtt__delay_duration`` and ``p_process_delay_weight`` exactly.
|
|
184
184
|
|
|
185
185
|
# process_source_(un)delayed: (process, source) frames
|
|
186
186
|
def _read_pse(name: str) -> pl.DataFrame | None:
|
|
@@ -255,7 +255,12 @@ def load_data(inp_dir: str | Path, sd_dir: str | Path, *,
|
|
|
255
255
|
rename_map["time_sink"] = "t_sink"
|
|
256
256
|
if "delay_duration" in raw.columns:
|
|
257
257
|
rename_map["delay_duration"] = "td"
|
|
258
|
-
|
|
258
|
+
# ``td`` is a duration in hours: Float64, as on the DB path
|
|
259
|
+
# (``dtt__delay_duration_from_source``). The CSV carries it as
|
|
260
|
+
# text whose formatting may differ between writers ("1" / "1.0").
|
|
261
|
+
dtt_df = (raw.rename(rename_map)
|
|
262
|
+
.select("d", "t_source", "t_sink",
|
|
263
|
+
pl.col("td").cast(pl.Float64)))
|
|
259
264
|
|
|
260
265
|
pw_path = sd / "p_process_delay_weight.csv"
|
|
261
266
|
pw_param = None
|
|
@@ -266,8 +271,11 @@ def load_data(inp_dir: str | Path, sd_dir: str | Path, *,
|
|
|
266
271
|
rename_map["process"] = "p"
|
|
267
272
|
if "delay_duration" in raw.columns:
|
|
268
273
|
rename_map["delay_duration"] = "td"
|
|
269
|
-
pw_long = raw.rename(rename_map).select(
|
|
274
|
+
pw_long = raw.rename(rename_map).select(
|
|
275
|
+
"p", pl.col("td").cast(pl.Float64),
|
|
276
|
+
pl.col("value").cast(pl.Float64))
|
|
270
277
|
pw_param = Param(("p", "td"), pw_long)
|
|
278
|
+
pdd_df = process_delayed__duration_from_weight(pw_param)
|
|
271
279
|
|
|
272
280
|
return dict(
|
|
273
281
|
process_delayed = pd_df.select("p"),
|
|
@@ -281,6 +289,106 @@ def load_data(inp_dir: str | Path, sd_dir: str | Path, *,
|
|
|
281
289
|
)
|
|
282
290
|
|
|
283
291
|
|
|
292
|
+
# ---------------------------------------------------------------------------
|
|
293
|
+
# Consistency check
|
|
294
|
+
|
|
295
|
+
class DelayDataError(RuntimeError):
|
|
296
|
+
"""The delay tables of a delayed unit do not line up.
|
|
297
|
+
|
|
298
|
+
An internal wiring error, raised instead of building a conversion
|
|
299
|
+
equation without the unit's input (which forces its output to zero
|
|
300
|
+
without any message).
|
|
301
|
+
"""
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def _p_utf8(df: pl.DataFrame, cols: tuple[str, ...]) -> pl.DataFrame:
|
|
305
|
+
return df.select(pl.col(c).cast(pl.Utf8) for c in cols).unique()
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
def check_delay_tables(d) -> None:
|
|
309
|
+
"""Raise :class:`DelayDataError` unless every delayed indirect unit can
|
|
310
|
+
get its delayed input term.
|
|
311
|
+
|
|
312
|
+
``conversion_indirect`` takes a delayed unit's inputs out of the
|
|
313
|
+
undelayed sum (``process_delayed``), so the delayed term must cover
|
|
314
|
+
them. For every unit in ``process_delayed`` that is indirect and has
|
|
315
|
+
inputs (``process_input_flows``):
|
|
316
|
+
|
|
317
|
+
* it has delayed input arcs (``process_source_sink_delayed``);
|
|
318
|
+
* it has ``process_delayed__duration`` rows;
|
|
319
|
+
* ``td`` has the same dtype in ``process_delayed__duration``,
|
|
320
|
+
``dtt__delay_duration`` and ``p_process_delay_weight``;
|
|
321
|
+
* every ``(p, td)`` has ``dtt__delay_duration`` rows and a weight.
|
|
322
|
+
|
|
323
|
+
Delayed connections are not indirect and are not checked here (no
|
|
324
|
+
delayed term applies to them).
|
|
325
|
+
"""
|
|
326
|
+
if not has_feature(d):
|
|
327
|
+
return
|
|
328
|
+
indirect = getattr(d, "process_indirect", None)
|
|
329
|
+
inputs = getattr(d, "process_input_flows", None)
|
|
330
|
+
if indirect is None or indirect.height == 0 or inputs is None:
|
|
331
|
+
return
|
|
332
|
+
units = (_p_utf8(d.process_delayed, ("p",))
|
|
333
|
+
.join(_p_utf8(indirect, ("p",)), on="p", how="semi")
|
|
334
|
+
.join(_p_utf8(inputs, ("p",)), on="p", how="semi"))
|
|
335
|
+
if units.height == 0:
|
|
336
|
+
return
|
|
337
|
+
names = sorted(units["p"].to_list())
|
|
338
|
+
|
|
339
|
+
def _fail(msg: str, which: list[str]) -> None:
|
|
340
|
+
raise DelayDataError(
|
|
341
|
+
f"delayed unit(s) {', '.join(which)}: {msg}. Their inputs are "
|
|
342
|
+
"excluded from the undelayed conversion, so the unit would "
|
|
343
|
+
"be forced to zero output.")
|
|
344
|
+
|
|
345
|
+
psse = getattr(d, "process_source_sink_delayed", None)
|
|
346
|
+
if psse is None or psse.height == 0:
|
|
347
|
+
_fail("no delayed input arcs (process_source_sink_delayed)", names)
|
|
348
|
+
arcs = (psse.select(pl.col(c).cast(pl.Utf8) for c in ("p", "sink"))
|
|
349
|
+
.filter(pl.col("sink") == pl.col("p")).select("p").unique())
|
|
350
|
+
missing = units.join(arcs, on="p", how="anti")
|
|
351
|
+
if missing.height > 0:
|
|
352
|
+
_fail("no delayed input arcs (process_source_sink_delayed)",
|
|
353
|
+
sorted(missing["p"].to_list()))
|
|
354
|
+
|
|
355
|
+
pdd = getattr(d, "process_delayed__duration", None)
|
|
356
|
+
dtt = getattr(d, "dtt__delay_duration", None)
|
|
357
|
+
pw = getattr(d, "p_process_delay_weight", None)
|
|
358
|
+
if pdd is None or pdd.height == 0:
|
|
359
|
+
_fail("no delay durations (process_delayed__duration)", names)
|
|
360
|
+
missing = units.join(_p_utf8(pdd, ("p",)), on="p", how="anti")
|
|
361
|
+
if missing.height > 0:
|
|
362
|
+
_fail("no delay durations (process_delayed__duration)",
|
|
363
|
+
sorted(missing["p"].to_list()))
|
|
364
|
+
if dtt is None or dtt.height == 0:
|
|
365
|
+
_fail("no time-shift rows (dtt__delay_duration)", names)
|
|
366
|
+
if pw is None or pw.frame.height == 0:
|
|
367
|
+
_fail("no delay weights (p_process_delay_weight)", names)
|
|
368
|
+
dtypes = {"process_delayed__duration": pdd.schema["td"],
|
|
369
|
+
"dtt__delay_duration": dtt.schema["td"],
|
|
370
|
+
"p_process_delay_weight": pw.frame.schema["td"]}
|
|
371
|
+
if len(set(dtypes.values())) != 1:
|
|
372
|
+
_fail("delay duration (td) dtypes differ: "
|
|
373
|
+
+ ", ".join(f"{k} {v}" for k, v in dtypes.items()), names)
|
|
374
|
+
used = (pdd.with_columns(pl.col("p").cast(pl.Utf8))
|
|
375
|
+
.join(units, on="p", how="semi"))
|
|
376
|
+
no_shift = used.join(dtt.select("td").unique(), on="td", how="anti")
|
|
377
|
+
if no_shift.height > 0:
|
|
378
|
+
_fail("delay duration(s) without time-shift rows "
|
|
379
|
+
"(dtt__delay_duration): "
|
|
380
|
+
+ ", ".join(f"{p} {td!r}" for p, td in no_shift.iter_rows()),
|
|
381
|
+
sorted(set(no_shift["p"].to_list())))
|
|
382
|
+
no_weight = used.join(
|
|
383
|
+
pw.frame.select(pl.col("p").cast(pl.Utf8), "td"),
|
|
384
|
+
on=["p", "td"], how="anti")
|
|
385
|
+
if no_weight.height > 0:
|
|
386
|
+
_fail("delay duration(s) without a weight "
|
|
387
|
+
"(p_process_delay_weight): "
|
|
388
|
+
+ ", ".join(f"{p} {td!r}" for p, td in no_weight.iter_rows()),
|
|
389
|
+
sorted(set(no_weight["p"].to_list())))
|
|
390
|
+
|
|
391
|
+
|
|
284
392
|
# ---------------------------------------------------------------------------
|
|
285
393
|
# Constraint contribution
|
|
286
394
|
|
|
@@ -313,10 +421,12 @@ def delayed_input_expr(d, v_flow):
|
|
|
313
421
|
* ``Sum`` over (source, td) leaves dims (p, d, t).
|
|
314
422
|
|
|
315
423
|
Returns ``None`` when there's no delayed-process data (caller should
|
|
316
|
-
use a no-op).
|
|
424
|
+
use a no-op). Raises :class:`DelayDataError` when a delayed indirect
|
|
425
|
+
unit's tables do not line up (:func:`check_delay_tables`).
|
|
317
426
|
"""
|
|
318
427
|
if not has_feature(d):
|
|
319
428
|
return None
|
|
429
|
+
check_delay_tables(d)
|
|
320
430
|
if d.dtt__delay_duration is None or d.p_process_delay_weight is None:
|
|
321
431
|
return None
|
|
322
432
|
if d.process_source_delayed is None or d.process_delayed__duration is None:
|