State Estimation

For further information on this topic, please see the PMU State Estimation or DC State Estimation sections of the Manual. Below, we have provided a list of functions that can be utilized for power flow analysis.


Observability Analysis
AC State Estimation
PMU State Estimation
DC State Estimation
Bad Data Analysis

To load state estimation API functionalities into the current scope, utilize the following command:

using JuliaGrid

Observability Analysis

JuliaGrid.islandTopologicalFlowMethod
islandTopologicalFlow(system::PowerSystem, device::Measurement)

The function utilizes a topological approach to detect flow observable islands, resulting in the formation of disconnected and loop-free subgraphs. It is assumed that active and reactive power measurements are paired, indicating a standard observability analysis. In this analysis, islands formed by active power measurements correspond to those formed by reactive power measurements.

Arguments

To define flow observable islands, this function necessitates the composite types PowerSystem and Measurement.

Returns

The function returns an type Island, containing information about the islands:

  • island: a list enumerating observable islands with indices of buses;
  • bus: the positions of buses in relation to each island;
  • tie: tie data associated with buses and branches.

Examples

Find flow islands for the provided set of measurements:

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")
statusWattmeter!(system, device; inservice = 15)
device.varmeter.reactive.status = copy(device.wattmeter.active.status)

islands = islandTopologicalFlow(system, device)
source
JuliaGrid.islandTopologicalMethod
islandTopological(system::PowerSystem, meter::Wattmeter)

The function employs a topological method to identify maximal observable islands. Specifically, it employs measurements positioned on the branches to pinpoint flow observable islands. Subsequently, these islands are merged based on the available injection measurements.

It is assumed that active and reactive power measurements are paired, indicating a standard observability analysis. In this analysis, islands formed by active power measurements correspond to those formed by reactive power measurements.

Arguments

To define flow observable islands, this function necessitates the composite types PowerSystem and Measurement.

Returns

The function returns an abstract type Island, containing information about the islands:

  • island: a list enumerating observable islands with indices of buses;
  • bus: the positions of buses in relation to each island;
  • tie: tie data associated with buses and branches.

Examples

Find maximal islands for the provided set of measurements:

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")
statusWattmeter!(system, device; inservice = 15)
device.varmeter.reactive.status = copy(device.wattmeter.active.status)

islands = islandTopological(system, device)
source
JuliaGrid.restorationGram!Method
restorationGram!(system::PowerSystem, device::Measurement, pseudo::Measurement,
    islands::Island; threshold)

Upon identifying the islands, the function incorporates measurements from the available pseudo-measurements in the pseudo variable into the device variable to reinstate observability. If the abstract type Island is derived from wattmeters, candidates for restoring observability include active power measurements and bus voltage angle measurements from the pseudo variable. This method relies on reduced coefficient matrices and the Gram matrix.

It is important to note that the device labels in the device and pseudo variables must be different to enable the function to successfully incorporate measurements from pseudo into the device set of measurements.

Arguments

This function requires the composite types PowerSystem and device, which holds measurements from which the islands variable is obtained. To restore observability, the function uses measurements from the pseudo variable and adds a non-redundant set from it to the device variable.

Keyword

The keyword threshold defines the zero pivot threshold value with a default value of 1e-5. More precisely, all computed pivots less than this value will be treated as zero pivots.

Updates

The function updates the device variable of the Measurement composite type.

Example

Restore observability for DC state estimation:

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")
statusWattmeter!(system, device; inservice = 10)
statusPmu!(system, device; inservice = 0)

pseudo = measurement("pseudomeasurement14.h5")
islands = islandTopological(system, device.wattmeter)
restorationGram!(system, device, pseudo, islands)

analysis = dcWlsStateEstimation(system, device)
solve!(system, analysis)
source

AC State Estimation

JuliaGrid.gaussNewtonFunction
gaussNewton(system::PowerSystem, device::Measurement, method)

The function sets up the the Gauss-Newton method to solve the nonlinaer or AC state estimation model, where the vector of state variables is given in polar coordinates. The Gauss-Newton method throuout iterations provied WLS estimator.

Arguments

This function requires the PowerSystem and Measurement composite types to establish the nonlinear WLS state estimation framework.

