Skip to content

Commit

Permalink
update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
mcosovic committed Jul 3, 2024
1 parent 394e782 commit d8f6b0d
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 12 deletions.
40 changes: 39 additions & 1 deletion docs/src/manual/dcStateEstimation.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,33 @@ nothing # hide

---

##### Print Results
Users have the option to print the results in the REPL using any units that have been configured, such as:
```@example WLSDCStateEstimationSolution
@voltage(pu, deg, V)
printBusData(system, analysis)
@default(unit) # hide
```

Next, users can easily customize the print results for specific buses, for example:
```julia
printBusData(system, analysis; label = "Bus 1", header = true)
printBusData(system, analysis; label = "Bus 2")
printBusData(system, analysis; label = "Bus 3", footer = true)
```

Users can also redirect print output to a file. For example, data can be saved in a text file as follows:
```julia
open("bus_data.txt", "w") do file
printBusData(system, analysis, file)
end
```

!!! tip "Tip"
We also provide functions to print state estimation results, such as estimated values and residuals. For more details, users can consult the [Power Analysis](@ref DCSEPowerAnalysisManual) section of this manual.

---

## [Bad Data Processing](@id DCBadDataDetectionManual)
After acquiring the WLS solution using the [`solve!`](@ref solve!(::PowerSystem, ::DCStateEstimation{LinearWLS{Normal}})) function, users can conduct bad data analysis employing the largest normalized residual test. Continuing with our defined power system and measurement set, let us introduce a new wattmeter. Upon proceeding to find the solution for this updated state:
```@example WLSDCStateEstimationSolution
Expand Down Expand Up @@ -334,7 +361,18 @@ print(system.bus.label, analysis.power.injection.active)
!!! note "Info"
To better understand the powers associated with buses, and branches that are calculated by the [`power!`](@ref power!(::PowerSystem, ::DCStateEstimation)) function, we suggest referring to the tutorials on.

To calculate specific quantities related to particular buses or branches, rather than computing values for all buses and branches, users can utilize one of the provided functions below.
---

##### Print Results
Users can utilize any of the print functions outlined in the [Print API](@ref setupPrintAPI) related to the DC analysis. For example, to print state estimation data related to wattmeters, we can use:
```@example WLSDCStateEstimationSolution
@power(MW, pu, pu)
printWattmeterData(system, device, analysis)
@default(unit) # hide
```

---


---

Expand Down
37 changes: 36 additions & 1 deletion docs/src/manual/pmuStateEstimation.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,33 @@ nothing # hide

---

##### Print Results
Users have the option to print the results in the REPL using any units that have been configured, such as:
```@example PMUOptimalPlacement
@voltage(pu, deg, V)
printBusData(system, analysis)
@default(unit) # hide
```

Next, users can easily customize the print results for specific buses, for example:
```julia
printBusData(system, analysis; label = "Bus 1", header = true)
printBusData(system, analysis; label = "Bus 2")
printBusData(system, analysis; label = "Bus 3", footer = true)
```

Users can also redirect print output to a file. For example, data can be saved in a text file as follows:
```julia
open("bus_data.txt", "w") do file
printBusData(system, analysis, file)
end
```

!!! tip "Tip"
We also provide functions to print state estimation results, such as estimated values and residuals. For more details, users can consult the [Power and Current Analysis](@ref PMUSEPowerCurrentAnalysisManual) section of this manual.

---

## [Bad Data Processing](@id PMUBadDataDetectionManual)
After acquiring the WLS solution using the [`solve!`](@ref solve!(::PowerSystem, ::PMUStateEstimation{LinearWLS{Normal}})) function, users can conduct bad data analysis employing the largest normalized residual test. Continuing with our defined power system and measurement set, let us introduce a new phasor measurement. Upon proceeding to find the solution for this updated state:
```@example PMUOptimalPlacement
Expand Down Expand Up @@ -425,7 +452,15 @@ print(system.branch.label, analysis.current.from.magnitude)
!!! note "Info"
To better understand the powers and currents associated with buses and branches that are calculated by the [`power!`](@ref power!(::PowerSystem, ::ACPowerFlow)) and [`current!`](@ref current!(::PowerSystem, ::AC)) functions, we suggest referring to the tutorials on [PMU State Estimation](@ref PMUPowerAnalysisTutorials).

To compute specific quantities for particular components, rather than calculating powers or currents for all components, users can utilize one of the provided functions below.
---

##### Print Results
Users can utilize any of the print functions outlined in the [Print API](@ref setupPrintAPI). For example, to print state estimation data related to PMUs, we can use:
```@example PMUStateEstimationSolution
@voltage(pu, deg, V)
printPmuData(system, device, analysis)
@default(unit) # hide
```

