Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# PowerSystemCaseBuilder.jl (PSB) — psy6 branch

The Sienna **test-system fixture factory**: a registry of 200+ named `PSY.System` cases built from raw data (Matpower, PSSE raw/dyr, tabular CSV, PowerFlowData) with an on-disk serialized cache, so downstream test suites (PSY, PNM, PF, POM) get systems in seconds. Not an optimization package. Its serialization is PSY's own IS-based JSON+HDF5 — **not** the OpenAPI/GridDB pipeline. Platform conventions: the `sienna-psy6` skill; workspace architecture: the psy6 workspace root `CLAUDE.md`.
The Sienna **test-system fixture factory**: a registry of 200+ named `PSY.System` cases built from raw data (Matpower, PSSE raw/dyr, tabular CSV, PowerFlowData) with an on-disk serialized cache, so downstream test suites (PSY, PNM, PF, POM) get systems in seconds. Not an optimization package. Both building and caching go through the OpenAPI document: parsers emit one, `PSY.from_file` reads it, and the cache is PSY's `.sns` archive of it. Platform conventions: the `sienna-psy6` skill; workspace architecture: the psy6 workspace root `CLAUDE.md`.

## Why this package matters platform-wide

Expand All @@ -16,7 +16,7 @@ build_system(PSITestSystems, "c_sys5"; force_build=true) # categories: PSY/PSI
list_systems(...); show_systems(...); list_categories()
```

- Flow (`src/build_system.jl` + `src/utils/utils.jl`): cache check → optional artifact download → registered `build_func(; raw_data, …)` → serialize (unless `skip_serialization`) → later calls deserialize. Cache dir: `data/serialized_system/<sha256 of case-args>/<name>.json` + `_metadata.json` + `_validation_descriptors.json` + `_time_series_storage.h5`.
- Flow (`src/build_system.jl` + `src/utils/utils.jl`): cache check → optional artifact download → registered `build_func(; raw_data, …)` → serialize (unless `skip_serialization`) → later calls deserialize. Cache entry: `data/serialized_system/<sha256 of case-args>/<name>.sns`, written by `PSY.to_file`.
- `build_system` splits kwargs: keys in `PSY.SYSTEM_KWARGS` forward to `PSY.System`; the rest must match the descriptor's `supported_arguments` or error. Non-encodable `sys_args` skip caching entirely.
- Catalog: `SYSTEM_CATALOG` in `src/system_descriptor_data.jl` (~228 `SystemDescriptor` entries; duplicate names error); builders in `src/library/` (8 catalog files); include order puts the catalog last, after all builders.
- Raw data via lazy artifacts (`Artifacts.toml`): `CaseData` = PowerSystemsTestData tarball (currently a 5.0-dev tag), `rts` = RTS-GMLC. **The CaseData download can flake — retry once before digging**; there is no retry in the code. Re-pin the sha256 when PowerSystemsTestData re-tags.
Expand All @@ -37,7 +37,7 @@ Why PSB feels this harder than other packages: **the cache stores serialized sys
- Branch `psy6`; `[sources]` pins in **both** root and `test/Project.toml`: IS→`IS4`, PowerSystems→`psy6`, PowerFlowFileParser→`psy6`, PowerTableDataParser→`psy6`. ⚠️ Org URLs are inconsistent across the manifests, but note which way: **`NLR-Sienna/PowerTableDataParser.jl` is correct, not a typo** — it is the canonical location, and `NREL-Sienna/PowerTableDataParser.jl` only reaches it via a GitHub 301 (`Sienna-Platform/PowerTableDataParser.jl` is a 404). Every *other* Sienna repo has moved the opposite way: `NREL-Sienna/*` now 301-redirects to `Sienna-Platform/*`. So most `NREL-Sienna` URLs here are stale-but-working, while the one that looks misspelled is the accurate one. Verify with `curl -sI` before "correcting" any of them.
- ⚠️ `test/Project.toml` may still pin PSY to `transformer-refactor` and PowerFlowFileParser to `mb/transformer-refactor`. Both are merged now — PSY `d19f3244f`, PFFP `adf5cb1` — so those revs are stale and should read `psy6`. The *root* `Project.toml` pin was always correct, which is why PSB works as a dependency even when its own test env does not resolve.
- **`src/utils/psy6_compat.jl` is a sanctioned exception to the no-shims policy**: method overloads accepting old `Nothing`/Float64 signatures (`ReserveDemandCurve`/`MarketBidCost`) because the pinned PowerSystemsTestData artifact still uses pre-psy6 constructor calls. Scoped to external artifact data only; include-order sensitive (after `definitions.jl`, before `system_library.jl`). Remove it when the artifact is regenerated — never widen it.
- Parsing goes through PowerFlowFileParser/PowerTableDataParser (PSY has no parsers in this line).
- Parsing goes through PowerFlowFileParser/PowerTableDataParser (PSY has no parsers in this line). Every PSS/E, Matpower and tabular case builds via `system_from_openapi` (`src/parsers/openapi_pipeline.jl`): parser → OpenAPI document → `PSY.from_file`. `.dyr` dynamics are still attached afterwards by PSB's own `add_dyn_injectors!` (`src/parsers/psse_dynamic_data.jl`); PowerFlowFileParser does not read `.dyr`.
- Reduction fixtures (for PNM/PF/POM work): `c_sys5`/`c_sys14` reduce **nothing**; `case11_network_reductions` has real series arcs but no forecasts; matpower RTS/case24 for larger cases.
- Compat still reads PSY ^5.10 / IS ^3.2 — the `[sources]` revs, not compat, select the breaking line. No version bumps until release.

Expand Down
2 changes: 0 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce"
TimeSeries = "9e3dc215-6440-5c97-bce1-76c03772f85e"
Unicode = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"

# PowerSystems depends on these unregistered packages and [sources] are not inherited
Expand Down Expand Up @@ -74,6 +73,5 @@ PrettyTables = "2.4, 3.1"
Random = "1"
SHA = "0.7, 1"
TimeSeries = "^0.24, ^0.25"
Unicode = "1.11.0"
YAML = "0.4.16"
julia = "^1.10"
5 changes: 0 additions & 5 deletions src/PowerSystemCaseBuilder.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ import PrettyTables
import PowerFlowFileParser
import PowerTableDataParser

# imports for parsers/ to work
import Unicode: normalize

#TimeStamp Management Imports
import TimeSeries
import Dates
Expand Down Expand Up @@ -147,10 +144,8 @@ Category for SiennaPRASInterface.jl examples.
struct SPISystems <: SystemCategory end

# Include Parsing files
include("parsers/common.jl")
include("parsers/known_stale_fixture_data.jl")
include("parsers/openapi_pipeline.jl")
include("parsers/power_models_data.jl")
include("parsers/psse_dynamic_data.jl")
include("parsers/psse_metadata_reimport.jl")

Expand Down
3 changes: 2 additions & 1 deletion src/library/matpowertest_library.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
function build_matpower(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
sys = make_system(PowerFlowFileParser.PowerModelsData(raw_data); sys_kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
sys = system_from_openapi(drop_known_unread_matpower_data!(pm_data); sys_kwargs...)
return sys
end
2 changes: 1 addition & 1 deletion src/library/psi_library.jl
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ end

function build_5_bus_hydro_uc_sys(; add_forecasts, raw_data, sys_kwargs...)
# `timeseries_metadata_file` is only known once `add_forecasts` is resolved, and
# `system_from_openapi` (unlike the retired `make_system`) has no per-call override
# `system_from_openapi` has no per-call override
# for it — it always reads whatever is set on `rawsys` itself, so `rawsys` is built
# per branch rather than shared.
if add_forecasts
Expand Down
12 changes: 6 additions & 6 deletions src/library/psid_library.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function build_psid_4bus_multigen(; raw_data, kwargs...)
dyr_file = joinpath(raw_data, "FourBus_multigen.dyr")

pm_data = PowerFlowFileParser.PowerModelsData(raw_file)
sys = make_system(pm_data; sys_kwargs...)
sys = system_from_openapi(pm_data; sys_kwargs...)
add_dyn_injectors!(sys, dyr_file)
for l in get_components(PSY.StandardLoad, sys)
transform_load_to_constant_impedance(l)
Expand All @@ -18,7 +18,7 @@ function build_psid_11bus_andes(; raw_data, kwargs...)
raw_file = joinpath(raw_data, "11BUS_KUNDUR.raw")
dyr_file = joinpath(raw_data, "11BUS_KUNDUR_TGOV.dyr")
pm_data = PowerFlowFileParser.PowerModelsData(raw_file)
sys = make_system(pm_data; sys_kwargs...)
sys = system_from_openapi(pm_data; sys_kwargs...)
add_dyn_injectors!(sys, dyr_file)
for l in get_components(PSY.StandardLoad, sys)
transform_load_to_constant_impedance(l)
Expand Down Expand Up @@ -56,7 +56,7 @@ function build_psid_14bus_multigen(; raw_data, kwargs...)
dyr_file = joinpath(raw_data, "dyn_data.dyr")

pm_data = PowerFlowFileParser.PowerModelsData(raw_file)
sys = make_system(pm_data; sys_kwargs...)
sys = system_from_openapi(pm_data; sys_kwargs...)
add_dyn_injectors!(sys, dyr_file)
for l in get_components(PSY.StandardLoad, sys)
transform_load_to_constant_impedance(l)
Expand All @@ -68,14 +68,14 @@ function build_3bus_inverter(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
raw_file = joinpath(raw_data, "ThreeBusInverter.raw")
pm_data = PowerFlowFileParser.PowerModelsData(raw_file)
sys = make_system(pm_data; sys_kwargs...)
sys = system_from_openapi(pm_data; sys_kwargs...)
return sys
end

function build_psid_wecc_9_dynamic(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
sys = make_system(pm_data; runchecks = false, sys_kwargs...)
sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)

# Manually change reactance of three branches to match Sauer & Pai (2007) Figure 7.4
set_x!(get_component(Branch, sys, "Bus 5-Bus 4-i_1"), 0.085 * IS.SU)
Expand Down Expand Up @@ -166,7 +166,7 @@ end
function build_psid_load_tutorial_omib(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
sys = make_system(pm_data; runchecks = false, sys_kwargs...)
sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)
l = first(get_components(StandardLoad, sys))
exp_load = PSY.ExponentialLoad(;
name = PSY.get_name(l),
Expand Down
46 changes: 23 additions & 23 deletions src/library/psidtest_library.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function build_psid_psse_test_avr(; raw_data, kwargs...)
)
end
pm_data = PowerFlowFileParser.PowerModelsData(raw_file)
avr_sys = make_system(pm_data; sys_kwargs...)
avr_sys = system_from_openapi(pm_data; sys_kwargs...)
add_dyn_injectors!(avr_sys, dyr_file)
_set_zip_load_model!(avr_sys, :impedance)
return avr_sys
Expand Down Expand Up @@ -109,7 +109,7 @@ function build_psid_psse_test_tg(; raw_data, kwargs...)
)
end
pm_data = PowerFlowFileParser.PowerModelsData(raw_file)
tg_sys = make_system(pm_data; sys_kwargs...)
tg_sys = system_from_openapi(pm_data; sys_kwargs...)
add_dyn_injectors!(tg_sys, dyr_file)

for l in get_components(PSY.StandardLoad, tg_sys)
Expand Down Expand Up @@ -158,7 +158,7 @@ function build_psid_psse_test_gen(; raw_data, kwargs...)
)
end
pm_data = PowerFlowFileParser.PowerModelsData(raw_file)
gen_sys = make_system(pm_data; sys_kwargs...)
gen_sys = system_from_openapi(pm_data; sys_kwargs...)
add_dyn_injectors!(gen_sys, dyr_file)

for l in get_components(PSY.StandardLoad, gen_sys)
Expand Down Expand Up @@ -192,7 +192,7 @@ function build_psid_psse_test_pss(; raw_data, kwargs...)
)
end
pm_data = PowerFlowFileParser.PowerModelsData(raw_file)
pss_sys = make_system(pm_data; sys_kwargs...)
pss_sys = system_from_openapi(pm_data; sys_kwargs...)
add_dyn_injectors!(pss_sys, dyr_file)

for l in get_components(PSY.StandardLoad, pss_sys)
Expand All @@ -205,7 +205,7 @@ end
function build_psid_test_omib(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
omib_sys = make_system(pm_data; runchecks = false, sys_kwargs...)
omib_sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)
add_source_to_ref(omib_sys)

function dyn_gen_classic(generator)
Expand Down Expand Up @@ -234,7 +234,7 @@ end
function build_psid_test_threebus_oneDoneQ(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
threebus_sys = make_system(pm_data; runchecks = false, sys_kwargs...)
threebus_sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)
add_source_to_ref(threebus_sys)

function dyn_gen_oneDoneQ(generator)
Expand Down Expand Up @@ -264,7 +264,7 @@ end
function build_psid_test_threebus_simple_marconato(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
threebus_sys = make_system(pm_data; runchecks = false, sys_kwargs...)
threebus_sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)
add_source_to_ref(threebus_sys)

function dyn_gen_simple_marconato(generator)
Expand Down Expand Up @@ -294,7 +294,7 @@ end
function build_psid_test_threebus_marconato(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
threebus_sys = make_system(pm_data; runchecks = false, sys_kwargs...)
threebus_sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)
add_source_to_ref(threebus_sys)

function dyn_gen_marconato(generator)
Expand Down Expand Up @@ -324,7 +324,7 @@ end
function build_psid_test_threebus_simple_anderson(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
threebus_sys = make_system(pm_data; runchecks = false, sys_kwargs...)
threebus_sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)
add_source_to_ref(threebus_sys)

function dyn_gen_simple_anderson(generator)
Expand Down Expand Up @@ -354,7 +354,7 @@ end
function build_psid_test_threebus_anderson(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
threebus_sys = make_system(pm_data; runchecks = false, sys_kwargs...)
threebus_sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)
add_source_to_ref(threebus_sys)

function dyn_gen_anderson(generator)
Expand Down Expand Up @@ -384,7 +384,7 @@ end
function build_psid_test_threebus_5shaft(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
threebus_sys = make_system(pm_data; runchecks = false, sys_kwargs...)
threebus_sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)
add_source_to_ref(threebus_sys)

#Reduce generator output
Expand Down Expand Up @@ -436,7 +436,7 @@ end
function build_psid_test_vsm_inverter(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
omib_sys = make_system(pm_data; runchecks = false, sys_kwargs...)
omib_sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)
add_source_to_ref(omib_sys)

function inv_darco(static_device)
Expand Down Expand Up @@ -467,7 +467,7 @@ end
function build_psid_test_threebus_machine_vsm(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
threebus_sys = make_system(pm_data; runchecks = false, sys_kwargs...)
threebus_sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)
add_source_to_ref(threebus_sys)

function dyn_gen_second_order(generator)
Expand Down Expand Up @@ -520,7 +520,7 @@ end
function build_psid_test_threebus_multimachine(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
threebus_sys = make_system(pm_data; runchecks = false, sys_kwargs...)
threebus_sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)

function dyn_gen_multi(generator)
return PSY.DynamicGenerator(;
Expand Down Expand Up @@ -566,7 +566,7 @@ end
function build_psid_test_threebus_psat_avrs(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
threebus_sys = make_system(pm_data; runchecks = false, sys_kwargs...)
threebus_sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)
add_source_to_ref(threebus_sys)

function dyn_gen_avr_type2(generator)
Expand Down Expand Up @@ -613,7 +613,7 @@ end
function build_psid_test_threebus_vsm_reference(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
threebus_sys = make_system(pm_data; runchecks = false, sys_kwargs...)
threebus_sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)

function inv_case78(static_device)
return DynamicInverter(;
Expand Down Expand Up @@ -660,7 +660,7 @@ end
function build_psid_test_threebus_genrou_avr(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
sys = make_system(pm_data; runchecks = false, sys_kwargs...)
sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)

#Replace Gen101 by Source
remove_component!(ThermalStandard, sys, "generator-101-1")
Expand Down Expand Up @@ -693,7 +693,7 @@ end
function build_psid_test_droop_inverter(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
omib_sys = make_system(pm_data; runchecks = false, sys_kwargs...)
omib_sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)
add_source_to_ref(omib_sys)

############### Data Dynamic devices ########################
Expand Down Expand Up @@ -724,7 +724,7 @@ end
function build_psid_test_gfoll_inverter(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
omib_sys = make_system(pm_data; runchecks = false, sys_kwargs...)
omib_sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)
add_source_to_ref(omib_sys)

############### Data Dynamic devices ########################
Expand Down Expand Up @@ -755,7 +755,7 @@ end
function build_psid_test_threebus_multimachine_dynlines(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
sys = make_system(pm_data; runchecks = false, sys_kwargs...)
sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)

############### Data Dynamic devices ########################
function dyn_gen_marconato(generator)
Expand Down Expand Up @@ -803,7 +803,7 @@ end
function build_psid_test_pvs(; raw_data, kwargs...)
sys_kwargs = filter_kwargs(; kwargs...)
pm_data = PowerFlowFileParser.PowerModelsData(raw_data)
sys = make_system(pm_data; runchecks = false, sys_kwargs...)
sys = system_from_openapi(pm_data; runchecks = false, sys_kwargs...)
add_source_to_ref(sys)

############### Data Dynamic devices ########################
Expand Down Expand Up @@ -863,7 +863,7 @@ function build_psid_psse_test_constantP_load(; raw_data, kwargs...)
raw_file = joinpath(raw_data, "ThreeBusMulti.raw")
dyr_file = joinpath(raw_data, "ThreeBus_GENROU.dyr")
pm_data = PowerFlowFileParser.PowerModelsData(raw_file)
sys = make_system(pm_data; sys_kwargs...)
sys = system_from_openapi(pm_data; sys_kwargs...)
add_dyn_injectors!(sys, dyr_file)
return sys
end
Expand Down Expand Up @@ -981,7 +981,7 @@ function build_psid_test_indmotor(; raw_data, kwargs...)
raw_file = joinpath(raw_data, "TVC_System_motor.raw")
dyr_file = joinpath(raw_data, "TVC_System_motor.dyr")
pm_data = PowerFlowFileParser.PowerModelsData(raw_file)
sys = make_system(pm_data; sys_kwargs...)
sys = system_from_openapi(pm_data; sys_kwargs...)
add_dyn_injectors!(sys, dyr_file)
return sys
end
Expand Down
Loading
Loading