Moreover, the presence of the method parameter is not mandatory. To address the WLS state estimation method, users can opt to utilize factorization techniques to decompose the gain matrix, such as LU, QR, or LDLt especially when the gain matrix is symmetric. Opting for the Orthogonal method is advisable for a more robust solution in scenarios involving ill-conditioned data, particularly when substantial variations in variances are present.

If the user does not provide the method, the default method for solving the estimation model will be LU factorization.

Updates

If the AC model has not been created, the function will automatically trigger an update of the ac field within the PowerSystem composite type.

Returns

The function returns an instance of the PMUStateEstimation abstract type, which includes the following fields:

  • voltage: the variable allocated to store the bus voltage magnitudes and angles;
  • power: the variable allocated to store the active and reactive powers;
  • method: the system model vectors and matrices.

Examples

Set up the AC state estimation model to be solved using the default LU factorization:

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")

analysis = gaussNewton(system, device)

Set up the ACC state estimation model to be solved using the orthogonal method:

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")

analysis = gaussNewton(system, device, Orthogonal)
source
JuliaGrid.acLavStateEstimationFunction
acLavStateEstimation(system::PowerSystem, device::Measurement, optimizer)

The function sets up the the LAV method to solve the nonlinaer or AC state estimation model, where the vector of state variables is given in polar coordinates.

Arguments

This function requires the PowerSystem and Measurement composite types to establish the LAV state estimation model. The LAV method offers increased robustness compared to WLS, ensuring unbiasedness even in the presence of various measurement errors and outliers.

Users can employ the LAV method to find an estimator by choosing one of the available optimization solvers. Typically, Ipopt.Optimizer suffices for most scenarios.

Updates

If the AC model has not been created, the function will automatically trigger an update of the ac field within the PowerSystem composite type.

Returns

The function returns an instance of the PMUStateEstimation abstract type, which includes the following fields:

  • voltage: the variable allocated to store the bus voltage magnitudes and angles;
  • power: the variable allocated to store the active and reactive powers;
  • method: the optimization model.

Example

using Ipopt

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")

analysis = acLavStateEstimation(system, device, Ipopt.Optimizer)
source
JuliaGrid.solve!Method
solve!(system::PowerSystem, analysis::ACStateEstimation)

By computing the bus voltage magnitudes and angles, the function solves the AC state estimation model.

Updates

The resulting bus voltage magnitudes and angles are stored in the voltage field of the ACStateEstimation type.

Examples

Solving the AC state estimation model and obtaining the WLS estimator:

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")

analysis = gaussNewton(system, device)
for iteration = 1:20
    stopping = solve!(system, analysis)
    if stopping < 1e-8
        break
    end
end
source

PMU State Estimation

JuliaGrid.pmuPlacementFunction
pmuPlacement(system::PowerSystem, optimizer; bridge)

The function determines the optimal placement of PMUs through integer linear programming. Specifically, it identifies the minimum set of PMU locations required for effective power system state estimation, ensuring observability with the least number of PMUs.

The function accepts a PowerSystem composite type as input to establish the framework for finding the optimal PMU placement. If the ac field within the PowerSystem composite type is not yet created, the function automatically initiates an update process.

Additionally, the optimizer argument is a crucial component for formulating and solving the optimization problem. Typically, using the GLPK or HiGHS solver is sufficient. For more detailed information, please refer to the JuMP JuMP documenatation.

Keyword

The bridge keyword enables users to manage the bridging mechanism within the JuMP package.

Returns

The function returns an instance of the PlacementPMU type, containing variables such as:

  • bus: bus labels with indices marking the positions of PMUs at buses;
  • from: branch labels with indices marking the positions of PMUs at "from" bus ends;
  • to: branch labels with indices marking the positions of PMUs at "to" bus ends.

Note that if the conventional understanding of a PMU involves a device measuring the bus voltage phasor and all branch current phasors incident to the bus, the result is saved only in the bus variable. However, if we consider that a PMU measures individual phasors, each described with magnitude and angle, then measurements are needed at each bus in the bus variable, and each branch with positions given according to from and to variables.

Example

using GLPK, Ipopt

system = powerSystem("case14.h5")
analysis = acOptimalPowerFlow(system, Ipopt.Optimizer)
solve!(system, analysis)
current!(system, analysis)

placement = pmuPlacement(system, GLPK.Optimizer)
device = measurement()

@pmu(label = "PMU ?: !")
for (bus, i) in placement.bus
    Vi, θi = analysis.voltage.magnitude[i], analysis.voltage.angle[i]
    addPmu!(system, device; bus = bus, magnitude = Vi, angle = θi)
