From dccf8d74e49653460d9b07fbe6728ab29e404559 Mon Sep 17 00:00:00 2001 From: Gord Stephen Date: Sun, 1 Dec 2024 20:17:58 -0800 Subject: [PATCH] Augment docstrings --- PRASCore/src/Results/Flow.jl | 31 ++++++++++--- PRASCore/src/Results/FlowSamples.jl | 30 +++++++++++-- PRASCore/src/Results/GeneratorAvailability.jl | 22 ++++++++-- .../Results/GeneratorStorageAvailability.jl | 23 ++++++++-- .../src/Results/GeneratorStorageEnergy.jl | 24 +++++++--- .../Results/GeneratorStorageEnergySamples.jl | 25 +++++++++-- PRASCore/src/Results/LineAvailability.jl | 22 ++++++++-- PRASCore/src/Results/Shortfall.jl | 44 +++++++++++++++---- PRASCore/src/Results/ShortfallSamples.jl | 41 +++++++++++++++-- PRASCore/src/Results/StorageAvailability.jl | 22 ++++++++-- PRASCore/src/Results/StorageEnergy.jl | 24 +++++++--- PRASCore/src/Results/StorageEnergySamples.jl | 23 ++++++++-- PRASCore/src/Results/Surplus.jl | 20 +++++++-- PRASCore/src/Results/SurplusSamples.jl | 22 ++++++++-- PRASCore/src/Results/Utilization.jl | 36 +++++++++++++-- PRASCore/src/Results/UtilizationSamples.jl | 40 +++++++++++++++-- PRASCore/src/Results/metrics.jl | 15 ++++++- PRASCore/src/Systems/SystemModel.jl | 11 +---- PRASFiles/src/read.jl | 13 ++++++ 19 files changed, 408 insertions(+), 80 deletions(-) diff --git a/PRASCore/src/Results/Flow.jl b/PRASCore/src/Results/Flow.jl index 3ecab7a6..4ea28e7d 100644 --- a/PRASCore/src/Results/Flow.jl +++ b/PRASCore/src/Results/Flow.jl @@ -1,12 +1,31 @@ """ Flow -Flow metric represents the flow between interfaces at timestamps -in a FlowResult with a (interfaces, timestamps) matrix API. - -Separate samples are averaged together into mean and std values. - -See [`FlowSamples`](@ref) for all flow samples. +The `Flow` result specification reports the estimated average flow across +transmission `Interfaces`, producing a `FlowResult`. + +A `FlowResult` can be indexed by a directional `Pair` of region names and a +timestamp to retrieve a tuple of sample mean and standard deviation, estimating +the average net flow magnitude and direction relative to the given directed +interface in that timestep. For a query of `"Region A" => "Region B"`, if +estimated average flow was from A to B, the reported value would be positive, +while if average flow was in the reverse direction, from B to A, the value +would be negative. + +Example: + +```julia +flows, = + assess(sys, SequentialMonteCarlo(samples=1000), Flow()) + +flow_mean, flow_std = + flows["Region A" => "Region B", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] +flow2_mean, flow2_std = + flows["Region B" => "Region A", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] +@assert flow_mean == -flow2_mean +``` + +See [`FlowSamples`](@ref) for sample-level flow results. """ struct Flow <: ResultSpec end diff --git a/PRASCore/src/Results/FlowSamples.jl b/PRASCore/src/Results/FlowSamples.jl index a3bc7fd8..b9939f5f 100644 --- a/PRASCore/src/Results/FlowSamples.jl +++ b/PRASCore/src/Results/FlowSamples.jl @@ -1,11 +1,33 @@ """ FlowSamples -Flow samples represent the flow between interfaces at timestamps, which has -not been averaged across different samples. This presents a -3D matrix API (interfaces, timestamps, samples). +The `FlowSamples` result specification reports the sample-level magnitude and +direction of power flows across `Interfaces`, producing a `FlowSamplesResult`. -See [`Flow`](@ref) for sample-averaged flow data. +A `FlowSamplesResult` can be indexed by a directional `Pair` of region names and a +timestamp to retrieve a vector of sample-level net flow magnitudes and +directions relative to the given directed interface in that timestep. For a +query of `"Region A" => "Region B"`, if flow in one sample was from A to B, the +reported value would be positive, while if flow was in the reverse direction, +from B to A, the value would be negative. + +Example: + +```julia +flows, = + assess(sys, SequentialMonteCarlo(samples=10), FlowSamples()) + +samples = flows["Region A" => "Region B", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] + +@assert samples isa Vector{Float64} +@assert length(samples) == 10 + +samples2 = flows["Region B" => "Region A", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] + +@assert samples == -samples2 +``` + +See [`Flow`](@ref) for estimated average flow results. """ struct FlowSamples <: ResultSpec end diff --git a/PRASCore/src/Results/GeneratorAvailability.jl b/PRASCore/src/Results/GeneratorAvailability.jl index 7d6b95ed..1728a7fd 100644 --- a/PRASCore/src/Results/GeneratorAvailability.jl +++ b/PRASCore/src/Results/GeneratorAvailability.jl @@ -1,10 +1,26 @@ """ GeneratorAvailability -Generator availability represents the availability of generators at timestamps -in a GeneratorAvailabilityResult with a (generators, timestamps, samples) matrix API. +The `GeneratorAvailability` result specification reports the sample-level +discrete availability of `Generators`, producing a `GeneratorAvailabilityResult`. -No averaging occurs. +A `GeneratorAvailabilityResult` can be indexed by generator name and +timestamp to retrieve a vector of sample-level availability states for +the unit in the given timestep. States are provided as a boolean with +`true` indicating that the unit is available and `false` indicating that +it's unavailable. + +Example: + +```julia +genavail, = + assess(sys, SequentialMonteCarlo(samples=10), GeneratorAvailability()) + +samples = genavail["MyGenerator123", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] + +@assert samples isa Vector{Bool} +@assert length(samples) == 10 +``` """ struct GeneratorAvailability <: ResultSpec end diff --git a/PRASCore/src/Results/GeneratorStorageAvailability.jl b/PRASCore/src/Results/GeneratorStorageAvailability.jl index 3cff9d62..ba040873 100644 --- a/PRASCore/src/Results/GeneratorStorageAvailability.jl +++ b/PRASCore/src/Results/GeneratorStorageAvailability.jl @@ -1,10 +1,27 @@ """ GeneratorStorageAvailability -Generator storage availability represents the availability of generatorstorage resources at timestamps -in a GeneratorStorageAvailabilityResult with a (generatorstorages, timestamps, samples) matrix API. +The `GeneratorStorageAvailability` result specification reports the sample-level +discrete availability of `GeneratorStorages`, producing a +`GeneratorStorageAvailabilityResult`. -No averaging occurs +A `GeneratorStorageAvailabilityResult` can be indexed by generator-storage +name and timestamp to retrieve a vector of sample-level availability states for +the unit in the given timestep. States are provided as a boolean with +`true` indicating that the unit is available and `false` indicating that +it's unavailable. + +Example: + +```julia +genstoravail, = + assess(sys, SequentialMonteCarlo(samples=10), GeneratorStorageAvailability()) + +samples = genstoravail["MyGenerator123", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] + +@assert samples isa Vector{Bool} +@assert length(samples) == 10 +``` """ struct GeneratorStorageAvailability <: ResultSpec end diff --git a/PRASCore/src/Results/GeneratorStorageEnergy.jl b/PRASCore/src/Results/GeneratorStorageEnergy.jl index 3aa5e40f..c943ec02 100644 --- a/PRASCore/src/Results/GeneratorStorageEnergy.jl +++ b/PRASCore/src/Results/GeneratorStorageEnergy.jl @@ -1,15 +1,27 @@ """ GeneratorStorageEnergy -Generator storage energy represents state-of-charge of generatorstorage -resources at timestamps in a StorageEnergyResult with a (generatorstorages, timestamps) -matrix API. +The `GeneratorStorageEnergy` result specification reports the average state of +charge of `GeneratorStorages`, producing a `GeneratorStorageEnergyResult`. -Separate samples are averaged together into mean and std values. +A `GeneratorStorageEnergyResult` can be indexed by generator-storage device +name and a timestamp to retrieve a tuple of sample mean and standard deviation, +estimating the average energy level for the given generator-storage device in +that timestep. -See [`GeneratorStorageEnergySamples`](@ref) for all generator storage energy samples. +Example: -See [`StorageEnergy`](@ref) for storage energy. +```julia +genstorenergy, = + assess(sys, SequentialMonteCarlo(samples=1000), GeneratorStorageEnergy()) + +soc_mean, soc_std = + genstorenergy["MyGeneratorStorage123", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] +``` +See [`GeneratorStorageEnergySamples`](@ref) for sample-level generator-storage +states of charge. + +See [`StorageEnergy`](@ref) for average storage states of charge. """ struct GeneratorStorageEnergy <: ResultSpec end diff --git a/PRASCore/src/Results/GeneratorStorageEnergySamples.jl b/PRASCore/src/Results/GeneratorStorageEnergySamples.jl index 62f71d03..e882b9ce 100644 --- a/PRASCore/src/Results/GeneratorStorageEnergySamples.jl +++ b/PRASCore/src/Results/GeneratorStorageEnergySamples.jl @@ -1,11 +1,28 @@ """ GeneratorStorageEnergySamples -Generator storage energy samples represent the state-of-charge of generatorstorage -resources at timestamps, which has not been averaged across different samples. -This presents a 3D matrix API (generatorstorages, timestamps, samples). +The `GeneratorStorageEnergySamples` result specification reports the +sample-level state of charge of `GeneratorStorages`, producing a +`GeneratorStorageEnergySamplesResult`. -See [`GeneratorStorageEnergy`](@ref) for sample-averaged generator storage energy. +A `GeneratorStorageEnergySamplesResult` can be indexed by generator-storage +device name and a timestamp to retrieve a vector of sample-level charge states +for the device in the given timestep. + +Example: + +```julia +genstorenergy, = + assess(sys, SequentialMonteCarlo(samples=10), GeneratorStorageEnergySamples()) + +samples = genstorenergy["MyGeneratorStorage123", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] + +@assert samples isa Vector{Float64} +@assert length(samples) == 10 +``` + +See [`GeneratorStorageEnergy`](@ref) for estimated average generator-storage +state of charge. """ struct GeneratorStorageEnergySamples <: ResultSpec end diff --git a/PRASCore/src/Results/LineAvailability.jl b/PRASCore/src/Results/LineAvailability.jl index 9af1e062..f03c9ed9 100644 --- a/PRASCore/src/Results/LineAvailability.jl +++ b/PRASCore/src/Results/LineAvailability.jl @@ -1,10 +1,26 @@ """ LineAvailability -Line availability represents the availability of lines at timestamps -in a LineAvailabilityResult with a (lines, timestamps, samples) matrix API. +The `LineAvailability` result specification reports the sample-level +discrete availability of `Lines`, producing a `LineAvailabilityResult`. -No averaging occurs. +A `LineAvailabilityResult` can be indexed by line name and +timestamp to retrieve a vector of sample-level availability states for +the unit in the given timestep. States are provided as a boolean with +`true` indicating that the unit is available and `false` indicating that +it's unavailable. + +Example: + +```julia +lineavail, = + assess(sys, SequentialMonteCarlo(samples=10), LineAvailability()) + +samples = lineavail["MyLine123", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] + +@assert samples isa Vector{Bool} +@assert length(samples) == 10 +``` """ struct LineAvailability <: ResultSpec end diff --git a/PRASCore/src/Results/Shortfall.jl b/PRASCore/src/Results/Shortfall.jl index 567be50e..801644c3 100644 --- a/PRASCore/src/Results/Shortfall.jl +++ b/PRASCore/src/Results/Shortfall.jl @@ -1,12 +1,43 @@ """ Shortfall -Shortfall metric represents lost load at regions and timesteps -in ShortfallResult with a (regions, timestamps) matrix API. +The `Shortfall` result specification reports expectation-based resource +adequacy risk metrics such as EUE and LOLE, producing a `ShortfallResult`. -Separate samples are averaged together into mean and std values. +A `ShortfallResult` can be directly indexed by a region name and a timestamp to retrieve a tuple of sample mean and standard deviation, estimating + the average unserved energy in that region and timestep. However, in most +cases it's simpler to use [`EUE`](@ref) and [`LOLE`](@ref) constructors to +directly retrieve standard risk metrics. -See [`ShortfallSamples`](@ref) for all shortfall samples. +Example: + +```julia +shortfall, = + assess(sys, SequentialMonteCarlo(samples=1000), Shortfall()) + +period = ZonedDateTime(2020, 1, 1, 0, tz"UTC") + +# Unserved energy mean and standard deviation +sf_mean, sf_std = shortfall["Region A", period] + +# System-wide risk metrics +eue = EUE(shortfall) +lole = LOLE(shortfall) + +# Regional risk metrics +regional_eue = EUE(shortfall, "Region A") +regional_lole = LOLE(shortfall, "Region A") + +# Period-specific risk metrics +period_eue = EUE(shortfall, period) +period_lolp = LOLE(shortfall, period) + +# Region- and period-specific risk metrics +period_eue = EUE(shortfall, "Region A", period) +period_lolp = LOLE(shortfall, "Region A", period) +``` + +See [`ShortfallSamples`](@ref) for recording sample-level shortfall results. """ struct Shortfall <: ResultSpec end @@ -86,11 +117,6 @@ end accumulatortype(::Shortfall) = ShortfallAccumulator -""" - ShortfallResult - -Matrix-like data structure for storing shortfall means -""" struct ShortfallResult{N, L, T <: Period, E <: EnergyUnit} <: AbstractShortfallResult{N, L, T} nsamples::Union{Int, Nothing} diff --git a/PRASCore/src/Results/ShortfallSamples.jl b/PRASCore/src/Results/ShortfallSamples.jl index 04087f87..c132a9c4 100644 --- a/PRASCore/src/Results/ShortfallSamples.jl +++ b/PRASCore/src/Results/ShortfallSamples.jl @@ -1,10 +1,45 @@ """ ShortfallSamples -ShortfallSamples metric represents lost load at regions and timesteps -in ShortfallSamplesResult with a (regions, timestamps, samples) matrix API. +The `ShortfallSamples` result specification reports sample-level unserved energy outcomes, producing a `ShortfallSamplesResult`. -See [`Shortfall`](@ref) for averaged shortfall samples. +A `ShortfallSamplesResult` can be directly indexed by a region name and a +timestamp to retrieve a vector of sample-level unserved energy results in that +region and timestep. [`EUE`](@ref) and [`LOLE`](@ref) constructors can also +be used to retrieve standard risk metrics. + +Example: + +```julia +shortfall, = + assess(sys, SequentialMonteCarlo(samples=10), ShortfallSamples()) + +period = ZonedDateTime(2020, 1, 1, 0, tz"UTC") + +samples = shortfall["Region A", period] + +@assert samples isa Vector{Float64} +@assert length(samples) == 10 + +# System-wide risk metrics +eue = EUE(shortfall) +lole = LOLE(shortfall) + +# Regional risk metrics +regional_eue = EUE(shortfall, "Region A") +regional_lole = LOLE(shortfall, "Region A") + +# Period-specific risk metrics +period_eue = EUE(shortfall, period) +period_lolp = LOLE(shortfall, period) + +# Region- and period-specific risk metrics +period_eue = EUE(shortfall, "Region A", period) +period_lolp = LOLE(shortfall, "Region A", period) +``` + +See [`Shortfall`](@ref) for average shortfall outcomes, which require much +less memory to store. """ struct ShortfallSamples <: ResultSpec end diff --git a/PRASCore/src/Results/StorageAvailability.jl b/PRASCore/src/Results/StorageAvailability.jl index 1a053d05..46b5aa27 100644 --- a/PRASCore/src/Results/StorageAvailability.jl +++ b/PRASCore/src/Results/StorageAvailability.jl @@ -1,10 +1,26 @@ """ StorageAvailability -Storage availability represents the availability of storage resources at timestamps -in a StorageAvailabilityResult with a (storages, timestamps, samples) matrix API. +The `StorageAvailability` result specification reports the sample-level +discrete availability of `Storages`, producing a `StorageAvailabilityResult`. -No averaging occurs. +A `StorageAvailabilityResult` can be indexed by storage device name and +a timestamp to retrieve a vector of sample-level availability states for +the unit in the given timestep. States are provided as a boolean with +`true` indicating that the unit is available and `false` indicating that +it's unavailable. + +Example: + +```julia +storavail, = + assess(sys, SequentialMonteCarlo(samples=10), StorageAvailability()) + +samples = storavail["MyStorage123", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] + +@assert samples isa Vector{Bool} +@assert length(samples) == 10 +``` """ struct StorageAvailability <: ResultSpec end diff --git a/PRASCore/src/Results/StorageEnergy.jl b/PRASCore/src/Results/StorageEnergy.jl index 7ca4ef3d..206e708b 100644 --- a/PRASCore/src/Results/StorageEnergy.jl +++ b/PRASCore/src/Results/StorageEnergy.jl @@ -1,15 +1,27 @@ """ StorageEnergy -Storage energy represents the state-of-charge of storage -resources at timestamps in a StorageEnergyResult with a (storages, timestamps) -matrix API. +The `StorageEnergy` result specification reports the average state of charge +of `Storages`, producing a `StorageEnergyResult`. -Separate samples are averaged together into mean and std values. +A `StorageEnergyResult` can be indexed by storage device name and a timestamp to +retrieve a tuple of sample mean and standard deviation, estimating the average +energy level for the given storage device in that timestep. -See [`StorageEnergySamples`](@ref) for all storage energy samples. +Example: -See [`GeneratorStorageEnergy`](@ref) for generator storage energy. +```julia +storenergy, = + assess(sys, SequentialMonteCarlo(samples=1000), StorageEnergy()) + +soc_mean, soc_std = + storenergy["MyStorage123", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] +``` + +See [`StorageEnergySamples`](@ref) for sample-level storage states of charge. + +See [`GeneratorStorageEnergy`](@ref) for average generator-storage states +of charge. """ struct StorageEnergy <: ResultSpec end diff --git a/PRASCore/src/Results/StorageEnergySamples.jl b/PRASCore/src/Results/StorageEnergySamples.jl index 043eb6d9..e8e9ed21 100644 --- a/PRASCore/src/Results/StorageEnergySamples.jl +++ b/PRASCore/src/Results/StorageEnergySamples.jl @@ -1,11 +1,26 @@ """ StorageEnergySamples -Storage energy samples represent the state-of-charge of storage -resources at timestamps, which has not been averaged across different samples. -This presents a 3D matrix API (storages, timestamps, samples). +The `StorageEnergySamples` result specification reports the sample-level state +of charge of `Storages`, producing a `StorageEnergySamplesResult`. -See [`StorageEnergy`](@ref) for sample-averaged storage energy. +A `StorageEnergySamplesResult` can be indexed by storage device name and +a timestamp to retrieve a vector of sample-level charge states for +the device in the given timestep. + +Example: + +```julia +storenergy, = + assess(sys, SequentialMonteCarlo(samples=10), StorageEnergySamples()) + +samples = storenergy["MyStorage123", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] + +@assert samples isa Vector{Float64} +@assert length(samples) == 10 +``` + +See [`StorageEnergy`](@ref) for estimated average storage state of charge. """ struct StorageEnergySamples <: ResultSpec end diff --git a/PRASCore/src/Results/Surplus.jl b/PRASCore/src/Results/Surplus.jl index a167410d..6c1e065b 100644 --- a/PRASCore/src/Results/Surplus.jl +++ b/PRASCore/src/Results/Surplus.jl @@ -1,12 +1,24 @@ """ Surplus -Surplus metric represents extra generation at regions and timestamps -in a SurplusResults with a (regions, timestamps) matrix API. +The `Surplus` result specification reports unused generation and storage +discharge capability of `Regions`, producing a `SurplusResult`. -Separate samples are averaged together into mean and std values. +A `SurplusResult` can be indexed by region name and timestamp to retrieve +a tuple of sample mean and standard deviation, estimating the average +unused capacity in that region and timestep. -See [`SurplusSamples`](@ref) for all surplus samples. +Example: + +```julia +surplus, = + assess(sys, SequentialMonteCarlo(samples=1000), Surplus()) + +surplus_mean, surplus_std = + surplus["Region A", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] +``` + +See [`SurplusSamples`](@ref) for sample-level surplus results. """ struct Surplus <: ResultSpec end diff --git a/PRASCore/src/Results/SurplusSamples.jl b/PRASCore/src/Results/SurplusSamples.jl index e0202df3..85fcf2a1 100644 --- a/PRASCore/src/Results/SurplusSamples.jl +++ b/PRASCore/src/Results/SurplusSamples.jl @@ -1,10 +1,26 @@ """ SurplusSamples -Surplus samples represent extra generation at regions and timestamps -in a SurplusSamplesResult with a (regions, timestamps, samples) matrix API. +The `SurplusSamples` result specification reports sample-level unused +generation and storage discharge capability of `Regions`, producing a +`SurplusSamplesResult`. -See [`Surplus`](@ref) for sample-averaged surplus data. +A `SurplusSamplesResult` can be indexed by region name and timestamp to retrieve +a vector of sample-level surplus values in that region and timestep. + +Example: + +```julia +surplus, = + assess(sys, SequentialMonteCarlo(samples=10), SurplusSamples()) + +samples = surplus["Region A", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] + +@assert samples isa Vector{Float64} +@assert length(samples) == 10 +``` + +See [`Surplus`](@ref) for estimated average surplus values. """ struct SurplusSamples <: ResultSpec end diff --git a/PRASCore/src/Results/Utilization.jl b/PRASCore/src/Results/Utilization.jl index e86a042b..ec5b2a4e 100644 --- a/PRASCore/src/Results/Utilization.jl +++ b/PRASCore/src/Results/Utilization.jl @@ -1,12 +1,40 @@ """ Utilization -Utilization metric represents how much an interface between regions is used -across timestamps in a UtilizationResult with a (interfaces, timestamps) matrix API. +The `Utilization` result specification reports the estimated average +absolute utilization of `Interfaces`, producing a `UtilizationResult`. -Separate samples are averaged together into mean and std values. +Whereas `Flow` reports the average directional power transfer across an +interface, `Utilization` reports the absolute value of flow relative to the +interface's transfer capability (counting the effects of line outages). +For example, a symmetrically-constrained interface which is fully congested +with max power flowing in one direction in half of the samples, and the other +direction in the remaining samples, would have an average flow of 0 MW, but +an average utilization of 100%. -See [`UtilizationSamples`](@ref) for all utilization samples. +A `UtilizationResult` can be indexed by a `Pair` of region names and a +timestamp to retrieve a tuple of sample mean and standard deviation, estimating +the average utilization of the interface. Given the absolute value nature of +the outcome, results are independent of direction. Querying +`"Region A" => "Region B"` will yield the same result as +`"Region B" => "Region A"`. + +Example: + +```julia +utils, = + assess(sys, SequentialMonteCarlo(samples=1000), Utilization()) + +util_mean, util_std = + utils["Region A" => "Region B", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] + +util2_mean, util2_std = + utils["Region B" => "Region A", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] + +@assert util_mean == util2_mean +``` + +See [`UtilizationSamples`](@ref) for sample-level utilization results. """ struct Utilization <: ResultSpec end diff --git a/PRASCore/src/Results/UtilizationSamples.jl b/PRASCore/src/Results/UtilizationSamples.jl index 8bcab203..556dd05a 100644 --- a/PRASCore/src/Results/UtilizationSamples.jl +++ b/PRASCore/src/Results/UtilizationSamples.jl @@ -1,11 +1,43 @@ """ UtilizationSamples -Utilization samples represent the utilization between interfaces at timestamps, which has -not been averaged across different samples. This presents a -3D matrix API (interfaces, timestamps, samples). +The `UtilizationSamples` result specification reports the sample-level +absolute utilization of `Interfaces`, producing a `UtilizationSamplesResult`. -See [`Utilization`](@ref) for averaged utilization samples. +Whereas `FlowSamples` reports the directional power transfer across an +interface, `UtilizationSamples` reports the absolute value of flow relative to the +interface's transfer capability (counting the effects of line outages). +For example, a 100 MW symmetrically-constrained interface which is fully +congested may have a flow of +100 or -100 MW, but in both cases the utilization +will be 100%. If a 50 MW line in the interface went on outage, flow may drop +to +50 or -50 MW, but utilization would remain at 100%. + +A `UtilizationSamplesResult` can be indexed by a `Pair` of region +names and a timestamp to retrieve a vector of sample-level utilizations of the +interface in that timestep. Given the absolute value nature of the outcome, +results are independent of direction. Querying +`"Region A" => "Region B"` will yield the same result as +`"Region B" => "Region A"`. + +Example: + +```julia +utils, = + assess(sys, SequentialMonteCarlo(samples=10), UtilizationSamples()) + +samples = + utils["Region A" => "Region B", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] + +@assert samples isa Vector{Float64} +@assert length(samples) == 10 + +samples2 = + utils["Region B" => "Region A", ZonedDateTime(2020, 1, 1, 0, tz"UTC")] + +@assert samples == samples2 +``` + +See [`Utilization`](@ref) for sample-averaged utilization results. """ struct UtilizationSamples <: ResultSpec end diff --git a/PRASCore/src/Results/metrics.jl b/PRASCore/src/Results/metrics.jl index 6e252a4d..a8e035af 100644 --- a/PRASCore/src/Results/metrics.jl +++ b/PRASCore/src/Results/metrics.jl @@ -69,7 +69,13 @@ Base.isapprox(x::ReliabilityMetric, y::ReliabilityMetric) = """ LOLE -Loss of load expectation metric. Contains a mean and standard error estimate. +`LOLE` reports loss of load expectation over a particular time period +and regional extent. When the reporting period is a single simulation +timestep, the metric is equivalent to loss of load probability (LOLP). + +Contains both the estimated value itself as well as the standard error +of that estimate, which can be extracted with `val` and `stderror`, +respectively. """ struct LOLE{N, L, T <: Period} <: ReliabilityMetric lole::MeanEstimate @@ -97,7 +103,12 @@ end """ EUE -Expected unserved energy expectation metric. Contains a mean and standard error estimate. +`EUE` reports expected unserved energy over a particular time period and +regional extent. + +Contains both the estimated value itself as well as the standard error +of that estimate, which can be extracted with `val` and `stderror`, +respectively. """ struct EUE{N,L,T<:Period,E<:EnergyUnit} <: ReliabilityMetric diff --git a/PRASCore/src/Systems/SystemModel.jl b/PRASCore/src/Systems/SystemModel.jl index 57b1d5f6..e46e29a7 100644 --- a/PRASCore/src/Systems/SystemModel.jl +++ b/PRASCore/src/Systems/SystemModel.jl @@ -1,15 +1,8 @@ """ SystemModel -SystemModel is the primary data structure for Probabilistic Resource Adequacy Studies (PRAS). - -You can also load a `SystemModel` from an appropriately-formatted HDF5 file on disk. - -# Examples - -```julia -pras = SystemModel("path/to/pras.pras") -``` +A `SystemModel` contains a representation of a power system to be studied +with PRAS. """ struct SystemModel{N, L, T <: Period, P <: PowerUnit, E <: EnergyUnit} regions::Regions{N, P} diff --git a/PRASFiles/src/read.jl b/PRASFiles/src/read.jl index cc95b6ce..493e8c1d 100644 --- a/PRASFiles/src/read.jl +++ b/PRASFiles/src/read.jl @@ -1,3 +1,16 @@ +""" + + SystemModel(filename::String) + +Load a `SystemModel` from an appropriately-formatted HDF5 file on disk. +These files typically have a .pras filename extension. + +# Examples + +```julia +sys = SystemModel("path/to/prasfile.pras") +``` +""" function SystemModel(inputfile::String) system = h5open(inputfile, "r") do f::File