Skip to content

Repository files navigation

raptrix-psse-rs

PSS/E (.raw + .dyr) to Raptrix PowerFlow Interchange (.rpf) conversion — built for large cases, deterministic Arrow IPC output, and modern grid constructs (IBRs, rich metadata) while staying faithful to legacy PSS/E.

Part of the Raptrix PowerFlow ecosystem.

For production-scale deployments and the broader solver stack, contact Raptrix PowerFlow via the GitHub organization.

Ecosystem Repos

Quick Start

raptrix-psse-rs convert --raw my_case.raw --output my_case.rpf
raptrix-psse-rs convert --raw my_case.raw --dyr my_case.dyr --output my_case_dynamic.rpf
raptrix-psse-rs convert --raw my_case.raw --output my_case_expanded.rpf --transformer-mode expanded
raptrix-psse-rs view --input my_case.rpf

Modern Grid Support Philosophy

The converter is built for modern 2026+ studies while preserving strong legacy PSS/E compatibility.

  • Prefer explicit modern-grid representations over lossy legacy flattening.
  • Use DYR model families as the primary source for IBR classification and controls.
  • Fall back to RAW WMOD where DYR is unavailable.
  • Always emit the 18 canonical required root tables for RPF v0.13.0 (zero-row where applicable) so downstream pipelines stay deterministic.

CLI Reference

convert

raptrix-psse-rs convert --raw <FILE> [--dyr <FILE>] --output <FILE> [--transformer-mode <MODE>] [--study-purpose <TEXT>] [--scenario-tag <TAG> ...] [--case-mode <MODE>] [--default-shunt-control-mode <MODE>]
Flag Required Description
--raw <PATH> yes PSS/E RAW file (.raw), versions 23-35.
--dyr <PATH> no Optional dynamic data file. Canonical format is .dyr; .dyn is accepted as fallback.
--output <PATH> yes Output RPF path.
--transformer-mode <MODE> no native-3w (default) or expanded.
--study-purpose <TEXT> no Metadata override for metadata.study_purpose.
--scenario-tag <TAG> no Repeatable metadata override for metadata.scenario_tags.
--case-mode <MODE> no Optional override for metadata.case_mode / root rpf.case_mode. Allowed: flat_start_planning, warm_start_planning, solved_snapshot, hour_ahead_advisory. If omitted, flat vs warm start is inferred from RAW bus voltages.
--default-shunt-control-mode <MODE> no Optional override for metadata.default_shunt_control_mode / root rpf.default_shunt_control_mode. When omitted, planning case_mode values default to planning_full.

view

raptrix-psse-rs view --input <FILE>

Prints a summary of every table in the .rpf file with row counts.

branch_deck_scan

cargo run --bin branch_deck_scan -- --raw <FILE.raw> [--rpf <FILE.rpf>] [--list-duplicate-in-service-keys]

Diagnostics for the PSS/E BRANCH section: raw ST token histogram, parsed vs rejected lines, in-service/out-of-service counts, optional duplicate (from_bus,to_bus,ckt) keys, and (with --rpf) an in-service multiset diff between the parsed RAW network and the RPF branches table. Use this when reconciling branch row counts against tools that omit ST=0 lines.

RPF v0.13.0 coverage

The converter emits the 18 required root tables from the locked v0.13.0 contract (see raptrix-cim-rs schema-contract), including:

  • metadata
  • buses
  • branches
  • multi_section_lines
  • dc_lines_2w
  • generators
  • loads
  • fixed_shunts
  • switched_shunts
  • switched_shunt_banks
  • transformers_2w
  • transformers_3w
  • areas
  • zones
  • owners
  • contingencies
  • interfaces
  • dynamics_models

IBR modeling is only on generators (is_ibr, ibr_subtype); the legacy ibr_devices table is not emitted.

