Skip to content

Add new risk metrics#103

Open
akrivi wants to merge 6 commits intoNatLabRockies:mainfrom
akrivi:main
Open

Add new risk metrics#103
akrivi wants to merge 6 commits intoNatLabRockies:mainfrom
akrivi:main

Conversation

@akrivi
Copy link

@akrivi akrivi commented Mar 13, 2026

This PR implements the following metrics:

  • LOLD: as defined in [1]
  • LOLEv: as defined in [2]

With the implementation of the above, all metrics defined in [2] are included in PRAS

Additionally, the following metrics commonly used in analysis are implemented:

  • MeanEventDuration

References:
[1] “Clarifying the interpretation and use of the LOLE Resource Adequacy Metric,”
[2] "Probabilistic Adequacy and Measures", NERC

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds new reliability metrics—LOLD (loss of load days), LOLEv (loss of load events), and MeanEventDuration—by introducing a new event-based result type (ShortfallEvents) and extending existing shortfall-sample metrics.

Changes:

  • Add new ReliabilityMetric types: LOLD, LOLEv, and MeanEventDuration.
  • Implement LOLD computation from ShortfallSamplesResult using day grouping derived from timestamps.
  • Introduce ShortfallEvents result recording/finalization to enable event-based metrics and add corresponding simulation tests.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
PRASCore.jl/test/Simulations/runtests.jl Adds tests for LOLD and event-based metrics (LOLEv/MeanEventDuration).
PRASCore.jl/src/Simulations/utils.jl Extends init_regionshortfall dispatch to include ShortfallEvents.
PRASCore.jl/src/Simulations/recording.jl Adds record!/reset! logic to accumulate contiguous shortfall events.
PRASCore.jl/src/Results/utils.jl Adds _day_ids helper to map timestamps to day identifiers.
PRASCore.jl/src/Results/metrics.jl Defines new metric structs and show/val/stderror behavior.
PRASCore.jl/src/Results/ShortfallSamples.jl Implements LOLD constructors and day-counting logic for samples.
PRASCore.jl/src/Results/ShortfallEvents.jl Adds new ShortfallEvents resultspec, accumulator/result types, and event-based metric constructors.
PRASCore.jl/src/Results/Results.jl Exports new metrics and includes the new ShortfallEvents result file/type.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +645 to +665
@testset "Shortfall Event Metrics" begin
# Single-region system
@test val(LOLEv(events_1a)) >= 0
@test stderror(LOLEv(events_1a)) >= 0
@test val(MeanEventDuration(events_1a)) >= 0
@test stderror(MeanEventDuration(events_1a)) >= 0

@test LOLEv(events_1a) ≈ LOLEv(events_1a, "Region")
@test MeanEventDuration(events_1a) ≈ MeanEventDuration(events_1a, "Region")

# Multi-region system
@test val(LOLEv(events_3)) >= 0
@test val(MeanEventDuration(events_3)) >= 0
@test val(LOLEv(events_3, "Region A")) >= 0
@test val(MeanEventDuration(events_3, "Region A")) >= 0

@test val(LOLEv(events_3)) >= val(LOLEv(events_3, "Region A"))

@test PRAS.PRASCore.Results.totalevents(events_1a) >= 0
@test PRAS.PRASCore.Results.totalevents(events_3, "Region A") >= 0
end
Comment on lines +593 to +609
@testset "LOLD Results" begin
lold_1a = LOLD(shortfall2_1a)
regional_lold_1a = LOLD(shortfall2_1a, "Region")

@test val(lold_1a) isa Float64
@test stderror(lold_1a) isa Float64
@test val(regional_lold_1a) isa Float64
@test stderror(regional_lold_1a) isa Float64

@test val(lold_1a) >= 0
@test stderror(lold_1a) >= 0
@test val(regional_lold_1a) >= 0
@test stderror(regional_lold_1a) >= 0

@test val(lold_1a) <= length(unique(Date.(shortfall2_1a.timestamps)))
@test val(regional_lold_1a) <= length(unique(Date.(shortfall2_1a.timestamps)))
@test val(lold_1a) >= val(regional_lold_1a)
Comment on lines +13 to +15
struct ShortfallEvents <: ResultSpec end
struct DemandResponseShortfallEvents <: ResultSpec end

Comment on lines 247 to 255
function init_regionshortfall(
::Type{S},
edges,
region) where {S <: Union{
Results.Shortfall,
Results.ShortfallSamples}}
Results.ShortfallSamples,
Results.ShortfallEvents}}
return edges[region].flow
end
Comment on lines +647 to +664
@test val(LOLEv(events_1a)) >= 0
@test stderror(LOLEv(events_1a)) >= 0
@test val(MeanEventDuration(events_1a)) >= 0
@test stderror(MeanEventDuration(events_1a)) >= 0

@test LOLEv(events_1a) ≈ LOLEv(events_1a, "Region")
@test MeanEventDuration(events_1a) ≈ MeanEventDuration(events_1a, "Region")

# Multi-region system
@test val(LOLEv(events_3)) >= 0
@test val(MeanEventDuration(events_3)) >= 0
@test val(LOLEv(events_3, "Region A")) >= 0
@test val(MeanEventDuration(events_3, "Region A")) >= 0

@test val(LOLEv(events_3)) >= val(LOLEv(events_3, "Region A"))

@test PRAS.PRASCore.Results.totalevents(events_1a) >= 0
@test PRAS.PRASCore.Results.totalevents(events_3, "Region A") >= 0
@sriharisundar sriharisundar self-requested a review March 13, 2026 19:52
@sriharisundar
Copy link
Member

Thanks @akrivi for the PR! Can you please check the test syntax and make sure tests are passing? Also please address any valid copilot comments and resolve them, and whatever you feel are not valid, leave them as it is or reply and I will resolve them.

For the docs, you just need to add the new metrics to the ##Results section in this file - https://github.com/akrivi/PRAS/blob/main/docs/src/PRASCore/api.md and docs should pass.

Please lmk if you want any inputs on getting the tests to pass and we can chat.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants