State Estimation and Measurements Reference
Sparlectra.Measurement — Type
MeasurementGeneric state-estimation measurement model.
Fields:
typ: Measurement type.value: Measured value (Vm in p.u., powers in MW/MVar, Va in degrees).sigma: Standard deviation in measurement units.weight: Weight used in WLS (1/sigma^2).active: Iffalse, measurement is ignored by estimator.busIdx: Bus index for bus measurements.branchIdx: Branch index for branch flow measurements.direction: Branch direction:fromor:to, otherwise:none.id: Optional measurement identifier.
Sparlectra.MeasurementType — Type
@enum MeasurementTypeSupported measurement types for the first WLS state-estimation implementation.
Sparlectra.addMeasurement! — Method
addMeasurement!(measurements; typ, value, sigma, active=true, busIdx=nothing, branchIdx=nothing, direction=:none, id="")Append a state-estimation measurement to measurements and return it.
Sparlectra.addPflowMeasurement! — Method
addPflowMeasurement!(measurements; net, value, sigma, direction=:from, branchNr=nothing, fromBus=nothing, toBus=nothing, active=true, id="")Append an active-power flow measurement identified by branchNr or a unique fromBus/toBus branch pair.
Sparlectra.addPinjMeasurement! — Method
addPinjMeasurement!(measurements; net, busName, value, sigma, active=true, id="")Append an active-power injection measurement identified by busName.
Sparlectra.addPmuPhasorMeasurement! — Method
addPmuPhasorMeasurement!(measurements; net, busName, vm_pu, va_deg, sigmaVm=0.002, sigmaVa=0.02, active=true, idPrefix="PMU")Append a complete PMU voltage-phasor measurement — magnitude and angle — for one bus and return the pair (vmMeas, vaMeas).
The magnitude enters as an ordinary VmMeas (p.u.); PMU accuracy is expressed solely through the tight default sigmaVm. The angle enters as a VaMeas (degrees, referenced to the common PMU time base; see the pmu_ref_offset handling in runse!).
Sparlectra.addQflowMeasurement! — Method
addQflowMeasurement!(measurements; net, value, sigma, direction=:from, branchNr=nothing, fromBus=nothing, toBus=nothing, active=true, id="")Append a reactive-power flow measurement identified by branchNr or a unique fromBus/toBus branch pair.
Sparlectra.addQinjMeasurement! — Method
addQinjMeasurement!(measurements; net, busName, value, sigma, active=true, id="")Append a reactive-power injection measurement identified by busName.
Sparlectra.addVaMeasurement! — Method
addVaMeasurement!(measurements; net, busName, value, sigma, active=true, id="")Append a bus voltage-angle measurement (PMU synchrophasor) identified by busName. value and sigma are in degrees, referenced to the common PMU time base (see the pmu_ref_offset handling in runse!).
Sparlectra.addVmMeasurement! — Method
addVmMeasurement!(measurements; net, busName, value, sigma, active=true, id="")Append a bus voltage-magnitude measurement identified by busName.
Sparlectra.addZeroInjectionMeasurements! — Method
addZeroInjectionMeasurements!(measurements; net, sigma=1e-6, busNames=nothing, busIdxs=nothing, active=true, idPrefix="ZI") -> Vector{Measurement}Append active- and reactive-power zero-injection pseudo-measurements for the selected buses and return the newly added measurements.
Selection rules:
- If
busIdxsis provided, those indices are used. - Else if
busNamesis provided, names are resolved to indices. - Else passive buses are detected automatically via
findPassiveBuses(net).
These pseudo-measurements are the current way to encode equality constraints P_inj = 0 and Q_inj = 0 in the WLS estimator.
Sparlectra.findPassiveBuses — Method
findPassiveBuses(net; atol=1e-9, includeSlack=false) -> Vector{Int}Return bus indices that have no generation, no load, and no shunt contribution within the given tolerance atol.
This is useful for state-estimation workflows where passive / transit buses are often modeled through zero-injection pseudo-measurements.
Sparlectra.generateMeasurementsFromPF — Method
generateMeasurementsFromPF(net; kwargs...) -> Vector{Measurement}Generate synthetic measurements from the current solved network state.
Keyword options:
includeVm,includePinj,includeQinj,includePflow,includeQflowincludeVa: add PMU voltage-angle measurements (degrees, defaultfalse)vaBusIdxs: restrict Va measurements to these bus indices (default: all buses)vaRefOffsetDeg: common angle offset added to all generated Va values, emulating a PMU time base that differs from the slack referencenoise: add Gaussian noise iftruestddev: dictionary fromMeasurementType => sigmarng: random number generator
Sparlectra.measurementStdDevs — Method
measurementStdDevs(; vm=0.005, pinj=1.0, qinj=1.0, pflow=1.0, qflow=1.0, va=0.02)Create default standard-deviation map for synthetic measurement generation. va is the PMU voltage-angle standard deviation in degrees; typical PMU accuracy is 0.01–0.05° (IEEE C37.118 TVE < 1 %).
Sparlectra.SEResult — Type
SEResultResult container for the first classical WLS state-estimation run.
vaRefOffsetDeg is the estimated common PMU reference-angle offset α in degrees (the slack-bus angle expressed in the PMU time base). It is nothing when no offset state was part of the estimation, i.e. when there are no active VaMeas measurements or pmu_ref_offset = :off.
Sparlectra.evaluate_global_observability — Method
evaluate_global_observability(net, measurements; kwargs...) -> NamedTupleEvaluate global observability on active measurements using the finite-difference measurement Jacobian.
Includes global redundancy metrics
redundancy = r = m - nredundancy_ratio = ρ = m / ndof = ν = m - n(a COUNT difference: for an observable set it equalsm - rank(H); for an unobservable set it can be negative and then reads as a shortfall, not a redundancy)
Quality classes:
:good: observable and no critical single measurement:critical: observable, but at least one single critical measurement (or ν <= 0):not_observable: not observable
For a not-observable set the result additionally names the dark states in unobservable_state_columns (state columns touched by the null space of H); empty when observable. This is the rigorous per-state answer that the column-restricted local check cannot give (see evaluate_local_observability).
Sparlectra.evaluate_local_observability — Method
evaluate_local_observability(net, measurements, stateCols; kwargs...) -> NamedTupleEvaluate local observability on selected Jacobian columns (stateCols).
Procedure:
- Build global Jacobian
Hfrom currently active measurements. - Keep only rows that have at least one nonzero entry in the selected columns. These rows correspond to measurements that are locally sensitive to the requested states.
- Evaluate observability/redundancy on the reduced matrix
Hlocal.
Returned NamedTuple extends global metrics with:
rows: selected row indices (within global active-Jacobian row numbering)stateCols: copied input state-column selection.
Interpretation:
:goodmeans local states are observable with positive redundancy and no single critical measurement.:criticalmeans still observable but vulnerable to a single outage (or ν <= 0).:not_observablemeans local states cannot be uniquely reconstructed.
Limitation: this column-restricted test is NECESSARY but not sufficient; a positive verdict can be wrong when the touching rows couple the selected states to neighbor states that are themselves undetermined. The rigorous per-state answer is unobservable_state_columns from evaluate_global_observability.
Sparlectra.evaluate_local_observability_matrix — Method
evaluate_local_observability_matrix(H, stateCols; tol=nothing) -> NamedTupleEvaluate local observability on a matrix H restricted to selected stateCols.
Limitation: this column-restricted submatrix test is NECESSARY but not sufficient; a positive verdict can be wrong when the touching rows couple the selected states to neighbor states that are themselves undetermined (the rigorous per-state answer is unobservable_state_columns from the global check).
Sparlectra.evaluate_observability_matrix — Method
evaluate_observability_matrix(H; tol=nothing) -> NamedTupleEvaluate global observability and single-row criticality directly on a matrix H (without building a network model).
The result includes unobservable_state_columns::Vector{Int}: for a numerically NOT observable H, the state columns with a component above tolerance in any null-space basis vector, i.e. exactly the states no measurement pins down (their union partitions the network into observable islands). Empty for observable systems; computed only on the not-observable path (a dense null-space probe, fine at workshop and distribution-network sizes).
Sparlectra.measurement_jacobian — Method
measurement_jacobian(net; flatstart=true, jacEps=1e-6, pmuRefOffset=...) -> NamedTupleBuild the measurement Jacobian H of the ACTIVE measurements on net, labeled for humans: the matrix the observability checks and the WLS normal equations run on, with one described row per measurement and one described column per state.
Returns (H, rows, cols):
H::Matrix{Float64}: m x n finite-difference Jacobian at the flat (or stored) start state, the same evaluationevaluate_global_observabilityuses.rows: one NamedTuple per active measurement,(index, type, location, sigma);indexis the position innet.measurements,locationnames the bus (injections, voltages) or the oriented branch (flows).cols: state-column labels in Jacobian order,"Va(bus)"for every non-slack bus, then"Vm(bus)"for every bus, plus"alpha"when PMUVameasurements activate the reference-offset state.
Errors when no active measurement exists. Intended for measurement-matrix reports and placement studies; see the state-estimation suite summary and the workshop's observability deep dive.
Sparlectra.numeric_rank — Method
numeric_rank(A; tol=nothing) -> IntCompute numerical matrix rank using singular values.
Sparlectra.numerical_observable — Method
numerical_observable(H; tol=nothing) -> BoolNumerical observability test on a Jacobian-like matrix H. Returns true when rank(H) == n (full column rank).
Sparlectra.numerical_row_redundant — Method
numerical_row_redundant(H, i; tol=nothing) -> BoolCheck if row i remains numerically redundant in H.
Sparlectra.print_se_diagnostics — Method
print_se_diagnostics(io, diag; topN=10)Pretty-print diagnostics from validate_measurements or runse_diagnostics including:
- explanation of
global_consistency - tabular measurement ranking
- BAD/OK marker per measurement
- optional rerun comparison if present
Sparlectra.runse! — Method
runse!(net, measurements; kwargs...) -> SEResultRun a first classical nonlinear weighted least-squares state estimator.
State representation:
- bus voltage angles for all non-slack buses (radians)
- bus voltage magnitudes for all buses (p.u.)
- optional PMU reference-angle offset α (radians), appended automatically when active
VaMeasmeasurements exist andpmu_ref_offset = :auto
PMU angle measurements (VaMeas, degrees) are modeled as z = θ_i + α + e: the network angles stay slack-referenced, α maps them into the common PMU time base. With pmu_ref_offset = :off the offset state is omitted and PMU angles are assumed to be slack-referenced already.
Sparlectra.runse_diagnostics — Method
runse_diagnostics(net, measurements; deactivate_and_rerun=false, kwargs...) -> NamedTupleExtended diagnostics workflow around validate_measurements with optional deactivate-and-rerun logic for the currently largest suspicious measurement.
Sparlectra.structural_observable — Method
structural_observable(H) -> BoolStructural observability test on a Jacobian-like matrix H. Returns true when the maximum bipartite matching size equals the number of state columns n.
Sparlectra.structural_row_redundant — Method
structural_row_redundant(H, i) -> BoolCheck if row i remains structurally redundant in H.
Sparlectra.summarize_se_diagnostics — Method
summarize_se_diagnostics(diag) -> NamedTupleCreate a compact interpretation summary for a diagnostics object returned by validate_measurements or runse_diagnostics.
global_consistency is interpreted as:
true: SE converged and objective is inside χ²-like 3σ plausibility bandfalse: either non-convergence or implausibly large objective
Sparlectra.validate_measurements — Method
validate_measurements(net, measurements; kwargs...) -> NamedTupleRun state-estimation diagnostics on currently active measurements and return a machine-readable report with:
- global bad-data consistency check (
global_consistency) - χ²-like objective plausibility summary
- largest-normalized-residual ranking
- suspicious measurement list (threshold-based)