flextool 4.0.4__tar.gz → 4.1.0__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.0}/PKG-INFO +6 -6
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/cmd_open_results_db.py +4 -9
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_axis_enums.py +3 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_benders.py +16 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_cumulative_invest.py +75 -20
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_delay.py +118 -8
- flextool-4.1.0/flextool/engine_polars/_derived_branch.py +1804 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_derived_existing.py +342 -11
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_derived_npv.py +120 -23
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_derived_params.py +1211 -152
- flextool-4.1.0/flextool/engine_polars/_derived_walks.py +487 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_direct_params.py +132 -65
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_dump_csvs.py +10 -3
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_arc_unions.py +67 -31
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_chain_params.py +28 -2
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_mid_sets.py +6 -3
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_per_solve.py +71 -8
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_period_calc.py +24 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_solve_time.py +14 -1
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_solve_writers.py +16 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_flex_data_accumulator.py +1 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_inmemory_reader.py +37 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_input_source.py +22 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_native_run_model.py +193 -4
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_orchestration.py +340 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_output_writer.py +5 -2
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_param_shapes.py +225 -14
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_pdt_join.py +25 -6
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_projection_params.py +5 -4
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_provider_keys.py +8 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_provider_translators.py +35 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_recursive_solve.py +74 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_region_filter.py +6 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_reserve.py +437 -13
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_solve_config.py +309 -6
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_solve_handoff.py +54 -1
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_solve_state.py +41 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_solver_dispatch.py +52 -2
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_spinedb_reader.py +531 -21
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_stochastic.py +240 -32
- flextool-4.1.0/flextool/engine_polars/_stochastic_detect.py +85 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_timeline.py +71 -15
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_warm.py +26 -4
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/autoscale/_layer2.py +26 -9
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/autoscale/_layer2_types.py +57 -1
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/autoscale/_quantity_types.py +30 -4
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/input.py +678 -14
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/model.py +1933 -394
- {flextool-4.0.4 → flextool-4.1.0}/flextool/export_to_tabular/export_settings.yaml +9 -2
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/db_editor_integration.py +30 -17
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/main_window.py +14 -11
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/platform_utils.py +40 -12
- {flextool-4.0.4 → flextool-4.1.0}/flextool/input_derivation/__init__.py +8 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/input_derivation/_process_method.py +4 -1
- {flextool-4.0.4 → flextool-4.1.0}/flextool/input_derivation/_specs.py +10 -8
- {flextool-4.0.4 → flextool-4.1.0}/flextool/input_derivation/_validators.py +259 -0
- flextool-4.1.0/flextool/process_outputs/_branch_weight.py +48 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/calc_costs.py +50 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/calc_slacks.py +27 -3
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/drop_levels.py +7 -1
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/read_highs_solution.py +82 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/read_parameters.py +38 -4
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/canonical_databases/howto_aggregate_output.json +235 -28
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/canonical_databases/howto_connections.json +235 -28
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/canonical_databases/howto_demand.json +235 -28
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/canonical_databases/howto_hydro_reservoir.json +235 -28
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/canonical_databases/howto_hydro_reservoir_with_pump.json +242 -48
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/canonical_databases/howto_non_sync_and_curtailment.json +235 -28
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/canonical_databases/howto_ramp_and_start_up.json +235 -28
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/canonical_databases/howto_stochastics.json +236 -29
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/canonical_databases/templates_examples.json +242 -35
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/canonical_databases/templates_time_settings_only.json +235 -28
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/flextool_axis_contract.json +1 -2
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/spinedb_schema.json +213 -33
- {flextool-4.0.4 → flextool-4.1.0}/flextool/solver_config/highs.opt.template +0 -3
- {flextool-4.0.4 → flextool-4.1.0}/flextool/update_flextool/__init__.py +1 -1
- {flextool-4.0.4 → flextool-4.1.0}/flextool/update_flextool/db_migration.py +813 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool.egg-info/PKG-INFO +6 -6
- {flextool-4.0.4 → flextool-4.1.0}/flextool.egg-info/SOURCES.txt +7 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool.egg-info/requires.txt +5 -5
- {flextool-4.0.4 → flextool-4.1.0}/pyproject.toml +26 -11
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_branch_weights.py +64 -37
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_cost_aggregation_semantics.py +59 -47
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_handoff_writers.py +19 -6
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_min_load_rolling.py +19 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_non_anticipativity.py +46 -38
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_parameter_group_coverage.py +6 -13
- flextool-4.1.0/tests/test_recourse_cost_reconciliation.py +111 -0
- flextool-4.1.0/tests/test_rolling_online_carry.py +247 -0
- flextool-4.1.0/tests/test_rolling_online_mintime_carry.py +353 -0
- flextool-4.1.0/tests/test_rolling_online_minuptime.py +204 -0
- flextool-4.1.0/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.0}/LICENSE.txt +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/README.md +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/_mem_sampler.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/_resources.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/calibrate/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/calibrate/__main__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/calibrate/_cli.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/calibrate/_db_alt.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/calibrate/_final_outputs.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/calibrate/_guard.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/calibrate/_loop.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/calibrate/_readers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/calibrate/_report.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/calibrate/_sizing.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/calibrate/_solve.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/calibrate/_solve_status.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/_console.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/_timing.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/cmd_execute_flextool_workflow.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/cmd_export_to_tabular.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/cmd_import_sensitivities.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/cmd_migrate_database.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/cmd_read_matpower.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/cmd_read_old_flextool.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/cmd_read_self_describing_tabular_input.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/cmd_read_tabular_input.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/cmd_run_flextool.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/cmd_scenario_results.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/cmd_solve_mps.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/cmd_update_flextool.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/cli/cmd_write_outputs.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/common_utils/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/common_utils/plot_mem_shape.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/common_utils/precision.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/decomposition/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/decomposition/region_decomposition.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/decomposition/region_filter.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_block_layout.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_blocks.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_commodity_ladder.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_db_loader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_db_reader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_dc_power_flow.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_derived_arithmetic.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_derived_block.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_derived_profile.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_determinism.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_calc_params.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_co2_accumulators.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_dispatchers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_energy_margin.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_energy_margin_adder.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_entity_annual.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_inflow_scaling.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_leaf_sets.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_lp_scaling.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_pdt_params.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_period_params.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_provider_io.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_emit_reserve.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_flex_data_provider.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_group_slack.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_invest_seeds.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_native_input_writer.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_parquet_bundle.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_pdt_lookup.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_per_solve_sets.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_solve_acceptance.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_solve_context.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_solver_base.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_subprocess_solve.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/_vectorize.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/autoscale/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/autoscale/_config.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/autoscale/_report.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/engine_polars/chain.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/env_check.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/export_to_tabular/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/export_to_tabular/db_reader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/export_to_tabular/excel_writer.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/export_to_tabular/export_to_excel.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/export_to_tabular/formatting.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/export_to_tabular/sheet_config.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/__main__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/calibrate_commands.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/calibrate_jobs.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/check_tree.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/cli_format.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/config_parser.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/data_models.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/db_version_check.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/dialogs/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/dialogs/add_dialog.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/dialogs/calibrate_dialog.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/dialogs/file_picker.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/dialogs/group_picker.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/dialogs/migration_consent_dialog.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/dialogs/migration_progress_dialog.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/dialogs/plot_dialog.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/dialogs/plot_settings_picker.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/dialogs/project_dialog.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/dialogs/update_dialog.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/downsampling.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/error_handling.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/execution_manager.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/execution_window.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/hover_tooltip.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/input_sources.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/network_graph.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/output_actions.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/output_log_window.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/plot_cache.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/plot_canvas.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/plot_config_reader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/project_utils.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/result_viewer.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/scenario_key.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/scenario_lists.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/settings_io.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/solve_reader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/tree_reorder.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/gui/ui_metrics.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/input_derivation/_commodity_ladder.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/input_derivation/_commodity_ladder_sets.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/input_derivation/_dc_power_flow.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/input_derivation/_method_constants.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/lean_parquet.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/model_builder/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/model_builder/build_model.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/model_builder/encoding.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/model_builder/names.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/model_builder/profiles.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/plot_outputs/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/plot_outputs/axis_helpers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/plot_outputs/color_template.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/plot_outputs/config.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/plot_outputs/format_helpers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/plot_outputs/legend_helpers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/plot_outputs/orchestrator.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/plot_outputs/perf.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/plot_outputs/plan.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/plot_outputs/plot_bars.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/plot_outputs/plot_bars_detail.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/plot_outputs/plot_lines.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/plot_outputs/shared_manifest.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/plot_outputs/subplot_helpers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_inputs/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_inputs/import_old_excel_input.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_inputs/read_matpower.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_inputs/read_old_flextool.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_inputs/read_self_describing_excel.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_inputs/read_tabular_with_specification.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_inputs/write_old_flextool_to_db.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_inputs/write_self_describing_to_db.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_inputs/write_to_input_db.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/_annualize.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/_inmemory_helpers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/_output_meta.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/calc_capacity_flows.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/calc_connections.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/calc_group_flows.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/calc_storage_vre.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/handoff_writers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/out_ancillary.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/out_capacity.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/out_costs.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/out_flowgroup.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/out_flows.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/out_group.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/out_node.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/persist_realized_slice.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/process_results.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/read_sets.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/read_variables.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/solve_order.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/spinedb_replay.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/union_realized_slice.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/write_outputs.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/process_outputs/write_spinedb.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/representative_periods/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/representative_periods/clustering.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/representative_periods/force_include.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/representative_periods/netload.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/representative_periods/netload_inputs.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/representative_periods/netload_iterate.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/representative_periods/preprocess.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/representative_periods/scenario_stack.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/representative_periods/weights.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/scenario_comparison/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/scenario_comparison/config_builder.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/scenario_comparison/constants.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/scenario_comparison/data_models.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/scenario_comparison/db_reader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/scenario_comparison/dispatch_data.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/scenario_comparison/dispatch_mappings.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/scenario_comparison/dispatch_plots.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/scenario_comparison/input_entity_colors.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/scenario_comparison/orchestrator.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/scenario_comparison/plan_union.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/scenario_comparison/plot_settings_seed.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/AXIS_CONTRACT.md +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/comparison_settings_template.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/default_plot_settings.yaml +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/default_plots.yaml +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/flextool_axis_contract.schema.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/old_flextool_import_template.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/output_info_template.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/output_settings_template.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/pre_v26/flextool_template_constant_default.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/pre_v26/flextool_template_default_optional_output.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/pre_v26/flextool_template_default_value.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/pre_v26/flextool_template_drop_down.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/pre_v26/flextool_template_lifetime_method.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/pre_v26/flextool_template_optional_outputs.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/pre_v26/flextool_template_output_node_flows.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/pre_v26/flextool_template_results_master.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/pre_v26/flextool_template_rolling_start_remove.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/pre_v26/flextool_template_rolling_window.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/pre_v26/flextool_template_storage_binding_defaults.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/pre_v26/flextool_template_v2.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/pre_v26/flextool_template_v25.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/schemas/spinedb_results_schema.json +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/solver_config/copt.opt.template +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/solver_config/cplex.opt.template +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/solver_config/gurobi.opt.template +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/solver_config/xpress.opt.template +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/spinedb_backend/__init__.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/spinedb_backend/_axis_enums.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/spinedb_backend/_backend.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/update_flextool/canonical_databases.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/update_flextool/ensure_settings_db.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/update_flextool/export_database.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/update_flextool/extend_tests_fixture.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/update_flextool/generate_canonical.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/update_flextool/initialize_database.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/update_flextool/install_info.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/update_flextool/self_update.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/update_flextool/sync_master_json_template.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool/update_flextool/test_fixtures.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool.egg-info/dependency_links.txt +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool.egg-info/entry_points.txt +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/flextool.egg-info/top_level.txt +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/setup.cfg +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_bar_layout.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_bar_sub_pixel_labels.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_blocks.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_color_template.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_commodity_ladder_rolling.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_comparison_excel.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_comparison_project_root.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_complete_period_share_reduction.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_connection_node_warnings.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_console_run_tool.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_cost_breakdown_by_entity.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_csv_dump_roundtrip.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_dc_power_flow.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_dispatch_consumer_and_connection_signs.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_dispatch_node_debug_and_tree.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_dispatch_order_specials.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_dispatch_scenario_tag.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_ensure_settings_db.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_entity_unitsize_invariant.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_entity_universe_carrier.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_env_check.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_export_to_tabular.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_extend_tests_fixture.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_flowgroup_indicators.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_force_include.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_group_output_warnings.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_input_entity_colors.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_lh2_three_region.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_old_flextool_importer_schema_drift.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_open_results_db.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_output_column_metadata.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_output_metadata_renderers.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_plan_union.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_plot_draw_order.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_plot_pipeline.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_plot_plan_chunk_reconstruction.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_plot_plan_time_labels_roundtrip.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_plot_settings_seed.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_precision.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_read_highs_solution.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_regional_filter.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_representative_periods.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_rp_alternative_name.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_rp_force_include_wiring.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_rp_solves_filter.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_scenario_colors.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_scenario_stack.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_scenarios.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_self_describing_reader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_shared_axis_manifest.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_simple_bar_entity_color.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_solve_config.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_solve_reader.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_synthesize_invest_dual.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_timings_csv.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_unidirectional_connection.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_unit_online_dt_columns.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_v52_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_v63_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_v64_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_v65_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_v66_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_v67_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_v68_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_v69_migration.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_workdir_empty_default.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_xlsx_workflow.py +0 -0
- {flextool-4.0.4 → flextool-4.1.0}/tests/test_years_represented.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flextool
|
|
3
|
-
Version: 4.0
|
|
3
|
+
Version: 4.1.0
|
|
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)
|
|
@@ -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:
|