The ultimate test of a retrospective trigger: would it have flagged the outbreaks that actually drew emergency money, and early enough to act? Northeast Nigeria received two CERF Rapid Response cholera allocations in the study period.
6.1 CERF cholera allocations
Show code
c = cerf.copy()c["date"] = c["date"].dt.datec.columns = ["Allocation date", "Label", "Note"]c.style.hide(axis="index")
Table 6.1: CERF Rapid Response cholera allocations for NE Nigeria used as reference events (per DS knowledge base). Both pre-date any AA framework.
Allocation date
Label
Note
2018-10-31
CERF RR 2018
Response to 2018 BAY-states cholera outbreak
2021-10-22
CERF RR 2021
Response to 2021 BAY-states cholera outbreak
6.2 Activation timeline with CERF overlay
Show code
fig, ax = plt.subplots(figsize=(11, 4.5))y_of = {s: i for i, s inenumerate(U.STATES)}for st in U.STATES: d = act[act["state"] == st] ax.scatter(d["week"], [y_of[st]] *len(d), s=70, color=U.STATE_COLORS[st], zorder=3, label=st)for _, r in cerf.iterrows(): ax.axvline(r["date"], color=U.HDX["gray_dark"], ls="--", lw=1.3, zorder=2) ax.text(r["date"], 2.55, r["label"], rotation=90, va="bottom", ha="right", color=U.HDX["gray_dark"], fontsize=9)ax.set_yticks(list(y_of.values()))ax.set_yticklabels(U.STATES)ax.set_ylim(-0.6, 2.9)ax.xaxis.set_major_locator(mdates.YearLocator())ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y"))ax.set_title("Trigger activations vs CERF Rapid Response dates")ax.grid(axis="y", visible=False)plt.tight_layout()plt.show()
Figure 6.1: Every trigger activation (dots, coloured by state) against the two CERF allocation dates (dashed lines). In both CERF years the trigger fires well before the allocation.
6.3 Alignment and lead time
Show code
rows = []for _, r in cerf.iterrows(): yr = r["date"].year prior = act[(act["week"] <= r["date"]) & (act["week"].dt.year == yr)]iflen(prior): first = prior.sort_values("week").iloc[0] lead_days = (r["date"] - first["week"]).days rows.append([ r["label"], r["date"].date(), first["ADM2_EN"], first["state"], first["week"].date(), len(prior), f"{lead_days} days (~{lead_days //7} wks)", ])else: rows.append([r["label"], r["date"].date(), "—", "—", "—", 0, "no prior activation"])lt = pd.DataFrame(rows, columns=["CERF event", "CERF date", "First-firing LGA", "State","First activation", "Activations before CERF", "Lead time",])lt.style.hide(axis="index")
Table 6.2: For each CERF allocation, the earliest trigger activation in that calendar year and the resulting lead time.
CERF event
CERF date
First-firing LGA
State
First activation
Activations before CERF
Lead time
CERF RR 2018
2018-10-31
Mubi North
Adamawa
2018-05-21
9
163 days (~23 wks)
CERF RR 2021
2021-10-22
Damaturu
Yobe
2021-08-16
5
67 days (~9 wks)
In both CERF years the trigger activates weeks-to-months ahead of the allocation date, in multiple LGAs. That is the encouraging headline: on this retrospective data the design would have surfaced the 2018 and 2021 outbreaks with genuine lead time, consistent with the earlier exploration’s finding that the trigger anticipates the CERF events by roughly 3–9 weeks.
6.4 Caveats
Lead time here is retrospective, not operational
The lead times above are measured against onset-dated cases. In production the clock that matters is the reporting clock — when the LGA’s cases actually reach an analyst. Nothing in this file measures that lag, and it is the single biggest open question for a BAY cholera framework. A trigger that fires 6 weeks before CERF on onset dates delivers zero lead time if the data arrives 6 weeks late.
Other caveats:
No 2022 CERF reference. 2022 was the largest outbreak year but is not in the CERF reference list; the trigger fires heavily in 2022, so whether that is a true positive or over-firing depends on the (undocumented) 2022 response.
2020 is invisible. Confirmed 2020 outbreaks cannot be tested — the data gap means the trigger is silent that year by construction.
Thresholds are illustrative. The p99/4×/3-week design is inherited, not calibrated to a target return period or a funding envelope for Nigeria.
6.5 Summary
On the 2018–2023 line-list, a percentile-plus-growth trigger behaves the way an AA trigger should: dormant between outbreaks, lit up during them, and firing ahead of both historical CERF allocations. The epidemiology (sharp seasonal waves concentrated in a handful of LGAs) supports an LGA-level observational trigger. The blockers are not epidemiological but operational and evidentiary: data timeliness is unconfirmed, the 2020 gap limits calibration, and the threshold and priority-LGA choices need explicit, documented justification before any of this becomes an endorsed framework.