Output functions

    collect_results

    MacroEnergy.collect_resultsFunction
    collect_results(system::System, model::Model, settings::NamedTuple, scaling::Float64=1.0)

    Returns a DataFrame with all the results after the optimization is performed.

    Arguments

    • system::System: The system object containing the case inputs.
    • model::Model: The model being optimized.
    • settings::NamedTuple: The settings for the system, including output configurations.
    • scaling::Float64: The scaling factor for the results.

    Returns

    • DataFrame: A `DataFrame containing all the outputs from a system.

    Example

    collect_results(system, model)
    198534×12 DataFrame
        Row │ case_name  commodity    commodity_subtype  zone        resource_id                component_id                       type              variable  segment  time   value
            │ Missing    Symbol       Symbol             Symbol      Symbol                     Symbol                             Symbol            Symbol    Int64    Int64  Float64
    ────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
          1 │   missing  Biomass      flow               bioherb_SE  SE_BECCS_Electricity_Herb  SE_BECCS_Electricity_Herb_biomas…  BECCSElectricity  flow            1      1  0.0
          2 │   missing  Biomass      flow               bioherb_SE  SE_BECCS_Electricity_Herb  SE_BECCS_Electricity_Herb_biomas…  BECCSElectricity  flow            1      2  0.0
          3 │   missing  Biomass      flow               bioherb_SE  SE_BECCS_Electricity_Herb  SE_BECCS_Electricity_Herb_biomas…  BECCSElectricity  flow            1      3  0.0
          ...
    source

    get_optimal_capacity

    MacroEnergy.get_optimal_capacityFunction
    get_optimal_capacity(system::System; scaling::Float64=1.0)

    Get the optimal capacity values for all assets/edges in a system.

    Arguments

    • system::System: The system containing the assets/edges to analyze
    • scaling::Float64: The scaling factor for the results.

    Returns

    • DataFrame: A dataframe containing the optimal capacity values for all assets/edges, with missing columns removed

    Example

    get_optimal_capacity(system)
    153×8 DataFrame
     Row │ commodity    commodity_subtype  zone           resource_id                        component_id                       type              variable  value    
         │ Symbol       Symbol             Symbol         Symbol                             Symbol                             Symbol            Symbol    Float64 
    ─────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
       1 │ Electricity  capacity           elec_SE        existing_solar_SE                  existing_solar_SE_edge             VRE               capacity   8.5022
       2 │ Electricity  capacity           elec_NE        existing_solar_NE                  existing_solar_NE_edge             VRE               capacity   0.0   
       3 │ Electricity  capacity           elec_NE        existing_wind_NE                   existing_wind_NE_edge              VRE               capacity   3.6545
    source

    get_optimal_discounted_costs

    get_optimal_flow

    MacroEnergy.get_optimal_flowFunction
    get_optimal_flow(
        system::System; 
        scaling::Float64=1.0, 
        commodity::Union{AbstractString,Vector{<:AbstractString},Nothing}=nothing, 
        asset_type::Union{AbstractString,Vector{<:AbstractString},Nothing}=nothing
    )

    Get the optimal flow values for all edges in a system.

    Filtering

    Results can be filtered by:

    • commodity: Specific commodity type(s)
    • asset_type: Specific asset type(s)

    Pattern Matching

    Two types of pattern matching are supported:

    1. Parameter-free matching:

      • "ThermalPower" matches any ThermalPower{...} type (i.e. no need to specify parameters inside {})
    2. Wildcards using "*":

      • "ThermalPower*" matches ThermalPower{Fuel}, ThermalPowerCCS{Fuel}, etc.
      • "CO2*" matches CO2, CO2Captured, etc.

    Arguments

    • system::System: The system containing the all edges to output
    • scaling::Float64: The scaling factor for the results.
    • commodity::Union{AbstractString,Vector{<:AbstractString},Nothing}: The commodity to filter by
    • asset_type::Union{AbstractString,Vector{<:AbstractString},Nothing}: The asset type to filter by

    Returns

    • DataFrame: A dataframe containing the optimal flow values for all edges, with missing columns removed

    Example

    get_optimal_flow(system)
    186984×11 DataFrame
        Row │ commodity    commodity_subtype  zone        resource_id                component_id                       type              variable  segment  time   value     
            │ Symbol       Symbol             Symbol      Symbol                     Symbol                             Symbol            Symbol    Int64    Int64  Float64
    ────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
          1 │ Biomass      flow               bioherb_SE  SE_BECCS_Electricity_Herb  SE_BECCS_Electricity_Herb_biomas…  BECCSElectricity  flow            1      1  0.0    
          2 │ Biomass      flow               bioherb_SE  SE_BECCS_Electricity_Herb  SE_BECCS_Electricity_Herb_biomas…  BECCSElectricity  flow            1      2  0.0    
          3 │ Biomass      flow               bioherb_SE  SE_BECCS_Electricity_Herb  SE_BECCS_Electricity_Herb_biomas…  BECCSElectricity  flow            1      3  0.0    
          ...
    # Filter by commodity
    get_optimal_flow(system, commodity="Electricity")
    # Filter by commodity and asset type using parameter-free matching
    get_optimal_flow(system, commodity="Electricity", asset_type="ThermalPower") # only ThermalPower{Fuel} will be returned
    # Filter by commodity and asset type using wildcard matching
    get_optimal_flow(system, commodity="Electricity", asset_type="ThermalPower*") # all types starting with ThermalPower (e.g., ThermalPower{Fuel}, ThermalPowerCCS{Fuel}) will be returned)
    source
    get_optimal_flow(asset::AbstractAsset, scaling::Float64=1.0)

    Get the optimal flow values for all edges in an asset.

    Arguments

    • asset::AbstractAsset: The asset containing the edges to analyze
    • scaling::Float64: The scaling factor for the results.

    Returns

    • DataFrame: A dataframe containing the optimal flow values for all edges, with missing columns removed

    Example

    asset = get_asset_by_id(system, :elec_SE)
    get_optimal_flow(asset)
    source

    get_optimal_new_capacity

    MacroEnergy.get_optimal_new_capacityFunction
    get_optimal_new_capacity(system::System; scaling::Float64=1.0)

    Get the optimal new capacity values for all assets/edges in a system.

    Arguments

    • system::System: The system containing the assets/edges to analyze
    • scaling::Float64: The scaling factor for the results.

    Returns

    • DataFrame: A dataframe containing the optimal new capacity values for all assets/edges, with missing columns removed

    Example

    get_optimal_new_capacity(system)
    153×8 DataFrame
     Row │ commodity    commodity_subtype  zone           resource_id                        component_id                       type              variable      value  
         │ Symbol       Symbol             Symbol         Symbol                             Symbol                             Symbol            Symbol        Float64
    ─────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
       1 │ Biomass      capacity           bioherb_SE     SE_BECCS_Electricity_Herb          SE_BECCS_Electricity_Herb_biomas…  BECCSElectricity  new_capacity      0.0
       2 │ Biomass      capacity           bioherb_MIDAT  MIDAT_BECCS_Electricity_Herb       MIDAT_BECCS_Electricity_Herb_bio…  BECCSElectricity  new_capacity      0.0
       3 │ Biomass      capacity           bioherb_NE     NE_BECCS_Electricity_Herb          NE_BECCS_Electricity_Herb_biomas…  BECCSElectricity  new_capacity      0.0
    source

    get_optimal_retired_capacity

    MacroEnergy.get_optimal_retired_capacityFunction
    get_optimal_retired_capacity(system::System; scaling::Float64=1.0)

    Get the optimal retired capacity values for all assets/edges in a system.

    Arguments

    • system::System: The system containing the assets/edges to analyze
    • scaling::Float64: The scaling factor for the results.

    Returns

    • DataFrame: A dataframe containing the optimal retired capacity values for all assets/edges, with missing columns removed

    Example

    get_optimal_retired_capacity(system)
    153×8 DataFrame
     Row │ commodity    commodity_subtype  zone           resource_id                        component_id                       type              variable      value    
         │ Symbol       Symbol             Symbol         Symbol                             Symbol                             Symbol            Symbol        Float64  
    ─────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
       1 │ Biomass      capacity           bioherb_SE     SE_BECCS_Electricity_Herb          SE_BECCS_Electricity_Herb_biomas…  BECCSElectricity  retired_capacity  0.0
       2 │ Biomass      capacity           bioherb_MIDAT  MIDAT_BECCS_Electricity_Herb       MIDAT_BECCS_Electricity_Herb_bio…  BECCSElectricity  retired_capacity  0.0
       3 │ Biomass      capacity           bioherb_NE     NE_BECCS_Electricity_Herb          NE_BECCS_Electricity_Herb_biomas…  BECCSElectricity  retired_capacity  0.0
    source

    write_balance_duals

    MacroEnergy.write_balance_dualsFunction
    write_balance_duals(results_dir::AbstractString, system::System, scaling::Float64=1.0)

    Write balance constraint dual values (marginal prices) to CSV file.

    Extracts dual values from the :demand balance equation on all nodes and exports them to balance_duals.csv. The dual values are automatically rescaled by subperiod weights to provide proper marginal values per unit of energy/commodity.

    Note: Only nodes with a :demand balance equation will be included in the output. Nodes with other balance equations (e.g., :emissions, :co2_storage) are skipped.

    Output Format

    Wide-format CSV with:

    • Rows: Time steps
    • Columns: Node IDs
    • Values: Rescaled dual values (shadow prices) for the :demand balance equation

    Arguments

    • results_dir::AbstractString: Directory where CSV file will be written
    • system::System: The system containing solved balance constraints
    • scaling::Float64: Scaling factor for the dual values (e.g. to account for discounting in multi-period models)

    Examples

    write_balance_duals("results/", system)
    # Creates: results/balance_duals.csv
    source

    write_capacity

    MacroEnergy.write_capacityFunction
    write_capacity(
        file_path::AbstractString, 
        system::System; 
        scaling::Float64=1.0, 
        drop_cols::Vector{AbstractString}=String[], 
        commodity::Union{AbstractString,Vector{AbstractString},Nothing}=nothing, 
        asset_type::Union{AbstractString,Vector{AbstractString},Nothing}=nothing
    )

    Write the optimal capacity results for all assets/edges in a system to a file. The extension of the file determines the format of the file. Capacity, NewCapacity, and RetiredCapacity are first concatenated and then written to the file.

    Filtering

    Results can be filtered by:

    • commodity: Specific commodity type(s)
    • asset_type: Specific asset type(s)

    Pattern Matching

    Two types of pattern matching are supported:

    1. Parameter-free matching:

      • "ThermalPower" matches any ThermalPower{...} type (i.e. no need to specify parameters inside {})
    2. Wildcards using "*":

      • "ThermalPower*" matches ThermalPower{Fuel}, ThermalPowerCCS{Fuel}, etc.
      • "CO2*" matches CO2, CO2Captured, etc.

    Arguments

    • file_path::AbstractString: The path to the file where the results will be written
    • system::System: The system containing the assets/edges to analyze as well as the settings for the output
    • scaling::Float64: The scaling factor for the results
    • drop_cols::Vector{AbstractString}: Columns to drop from the DataFrame
    • commodity::Union{AbstractString,Vector{AbstractString},Nothing}: The commodity to filter by
    • asset_type::Union{AbstractString,Vector{AbstractString},Nothing}: The asset type to filter by

    Returns

    • nothing: The function returns nothing, but writes the results to the file

    Example

    write_capacity("capacity.csv", system)
    # Filter by commodity
    write_capacity("capacity.csv", system, commodity="Electricity")
    # Filter by commodity and asset type using parameter-free matching
    write_capacity("capacity.csv", system, asset_type="ThermalPower")
    # Filter by asset type using wildcard matching
    write_capacity("capacity.csv", system, asset_type="ThermalPower*")
    # Filter by commodity and asset type
    write_capacity("capacity.csv", system, commodity="Electricity", asset_type=["ThermalPower", "Battery"])
    source

    write_co2_cap_duals

    MacroEnergy.write_co2_cap_dualsFunction
    write_co2_cap_duals(results_dir::AbstractString, system::System, scaling::Float64=1.0)

    Write CO2 cap constraint dual values (carbon prices) and penalty costs to CSV file.

    Extracts dual values from CO2 cap policy budget constraints and exports them to co2_cap_duals.csv. If slack variables exist, also exports penalty costs.

    Output Format

    Long-format CSV with columns:

    • node: Node ID
    • co2_shadow_price: Carbon price
    • co2_penalty_cost: Total penalty cost across subperiods (if slack variables exist)

    Arguments

    • results_dir::AbstractString: Directory where CSV file will be written
    • system::System: The system containing solved CO2 cap constraints
    • scaling::Float64: Scaling factor for the dual values (e.g. to account for discounting in multi-period models)

    Examples

    write_co2_cap_duals("results/", system)
    # Creates: results/co2_cap_duals.csv
    source

    write_costs

    MacroEnergy.write_costsFunction
    write_costs(
        file_path::AbstractString, 
        system::System, 
        model::Union{Model,NamedTuple}; 
        scaling::Float64=1.0, 
        drop_cols::Vector{AbstractString}=String[]
    )

    Write the optimal cost results for all assets/edges in a system to a file. The extension of the file determines the format of the file.

    Arguments

    • file_path::AbstractString: The path to the file where the results will be written
    • system::System: The system containing the assets/edges to analyze as well as the settings for the output
    • model::Union{Model,NamedTuple}: The optimal model after the optimization
    • scaling::Float64: The scaling factor for the results
    • drop_cols::Vector{AbstractString}: Columns to drop from the DataFrame

    Returns

    • nothing: The function returns nothing, but writes the results to the file
    source

    write_duals

    MacroEnergy.write_dualsFunction
    write_duals(results_dir::AbstractString, system::System, scaling::Float64=1.0)

    Write dual values for all supported constraint types to separate CSV files.

    Currently, this function exports dual values for:

    • Balance constraints → balance_duals.csv
    • CO2 cap constraints → co2_cap_duals.csv

    Arguments

    • results_dir::AbstractString: Directory where CSV files will be written
    • system::System: The system containing solved constraints with dual values
    • scaling::Float64: Scaling factor for the dual values (e.g. to account for discounting in multi-period models)

    Examples

    # After solving the model
    (case, model) = solve_case(case, optimizer);
    system = case.systems[1]; # single period case
    
    # Export all dual values
    write_duals("results/", system)

    See Also

    source

    write_duals_benders

    MacroEnergy.write_duals_bendersFunction
    write_duals_benders(
        results_dir::AbstractString,
        system::System,
        scaling::Float64=1.0
    )

    Write dual values for Benders decomposition results.

    This function is slightly different than the one for other solution algorithms as the dual values for balance constraints are already undiscounted (the objective function for the operational subproblems is already undiscounted). CO2 cap constraint duals come from the planning problem which is discounted (so scaling is applied).

    Arguments

    • results_dir::AbstractString: Directory where CSV files will be written
    • system::System: The system containing solved constraints with dual values
    • scaling::Float64: Scaling factor for CO2 cap constraint duals (default is 1.0)
    source

    write_flow

    MacroEnergy.write_flowFunction
    write_flow(
        file_path::AbstractString, 
        system::System; 
        scaling::Float64=1.0, 
        drop_cols::Vector{<:AbstractString}=String[],
        commodity::Union{AbstractString,Vector{<:AbstractString},Nothing}=nothing,
        asset_type::Union{AbstractString,Vector{<:AbstractString},Nothing}=nothing
    )

    Write the optimal flow results for the system to a file. The extension of the file determines the format of the file.

    Filtering

    Results can be filtered by:

    • commodity: Specific commodity type(s)
    • asset_type: Specific asset type(s)

    Pattern Matching

    Two types of pattern matching are supported:

    1. Parameter-free matching:

      • "ThermalPower" matches any ThermalPower{...} type (i.e. no need to specify parameters inside {})
    2. Wildcards using "*":

      • "ThermalPower*" matches ThermalPower{Fuel}, ThermalPowerCCS{Fuel}, etc.
      • "CO2*" matches CO2, CO2Captured, etc.

    Arguments

    • file_path::AbstractString: The path to the file where the results will be written
    • system::System: The system containing the edges to analyze as well as the settings for the output
    • scaling::Float64: The scaling factor for the results
    • drop_cols::Vector{<:AbstractString}: Columns to drop from the DataFrame
    • commodity::Union{AbstractString,Vector{<:AbstractString},Nothing}: The commodity to filter by
    • asset_type::Union{AbstractString,Vector{<:AbstractString},Nothing}: The asset type to filter by

    Returns

    • nothing: The function returns nothing, but writes the results to the file

    Example

    write_flow("flow.csv", system)
    # Filter by commodity
    write_flow("flow.csv", system, commodity="Electricity")
    # Filter by commodity and asset type using parameter-free matching
    write_flow("flow.csv", system, commodity="Electricity", asset_type="ThermalPower")
    # Filter by commodity and asset type using wildcard matching
    write_flow("flow.csv", system, commodity="Electricity", asset_type="ThermalPower*")
    source

    write_settings

    MacroEnergy.write_settingsFunction
    write_settings(case::Case, filepath::AbstractString)

    Write the case and system settings to a JSON file.

    This function extracts the settings from a Case object and writes them to a JSON file. The settings include both case-level settings and system-level settings for all systems in the case.

    Arguments

    • case::Case: The case object containing the settings to write
    • filepath::AbstractString: The full path to the output JSON file

    Returns

    • nothing: The function returns nothing, but writes the settings to the specified file

    Example

    # Write settings to a JSON file
    write_settings(case, "output/settings.json")
    
    # Write settings to a case results directory
    write_settings(case, joinpath(case_path, "settings.json"))

    Output Format

    The JSON file will contain:

    • case_settings: The case-level settings
    • system_settings: An array of settings for each system in the case
    source

    write_dataframe

    MacroEnergy.write_dataframeFunction
    write_dataframe(
        file_path::AbstractString, 
        df::AbstractDataFrame, 
        drop_cols::Vector{<:AbstractString}=String[]
    )

    Write a DataFrame to a file in the appropriate format based on file extension. Supported formats: .csv, .csv.gz, .parquet

    Arguments

    • file_path::AbstractString: Path where to save the file
    • df::AbstractDataFrame: DataFrame to write
    • drop_cols::Vector{<:AbstractString}: Columns to drop from the DataFrame
    source

    write_results

    MacroEnergy.write_resultsFunction
    write_results(file_path::AbstractString, system::System, model::Model, settings::NamedTuple)

    Collects all the results as a DataFrame and then writes them to disk after the optimization is performed.

    Arguments

    • file_path::AbstractString: full path of the file to export.
    • system::System: The system object containing the case inputs.
    • model::Model: The model being optimized.
    • settings::NamedTuple: The settings for the system, including output configurations.

    Returns

    Example

    write_results(case_path, system, model, settings, ext=".csv") # CSV
    write_results(case_path, system, model, settings, ext=".csv.gz")  # GZIP
    write_results(case_path, system, model, settings, ext=".parquet") # PARQUET
    source

    MacroEnergy.write_outputs

    MacroEnergy.write_outputsFunction

    Write results when using Monolithic as solution algorithm.

    source

    Write results when using Myopic as solution algorithm.

    source

    Write results when using Benders as solution algorithm.

    source
    Fallback function to write outputs for a single period.
    source

    MacroEnergy.write_period_outputs