end
for branch in keys(placement.from)
    Iij, ψij = fromCurrent(system, analysis; label = branch)
    addPmu!(system, device; from = branch, magnitude = Iij, angle = ψij)
end
for branch in keys(placement.to)
    Iji, ψji = toCurrent(system, analysis; label = branch)
    addPmu!(system, device; to = branch, magnitude = Iji, angle = ψji)
end
source
JuliaGrid.pmuWlsStateEstimationFunction
pmuWlsStateEstimation(system::PowerSystem, device::Measurement, method)

The function establishes the linear WLS model for state estimation with PMUs only. In this model, the vector of state variables contains bus voltage magnitudes and angles, given in rectangular coordinates.

Arguments

This function requires the PowerSystem and Measurement composite types to establish the WLS state estimation model.

Moreover, the presence of the method parameter is not mandatory. To address the WLS state estimation method, users can opt to utilize factorization techniques to decompose the gain matrix, such as LU, QR, or LDLt especially when the gain matrix is symmetric. Opting for the Orthogonal method is advisable for a more robust solution in scenarios involving ill-conditioned data, particularly when substantial variations in variances are present.

If the user does not provide the method, the default method for solving the estimation model will be LU factorization.

Updates

If the AC model has not been created, the function will automatically trigger an update of the ac field within the PowerSystem composite type.

Returns

The function returns an instance of the PMUStateEstimation abstract type, which includes the following fields:

  • voltage: the variable allocated to store the bus voltage magnitudes and angles;
  • power: the variable allocated to store the active and reactive powers;
  • method: the system model vectors and matrices.

Examples

Set up the PMU state estimation model to be solved using the default LU factorization:

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")

analysis = pmuWlsStateEstimation(system, device)

Set up the PMU state estimation model to be solved using the orthogonal method:

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")

analysis = pmuWlsStateEstimation(system, device, Orthogonal)
source
JuliaGrid.pmuLavStateEstimationFunction
pmuLavStateEstimation(system::PowerSystem, device::Measurement, optimizer)

The function establishes the LAV model for state estimation with PMUs only. In this model, the vector of state variables contains bus voltage magnitudes and angles, given in rectangular coordinates.

Arguments

This function requires the PowerSystem and Measurement composite types to establish the LAV state estimation model. The LAV method offers increased robustness compared to WLS, ensuring unbiasedness even in the presence of various measurement errors and outliers.

Users can employ the LAV method to find an estimator by choosing one of the available optimization solvers. Typically, Ipopt.Optimizer suffices for most scenarios.

Updates

If the AC model has not been created, the function will automatically trigger an update of the ac field within the PowerSystem composite type.

Returns

The function returns an instance of the PMUStateEstimation abstract type, which includes the following fields:

  • voltage: the variable allocated to store the bus voltage magnitudes and angles;
  • power: the variable allocated to store the active and reactive powers;
  • method: the optimization model.

Example

using Ipopt

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")

analysis = pmuLavStateEstimation(system, device, Ipopt.Optimizer)
source
JuliaGrid.solve!Method
solve!(system::PowerSystem, analysis::PMUStateEstimation)

By computing the bus voltage magnitudes and angles, the function solves the PMU state estimation model.

Updates

The resulting bus voltage magnitudes and angles are stored in the voltage field of the PMUStateEstimation type.

Examples

Solving the PMU state estimation model using the WLS method:

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")

analysis = pmuWlsStateEstimation(system, device)
solve!(system, analysis)

Solving the PMU state estimation model using the LAV method:

using Ipopt

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")

analysis = pmuLavStateEstimation(system, device, Ipopt.Optimizer)
solve!(system, analysis)
source

DC State Estimation

JuliaGrid.dcWlsStateEstimationFunction
dcWlsStateEstimation(system::PowerSystem, device::Measurement, method)

The function establishes the WLS model for DC state estimation, where the vector of state variables contains only bus voltage angles.

Arguments

This function requires the PowerSystem and Measurement composite types to establish the WLS state estimation model.

Moreover, the presence of the method parameter is not mandatory. To address the WLS state estimation method, users can opt to utilize factorization techniques to decompose the gain matrix, such as LU, QR, or LDLt especially when the gain matrix is symmetric. Opting for the Orthogonal method is advisable for a more robust solution in scenarios involving ill-conditioned data, particularly when substantial variations in variances are present.

