API Reference

Docstrings for the exported PowerGridPlanning API. See the Usage Guide for the full parameter reference and the Examples for worked end-to-end runs.

Planning and verification

PowerGridPlanning.solve_otsFunction
solve_ots(opt_parameters::Dict)

Solve a wildfire-aware Optimal Transmission Switching problem.

Required Parameters

  • :network => String - Network name (e.g., "RTS", "CATS", "Texas7k", "Texas2k", "WECC240"). Optional when :case_file is given (defaults to the case file's basename, used as a label).
  • :model => String - "DCOTS" or "LACOTS"
  • :objective => String - "loadshed", "wildfire", "cost", or "tradeoff"
  • :times => Array or String - Time specification:
    • Array of tuples: [(year, month, day), ...]
    • Year string: "2020"
    • Month string: "June 2021"

User-Supplied Networks

  • :case_file => String - Path to any MATPOWER .m case (absolute or relative to the current directory). Bypasses the named-network lookup. Loads default to the case's Pd/Qd scaled by the built-in synthetic hourly profile. A bare case has no geographic data, so features that correlate the grid with geodata degrade explicitly:
    • DCOTS/LACOTS require :risk_per_line (USGS FPI auto-load is unavailable); DCOPF/LACOPF work out of the box.
    • Plotting (:plots) and hardening require :bus_coords (hardening alternatively accepts :line_lengths); both error up front if missing.
    • Solar siting works without geodata via the flat :solar_capacity_factor_default, or supply per-bus profiles via :solar_data_path.
  • :bus_coords => String or DataFrame - Bus coordinates with columns BusID, lat, lng (common aliases like busid/latitude/lon accepted). Also overrides the bundled coordinates for named networks.
  • :line_lengths => Dict{Int,Float64} - Per-line lengths in miles for hardening costs; alternative to :bus_coords. Lines not listed get length 0 (with a warning).

Optional Parameters

  • :switching_method => String - Solution method: "optimal" (default) or "thresholded"
  • :wildfire_data => Dict - Wildfire risk data (lineid => riskvalue). Auto-loaded from data/USGS_FPI if not provided
  • :risk_metric => String - For CATS: risk metric to use ("maxwfpi", "meanwfpi", "cumwfpi", etc.) (default: "cumwfpi")
  • :T => Int - Hours per day (default: 24)
  • :tradeoff_weight => Float64 - For "tradeoff" objective, 0=loadshed, 1=wildfire (default: 0.5)
  • :threshold => Float64 - Risk threshold (loadshed obj) or loadshed threshold (wildfire obj). Required for "thresholded" method.
  • :threshold_pct => Float64 - Percentage threshold (0.8 = keep 80% of risk, remove 20%)
  • :voll => Float64 - Value of Lost Load in USD/MWh for "cost" objective (default: 10000.0)
  • :warm_start => Dict or String - For LACOTS: warm start values or "auto" to run DCOTS first
  • :non_linear => Bool - For LACOTS: use non-linear apparent power constraints (default: false)
  • :optimizer - JuMP optimizer constructor, e.g. HiGHS.Optimizer (default: Gurobi.Optimizer)
  • :silent => Bool - Suppress solver log output (default: false)
  • :time_limit => Float64 - Solver time limit in seconds (default: 86400.0)
  • :mip_gap => Float64 - MIP optimality gap (default: 0.01)
  • :output_format => String - "dict", "jld2", or "txt" (default: "dict")
  • :output_path => String - File path for output (required if format is "jld2" or "txt")
  • :lp_str => String - If provided, save the optimization model to an LP file at this path (default: "")
  • :log_str => String - If provided, save Gurobi solver log output to a file at this path (default: "")

Returns

Results dictionary or writes to file based on output_format

source
PowerGridPlanning.solve_opfFunction
solve_opf(opt_parameters::Dict, planning_results::Union{Dict,Nothing}=nothing)

Solve a non-switching OPF planning model (:model => "DCOPF" or "LACOPF") using the same investment-planning controls as solve_ots. For nonlinear AC replay or recovery (:mode => "ACPF" or "ACOPF"), delegates to verify_ac.

source
PowerGridPlanning.verify_acFunction
verify_ac(ac_parameters::Dict, planning_results::Union{Dict,Nothing}=nothing)

Run package-owned polar AC feasibility checks (mode = "ACPF") or redispatch with load shedding (mode = "ACOPF"). Planning results are replayed as fixed line statuses, fixed load allocations, and fixed resource capacities; no AC planning variables are created.

source
PowerGridPlanning.solve_with_ac_feedbackFunction
solve_with_ac_feedback(opt_parameters::Dict, ac_parameters::Dict; max_iterations::Int=1)

Run one planning solve with solve_ots, verify the fixed planning decisions with verify_ac, and return the planning results, AC results, and diagnostic feedback hints. The feedback loop currently supports a single planning/verification pass.

source
PowerGridPlanning.write_ac_diagnostic_reportFunction
write_ac_diagnostic_report(results::Dict, filepath::String)

Write a Markdown AC diagnostic report from verify_ac results. The report summarizes feasibility, violation counts, top violations, and feedback hints, creating the destination directory when needed.

source

Plotting

PowerGridPlanning.plot_resultsFunction
plot_results(results, features; format="pdf", output_dir=".", plot_dir="", day=nothing, infrastructure_off=false, ls_off=false, kwargs...)

Generate publication-quality plots from solveots() or solveopf() results.

Arguments

  • results: Dict from solveots()/solveopf(), String path to .jld2 file, or Vector{Dict} for :tradeoff_curve
  • features: Vector of Symbols — which plots to generate (see documentation for full list)
  • format: Output format — "png", "pdf", "svg", "eps" (default: "pdf")
  • output_dir: Directory to save output files (default: current directory)
  • plot_dir: Alternative to output_dir — if non-empty, takes precedence (default: "")
  • day: For geographic plots — nothing=aggregate view, Int=specific day (default: nothing)
  • infrastructure_off: For :network_overview — hide infrastructure layer (batteries, solar, hardened lines) (default: false)
  • ls_off: For :network_overview — hide load shed bubble layer (default: false)
  • kwargs...: Passed through to underlying renderers (dpi, size, fontsize, etc.)

Feature Symbols

  • :network_overview — All layers combined (branches, buses, infrastructure, load shed)
  • :load_shed_timeseries — Hourly load shedding bar chart (T1)
  • :battery_dispatch — SOC and charge/discharge profiles (T2)
  • :solar_generation — Hourly solar generation (T3)
  • :generation_dispatch — Total generation over time (T4)
  • :tradeoff_curve — Risk vs. load shed Pareto curve (S1); requires Vector{Dict} input
  • :cost_breakdown — Infrastructure cost bar chart (S2)
source

Results I/O

PowerGridPlanning.load_txtFunction
load_txt(filepath::String) -> Dict

Load results from a text file saved by save_txt. Returns a dictionary containing all variable data.

source

Data fetchers

PowerGridPlanning.get_network_solar_dataFunction
get_network_solar_data(network_name::String, date; api_key::String="", save_to_file::Bool=false, output_dir::String="")

Fetch solar generation profiles for all buses in a network.

Arguments

  • network_name: Name of the network (e.g., "RTS", "Texas7k")
  • date: Date input. Can be:
    • Date object
    • Tuple (year, month, day)
    • String "all" for the full year (8760 hours)
  • api_key: NREL API key. If not provided, checks ENV["NRELAPIKEY"] or uses "DEMO_KEY"
  • save_to_file: If true, saves data to CSV instead of returning it.
  • output_dir: Optional override for output directory. If empty, defaults to "data/solarcurves/<networkmapped_name>"

Returns

  • If save_to_file is false: Dict{Int, Dict{String, Vector{Float64}}}
  • If save_to_file is true: Nothing
source
PowerGridPlanning.get_network_censusFunction
get_network_census(network_name; kwargs...) -> String

End-to-end entry point. Pulls tract demographics within radius_m of any bus in the network, runs the 3-pass assignment against load buses, aggregates to per-bus totals, and writes a single CSV to <data_dir>/census_data/<network_name>_census_<acs_year>.csv. Returns the output path.

Keyword arguments

  • api_key::String="" — Census API key (or CENSUS_API_KEY env var; anonymous fallback ~500 req/day)
  • acs_year::Int=2022
  • radius_m::Float64=25_000.0 — per-bus tract-inclusion radius (meters)
  • weighting::Symbol=:inverse:inverse (default) or :proportional
  • data_dir::String="data"
  • output_path::String="" — override the default output location
source
PowerGridPlanning.load_census_dataFunction
load_census_data(network_name; acs_year=2022, data_dir="data", file_path="") -> DataFrame

Load the unified per-bus Census ACS demographics for a network.

Expects a CSV at <data_dir>/census_data/<network_name>_census_<acs_year>.csv produced by get_network_census. Returns an empty typed DataFrame (with @warn) if the file is missing — plotting and downstream use should degrade gracefully rather than crash.

Returns

DataFrame with columns: BusID, totalpop, numhouseholds, numwhite, numblack, numnative, numasian, numhispanic, numbelowpoverty, numabovepoverty, numlowincome, nummiddleincome, numhighincome, median_income.

source