The LankaFlood AI guide
This guide teaches the mathematics behind the project and records what has been done. Every section says whether it is measured (run on real data) or planned (the design for a later stage). No world model has been trained yet.
What has been done
| Stage | Status | What exists |
|---|---|---|
| 1. Foundation | Done | Repository, tests, static site, deployment, portfolio link |
| 2. Historical GIS data | Done | UNESCO and Copernicus layers on one aligned 11 m grid, an interactive map, alignment tests |
| 3. Historical rainfall and terrain | Done | Half-hourly IMERG rainfall on its native 0.1° grid, a timeline, a 30 m terrain overlay, unit, datum and timestamp tests |
| 4. Reference simulator | Done | A simplified 32 by 32 simulator, conservation tests, 9,720 synthetic training examples |
| 5 to 8 | Planned | Training, browser inference, evaluation, landslides |
The rest of this guide follows the path of the data: from map grid, to flood scores, to rainfall and terrain, to water physics, to the learned model.
1. Turning a map into a grid (measured)
A raster is a table of numbers. An affine transform says where each table cell sits on Earth. For column and row :
Here is longitude, is latitude, and is the top-left corner. Latitude has a minus sign because rows count downwards while latitude increases upwards.
The UNESCO raster has . Our crop starts at a whole-number column and row, so every pixel is the source's own pixel, and nothing is resampled. A test confirms the crop matches the source exactly.
How big is one pixel?
An arc of angle radians on a sphere of radius has length :
East-west distances shrink towards the poles by , so the area of a cell depends on its row:
The pipeline uses the more accurate WGS 84 ellipsoid, which gives about per cell at N. Flooded area is the sum over wet cells:
Check against the source: rasterising the Copernicus polygons this way gave 3,376.2 ha against the published 3,377.0 ha, a difference of 0.02%. That is the evidence that the grid and area maths are right.
Why a flat image lines up on a web map
Web maps use Web Mercator, where north-south position is:
Our pixels are evenly spaced in latitude, but is curved. MapLibre pins an image by its corners and stretches it in a straight line, so there is an error. The maximum error of a straight line across a curve over an interval of height is:
Our crop is radians tall, near :
The numerical check gives 0.504 m, about one twentieth of a pixel. So keeping the data in its original EPSG:4326 and overlaying it is safe at this size. Because grows with , a crop 10 times taller would be 100 times worse, about 50 m, and this shortcut would stop working. There's a test for that as well.
2. Scoring one flood map against another (measured)
For any two wet-or-dry maps, every cell falls into one of four boxes:
| Reference wet | Reference dry | |
|---|---|---|
| Predicted wet | Hit, | False alarm, |
| Predicted dry | Miss, | Correct dry, |
Plain accuracy is a trap. Most cells are dry, so a model that always says "dry" scores very well while being useless. The critical success index ignores correct dry cells:
It's the same formula as intersection over union (IoU). It runs from 0 (no overlap) to 1 (perfect). Two companions show the type of error:
The probability of detection (POD) falls when you miss water, and the false alarm ratio (FAR) rises when you invent it.
The seen mask
You can't score a model where nobody could see the ground. Define a mask , where only if both images analysed that cell, and count , and only there. This matters a lot here:
| Measure | 30 Nov | 3 Dec |
|---|---|---|
| Observed flood, all of it | 3,377.0 ha | 688.3 ha |
| Not analysed | 636.2 ha | 7,122.3 ha |
| Observed flood, where both dates saw the ground | 1,969.6 ha | 685.4 ha |
The naive fall is 80%. The fair fall is 65%. The source doesn't say why ground wasn't analysed, and the two images come from different sensors, so even 65% is not a clean measure.
The score to beat
The simplest possible forecast is that nothing changes, so the 30 November map also serves as the prediction for 3 December. Its measured score on the seen mask is:
This is the project's first real research number. A world model that can't beat 0.27 has learned nothing useful about this transition.
Checking alignment
If two sources were misregistered, sliding one over the other would raise the overlap. So for each shift up to 12 pixels each way we compute:
The best shift between UNESCO and Copernicus is on both dates. There is no systematic offset. Their IoU is only 0.53 and 0.24, which isn't a contradiction, since they cover different times and methods. Alignment and agreement are different questions.
3. Rainfall and terrain (measured)
These two datasets look like they belong together, but they work at very different scales.
| Rainfall | Terrain | |
|---|---|---|
| Product | NASA IMERG, public imagery | Copernicus DEM GLO-30 |
| Cell size | , about 11 km | 1 arc-second, about 30 m |
| Time | Every 30 minutes | One fixed surface |
| Units | mm/h | Metres above the EGM2008 geoid |
Why coarse rain can't be sharpened
One rain cell covers this many terrain cells:
In the rain cell at E, N, the surface runs from 5 m to 253.9 m. IMERG gives that whole cell one value . Now suppose we interpolate onto the fine grid. To keep the cell's rain volume, the fine values must satisfy:
That is one equation with unknowns. Countless patterns fit it, and the data can't tell them apart, so a smooth interpolated map only shows a guess. It would look more detailed without being more accurate. That's why the map draws rain as coarse squares.
From rates to rainfall
A rate in mm/h held for half an hour gives a depth in mm:
Rain cells shrink slightly with latitude, so an area average weights each cell by its area :
Reading rain from colours
NASA's public imagery needs no login, but it stores colours, not numbers. Its legend maps each colour to one of 220 narrow ranges , so each cell gives bounds and not an exact value:
Colours mean rain of at least 0.1 mm/h, and a transparent cell could still be anything below that. So a fully dry half-hour has bounds of 0 and 0.1 mm/h, and across the 528 half-hours these bounds give an area-average total between 266.2 and 299.7 mm.
What the measurement shows
| Period | Area-average rain |
|---|---|
| 25 Nov to the 30 Nov image | 235 to 254 mm |
| Between the two flood images | 0.4 to 7.7 mm |
Why it matters: the only real test we have (H3) is almost pure drainage. With so little rain in that window, adding rain as a model input may change little on that one test. H4's evidence on the value of weather therefore has to come mostly from simulated floods, and the rain before 30 November reaches the test only through the starting state and through upstream river flow.
Three checks on the rainfall
- Decoding: every cell in every frame was one solid colour, and every colour was in NASA's legend.
- Timestamps: the 528 frames form an unbroken half-hourly series in UTC, and daily totals use Sri Lanka time, .
- A separate source: daily rain at one cell has a correlation of with NASA POWER's MERRA-2 reanalysis over 11 days.
Correlation shows that the two rise and fall together, not that the amounts match. On 28 November, IMERG gives 32 to 35 mm for that cell and MERRA-2 gives 95 mm. None of this checks against rain gauges, and that remains to be done.
Which IMERG is this?
The gauge-adjusted Final Run wasn't listed in NASA's catalogue for these dates when checked: its coverage ended on 30 September 2025. The public imagery's newest frames are only hours old, which points to a near-real-time run, although the service doesn't state which. Near-real-time runs don't get the Final Run's gauge adjustment, so treat these amounts with care. The pipeline can be switched to numeric data later, using a NASA Earthdata login.
Heights have reference points
A height is only meaningful against a reference surface. GPS heights use the ellipsoid, and this terrain uses the geoid. They are related through the geoid undulation :
Mixing the two without this conversion would shift heights by tens of metres in some regions.
The terrain is also a surface model, so it includes tree canopy and buildings:
To a flood model, a row of tall trees can look like a wall that water can't pass. The 32 by 32 simulator softens this by averaging, but doesn't remove it.
A half-pixel lesson: these tiles are stamped AREA_OR_POINT = Point, so each pixel is centred on a whole arc-second. Cropping at a round coordinate would have shifted the map by half a cell, about 15 m. The pipeline now snaps crops to the tile's own grid, and a test guards this.
Shaded relief
The overlay's shading is computed from the slope and aspect at each cell, for a sun at altitude and azimuth :
Does terrain agree with the flood maps? Observed flood on 30 November lies at a median height of 7.9 m, against 22.9 m for land mapped dry. That is what you would expect, but it's only a sanity check.
4. How water moves (built, simplified)
This simulator is simplified and not validated hydrology. It teaches the model how water tends to behave, and it doesn't predict any real flood. Full details are in the simulator notes.
Conservation is bookkeeping
Water depth changes for two reasons: it flows between cells, or it's added and removed. As an equation:
On a grid, this becomes a ledger. Every face takes depth from one cell and gives exactly to its neighbour, so water moving around inside the grid can't change the total. Only the sources and sinks can:
Measured: across 9,720 transitions, this balances to about m³, which is rounding.
What makes water move
Water runs down the slope of its surface, not the ground. With surface height , Manning's equation gives the flow per metre of width:
The power is why deep water moves much faster than shallow water: doubling the depth multiplies the flow by . is the roughness, and is the water depth above the higher of the two beds, so water can't flow through a bank it hasn't reached.
A worked step
Take two neighbouring flat cells, 430 m wide, with . Cell holds 1.0 m of water and cell holds 0.5 m, and the substep is 60 s:
So cell falls to 0.905 m and cell rises to 0.595 m.
Keeping it stable
Nothing stops that formula from moving too much, and if water overshoots, the cells swap places and the solution oscillates or blows up. Three rules prevent this:
- A limiter: a face can move at most a quarter of the level difference, . Since a cell has four faces, even all four together can't reverse a difference.
- Positive depth: if a cell's outgoing total exceeds its water, each outgoing flow is scaled by .
- Fixed substeps: each 10-minute step always uses 10 substeps, so results are repeatable.
The limiter trades accuracy for stability. When it applies, water moves more slowly than Manning's equation says.
Why a learned model might still help
The usual time-step limit for a wave of speed is:
For 30 m cells, 4 m depth and , that's about 3.4 s, or about 79,000 steps over the 73.45 hours between our two Kelani maps. Fine-scale physics is slow. A world model can learn a rule that jumps further per step. On this small 32 by 32 grid the simulator is already fast, so the speed benefit is not something this stage shows. It only matters at finer scales.
Filling false pits
The first version looked wrong despite passing every test: water sat in hundreds of isolated cells instead of flowing. Averaging a surface model into 430 m cells leaves many false pits, and water can't leave a cell lower than all its neighbours.
The standard fix is depression filling, using the priority-flood algorithm. Starting at the open edges, it visits cells from lowest to highest, and raises any cell that is too low:
Here is the filled height of the neighbour that reached cell first, which is on its lowest way out. Afterwards, every cell has a downhill path to an open edge, and a test checks this. The cost is that real hollows get filled too, and filled areas are very flat, so they drain slowly. Walls are added after filling, so they can still hold water back.
The lesson: passing tests only shows that the code does what it was told. Looking at the output is what showed that the terrain was wrong.
What the simulator shows
In the heavy-rain demo over real terrain, the deepest water keeps rising after the rain stops, from 0.5 m at 3 hours to 0.75 m at 6 hours, as water gathers along flow paths. About 25% of the rain leaves through the open edges within 6 hours, and adding a wall ponds water up to 2.2 m behind it. Much of the remainder stays because nothing soaks in, filled ground is nearly flat, and open edges are an assumption.
What it leaves out
| Left out | Effect |
|---|---|
| Infiltration and evaporation | Too much water stays on the surface |
| Inertia | Fast surges and backwater are simplified |
| River channels | Too small for 430 m cells |
| Varying roughness | Forest, paddy and towns are treated alike |
| Bare-earth terrain | Averaged trees and buildings can still deflect water |
| Real hollows | Depression filling removes them along with the false pits |
A model that matches this simulator has learned the simulator, not the river. That's why H3 tests against real observations.
The training data
A world model learns from transitions: a state, an action and the state that follows:
The dataset has 270 synthetic runs of 36 steps, split by whole run so that no run leaks across splits: 168 for training, 36 for validation, 36 for testing, and 30 out-of-range for testing warnings (H2).
5. The world model (planned, stage 5)
A world model learns the rule for what happens next:
| Symbol | Meaning |
|---|---|
| Water depth on the grid at time | |
| Terrain, obstacles and drainage | |
| Weather inputs, if this version uses them | |
| A small neural network with weights |
It predicts the change in water. Most cells change little per step, so "no change" becomes its natural starting point. Depth can't be negative, so the output is clipped: .
Training
The weights are chosen to minimise prediction error across simulated floods:
The first term is weighted error, where wet cells get a larger so the model can't win by predicting dry land. The second penalises creating or destroying water, with setting its strength.
Rollout: why errors compound
To look further ahead, each prediction becomes the next input. Suppose each step adds a fresh error of size , and the network amplifies existing errors by up to . Then:
With m and , these are illustrative values rather than measurements:
| Steps | Worst-case error |
|---|---|
| 1 | 0.01 m |
| 5 | 0.06 m |
| 10 | 0.13 m |
| 20 | 0.33 m |
This is a bound and not a forecast of behaviour, but it explains why a model that looks excellent at one step can fail at 20. Rollout error is therefore the main metric, and it's what H1 measures.
What does "tiny" mean?
A convolution layer with kernel size , input channels and output channels has this many weights:
At 4 bytes per weight, 200,000 weights take about 0.8 MB, which is a reasonable download. For scale, the closest published flood model we found has about 2.7 million weights and ran on a GPU. H1 asks how much accuracy you lose as falls.
6. With and without weather (rainfall measured, models planned for stage 5)
You asked to predict both with and without weather. In research this is an ablation study: remove one input, keep everything else the same, and measure what you lose.
| Version | Inputs | Question |
|---|---|---|
| M0 | Water and terrain | How far do terrain and the current flood get us? |
| M1 | M0 + rainfall and inflow | What does knowing incoming water add? |
| M2 | M1 + cloud | Does cloud add anything once rain is known? |
What each input physically means
Rain adds volume directly:
Cloud doesn't add water. Clouds are only a clue that rain may be coming, and physics never needs them once rain is known. So the honest expectation is that M2 may barely beat M1 for water depth. That would still be a useful result. Cloud could matter more for forecasting, when future rain isn't known yet.
Cloud also matters in a second way. It can hide the ground from optical satellites like the ones used here:
So cloud may explain some of the missing ground on 3 December, although the source doesn't state the reason. Stage 5 can test that against real cloud data.
The crop's limit: most water reaching the lower Kelani falls as rain further upstream. Rain inside our crop isn't enough, so the upstream inflow has to be either supplied or estimated.
How to compare fairly
Each version gets the same architecture budget, training data and random seeds. The gain from weather is a difference in scores on the same test floods:
Averages can mislead, so the comparison is paired per flood. Repeatedly resampling those test floods gives a confidence interval (a bootstrap). If the interval includes zero, we can't claim a gain. A skill score then measures improvement over the no-change baseline, on a scale where 1 is perfect and 0 is no better:
On the real Kelani transition, a model scoring 0.50 would have . That number is an example only. And with only one real transition there is no interval at all, so real-event results stay a case study.
The trap: hindcast versus forecast
Using rain measured after the event is a hindcast. In a real forecast, future rain is itself uncertain:
A model tested on observed rain will look better than it would in real use. Every result in this project must say which one it is, and inputs at time may only use data available by time .
7. Knowing when it's guessing (planned, H2)
Train copies of a model from different random starts. Where they disagree, they're probably guessing:
This works in published flood models, but downloading copies costs times the size. H2 compares cheaper signals, judging each by whether a high warning really predicts a failed rollout on scenarios the model never saw.
8. Getting ready for landslides (data acquired, model planned for stage 8)
Landslides are not floods with different labels. The mathematics differs:
| Flood | Landslide | |
|---|---|---|
| Physics | Water moving continuously | A slope failing suddenly |
| Output | Depth per cell, over time | Probability of failure per cell |
| Key input | Water state, inflow | Slope, soil, saturation |
| Rollout | Natural | Rarely meaningful after failure |
| Class balance | Common in floodplains | Extremely rare |
The physics: factor of safety
A simple model treats the slope as an infinite tilted layer of soil:
Here is slope angle, is soil depth, is soil unit weight, is cohesion, is friction angle (not latitude here), and is water pressure. means the slope is predicted to fail. Rain raises , which reduces the numerator. That's the physical link between weather and landslides.
Soil properties are rarely known at this scale, so a data-driven approach is common. A classic form is a rainfall threshold, where failures become likely when intensity over duration exceeds:
A learned version estimates a probability from terrain and weather features :
Why plain accuracy fails even worse here
UNESCO maps about 2,163 ha of landslides nationally, against about 414,789 ha of flood. Landslide cells are so rare that "never" would be nearly always right. The right tools are precision and recall:
What readiness means today
- Data: the UNESCO landslide raster is downloaded, checksummed and measured.
- Structure: the region config and map manifest list hazards separately, so adding one doesn't change flood code.
- Design: terrain and weather inputs are shared, and each hazard gets its own output and loss:
Two limits to remember: the landslide layer starts at E, east of our flood crop, so landslide work needs its own area. Its metadata is also inconsistent (the file is named for Sentinel-2, but the attribute says Sentinel-1), and it's unvalidated. So it's a starting label set, not ground truth.
9. What the data can and can't support
| Layer | Use it for | Don't use it for |
|---|---|---|
| Copernicus observed | Main score for H3 | Anywhere not analysed |
| Copernicus extrapolated | Comparison, with care | Ground truth: it comes from a terrain model, like ours will |
| Copernicus depth | Rough depth classes for the start state | A measured depth target |
| UNESCO composite | Where water appeared in the window | A time step: it has no per-area dates |
| IMERG imagery | Area-scale timing and rough amounts | Street-level rain, or exact gauge-quality totals |
| Copernicus DEM | Broad terrain and flow paths | True ground height under trees and buildings |
The circularity risk: Copernicus extrapolates with FABDEM terrain. If our model used the same terrain and were scored against that extrapolated layer, a high score could just mean that two terrain-based methods agree. That's why H3 scores on observed water.
10. Check yourself
- Why does a model that always predicts "dry" get high accuracy but a CSI of 0? Because it has no hits. CSI ignores correct dry cells, and makes the score 0.
- If the crop were twice as tall, how much would the overlay error grow? Four times, since it grows with .
- Why compare only where both images saw the ground? Otherwise a cell that went unseen counts as "no flood", and it looks as though water receded.
- If M1 beats M0 on simulated floods, have we shown rainfall helps on the real river? No. It shows that for the simulator. The real pair is one case study.
- Why might cloud not help once rain is known? Cloud doesn't add water. It's a clue about rain, which is already known.
- Why not interpolate IMERG onto the 30 m terrain grid? One cell value can't determine 129,600 fine values, so the result would look sharper while adding no information.
- If rainfall has no effect on the real transition, does that prove rain doesn't matter? No. Almost no rain fell between those images, so that test can't show what rain is worth.
- Why can't internal flow change the total water? Each face takes from one cell and gives the same to its neighbour, so it cancels when you add up the grid.
- Doubling the depth multiplies flow by how much? , at the same slope.
- Why fill pits before simulating? Averaged terrain has many false pits. Water can't leave a cell lower than all its neighbours, so without filling it collects in scattered cells instead of flowing.
Further reading
- Bates and colleagues (2010), a simple inertial formulation of the shallow water equations.
- The closest published flood model found so far.
- Uncertainty-aware flood modelling with ensembles.
- The project's research question and data sources. These links need repository access.