Results Module#
The results module provides structured data classes for storing and accessing optimization results.
OptimizationResults Class#
The OptimizationResults dataclass is the primary container for all optimization results returned by run_solver().
- class sdom.results.OptimizationResults(termination_condition: str = '', solver_status: str = '', total_cost: float = 0.0, gen_mix_target: float = 0.0, generation_df: ~pandas.core.frame.DataFrame = <factory>, storage_df: ~pandas.core.frame.DataFrame = <factory>, thermal_generation_df: ~pandas.core.frame.DataFrame = <factory>, installed_plants_df: ~pandas.core.frame.DataFrame = <factory>, summary_df: ~pandas.core.frame.DataFrame = <factory>, problem_info: dict = <factory>, capacity: dict = <factory>, storage_capacity: dict = <factory>, generation_totals: dict = <factory>, cost_breakdown: dict = <factory>)[source]#
Data class containing all optimization results from SDOM.
This class stores the complete results from an SDOM optimization run, organized into DataFrames for different result categories (generation, storage, summary) and provides convenient accessors for specific metrics.
- generation_df#
Hourly generation dispatch results for all technologies.
- Type:
pd.DataFrame
- storage_df#
Hourly storage operation results (charge, discharge, SOC).
- Type:
pd.DataFrame
- thermal_generation_df#
Disaggregated hourly thermal generation by plant.
- Type:
pd.DataFrame
- installed_plants_df#
Installed capacity for each individual power plant (solar, wind, thermal).
- Type:
pd.DataFrame
- summary_df#
Summary metrics including capacities, costs, and totals.
- Type:
pd.DataFrame
- generation_df: DataFrame#
- storage_df: DataFrame#
- thermal_generation_df: DataFrame#
- installed_plants_df: DataFrame#
- summary_df: DataFrame#
- get_generation_dataframe() DataFrame[source]#
Get the hourly generation dispatch DataFrame.
- Returns:
DataFrame with columns: Scenario, Hour, Solar PV Generation (MW), Solar PV Curtailment (MW), Wind Generation (MW), Wind Curtailment (MW), All Thermal Generation (MW), Hydro Generation (MW), Nuclear Generation (MW), Other Renewables Generation (MW), Imports (MW), Storage Charge/Discharge (MW), Exports (MW), Load (MW).
- Return type:
pd.DataFrame
- get_storage_dataframe() DataFrame[source]#
Get the hourly storage operation DataFrame.
- Returns:
DataFrame with columns: Hour, Technology, Charging power (MW), Discharging power (MW), State of charge (MWh).
- Return type:
pd.DataFrame
- get_thermal_generation_dataframe() DataFrame[source]#
Get the disaggregated hourly thermal generation DataFrame.
- Returns:
DataFrame with columns: Hour, and one column per thermal plant.
- Return type:
pd.DataFrame
- get_summary_dataframe() DataFrame[source]#
Get the summary metrics DataFrame.
- Returns:
DataFrame with columns: Metric, Technology, Run, Optimal Value, Unit.
- Return type:
pd.DataFrame
- get_installed_plants_dataframe() DataFrame[source]#
Get the installed power plants capacity DataFrame.
- Returns:
DataFrame with columns: Plant ID, Technology, Installed Capacity (MW), Max Capacity (MW), Capacity Fraction.
- Return type:
pd.DataFrame
- get_problem_info() dict[source]#
Get solver problem information.
- Returns:
Dictionary with keys: Number of constraints, Number of variables, Number of binary variables, Number of objectives, Number of nonzeros.
- Return type:
- __init__(termination_condition: str = '', solver_status: str = '', total_cost: float = 0.0, gen_mix_target: float = 0.0, generation_df: ~pandas.core.frame.DataFrame = <factory>, storage_df: ~pandas.core.frame.DataFrame = <factory>, thermal_generation_df: ~pandas.core.frame.DataFrame = <factory>, installed_plants_df: ~pandas.core.frame.DataFrame = <factory>, summary_df: ~pandas.core.frame.DataFrame = <factory>, problem_info: dict = <factory>, capacity: dict = <factory>, storage_capacity: dict = <factory>, generation_totals: dict = <factory>, cost_breakdown: dict = <factory>) None#
Result Collection Function#
- sdom.results.collect_results_from_model(model, solver_result, case_name: str = 'run') OptimizationResults[source]#
Collect all optimization results from a solved Pyomo model.
This function extracts all relevant results from a solved SDOM model and organizes them into an OptimizationResults dataclass. It combines the functionality previously split between collect_results() and export_results().
- Parameters:
model (pyomo.core.base.PyomoModel.ConcreteModel) – The solved Pyomo model instance.
solver_result (pyomo.opt.SolverResults) – The solver results object from solver.solve().
case_name (str, optional) – Case identifier for the scenario column. Defaults to “run”.
- Returns:
A dataclass containing all optimization results.
- Return type:
Example Usage#
Basic Result Access#
from sdom import load_data, initialize_model, run_solver, get_default_solver_config_dict
# Load and solve model
data = load_data('./Data/scenario/')
model = initialize_model(data, n_hours=168)
solver_config = get_default_solver_config_dict(solver_name="highs")
# Run optimization - returns OptimizationResults
results = run_solver(model, solver_config)
# Check solution status
if results.is_optimal:
print(f"Optimization successful!")
print(f"Total Cost: ${results.total_cost:,.2f}")
else:
print(f"Solver terminated with: {results.termination_condition}")
Accessing Capacities#
# Generation capacities
print(f"Solar PV Capacity: {results.total_cap_pv:.2f} MW")
print(f"Wind Capacity: {results.total_cap_wind:.2f} MW")
print(f"Thermal Capacity: {results.total_cap_thermal:.2f} MW")
# Storage capacities by technology
for tech, cap in results.total_cap_storage_charge.items():
print(f"{tech} Charge Capacity: {cap:.2f} MW")
for tech, energy in results.total_cap_storage_energy.items():
print(f"{tech} Energy Capacity: {energy:.2f} MWh")
Accessing DataFrames#
# Get hourly generation dispatch
gen_df = results.get_generation_dataframe()
print(gen_df.head())
# Get storage operation details
storage_df = results.get_storage_dataframe()
# Get summary metrics
summary_df = results.get_summary_dataframe()
# Get disaggregated thermal generation (if multiple plants)
thermal_df = results.get_thermal_generation_dataframe()
Accessing Cost Breakdown#
# CAPEX by technology
capex = results.cost_breakdown["capex"]
print(f"Solar CAPEX: ${capex['Solar PV']:,.2f}")
print(f"Wind CAPEX: ${capex['Wind']:,.2f}")
# Storage costs
power_capex = results.cost_breakdown["power_capex"]
energy_capex = results.cost_breakdown["energy_capex"]
# Operating costs
fom = results.cost_breakdown["fom"]
vom = results.cost_breakdown["vom"]
# Import/export costs
print(f"Import Cost: ${results.cost_breakdown['imports_cost']:,.2f}")
print(f"Export Revenue: ${results.cost_breakdown['exports_revenue']:,.2f}")
Accessing Problem Information#
# Solver problem statistics
problem_info = results.get_problem_info()
print(f"Constraints: {problem_info['Number of constraints']}")
print(f"Variables: {problem_info['Number of variables']}")
print(f"Binary Variables: {problem_info['Number of binary variables']}")
OptimizationResults Attributes#
Solver Information#
Attribute |
Type |
Description |
|---|---|---|
|
str |
Solver termination status (e.g., ‘optimal’, ‘infeasible’) |
|
str |
Overall solver status (e.g., ‘ok’, ‘warning’) |
|
bool |
Property: True if solution is optimal |
Core Results#
Attribute |
Type |
Description |
|---|---|---|
|
float |
Total objective value ($) |
|
float |
Generation mix target used |
Capacity Results#
Attribute |
Type |
Description |
|---|---|---|
|
dict |
Generation capacities by technology (MW) |
|
dict |
Nested dict with ‘charge’, ‘discharge’, ‘energy’ by technology |
|
float |
Property: Solar PV capacity (MW) |
|
float |
Property: Wind capacity (MW) |
|
float |
Property: Thermal capacity (MW) |
|
dict |
Property: Storage charge capacity by tech (MW) |
|
dict |
Property: Storage discharge capacity by tech (MW) |
|
dict |
Property: Storage energy capacity by tech (MWh) |
Generation Results#
Attribute |
Type |
Description |
|---|---|---|
|
dict |
Total generation by technology (MWh) |
|
float |
Property: Total PV generation (MWh) |
|
float |
Property: Total wind generation (MWh) |
|
float |
Property: Total thermal generation (MWh) |
Cost Breakdown#
Attribute |
Type |
Description |
|---|---|---|
|
dict |
Nested dict with ‘capex’, ‘power_capex’, ‘energy_capex’, ‘fom’, ‘vom’, ‘fuel_cost’, ‘imports_cost’, ‘exports_revenue’ |
DataFrames#
Attribute |
Type |
Description |
|---|---|---|
|
pd.DataFrame |
Hourly generation dispatch |
|
pd.DataFrame |
Hourly storage operation |
|
pd.DataFrame |
Disaggregated thermal generation |
|
pd.DataFrame |
Summary metrics |