---

Expand Down
78 changes: 68 additions & 10 deletions src/print/measurement.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function printVoltmeterData(system::PowerSystem, device::Measurement, io::IO = s
_printVoltmeterData(system, device, voltage, io, label, header, footer, width)
end

function printVoltmeterData(system::PowerSystem, device::Measurement, analysis::AC, io::IO = stdout;
function printVoltmeterData(system::PowerSystem, device::Measurement, analysis::Union{PMUStateEstimation, ACStateEstimation}, io::IO = stdout;
label::L = missing, header::B = missing, footer::Bool = false,
width::Dict{String, Int64} = Dict{String, Int64}())

Expand Down Expand Up @@ -159,7 +159,7 @@ function printAmmeterData(system::PowerSystem, device::Measurement, io::IO = std
_printAmmeterData(system, device, current, io, label, header, footer, width)
end

function printAmmeterData(system::PowerSystem, device::Measurement, analysis::AC, io::IO = stdout;
function printAmmeterData(system::PowerSystem, device::Measurement, analysis::Union{PMUStateEstimation, ACStateEstimation}, io::IO = stdout;
label::L = missing, header::B = missing, footer::Bool = false,
width::Dict{String, Int64} = Dict{String, Int64}())

Expand Down Expand Up @@ -283,14 +283,14 @@ function printWattmeterData(system::PowerSystem, device::Measurement, io::IO = s
_printWattmeterData(system, device, power, io, label, header, footer, width)
end

function printWattmeterData(system::PowerSystem, device::Measurement, analysis::AC, io::IO = stdout;
function printWattmeterData(system::PowerSystem, device::Measurement, analysis::Union{PMUStateEstimation, ACStateEstimation, DCStateEstimation}, io::IO = stdout;
label::L = missing, header::B = missing, footer::Bool = false,
width::Dict{String, Int64} = Dict{String, Int64}())

_printWattmeterData(system, device, analysis.power, io, label, header, footer, width)
end

function _printWattmeterData(system::PowerSystem, device::Measurement, power::ACPower, io::IO,
function _printWattmeterData(system::PowerSystem, device::Measurement, power::Union{ACPower, DCPower}, io::IO,
label::L, header::B, footer::Bool, width::Dict{String, Int64})

wattmeter = device.wattmeter
Expand All @@ -315,7 +315,7 @@ function _printWattmeterData(system::PowerSystem, device::Measurement, power::AC
end
end

function formatWattmeterData(system::PowerSystem, wattmeter::Wattmeter, power::ACPower, scale::Dict{String, Float64}, label::L, width::Dict{String,Int64})
function formatWattmeterData(system::PowerSystem, wattmeter::Wattmeter, power::Union{ACPower, DCPower}, scale::Dict{String, Float64}, label::L, width::Dict{String,Int64})
format, minmax = formatDevice(wattmeter.active.mean, power.injection.active)
format = formatWidth(format, width)
labels = toggleLabel(label, wattmeter, wattmeter.label, "wattmeter")
Expand Down Expand Up @@ -384,7 +384,7 @@ function printVarmeterData(system::PowerSystem, device::Measurement, io::IO = st
_printVarmeterData(system, device, power, io, label, header, footer, width)
end

function printVarmeterData(system::PowerSystem, device::Measurement, analysis::AC, io::IO = stdout;
function printVarmeterData(system::PowerSystem, device::Measurement, analysis::Union{PMUStateEstimation, ACStateEstimation}, io::IO = stdout;
label::L = missing, header::B = missing, footer::Bool = false,
width::Dict{String, Int64} = Dict{String, Int64}())

Expand Down Expand Up @@ -485,13 +485,20 @@ function printPmuData(system::PowerSystem, device::Measurement, io::IO = stdout;
_printPmuData(system, device, voltage, current, io, label, header, footer, width)
end

function printPmuData(system::PowerSystem, device::Measurement, analysis::AC, io::IO = stdout;
function printPmuData(system::PowerSystem, device::Measurement, analysis::Union{PMUStateEstimation, ACStateEstimation}, io::IO = stdout;
label::L = missing, header::B = missing, footer::Bool = false,
width::Dict{String, Int64} = Dict{String, Int64}())

_printPmuData(system, device, analysis.voltage, analysis.current, io, label, header, footer, width)
end

function printPmuData(system::PowerSystem, device::Measurement, analysis::DCStateEstimation, io::IO = stdout;
label::L = missing, header::B = missing, footer::Bool = false,
width::Dict{String, Int64} = Dict{String, Int64}())

_printPmuData(system, device, analysis.voltage, io, label, header, footer, width)
end

function _printPmuData(system::PowerSystem, device::Measurement, voltage::Polar, current::ACCurrent, io::IO,
label, header, footer, width::Dict{String, Int64})

Expand Down Expand Up @@ -570,6 +577,33 @@ function _printPmuData(system::PowerSystem, device::Measurement, voltage::Polar,
end
end

function _printPmuData(system::PowerSystem, device::Measurement, voltage::PolarAngle, io::IO,
label, header, footer, width::Dict{String, Int64})

pmu = device.pmu

scale = printScale(system, prefix)
format = formatPmuData(system, pmu, voltage, scale, label, width)
labels, header = toggleLabelHeader(label, pmu, pmu.label, header, "pmu")

if format["device"]
maxLine = maxLineDevice(format)
printTitle(maxLine, "PMU Voltage Angle Data", header, io)
headerDevice(io, format, header, maxLine, label, unitList.voltageAngleLive)

for (label, i) in labels
if pmu.layout.bus[i]
indexBus = pmu.layout.index[i]
printDevice(io, format, label, pmu.angle, voltage.angle, scale["voltageAngle"], i, indexBus)
end
end

if !isset(label) || footer
Printf.@printf(io, "|%s|\n", "-"^maxLine)
end
end
end

function formatPmuData(system::PowerSystem, pmu::PMU, voltage::Polar, current::ACCurrent, scale::Dict{String, Float64}, label::L, width::Dict{String,Int64})
formatV, minmaxV = formatDevice(pmu.magnitude.mean, voltage.magnitude)
formatV = formatWidth(formatV, width)
Expand Down Expand Up @@ -634,6 +668,29 @@ function formatPmuData(system::PowerSystem, pmu::PMU, voltage::Polar, current::A
return formatV, formatθ, formatI, formatψ
end

function formatPmuData(system::PowerSystem, pmu::PMU, voltage::PolarAngle, scale::Dict{String, Float64}, label::L, width::Dict{String,Int64})
format, minmax = formatDevice(pmu.magnitude.mean, voltage.angle)
format = formatWidth(format, width)

labels = toggleLabel(label, pmu, pmu.label, "pmu")

if format["device"]
for (label, i) in labels
if pmu.layout.bus[i]
formatDevice(format, minmax, label, pmu.angle, voltage.angle, scale["voltageAngle"], i, pmu.layout.index[i])
end
end

if format["Label"] == 0
format["device"] = false
else
formatDevice(format, minmax)
end
end

return format
end

function formatDevice(deviceMean::Array{Float64,1}, analysisArray::Array{Float64,1})
format = Dict(
"Label" => 0,
Expand Down Expand Up @@ -856,7 +913,7 @@ function printDevice(io::IO, format::Dict{String,Integer}, label::L, meter::Gaus
)
if meter.status[i] == 1
Printf.@printf(io, " %*.4f |",
format["State Estimation Residual"], abs(estimate[j] - meter.mean[i]) * scale,
format["State Estimation Residual"], (meter.mean[i] - estimate[j]) * scale,
)
else
Printf.@printf(io, " %*s |",
Expand Down Expand Up @@ -896,7 +953,8 @@ function formatDevice(format::Dict{String,Integer}, minmax::Dict{String, Float64
minmax["minEstimate"] = min(estimate[j] * scale, minmax["minEstimate"])

if meter.status[i] == 1
minmax["maxResidual"] = max(abs(estimate[j] - meter.mean[i]) * scale, minmax["maxResidual"])
minmax["minResidual"] = min((meter.mean[i] - estimate[j]) * scale, minmax["minResidual"])
minmax["maxResidual"] = max((meter.mean[i] - estimate[j]) * scale, minmax["maxResidual"])
end
end

Expand All @@ -910,7 +968,7 @@ function formatDevice(format::Dict{String,Integer}, minmax::Dict{String, Float64

if format["analysis"]
format["State Estimation Estimate"] = max(length(Printf.@sprintf("%.4f", minmax["maxEstimate"])), length(Printf.@sprintf("%.4f", minmax["minEstimate"])), format["State Estimation Estimate"])
format["State Estimation Residual"] = max(length(Printf.@sprintf("%.4f", minmax["maxResidual"])), format["State Estimation Residual"])
format["State Estimation Residual"] = max(length(Printf.@sprintf("%.4f", minmax["maxResidual"])), length(Printf.@sprintf("%.4f", minmax["minResidual"])), format["State Estimation Residual"])
end
end

Expand Down

0 comments on commit d8f6b0d

Please sign in to comment.