Metadata includes modern-grid fields plus v0.9.0/0.9.1 additional nullable columns (left null for typical PSS/E planning exports when the source deck has no values for them):

  • modern_grid_profile
  • ibr_penetration_pct
  • has_ibr
  • has_smart_valve
  • has_multi_terminal_dc
  • study_purpose
  • scenario_tags
  • hour_ahead_uncertainty_band
  • commitment_source
  • solver_q_limit_infeasible_count
  • pv_to_pq_switch_count
  • real_time_discovery
  • default_shunt_control_mode (nullable — typical planning exports use planning_full)
  • computational_load_mode (v0.10.0+; nullable Boolean — null on the standard PSS/E path; optional computational_load_profiles is not emitted here)
  • source_format / source_format_version / source_identity_scheme (v0.13.0; PSS/E path uses psse_raw, RAW rev string, dense_bus_id)
  • baseline_source_case_id and other baseline-provenance columns (nullable; null on standard PSS/E planning exports)

v0.13.0 maps PSS/E IREG to nullable generators.controlled_bus_id (null = local regulation; remote dense bus_id otherwise). Bus types are dictionary tokens PQ / PV / Slack. Timestamps are Arrow Timestamp(Microsecond, UTC).

v0.10.0 also carries nullable dynamics_models.perc1_params (PERC1 baseline struct; all-null until mapped from DYR). v0.13.0 adds nullable dynamics_models.classical_params when DYR params supply classical first-swing fields.

Trailing nullable mrid columns exist on equipment tables (branches, generators, transformers_2w, transformers_3w) plus loads/fixed/switched shunts (null from PSS/E when unknown). Nullable buses.latitude / buses.longitude are always null from PSS/E (no standard GIS in RAW). Optional remedial_action_schemes / contingency_island_analysis root tables are not emitted on the standard PSS/E path.

The optional scenario_context root table is not written by default. The library API rejects non-empty ExportOptions::scenario_context_rows when optional-root IPC emission is unavailable in the linked raptrix-cim-arrow build (see crate error text).

For schema v0.9.3 onward, nominal-kV fields are required on branches, transformers_2w, and transformers_3w. Export uses RAW nominal values when present and falls back to connected bus nominal-kV; if no valid value can be resolved, conversion fails fast.

Recent release (v0.6.0)

  • RPF v0.13.0 (raptrix.version / raptrix-cim-arrow 0.6.0): clean-cut contract — re-export required for all pre-0.13 .rpf files (no dual-read of v0.12.x).
  • Provenance, dictionary bus types, nullable local controlled_bus_id, native UTC timestamps, optional load/shunt mrid, and classical_params on dynamics when available.
  • raptrix-cim-arrow is pinned to git tag v0.6.0. For a sibling raptrix-cim-rs checkout, use a local [patch] in .cargo/config.toml (not committed) so CI and fresh clones keep building from GitHub.

See CHANGELOG.md for full release history and MIGRATION.md for schema version notes.

