Repository navigation
Add report generation package #92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
88c20c3
ae92a54
c63daeb
28edc36
cbe11c4
71494cc
6449d12
3b5ba7f
835c224
ea5a1d3
6f7fca3
b94eab2
befdb54
23c1488
60048b0
06d6686
cdf5e74
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| name: PRASReport.jl tests | ||
| # Run on master, tags, or any pull request | ||
| on: | ||
| schedule: | ||
| - cron: '0 2 * * *' # Daily at 2 AM UTC (8 PM CST) | ||
| push: | ||
| branches: [main] | ||
| tags: ["*"] | ||
| pull_request: | ||
| jobs: | ||
| test: | ||
| name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} | ||
| runs-on: ${{ matrix.os }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| version: | ||
| - "lts" # Latest LTS release, min supported | ||
| - "1" # Latest release | ||
| os: | ||
| - ubuntu-latest | ||
| - macOS-latest | ||
| - windows-latest | ||
| arch: | ||
| - x64 | ||
| - aarch64 | ||
| exclude: | ||
| - os: windows-latest | ||
| arch: aarch64 | ||
| - os: ubuntu-latest | ||
| arch: aarch64 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: julia-actions/setup-julia@v2 | ||
| with: | ||
| version: ${{ matrix.version }} | ||
| arch: ${{ matrix.arch }} | ||
| - uses: actions/cache@v4 | ||
| env: | ||
| cache-name: cache-artifacts | ||
| with: | ||
| path: ~/.julia/artifacts | ||
| key: ${{ runner.os }}-${{ matrix.arch }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-${{ matrix.arch }}-test-${{ env.cache-name }}- | ||
| ${{ runner.os }}-${{ matrix.arch }}-test- | ||
| ${{ runner.os }}-${{ matrix.arch }}- | ||
| ${{ runner.os }}- | ||
| - run: julia --project=PRASReport.jl -e 'import Pkg; | ||
| Pkg.develop([ | ||
| (path="PRASCore.jl",), | ||
| (path="PRASFiles.jl",), | ||
| ])' | ||
| shell: bash | ||
| - uses: julia-actions/julia-buildpkg@latest | ||
| with: | ||
| project: PRASReport.jl | ||
| - run: | | ||
| git config --global user.name Tester | ||
| git config --global user.email te@st.er | ||
| - uses: julia-actions/julia-runtest@latest | ||
| with: | ||
| project: PRASReport.jl | ||
| env: | ||
| JULIA_NUM_THREADS: 2 | ||
| - uses: julia-actions/julia-processcoverage@v1 | ||
| with: | ||
| directories: PRASReport.jl/src | ||
| - uses: codecov/codecov-action@v4 | ||
| with: | ||
| token: ${{ secrets.CODECOV_TOKEN }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| MIT License | ||
|
|
||
| Copyright (c) 2026 Alliance for Energy Innovation, LLC | ||
|
|
||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
|
|
||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
|
|
||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| name = "PRASReport" | ||
| uuid = "c003f3f0-f5d5-4077-8f93-207e59ecb3ff" | ||
| authors = ["Hari Sundar <Hari.Sundar@nlr.gov>"] | ||
| version = "0.1.0" | ||
|
|
||
| [deps] | ||
| Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" | ||
| Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" | ||
| DuckDB = "d2f5444f-75bc-4fdf-ac35-56f514c445e1" | ||
| PRASCore = "c5c32b99-e7c3-4530-a685-6f76e19f7fe2" | ||
| PRASFiles = "a2806276-6d43-4ef5-91c0-491704cd7cf1" | ||
| StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" | ||
| Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" | ||
| TimeZones = "f269a46b-ccf7-5d73-abea-4c690281aa53" | ||
|
|
||
| [compat] | ||
| Dates = "1" | ||
| PRASCore = "0.9.0" | ||
| PRASFiles = "0.9.0" | ||
| StatsBase = "0.34" | ||
| TimeZones = "^1.14" | ||
| julia = "1.10" | ||
|
|
||
| [extras] | ||
| Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" | ||
| Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb" | ||
|
|
||
| [targets] | ||
| test = ["Test","Suppressor"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # PRASReport.jl | ||
|
|
||
| ## Usage | ||
| ```julia | ||
| using PRASReport | ||
|
|
||
| create_pras_report(system_path="path_to_sys.pras", # Path to your .pras file | ||
| samples=100,seed=1, # Number of samples and random seed for analysis | ||
| report_name="report", # Name of the output HTML file | ||
| report_path=pwd(), # Path for HTML file output | ||
| threshold=0, # hourly EUE threshold to be considered part of event | ||
| title="Resource Adequacy Report") # Report title | ||
| ``` |
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if this should be here. We don't have this in any other repos.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do have this in PRAS.jl/examples. I felt like since this is an example specifically for report generation, this should be here rather than in PRAS.jl/examples which goes over more holistic functionality across multiple packages. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| using Revise | ||
| using PRAS | ||
| using PRASReport | ||
|
|
||
| rts_sys = rts_gmlc(); | ||
| rts_sys.regions.load .+= 375; | ||
|
|
||
| sf,flow = assess(rts_sys,SequentialMonteCarlo(samples=100),Shortfall(),Flow()); | ||
|
|
||
| create_pras_report(sf,flow, report_name="rts_report", | ||
| title="RTS-GMLC (load modified) RA Report", | ||
| threshold=1) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| module PRASReport | ||
|
|
||
| import PRASCore.Systems: SystemModel, Regions, Interfaces, | ||
| Generators, Storages, GeneratorStorages, Lines, | ||
| timeunits, powerunits, energyunits, unitsymbol, | ||
| unitsymbol_long | ||
| import PRASCore.Simulations: assess, SequentialMonteCarlo | ||
| import PRASCore.Results: EUE, LOLE, NEUE, | ||
| Shortfall, Flow, | ||
| ShortfallResult, FlowResult, | ||
| ShortfallSamplesResult, AbstractShortfallResult, | ||
| Result, MeanEstimate, findfirstunique, | ||
| val, stderror | ||
| import PRASFiles: SystemModel | ||
| import StatsBase: mean | ||
| import Dates: @dateformat_str, format, now, DateTime | ||
| import TimeZones: ZonedDateTime, @tz_str, TimeZone | ||
| import Base64: base64encode | ||
| import Tables: columntable | ||
| import DuckDB | ||
|
|
||
| export | ||
| Event, get_events, event_length, | ||
| Shortfall_timeseries, Flow_timeseries, | ||
| get_db, create_pras_report | ||
|
|
||
| include("events.jl") | ||
| include("writedb.jl") | ||
| include("report.jl") | ||
|
|
||
| end # module PRASReport |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| -- System and Simulation parameters | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. General comment here: DuckDB is incredbly fast at doing some of the calculatins we do for EUE, nEUE, etc. I know this might mean a full overhaul of the schema but something to think about. |
||
| CREATE TABLE systemsiminfo ( | ||
| timesteps INTEGER, | ||
| step_size INTEGER NOT NULL, | ||
| time_unit TEXT NOT NULL, | ||
| power_unit TEXT NOT NULL, | ||
| energy_unit TEXT NOT NULL, | ||
| start_timestamp TIMESTAMP WITHOUT TIME ZONE, | ||
| end_timestamp TIMESTAMP WITHOUT TIME ZONE, | ||
| timezone TEXT, | ||
| n_samples INTEGER, | ||
| eue_mean REAL NOT NULL, | ||
| eue_stderr REAL NOT NULL, | ||
| lole_mean REAL NOT NULL, | ||
| lole_stderr REAL NOT NULL, | ||
| neue_mean REAL NOT NULL, | ||
| neue_stderr REAL NOT NULL, | ||
| eventthreshold INTEGER NOT NULL, | ||
|
|
||
| -- Constraint to ensure valid ISO 8601 duration units | ||
| CONSTRAINT valid_time_unit CHECK ( | ||
| time_unit IN ('Year', 'Day', 'Hour', 'Minute', 'Second') | ||
| ) | ||
| ); | ||
|
|
||
| -- Regions lookup table | ||
| CREATE TABLE regions ( | ||
| id INTEGER PRIMARY KEY, | ||
| name TEXT UNIQUE NOT NULL | ||
| ); | ||
|
|
||
| -- Interfaces lookup table (region to region connections) | ||
| CREATE TABLE interfaces ( | ||
| id INTEGER PRIMARY KEY, | ||
| region_from_id INTEGER REFERENCES regions(id), | ||
| region_to_id INTEGER REFERENCES regions(id), | ||
| name TEXT, -- name like "Region1->Region2" | ||
| UNIQUE(region_from_id, region_to_id) | ||
| ); | ||
|
|
||
| -- Main events table (clean, no parameters) | ||
| CREATE SEQUENCE eventid_sequence START 1; | ||
| CREATE TABLE events ( | ||
| id INTEGER PRIMARY KEY DEFAULT nextval('eventid_sequence'), | ||
| name TEXT NOT NULL, | ||
| start_timestamp TIMESTAMP WITHOUT TIME ZONE NOT NULL, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this different from the start_timestamp in the systemsinfo table? |
||
| end_timestamp TIMESTAMP WITHOUT TIME ZONE NOT NULL, | ||
| time_period_count INTEGER NOT NULL -- N parameter | ||
| ); | ||
|
|
||
| -- System-level metrics for each event (aggregated) | ||
| CREATE TABLE event_system_shortfall ( | ||
| event_id INTEGER REFERENCES events(id), | ||
| lole REAL NOT NULL, | ||
| eue REAL NOT NULL, | ||
| neue REAL NOT NULL, | ||
| PRIMARY KEY (event_id) | ||
| ); | ||
|
|
||
| -- Regional metrics for each event (aggregated) | ||
| CREATE TABLE event_regional_shortfall ( | ||
| id INTEGER PRIMARY KEY, | ||
| event_id INTEGER REFERENCES events(id), | ||
| region_id INTEGER REFERENCES regions(id), | ||
| lole REAL NOT NULL, | ||
| eue REAL NOT NULL, | ||
| neue REAL NOT NULL, | ||
| UNIQUE(event_id, region_id) | ||
| ); | ||
|
|
||
| -- Time-series metrics for each timestamp within an event (from sf_ts struct) | ||
| -- Optimized with better data types and ordering for columnar storage | ||
| CREATE TABLE event_timeseries_shortfall ( | ||
| event_id INTEGER NOT NULL, | ||
| region_id INTEGER NOT NULL, | ||
| timestamp_value TIMESTAMP WITHOUT TIME ZONE NOT NULL, | ||
| lole REAL NOT NULL, | ||
| eue REAL NOT NULL, | ||
| neue REAL NOT NULL, | ||
| FOREIGN KEY (event_id) REFERENCES events(id), | ||
| FOREIGN KEY (region_id) REFERENCES regions(id), | ||
| PRIMARY KEY (event_id, region_id, timestamp_value) | ||
| ); | ||
|
|
||
| -- Flow data for each timestamp within an event (from flow_ts struct) | ||
| -- Optimized with better data types and ordering for columnar storage | ||
| CREATE TABLE event_timeseries_flows ( | ||
| event_id INTEGER NOT NULL, | ||
| interface_id INTEGER NOT NULL, | ||
| timestamp_value TIMESTAMP WITHOUT TIME ZONE NOT NULL, | ||
| flow REAL NOT NULL, -- Flow value (NEUE units) | ||
| FOREIGN KEY (event_id) REFERENCES events(id), | ||
| FOREIGN KEY (interface_id) REFERENCES interfaces(id), | ||
| PRIMARY KEY (event_id, interface_id, timestamp_value) | ||
| ); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check if the load = 0 update ever made it through as tests might fail.