If the user does not provide the method, the default method for solving the estimation model will be LU factorization.

Updates

If the DC model was not created, the function will automatically initiate an update of the dc field within the PowerSystem composite type. Additionally, if the slack bus lacks an in-service generator, JuliaGrid considers it a mistake and defines a new slack bus as the first generator bus with an in-service generator in the bus type list.

Returns

The function returns an instance of the DCStateEstimation type, which includes the following fields:

  • voltage: the variable allocated to store the bus voltage angles;
  • power: the variable allocated to store the active powers;
  • method: the system model vectors and matrices.

Examples

Set up the DC state estimation model to be solved using the default LU factorization:

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")

analysis = dcWlsStateEstimation(system, device)

Set up the DC state estimation model to be solved using the orthogonal method:

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")

analysis = dcWlsStateEstimation(system, device, Orthogonal)
source
JuliaGrid.dcLavStateEstimationFunction
dcLavStateEstimation(system::PowerSystem, device::Measurement, optimizer)

The function establishes the LAV model for DC state estimation, where the vector of state variables contains only bus voltage angles.

Arguments

This function requires the PowerSystem and Measurement composite types to establish the LAV state estimation model. The LAV method offers increased robustness compared to WLS, ensuring unbiasedness even in the presence of various measurement errors and outliers.

Users can employ the LAV method to find an estimator by choosing one of the available optimization solvers. Typically, Ipopt.Optimizer suffices for most scenarios.

Updates

If the DC model was not created, the function will automatically initiate an update of the dc field within the PowerSystem composite type. Additionally, if the slack bus lacks an in-service generator, JuliaGrid considers it a mistake and defines a new slack bus as the first generator bus with an in-service generator in the bus type list.

Returns

The function returns an instance of the DCStateEstimation abstract type, which includes the following fields:

  • voltage: the variable allocated to store the bus voltage angles;
  • power: the variable allocated to store the active powers;
  • method: the optimization model.

Example

using Ipopt

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")

analysis = dcLavStateEstimation(system, device, Ipopt.Optimizer)
source
JuliaGrid.solve!Method
solve!(system::PowerSystem, analysis::DCStateEstimation)

By computing the bus voltage angles, the function solves the DC state estimation model.

Updates

The resulting bus voltage angles are stored in the voltage field of the DCStateEstimation type.

Examples

Solving the DC state estimation model using the WLS method:

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")

analysis = dcWlsStateEstimation(system, device)
solve!(system, analysis)

Solving the DC state estimation model using the LAV method:

using Ipopt

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")

analysis = dcLavStateEstimation(system, device, Ipopt.Optimizer)
solve!(system, analysis)
source

Bad Data Analysis

JuliaGrid.residualTest!Function
residualTest!(system::PowerSystem, device::Measurement, analysis::StateEstimation;
    threshold)

The function conducts bad data detection and identification using the largest normalized residual test, subsequently removing measurement outliers from the measurement set. It can be executed after obtaining WLS estimator.

Arguments

This function requires the composite types PowerSystem and Measurement, along with an abstract type. The abstract type StateEstimation can have the following subtypes:

  • ACStateEstimation: conducts bad data analysis within AC state estimation;
  • PMUStateEstimation: conducts bad data analysis within PMU state estimation;
  • DCStateEstimation: conducts bad data analysis within DC state estimation.

Keyword

The keyword threshold establishes the identification threshold. If the largest normalized residual surpasses this threshold, the measurement is flagged as bad data. The default threshold value is set to threshold = 3.0.

Updates

In case bad data is detected, the function removes measurements from the coefficient and precision matrices, and mean vector within the DCStateEstimation type. Additionally, it marks the respective measurement within the Measurement type as out-of-service.

Returns

The function returns an instance of the BadData type, which includes:

  • detect: returns true after the function's execution if bad data is detected;
  • maxNormalizedResidual: denotes the value of the largest normalized residual;
  • label: signifies the label of the bad data;
  • index: represents the index of the bad data.

Example

Obtaining the solution after detecting and removing bad data:

system = powerSystem("case14.h5")
device = measurement("measurement14.h5")

analysis = dcWlsStateEstimation(system, device)
solve!(system, analysis)

outlier = residualTest!(system, device, analysis; threshold = 4.0)
solve!(system, analysis)
source