{"id":51106267,"url":"https://github.com/feashliaa/severe_weather_event_reporter","last_synced_at":"2026-06-24T14:01:47.146Z","repository":{"id":364395280,"uuid":"1240872743","full_name":"Feashliaa/Severe_Weather_Event_Reporter","owner":"Feashliaa","description":"Automated severe weather event analysis. Enter a location and date, get a full post-event report in ~3 minutes: animated NEXRAD radar loops, Skew-T/hodograph sounding analysis, NWS warnings, storm survey data, interactive damage track maps, and an AI-written narrative grounded in real meteorological data from 8 federal sources.","archived":false,"fork":false,"pushed_at":"2026-06-12T22:21:40.000Z","size":3375,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-12T22:23:25.946Z","etag":null,"topics":["ai","data-pipeline","etl","fastapi","leaflet","llm","meterology","metpy","nexrad","noaa","nws","pyart","python","radar","severe-weather","storm-events","tornado","weather"],"latest_commit_sha":null,"homepage":"https://severeweathereventreporter-production.up.railway.app/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Feashliaa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-16T17:15:10.000Z","updated_at":"2026-06-12T22:21:44.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Feashliaa/Severe_Weather_Event_Reporter","commit_stats":null,"previous_names":["feashliaa/severe_weather_event_reporter"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/Feashliaa/Severe_Weather_Event_Reporter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Feashliaa%2FSevere_Weather_Event_Reporter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Feashliaa%2FSevere_Weather_Event_Reporter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Feashliaa%2FSevere_Weather_Event_Reporter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Feashliaa%2FSevere_Weather_Event_Reporter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Feashliaa","download_url":"https://codeload.github.com/Feashliaa/Severe_Weather_Event_Reporter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Feashliaa%2FSevere_Weather_Event_Reporter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34735266,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-24T02:00:07.484Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","data-pipeline","etl","fastapi","leaflet","llm","meterology","metpy","nexrad","noaa","nws","pyart","python","radar","severe-weather","storm-events","tornado","weather"],"created_at":"2026-06-24T14:01:42.501Z","updated_at":"2026-06-24T14:01:47.141Z","avatar_url":"https://github.com/Feashliaa.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Severe Weather Event Reporter\n\nAn AI-powered post-event severe weather report generator. Input a location, date, and time window - the tool fetches NWS warnings, Local Storm Reports (IEM), NCEI Storm Events survey data, pre-event upper air soundings, NWS Damage Assessment Toolkit survey geometry, SPC convective outlooks, and archived NEXRAD Level II radar, then produces a polished HTML report with an animated radar loop, interactive event map, Skew-T/hodograph sounding analysis, volume scan analysis table, and a structured LLM narrative grounded entirely in real meteorological data.\n\nThe kind of breakdown that normally takes a meteorologist hours to assemble manually - automated down to about 2 minutes.\n\n![Animated NEXRAD radar loop - Moore, OK EF5, May 20 2013](docs/radar-loop.gif)\n\n## The Problem\n\nMajor events get coverage. EF4-5s, significant outbreaks, high-fatality events - NWS publishes service assessments, media writes them up, researchers document them. But the long tail doesn't. EF1-EF3s in rural counties, isolated hail events, derecho segments, marginally tornadic nights - they get a database entry and maybe a tweet. Weeks later, nobody can answer \"what actually happened Tuesday night in [county]\" without spending an hour piecing together IEM, NCEI, and S3 radar files manually.\n\nThis tool fills that gap.\n\n## What It Produces\n\nEach report includes:\n\n- **Impact summary card** - EF rating, fatalities, injuries, warning lead time, path length (DAT surveyed or NCEI), max reflectivity, echo tops, warning count, LSR count, and property damage at a glance\n\n![Impact summary card - Moore, OK 2013](docs/impact-summary.png)\n\n- **Warning lead time analysis** - minutes between the first tornado warning and the highest-rated tornado's touchdown, computed from VTEC issuance times and NCEI survey times, with data-quality flagging when sources conflict\n- **Outbreak context** - if the event falls within a NOAA Billion-Dollar Disaster, the report surfaces the outbreak name, total economic damage, and total deaths (1980-2024 archive)\n- **Pre-event sounding + VAD hodograph** - Skew-T log-P diagram with parcel path and CAPE/CIN shading alongside a VAD hodograph derived from event-time radar velocity data, plus computed indices (CAPE, CIN, 0-6km bulk shear, 0-1km SRH, 0-3km SRH, surface conditions)\n\n![Skew-T log-P sounding - OUN, May 20 2013 12Z](docs/sounding_skewt.png)\n![VAD hodograph](docs/hodograph.png)\n\n- **AI narrative** - structured overview, environmental context, storm evolution, warnings issued, and impacts. Written from extracted numeric radar features and structured warning/LSR/NCEI/sounding/DAT data, not hallucinated from images\n- **Animated radar loop** - reflectivity + velocity (+ correlation coefficient + spectrum width for 2013+ events), dark map background, county lines, city labels, event location marked\n- **Volume scan analysis table** - max dBZ, echo tops, velocity couplet, timestamped for each processed scan\n- **Interactive event map** - Leaflet map with SPC Day 1 convective outlook overlay, NWS DAT surveyed tornado tracks (with EF-comment override), warning polygons, LSR points, and NCEI straight-line fallback for unsurveyed events\n\n![Event map - Moore, OK 2013 with DAT track, warning polygons, and SPC outlook](docs/event-map.png)\n\n- **Active warnings section** - all VTEC warnings with issued/expired times, polygon coverage, forecaster\n- **Local storm reports** - deduplicated, polygon-filtered, color-coded by type\n- **NCEI Storm Survey data** - post-survey verified EF rating, path length/width, fatalities, injuries, property damage, full NWS event narrative\n\n## Stack\n\n| Layer             | Choice                               |\n| ----------------- | ------------------------------------ |\n| Backend           | Python + FastAPI                     |\n| Frontend          | Vanilla JS + Tailwind CSS + Jinja2   |\n| Radar processing  | Py-ART + matplotlib + Cartopy        |\n| Sounding analysis | MetPy + siphon                       |\n| Maps              | Leaflet + CartoDB dark tiles         |\n| LLM               | Model-agnostic (Claude, Gemini, GPT) |\n| Geocoding         | OSM Nominatim + timezonefinder       |\n\n## Data Sources\n\n| Source                                       | What it provides                                                                                 |\n| -------------------------------------------- | ------------------------------------------------------------------------------------------------ |\n| NOAA NEXRAD on AWS S3 (`noaa-nexrad-level2`) | Level II radar archive, 1991-present                                                             |\n| IEM Mesonet                                  | VTEC warning archive, storm-based warning polygons, LSRs, RAOB soundings                         |\n| University of Wyoming Upper Air Archive      | Sounding fallback when IEM archive has gaps (via siphon)                                         |\n| NCEI Storm Events Database                   | Post-survey EF ratings, path dimensions, casualties, damage estimates, episode IDs               |\n| NWS Damage Assessment Toolkit (DAT)          | Surveyed tornado track geometry - real curved multi-point paths, variable-width damage corridors |\n| SPC Convective Outlook Archive               | Day 1 categorical outlook overlay - GeoJSON (2020+), shapefile fallback (2003+)                  |\n| NOAA Billion-Dollar Disasters                | Outbreak-level economic damage and death tolls, 1980-2024 (discontinued, archived locally)       |\n| OSM Nominatim                                | Geocoding + location autocomplete                                                                |\n\n## Feature Availability by Date\n\nThe pipeline gates features based on historical product availability and per-radar commissioning dates:\n\n| Feature                                | Available from                                           |\n| -------------------------------------- | -------------------------------------------------------- |\n| NEXRAD Level II radar                  | Per-radar (most 1993-1996, all CONUS by 1997)            |\n| IEM LSR archives                       | ~2002                                                    |\n| VTEC warning system                    | January 1996                                             |\n| Storm-based warning polygons           | October 2007                                             |\n| Dual-polarization (CC, spectrum width) | March 2013                                               |\n| Upper air soundings                    | 1989+ (Wyoming archive), coverage varies by station/date |\n| NWS DAT tornado surveys                | ~2011+, consistent coverage from ~2015                   |\n| SPC outlook shapefiles                 | January 2003                                             |\n| SPC outlook GeoJSON                    | ~2020                                                    |\n\nPre-cutoff events generate reports with available data and a notice explaining what's missing.\n\n## Getting Started\n\n```bash\ngit clone https://github.com/Feashliaa/Severe_Weather_Event_Reporter\ncd Severe_Weather_Event_Reporter\n\npython -m venv .venv\n.venv\\Scripts\\activate        # Windows\n# source .venv/bin/activate   # Linux/macOS\n\npip install -r requirements.txt\ncp .env.example .env\n# Add your LLM API key to .env (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)\n\nuvicorn src.web.app:app --reload --port 8000\n```\n\nOpen `http://localhost:8000`, enter an event name, location, and date range.\n\nReports take about 2 minutes to generate for most events. Progress is shown live on the status page with a time estimate.\n\n## Project Structure\n\n```\nsevere_weather_event_reporter/\n├── src/\n│   ├── config.py                   # env vars, paths\n│   ├── event_config.py             # Event configuration loader\n│   ├── models.py                   # shared dataclasses\n│   ├── pipeline.py                 # main orchestrator\n│   ├── feature_gates.py            # date-based product availability\n│   │\n│   ├── data_sources/\n│   │   ├── billion_dollar.py       # NOAA Billion-Dollar Disasters lookup\n│   │   ├── dat.py                  # NWS Damage Assessment Toolkit ArcGIS client\n│   │   ├── discovery.py            # auto-discover warnings at a point\n│   │   ├── geocoding.py            # Nominatim + timezone + state/county parsing\n│   │   ├── iem.py                  # IEM warnings + LSRs\n│   │   ├── ncei.py                 # NCEI Storm Events CSV client\n│   │   ├── nexrad_stations.json    # NEXRAD station metadata\n│   │   ├── nexrad.py               # NEXRAD Level II from S3\n│   │   ├── radar_locator.py        # nearest NEXRAD lookup\n│   │   ├── sounding.py             # IEM RAOB + Wyoming fallback, MetPy Skew-T, VAD hodograph\n│   │   └── spc_outlook.py          # SPC Day 1 outlook GeoJSON + shapefile fallback\n│   │\n│   ├── llm/\n│   │   ├── base.py                 # Base runner/loader\n│   │   ├── anthropic_client.py     # Anthropic setup\n│   │   ├── gemini_client.py        # Gemini setup\n│   │   └── openai_client.py        # OpenAI setup\n│   │\n│   ├── radar/\n│   │   ├── processor.py            # Py-ART feature extraction\n│   │   └── renderer.py             # Cartopy quad-panel rendering\n│   │\n│   ├── report/\n│   │   ├── builder.py              # EventReport dataclass + summary + lead time + LLM prompt\n│   │   ├── templates/              # report.html\n│   │   └── static/                 # radar-loop.js, report.css, favicon.svg\n│   │\n│   └── web/\n│       ├── app.py                  # FastAPI routes + background jobs\n│       ├── templates/              # index.html, gallery.html, status.html\n│       └── static/                 # form.js, event-map.js, radar-loop.js, report.css, favicon.svg\n│\n├── scripts/\n│   ├── run_event.py                # CLI runner for JSON event configs\n│   └── download_ncei.py            # bulk NCEI CSV downloader\n│\n├── events/                         # JSON event configs (for CLI use)\n├── .cache/                         # downloaded radar + NCEI CSVs + soundings (gitignored)\n└── output/                         # generated reports (gitignored)\n```\n\n## Tested Events\n\n| Event                       | Date              | Notes                                    |\n| --------------------------- | ----------------- | ---------------------------------------- |\n| Joplin, MO tornado          | May 22, 2011      | EF5, 158 direct fatalities               |\n| Moore, OK tornado           | May 20, 2013      | EF5, first dual-pol test                 |\n| Hackleburg, AL tornado      | April 27, 2011    | Part of 2011 Super Outbreak              |\n| Greenfield, IA tornado      | May 21, 2024      | EF4, DOW-measured 300+ mph winds         |\n| Mayfield, KY tornado        | December 10, 2021 | EF4, night event, long track             |\n| Rolling Fork, MS tornado    | March 24, 2023    | EF4                                      |\n| Greentown, IN tornado       | June 11, 1998     | F3, pre-VTEC-polygon era test            |\n| Enderlin, ND tornado        | June 20, 2025     | EF5, train derailment                    |\n| Somerset-London, KY tornado | May 16, 2025      | EF4, 19 fatalities, cross-midnight event |\n\n## Roadmap\n\n**Done:**\n- End-to-end pipeline (warnings -\u003e LSRs -\u003e NCEI -\u003e DAT -\u003e SPC -\u003e sounding -\u003e radar -\u003e LLM -\u003e report)\n- Auto-discovery of warnings via 9-point grid search\n- S3 radar fallback loop (tries nearest radar, falls back if no archive data)\n- Feature gating with graceful degradation for historical events\n- Dual-polarization radar panels (CC + spectrum width) for 2013+ events\n- Cartopy map overlay with dark background, county/state lines, city labels\n- Parallel radar rendering via ProcessPoolExecutor\n- Background jobs with real-time progress updates and time estimates\n- Report caching + gallery with EF rating, deaths, and max dBZ on cards\n- NCEI Storm Events integration (multi-county, episode IDs, polygon filtering)\n- Warning lead time calculation with episode deduplication and data-quality flagging\n- Billion-Dollar Disasters outbreak context lookup\n- Pre-event sounding: IEM RAOB with Wyoming fallback, MetPy indices, Skew-T with parcel path and CAPE/CIN shading\n- VAD hodograph from event-time radar velocity field + SRH computation\n- Impact summary card with DAT path length priority\n- NWS DAT tornado track integration (curved multi-point geometry, EF override from survey comments, distance filter)\n- SPC Day 1 convective outlook overlay (GeoJSON + shapefile fallback, legacy DN mapping, modern/legacy legend)\n- NCEI polygon filter with EF3+ rescue clause\n- Concurrent pipeline prevention\n- Raw radar scan cleanup after rendering\n\n**Planned:**\n- Multi-radar support for long-track events\n- Storm-relative velocity (SRV) product\n- Automated tests\n- About page\n- Google OAuth + tiered accounts (free/monthly/lifetime)\n- Stripe integration\n- Cache eviction policy (tiered by EF rating)\n\n## Notes\n\n- Reports are generated on-demand and cached. Re-requesting the same event name redirects to the existing report instantly.\n- Only one pipeline runs at a time. Concurrent submissions return a 429 with a retry message.\n- NEXRAD archive starts June 1991. Events before that date are not supported.\n- NCEI Storm Events data lags 4-8 weeks for recent events. The pipeline falls back to LSR data when NCEI has no record yet.\n- DAT tornado track geometry is available for most significant events from ~2011 onward. Pre-DAT events fall back to NCEI straight-line tracks.\n- NCEI tornado records are split by county. The impact summary uses DAT path length when available, otherwise the longest single county segment.\n- NCEI property damage estimates are unreliable for complex outbreaks and are suppressed when clearly incomplete relative to event severity.\n- The event narrative is AI-generated from structured data and may contain errors. The structured data sections (NCEI, warnings, LSRs, radar table) are authoritative.\n- LLM API keys are user-supplied (BYOK) when self-hosting. The tool is model-agnostic - Claude, GPT, and Gemini are all supported.\n\n## License\n\nMIT License with Commons Clause. Free for personal use and self-hosting. Commercial use requires a separate license - contact [rwdorrington@gmail.com].\n\nSee [LICENSE](LICENSE) for full terms.\n\n## Resources\n\n**Primary data sources:**\n- NEXRAD Level II radar: [noaa-nexrad-level2](https://noaa-nexrad-level2.s3.amazonaws.com)\n- IEM Mesonet (warnings + LSRs + soundings): [mesonet.agron.iastate.edu](https://mesonet.agron.iastate.edu)\n- University of Wyoming (soundings): [weather.uwyo.edu](https://weather.uwyo.edu/upperair/sounding.shtml)\n- NCEI Storm Events CSV: [ncei.noaa.gov](https://www.ncei.noaa.gov/pub/data/swdi/stormevents/csvfiles/)\n- NWS Damage Assessment Toolkit: [services.dat.noaa.gov](https://services.dat.noaa.gov/arcgis/rest/services/nws_damageassessmenttoolkit/DamageViewer/FeatureServer)\n- SPC Outlook Archive: [spc.noaa.gov](https://www.spc.noaa.gov/products/outlook/archive/)\n- OSM Nominatim (geocoding): [nominatim.openstreetmap.org](https://nominatim.openstreetmap.org)\n\n**Reference/lookup:**\n- NOAA Billion-Dollar Disasters (discontinued): [ncei.noaa.gov](https://www.ncei.noaa.gov/access/metadata/landing-page/bin/iso?id=gov.noaa.nodc:0209268)\n- SPC severe weather GIS: [spc.noaa.gov](https://www.spc.noaa.gov/gis/svrgis/)\n\n**Frontend libraries:**\n- Leaflet: [leafletjs.com](https://leafletjs.com)\n- CartoDB basemaps: [carto.com](https://carto.com/basemaps)\n- Tailwind CSS: [tailwindcss.com](https://tailwindcss.com)\n- Oswald font: [fonts.google.com](https://fonts.google.com/specimen/Oswald)\n\n**NWS/NOAA institutional:**\n- NEXRAD network info: [roc.noaa.gov](https://www.roc.noaa.gov/WSR88D/)\n- IEM VTEC archive: [mesonet.agron.iastate.edu/vtec](https://mesonet.agron.iastate.edu/vtec/)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffeashliaa%2Fsevere_weather_event_reporter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffeashliaa%2Fsevere_weather_event_reporter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffeashliaa%2Fsevere_weather_event_reporter/lists"}