Session: 2026-05-28

Session: 2026-05-28

← Index


Summary

Created two new notebooks — 19_model_reanalysis_comparison.ipynb (Google GRRR gauge correlation analysis) and 20_trigger_tuning.ipynb (trigger grid search) — and made several refinements to the trigger explorer web dashboard.


New notebooks

19_model_reanalysis_comparison.ipynb — GRRR gauge correlation analysis

Compares Google GRRR and GloFAS reanalysis correlations with Floodscan SFED across all gauges within the selected state’s LGAs. Parameterisable by STATE (“Adamawa” or “Benue”).

Approach: - Gauge discovery via grrr.get_gauges_by_area(gdf_selected, include_non_quality_verified=True), using LGAs from STATE_CONFIG["lga_pcodes"] (same pattern as notebook 16) - Spearman correlation on raw wet-season (Aug–Nov) daily values against Floodscan SFED, across a lag range of [-7, +14] days — raw values chosen to match notebook 13; deseasonalisation was tested but rejected as it removes the shared seasonal cycle and lowers correlations - Gauges flagged by is_benue (river name contains “benue”) and quality_verified - Annual peak correlation diagnostics (cells after cell-12): Spearman ρ on wet-season annual maxima per gauge vs Floodscan, plus mean peak timing difference (gauge peak DOY − Floodscan peak DOY). These address the concern that daily correlation can be high even if peaks occur at different times of year - Top 10 gauges by best Spearman ρ saved to blob: ds-aa-nga-flooding/processed/model_comparison/{state}_top10_gauges.parquet

Outputs: - figures/{state}_corr_histograms.png — distribution of best ρ and best lag - figures/{state}_corr_lag_profiles.png — lag profile curves (median + IQR) by group - figures/{state}_corr_dot_plot.png — Cleveland dot plot per gauge, coloured by category - figures/{state}_corr_gauge_map.png — gauge map, sized by ρ, coloured by category - figures/{state}_annual_peak_diagnostics.png — annual peak ρ histogram + peak timing difference chart

Category colours (shared across all plots):

Category Colour
GloFAS #F2645A (coral)
Google (high confidence) #F4A93B (amber)
Google (Benue) #007CE0 (OCHA blue)
Google (non-Benue) #1EBFB3 (teal)

Grid search over trigger configurations using the top 10 gauges from notebook 19. Trigger fires if N of the top 10 gauges exceed a Y-year return period threshold in a wet-season annual maximum.

Two threshold approaches:

Grid search: for each (N gauges, RP threshold, Floodscan RP level) triple, computes POD / FAR / F1 against Floodscan event years from the trigger matrix. Results shown as heatmaps and a summary table disaggregated by Floodscan RP level (3-, 4-, 5-yr).

Evaluation period: 1998–2023 (full GRRR reanalysis record, ~26 years).


Dashboard refinements (exploration/2026/cerf/web/)

Collapsible sections

Restructured index.html into five collapsible <details> sections (native HTML, no JS required):

  1. Geographic Selection — state dropdown + affected LGA pills
  2. Reference Flooding Years — Floodscan event year dot timeline
  3. Action Trigger — placeholder (not yet configured)
  4. Readiness Trigger — GloFAS Reforecast — controls, summary, dot timeline
  5. Signal Timeline — GloFAS Trigger vs Floodscan — canvas chart (moved out of readiness trigger section)

Floodscan threshold bug fix (generate_data.py)

get_floodscan_data was computing RP thresholds from all years in the raw Floodscan data (1998–2025), while the trigger matrix uses only the analysis years (1998–2023). This caused some event years to be missing from fs_crossings on the signal timeline (2003 and 2019 for Adamawa 3-yr RP).

Fix: thresholds are now derived from the trigger matrix event years directly — for each RP level, the threshold is the minimum annual max SFED across the years classified as events at that RP. This guarantees consistency with notebook 08. If the trigger matrix is unavailable, get_floodscan_data returns empty dicts rather than falling back to independent computation.

Other dashboard changes


Open questions / next steps

Action trigger in dashboard

The main next step is wiring up the Action Trigger section in index.html using the grid-search outputs from 20_trigger_tuning.ipynb. The trigger for each state should be of the form: “trigger if N of the top 10 gauges exceed Y-year RP”. The selected (N, Y) configuration from notebook 20 needs to be:

  1. Recorded in STATE_CONFIG (or passed to generate_data.py directly)
  2. Added as a new data loader in generate_data.py — load GRRR reanalysis annual maxima for the top 10 gauges, apply the selected RP threshold, check exceedance count ≥ N for each year
  3. Rendered in the Action Trigger section of index.html with a dot timeline and summary sentence (same pattern as readiness trigger)

Gauge selection for trigger

Notebook 20 uses the top 10 gauges ranked by Spearman ρ (daily correlation). The annual peak diagnostics added to notebook 19 (peak ρ and peak timing difference) are available as additional filters but have not yet been applied to the selection. Consider whether any gauges should be excluded based on poor peak timing alignment before finalising the trigger gauge set.


Notebook index

Notebook Purpose
08_trigger_events.ipynb Trigger matrix — Floodscan flood year flags (canonical source of truth)
13_model_performance.ipynb Annual peak correlation and daily correlation for GloFAS and Google reanalysis
14_forecast_performance.ipynb Skill metrics for GloFAS and Google reforecasts
15_trigger_performance.ipynb GloFAS reforecast trigger performance vs leadtime
17_threshold_selection.ipynb Benue threshold grid search (GloFAS + Google OR trigger)
18_trigger_summary_performance.ipynb Summary trigger performance at configured action/readiness leadtimes
19_model_reanalysis_comparison.ipynb Google GRRR gauge correlation analysis; top 10 gauge selection
20_trigger_tuning.ipynb Multi-gauge trigger grid search using top 10 GRRR gauges