Singapore Rain Nowcaster

Research prototype · Phase 1 complete

Forecasting Singapore's flash-flood downpours with a diffusion model

It reads the last 30 minutes of rain radar and imagines eight possible futures for the next 35–95 minutes. Where the futures agree on heavy rain, there is a warning.

38%lower forecast error than the naive forecast, 30 min ahead
82 minwarning before the 27 Sep flash-flood report, out of sample
20 s8 members × 3 lead times on a laptop GPU

Not solved yet: heavy downpours, where it is still no better than assuming the latest radar map stays put. Read the limits.

— SGT · 22 Sep 2026 · the real radar during the King's Road storm

Colours show how hard it is raining: light blue is drizzle, green moderate, yellow to red heavy, purple torrential. Red rings mark where flash floods were reported.

Why this matters

Flash floods start fast. On 27 Sep the flood site went from dry to 100 mm/hr — the top of the radar's scale — in about 25 minutes.
Alerts come when drains are already filling. PUB's flood-risk alerts go out when a drain's sensor reads 90% full — by then it is pouring. On 27 Sep this model flagged the spot about an hour before that alert, and across all 23 drain alerts in three storms it never trained on, it warned first every time (median about an hour ahead).
Minutes are what count. Half an hour to an hour of street-level notice is time to move a car or avoid a road. This prototype predicts rain, not floods, and is right about 1 time in 3 when it warns — a real signal, not yet a warning service.

How it works

  1. Radar in. NEA publishes a rain map every 5 minutes. We decode its 33 colour levels into rain rates on a 0.29 km grid and feed the model the last six maps.
  2. Noise to rain. A diffusion model starts from pure noise and removes it in 50 small steps, guided by those six maps, until a plausible future rain map remains.
  3. Eight futures. Starting from different noise gives different, equally plausible futures. The share of futures with heavy rain over a place is its forecast probability.

Watch the model draw one forecast. It is given the six radar maps below (the last 30 minutes up to 16:15) and asked to draw the rain at 16:50. It starts from pure noise (left) and cleans it up in 50 small steps; the middle panel is its best guess so far. Press play or drag the slider. The finished guess puts the storm in roughly the right place but weaker than reality (right) — its known weakness. Why it matters: start again from different noise and you get a different, equally plausible map. Drawing eight of them is how the model says how sure it is.

Input: last 30 min

Noisy sample at this step
Model's current guess of the clean map
What actually happened

Would it have warned us? Three real flash-flood days

Pick a flood and how far ahead to forecast, then step through the forecasts made before it. For each one you see what the AI model predicted, what a naive forecast would say (assume the latest radar map simply stays as it is — the standard baseline) and what actually happened. Start with the buttons below.

—

1 · What actually fell at that time
2 · Naive forecast: the latest radar map, unchanged
3 · AI model: the typical rain of its 8 futures
4 · AI model's warning: how many futures show heavy rain (≥10 mm/hr)
Rain at the flood site (the most in a 2 × 2 km box). Press ▶ to step through the forecasts; the arrows follow the one you are viewing. Look for bars that rise before the bold line does: that is a warning given in advance.

The evidence

Two floods are anecdotes. The real test is 200 forecasts, each with 8 futures, spread across a 12-day period () that the model never saw in training, each compared with the naive forecast.

When it warns of heavy rain, is it right?

The practical question for anyone deciding whether to act: split Singapore into 2 × 2 km squares and, for every forecast in the test period, check whether heavy rain (10 mm/hr or more) really came where a warning was given.

For researchers: overall accuracy is CRPS skill against persistence; placement is the pooled fractions skill score (FSS, 0 to 1, higher is better) within a 12 km neighbourhood. At 60–90 min CRPS alone flatters a model that spreads weak rain around, which is why both are shown. Full details in docs/RESULTS.md.

Placement at different map scales (score, model / naive; blue = model better, red = worse)

Did it put rain on real flood sites beforehand?

Counts of flood reports where the forecast put rain (≥2 mm/hr in at least 4 of 8 futures) within 1.4 km beforehand. The last column checks the model is not simply raining everywhere: on ordinary days it raises an alarm at these places rarely. Only floods the model never trained on are counted, and they come from about three storms, so read these as indicative.

A live forecast in 20 seconds

From the newest radar map to three forecasts (30, 60 and 90 minutes ahead) × eight futures each, on an ordinary laptop graphics card. Why it matters: the radar updates every 5 minutes, so a forecast that takes 20 seconds can be refreshed with every new map, on hardware a city agency or even an individual could run.

python src/inference/nowcast.py --checkpoint <30-min> <60-min> <90-min>

What radar alone cannot see — and what comes next

Heavy rain is where this model falls short: storms that form in place, or arrive from beyond the 35 × 63 km radar window, are invisible until they appear. Phase 2 tried to add what the model is missing. None of these beat simple extrapolation (moving the latest radar map along its motion) for 60-minute heavy-rain warnings:

  • Wide-range radar (240 km): collected since September; it caught no more incoming downpours, which mostly form nearby rather than arrive.
  • Himawari-9 satellite: cold cloud tops caught more downpours only by warning over a much wider area; a learned radar + satellite warning added nothing.
  • NVIDIA CorrDiff and ERA5 weather input: CorrDiff tracked when island rain fell but never reached realistic amounts, and the weather input did not help.

All of this was learned from about three months of one monsoon season, so "did not help" means "not yet measurable". Next: keep collecting radar and flood alerts through the Northeast Monsoon (Dec–Mar), then retrain, re-run every comparison, and start learning which spots flood at what rainfall from PUB's drain-sensor alerts.

NEA 240 km rain radar, 22 Sep — the wider view tried in Phase 2 (NEA's image as published)

Limits, stated plainly