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_ots — Function
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_fileis 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.mcase (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.
- DCOTS/LACOTS require
: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
PowerGridPlanning.solve_opf — Function
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.
PowerGridPlanning.verify_ac — Function
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.
PowerGridPlanning.solve_with_ac_feedback — Function
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.
PowerGridPlanning.write_ac_diagnostic_report — Function
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.
Plotting
PowerGridPlanning.plot_results — Function
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_curvefeatures: 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 tooutput_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)
Results I/O
PowerGridPlanning.load_txt — Function
load_txt(filepath::String) -> DictLoad results from a text file saved by save_txt. Returns a dictionary containing all variable data.
Data fetchers
PowerGridPlanning.get_network_solar_data — Function
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_fileis false: Dict{Int, Dict{String, Vector{Float64}}} - If
save_to_fileis true: Nothing
PowerGridPlanning.get_network_census — Function
get_network_census(network_name; kwargs...) -> StringEnd-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 (orCENSUS_API_KEYenv var; anonymous fallback ~500 req/day)acs_year::Int=2022radius_m::Float64=25_000.0— per-bus tract-inclusion radius (meters)weighting::Symbol=:inverse—:inverse(default) or:proportionaldata_dir::String="data"output_path::String=""— override the default output location
PowerGridPlanning.load_census_data — Function
load_census_data(network_name; acs_year=2022, data_dir="data", file_path="") -> DataFrameLoad 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.