Maintainer checklist (before tagging)

  • ./scripts/sync-versions.ps1 -Check (Cargo.toml version must match CHANGELOG.md ## [x.y.z]).
  • ./scripts/pre-release-check.ps1 (format, optional staged public-safety scan via bash, full cargo test).
  • Keep raptrix-cim-arrow’s git rev (or crates.io version) in sync with the released raptrix-cim-rs tag; do not commit a path [patch] for it in Cargo.toml (CI clones this repo alone).

Releases & Downloads

Precompiled binaries are available on the Releases page:

  • Windows (x86_64): .exe binary in zip archive.
  • Linux (x86_64): Static binary in tar.gz archive.
  • macOS (arm64): Native Apple Silicon binary in tar.gz archive.

To use a release binary, extract the archive and run:

./raptrix-psse-rs convert --raw my_case.raw --dyr my_case.dyr --output my_case.rpf

Build From Source

Rust 1.85+ is required.

git clone https://github.com/RaptrixPowerFlow/raptrix-cim-rs.git
git clone https://github.com/RaptrixPowerFlow/raptrix-psse-rs.git
cd raptrix-psse-rs
cargo build --release

Testing

Place any confidential or licensed PSS/E input files under tests/data/external/, then run:

cargo test --release -- --nocapture

The golden_test integration suite (tests/golden_test.rs) converts every file in that corpus to v0.13.0 .rpf under tests/golden/. Dynamic is canonical: when a .dyr / .dyn companion exists it is attached to <stem>.rpf (and mirrored as <stem>_dynamic.rpf); a no-DYR <stem>_static.rpf is also written for A/B. Cases without a dynamics deck are static-only.

Windows, OneDrive, and WSL

Some Windows setups block or slow direct access to large files under OneDrive. The same pattern as raptrix-cim-rs applies: run Rust through WSL Ubuntu so the repo is under /mnt/... and file access matches Linux expectations.

# From repo root — same helper as raptrix-cim-rs
.\scripts\test-wsl.ps1 -CargoCommand "test --workspace --release --test golden_test -- --nocapture"

Maintainer verification (full corpus)

After cargo build --release, regenerate or check all golden outputs (mirrors golden_test paths):

./scripts/verify-external-golden.sh
  • Strict by default: every input listed in the script must exist (set RELAX_MISSING=1 to only run what is present).
  • On Windows, run that script inside WSL from the repo’s /mnt/... path, or use:
.\scripts\verify.ps1 -ExternalGolden   # fmt + clippy + test, then WSL verify script

An optional GitHub Action External golden (optional) (external-golden.yml) runs the same script with RELAX_MISSING=1 so the workflow stays green on hosted runners without licensed data.

Performance snapshot

End-to-end timings are parse RAW (+ optional DYR) + build Arrow tables + write .rpf, measured inside golden_test with Instant (or the CLI for spot checks), release build, April 2026, on a typical developer machine (Windows, OneDrive-backed tree). WSL on /mnt/c/... is often noticeably slower for the same conversions (disk latency); the table below reflects native Windows golden_test unless noted.

Case Mode Approx. wall time
IEEE 14-bus static ~26 ms
IEEE 118-bus static ~28 ms
Texas2k (2.7k buses) static ~45 ms
Texas2k (2.7k buses) + DYR ~190 ms
NYISO ~1.5k-bus snapshots static ~70–85 ms
Texas7k (~6.7k buses) static ~170 ms
Texas7k 2030 static ~190 ms
Texas7k + DYR ~210 ms
ACTIVSg10k (~10k buses) + DYR (CLI) ~1.5 s
ACTIVSg25k static ~410 ms
Midwest24k static ~490 ms
ACTIVSg70k static ~990 ms
Eastern Interconnect 515GW static ~1.1 s

These are local engineering reference numbers, not vendor benchmarks. Use them to spot regressions between commits; re-run cargo test --release --test golden_test -- --nocapture or ./scripts/verify-external-golden.sh on your host to refresh.

Known fidelity limits (today’s export)

The converter aims for predictable, contract-aligned .rpf output. Like any interchange layer, not every PSS/E field becomes a first-class column—some are folded into aggregates, omitted when the RPF schema has no home, or left for consumers to interpret from raw dynamics rows. Authoritative per-field rules live in docs/psse-mapping.md; highlights include:

  • Aggregates vs. raw fields: e.g. line-end shunts feed bus g_shunt / b_shunt; loads export the PQ portion documented in the mapping doc.
  • Coverage matrix: see PSS/E RAW coverage in the mapping doc for what is exported, folded into other tables, skipped by the parser, or blocked by interchange schema (ZIP loads, optional MTDC / node-breaker tables, etc.).
  • Parser coverage: some RAW sections and rows are skipped or rejected with counts logged; see the mapping doc and parser.rs for current behavior.
  • Dynamics: DYR numeric rows are preserved where parsed; attachment and interpretation follow the mapping doc—validate against your toolchain.

Golden tests (with local external inputs) help catch regressions; they are not a statement of future scope.

Versioning & Schema Contract

This crate is pinned to raptrix-cim-arrow 0.6.0 (git tag v0.6.0). Every emitted .rpf is validated against the locked v0.13.0 contract before returning. Readers accept only v0.13.0 — re-export all older .rpf files through this converter.

See raptrix-cim-rs schema-contract for the full RPF specification.

License

License: MPL-2.0

MPL 2.0 - free to use, modify, and distribute.

About

High-performance PSS/E (.raw + .dyr) to Raptrix PowerFlow Interchange (.rpf) conversion for modern grid workflows. Part of the Raptrix PowerFlow ecosystem.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages