Monday, November 2, 2026

Slides, Storyboards, RealBooks

For a while now, my lessons have come with three objects instead of one: the slides, a storyboard and a Real Book. Each does a different job, and this post explains which. The first complete set is the one for The Hydrology of Soil, Lausanne version, which I am using for the soil lesson at the University of Lausanne (UNIL). The same scheme is used for the series Statistical physics of soil water.



The slides

The slides are what you see in the classroom, and they carry the story: one idea per slide, a figure or an equation, a few words. On their own they are deliberately incomplete. A slide shows the result of a derivation, not the derivation; it names an assumption, but does not discuss it. The colours of the boxes follow a code that is the same in all my recent decks:

  • blue for definitions and facts;
  • orange for consequences, assumptions and caveats;
  • green for what is new and for pointers forward;
  • red for open problems and corrections.

The PDFs are on OSF. Editable versions, PowerPoint files with real text boxes and LaTeX equations that open in Keynote or PowerPoint, are available on request.

The storyboard

The storyboard is the script of the deck. It is a table with one row per slide and five columns:

  • the slide number;
  • the spoken text, a suggested narration;
  • what is on the screen;
  • the speaker notes;
  • the mounting comments for whoever edits a recording: which build slides were merged, where a figure comes from, what was corrected.

Storyboards were born with the soil MOOC we produced for the EU project EDVANCE, where every episode had to be recorded and edited. I kept them because they answer the question a student asks when looking at a slide alone: what was he saying here? They are also the place where the changes between versions of a deck are listed. Each storyboard now ends with a bibliography in three parts: the sections of Freeze and Cherry's Groundwater (1979, openly available) to read with that deck, the works cited on the slides, and further reading.

The Real Book

The name comes from jazz. The Real Book is the collection of lead sheets that musicians actually play from: the melody and the chords, written out, no frills. My Real Books are the same for a lesson: every step, written out. Where a slide shows a result, the Real Book derives it. It also does the following:

  • keeps track of units, the most frequent source of error in this subject;
  • gives orders of magnitude;
  • states which hypotheses are being used, and where they fail;
  • lists the corrections to earlier versions of the slides (every deck has had its share of sign errors and missing factors).

The text uses the same colour code as the slides: Mathematics, Physics, Result and Correction boxes, plus Numbers boxes in the statistical-physics series. Each section starts by saying which slides it covers, and every Real Book opens with a table that maps each slide to the section where it is discussed. You can follow the lesson with the slides and open the Real Book only where a step is not obvious. Or you can read the Real Book from start to end, as a short textbook chapter.

How to use the three together

The three objects are meant to be used together:

  • In class, the slides.
  • To review a lesson, or to study it without having attended, the slides together with the storyboard.
  • To understand where an equation comes from, or to check it, the Real Book.
  • To go further, the bibliography at the end of the storyboard.

What they can serve

Beyond my own lessons, the three objects are meant to be reused.

  • Students can study a topic without having attended. They can check a derivation step by step and find the one or two readings that matter. The exercises at the end of each Real Book, with answers, help prepare for an exam.
  • Teachers can take a deck, or part of it, for their own course. They can cut it, reorder it or translate it, keeping the Real Book as the reference text behind the slides. The mapping from slides to sections makes it easy to see what is lost when slides are removed.
  • Anyone recording a lesson or a MOOC has, in the storyboard, the script and the editing instructions ready.
  • Researchers and reviewers have, in the Real Book, a place where every equation can be checked. Corrections are listed openly instead of being silently fixed.
  • Translators and adapters work from the LaTeX and editable sources rather than retyping from a PDF. This also includes adapting the material to another audience, for instance a shorter lesson for practitioners or a longer one for a doctoral school.

Since the Real Books and storyboards are written in LaTeX, they are easy to keep under version control and to update together with the slides.

Everything is released under a Creative Commons Attribution 4.0 licence (CC BY 4.0), except the paintings on the covers, which are copyrighted by the original authors and used according a FAIR use agreement. The materials are a work in progress, and will be improved after the lesson. If you find an error, a missing step or a better reference, please tell me: that is exactly what the Correction boxes are for.

Soil Kinetic Theory - Sion EPFL Lecture

Work in progress.

After the soil lesson at UNIL, I am going to Sion, to the Laboratory of Catchment Hydrology and Geomorphology (CHANGE) of EPFL. There I will talk about what I have been doing in the last months on soil water. If Lausanne was about the classical picture, Sion is about what lies under it. In the talk I will probably go only through the index of the lectures, Deck 0 below, which tells the whole story in two slides per deck. The full decks are here for the curious who want to see how each step is actually done. The slides belong to the series Statistical physics of soil water, built on the preprint arXiv:2607.09416 and two companion papers. One companion is on the Chapman–Enskog reduction, the other on water age.

The idea in a few lines

Richards' equation is usually postulated: mass conservation, the Darcy–Buckingham law, a retention curve and a conductivity curve fitted to data. The series asks whether it can be derived, in the way the Navier–Stokes equations are derived from the kinetic theory of gases.

The state of soil water is not one number, the water content, but a function: the occupancy g(r, x, t), the filled fraction of each class of pores. Water moves between pore classes inside a volume and between neighbouring volumes. This gives a kinetic equation with two currents. When redistribution among the pores is fast compared with the exchange between places, the occupancy is slaved to its equilibrium. A Chapman–Enskog expansion in the Damköhler number then returns Richards' equation:

  • the retention curve at order zero;
  • the conductivity at order one, as a sum over relaxation modes.

Where the Damköhler number is not small, Richards' equation stops being valid. That is where dual permeability, preferential flow and hysteresis come from. One more coordinate, the age of the water, gives the StorAge Selection functions that catchment hydrologists use, derived rather than assumed. This last part is the bridge to the work of a catchment hydrology lab, and the reason I was glad to bring it to Sion.

Deck 0. The whole story (the talk)

This is the deck I will use in Sion, and if you read only one deck, read this. It gives two slides for each of the other decks. The first states the question and its key equation; the second shows the key figure and what changes in practice. Each slide says which deck to open for the details. It is written for hydrologists, not for statistical physicists.
→ Slides · Storyboard · Real Book

The fifteen decks that follow are not part of the talk. They are the lectures behind it, in four parts.

Part I. The pieces: geometry, potential, state

  • Deck 1. The nature of hydraulic conductivity. K(θ) is built from a network of pores: Hagen–Poiseuille in each pore, the connectivity between pore classes, and a cutoff fixed by suction. Burdine's and Mualem's formulas turn out to be two bounds of the same network, and the conductivity vanishes at percolation.
    → Slides · Storyboard · Real Book
  • Deck 2. Micro potential and macro potential. The chemical potential of water has capillary, adsorptive, osmotic and gravitational terms. The potential between two pores is separated from the potential between places. Suction is the level of the largest filled pore, and it is defined only at equilibrium.
    → Slides · Storyboard · Real Book
  • Deck 3. The occupancy as the state. Many occupancies share the same water content. This degeneracy is where history dependence comes from. The deck also proposes how the occupancy could be measured.
    → Slides · Storyboard · Real Book
  • Deck 3b. Equilibrium occupancies. Gravity, adsorbed films, solutes and temperature are added one at a time, to see how each moves or deforms the equilibrium step. This also shows why sample height, specific surface and salinity change a measured retention curve.
    → Slides · Storyboard · Real Book

Part II. From the pore to Richards' equation

  • Deck 4. The kinetic continuum equation. It starts from the budget of one pore class in one REV, then the exchange between REVs, then the limit to a point. The result is one equation with two currents.
    → Slides · Storyboard · Real Book
  • Deck 5. Mass conservation and the forbidden operation. Integrating the kinetic equation over pore sizes gives mass conservation, exact and empty. Integrating first and then looking for a flux law in θ is the shortcut that the classical theory takes.
    → Slides · Storyboard · Real Book
  • Deck 6. The right procedure. It introduces the two clocks and their ratio, the Damköhler number. The state is split into mean and shape, and the shape is slaved and eliminated. These are the ideas of the Chapman–Enskog expansion, shown on a simple model.
    → Slides · Storyboard · Real Book
  • Deck 7. Free energy and the Rayleighian. The free energy of pore water has its minimum in a Fermi–Dirac occupancy. The kinetic equation is a descent of this free energy, and an H-theorem says the free energy only decreases.
    → Slides · Storyboard · Real Book
  • Deck 8. The Chapman–Enskog development. The expansion is carried out term by term. Richards' equation comes out as a limit, with the band of conditions where it does not hold.
    → Slides · Storyboard · Real Book
  • Deck 9. The spectrum. The operator inverted in Deck 8 is a graph Laplacian on the pore classes. The conductivity is a sum over its relaxation modes (Green–Kubo), the gap closes at percolation, and Burdine and Mualem return as trial functions.
    → Slides · Storyboard · Real Book

Part III. Structure and memory

  • Deck 10. Soil structure and dual permeability. A bimodal pore population splits the spectrum into a fast and a slow band. Dual permeability is derived, with the exchange coefficient computed, and preferential flow appears as the same mechanism.
    → Slides · Storyboard · Real Book
  • Deck 11. Hysteresis. Wetting and drying are two operators that do not commute, and a small cycle does not close. Hysteresis is the holonomy of the forcing: it has a rate-independent part from trapping, and a rate-dependent part that grows with the square of the intensity.
    → Slides · Storyboard · Real Book

Part IV. The age of water

  • Deck 12. Volume and flux. The same pore classes are weighted by the water they hold and by the water they release. Tracers see volume and the water balance sees flux, and both are right. Residence times are longer than the turnover time by a factor 1 + χ².
    → Slides · Storyboard · Real Book
  • Deck 13. Water age as a kinetic coordinate. The StorAge Selection function is derived as the age-marginal of the kinetic flux. Segregation alone selects nothing, and fast exchange gives uniform sampling.
    → Slides · Storyboard · Real Book
  • Deck 14. Two numbers, not one. The mismatch between the two weightings sets the amplitude of the selection, and a mixing Damköhler number sets how much of it survives. The direction of the bias depends on where rain enters.
    → Slides · Storyboard · Real Book
  • Deck 15. Old aquifers, young rivers. The same mismatch is read on mean ages and inverted for three catchments. A passive store is a corner of the family, and the inverse storage effect needs percolation.
    → Slides · Storyboard · Real Book

Real Books, Jupyter Notebooks and storyboards

Every deck comes with a Real Book, where every step is written out, and a storyboard, the script of the deck with its bibliography. Another  post explains what these are and what they can serve. The slides are on OSF as PDF. The editable slides (PowerPoint, with real text boxes and LaTeX equations), the LaTeX originals of the Real Books, and the figure notebooks are available on request. Every Python figure has its own notebook that reproduces it.

Everything is released under a Creative Commons Attribution 4.0 licence (CC BY 4.0), except the Mark Rothko paintings on the covers, which are only reproduced. This is work in progress, and some of it is still being written as papers. Objections, counterexamples and data that could falsify it are the most welcome comments. I thank the colleagues of CHANGE for the invitation, and Marialaura Bancheri and Antonio Basile, with whom the hydrological consequences are being written.

Monday, October 26, 2026

Before the Kinetic Theory of water flow in porous media - What you need to know about soil - Lausanne (UNIL) seminar

I will give a long lesson on soil water at the University of Lausanne (UNIL) Hydrology lab. These are the slides I plan to use. They are the Lausanne version of The Hydrology of Soil, the course I prepared for the soil MOOC of the EU project EDVANCE, revised for this occasion. The whole course, included the parts which I have skipped here are available at the MOOC site. A last deck opens a window on the work I am doing now on the statistical physics of soil water and which is the topic of my talk at Sion EPFL Hydrology and Geomorphology lab. All the slides and the companion material are available as PDF files in the OSF repository. 

The story runs from what a soil is to the equation we use to describe water moving in it, Richards' equation, and then to the places where that equation stops working. Each deck below is followed by a few lines on what it contains.

Please consider all the material as a work in progress.  Though there should not be error in the hydrology, ll the material can be considered as a preprint to be subject to revision. Not sure, I will be able to tell everything, but parts can be skipped, and the whole amount of material is left to inspection by curious. 


Please find the slides at the links. You'll be maybe surprised to find two two other objects: a storyboard and a Real Book. This post explains what they are. 

0. What soil is

This is an introduction to what I assume to be known. It covers the five constituents that share the soil volume (solid particles, liquid water, ice, gas with its water vapour, and biota), soil profiles and horizons, and texture. That means sand, silt and clay, the particle-size distribution, and the texture triangle. It closes with the key definitions used in the rest of the lesson: masses, volumes and densities, volumetric water content, porosity, and relative and effective saturation.

Slides, Storyboard, Realbook, Notebook

1. The energy of water in soil

This is the longest deck, and the one on which everything else rests. It starts from the forms of energy that water in soil can have, and arrives at the chemical potential as the quantity that tells where water goes. From there it recovers the traditional pressures and heads (matric, osmotic and gravitational). It then treats capillarity: Young–Laplace, Jurin's law and the meaning of a negative pressure. Next comes the passage from single pores to the soil water retention curve, which is the pore-size distribution seen in suction coordinates. The deck ends with hydraulic hysteresis and the parametric forms of the retention curve (Brooks–Corey, van Genuchten, Kosugi, do not worry about, they are explained in the slides).

Slides, Storyboard, Realbook, Notebook

2. Darcy and Buckingham laws

The deck starts from Darcy's experiment, and asks whether Darcy's law can be derived from the Navier–Stokes equations (it can, under well-defined conditions). It then goes down to the pore with the Hagen–Poiseuille law, and back up to the Representative Elementary Volume. In unsaturated soil, Buckingham's law asks whether the flux can keep Darcy's form with a conductivity that depends on water content. Mualem's hypothesis of mutually accessible pores is what makes this work. The deck ends with the van Genuchten–Mualem conductivity and its siblings: Brooks–Corey–Mualem, Kosugi–Mualem and Peters–Kosugi–Mualem.

Slides, Storyboard, Realbook, Notebook

3. Soil water budget

This deck goes from a budget to a differential equation: conservation laws, the divergence operator, and the local form of the balance. Combining continuity, the Darcy–Buckingham law and the retention curve gives Richards' equation. Along the way it pays attention to which potential drives the flow. The excess of potential sits in the largest filled pores, and this is true only at equilibrium. The two foundational hypotheses are stated explicitly: internal redistribution is instantaneous, and all pores are mutually accessible. The deck closes with 1D simulations made with GEOframe (with Niccolò Tubini): sand, clay, ponding, and sand over clay.

Slides, Storyboard, Realbook, Notebook

4. Solving Richards' equation, and its limits

The deck starts with where the parameters come from: pedotransfer functions, from Rawls' regressions to today's tools (Rosetta, euptf and others). It then looks at what the soil column does not contain. Bedrock topography, pipes and macropores control much of the subsurface flow, and flow switches on above thresholds (Tromp-van Meerveld and coworkers; Koestel, Larsbo and Jarvis). It ends with the breakdowns of Richards' equation: hydrophobicity, a conductivity that grows with sample size, fingering and saturation overshoot. A few philosophical remarks on what a model leaves out close the deck.

Slides, Storyboard, Realbook, Notebook

5. The nature of hydraulic conductivity (statistical physics of soil water, Deck 1)

This last deck turns the question around: can K(θ) be derived from the pore space, instead of being postulated? It builds the conductivity from a network of pores: Hagen–Poiseuille in each pore, the connectivity between pore classes, and a cutoff fixed by suction. It then sums the network in parallel, in series and exactly (Kirchhoff's laws, effective medium). Burdine's and Mualem's formulas turn out to be two bounds of the same network. The conductivity vanishes at percolation, and water enters from the boundaries. The same question, one scale up, is the effective conductivity of stochastic hydrogeology. It is the first deck of a series built on the preprint arXiv:2607.09416, in which Richards' equation appears as a limit of a kinetic theory of pore water.

Slides, Storyboard, Realbook, Notebook


The slides of decks 0–4 have accompanying Real Book chapters where every step is written out, and the decks will be improved after the lesson. Comments and corrections are welcome. The paintings that open the decks are by Jay Stratton Noller and Mark Rothko. I thank Chiara Baldo and Lorenzo Duchi, who helped with the MOOC version, and the colleagues at UNIL for the invitation.

Daniele Andreis' PhD.

Under construction

 

Gaia Roati's Ph.D.

Under construction 


Wednesday, October 7, 2026

Daily Forcings Datasets (Rainfall and Temperature) for hydrological Purposes over the Po river district

If you want to run a hydrological model in the Po basin, or anywhere in northern Italy, the first question is which meteorological forcing to use. A few years ago the choice was short. Today there are at least a dozen gridded products, regional and European, built with different networks, methods and purposes. This post is a review of what is available, written from the point of view of someone who needs daily forcing for water budgets with GEOframe or a similar model.

A disclosure: with Hossein Salehi and colleagues I have a dataset of my own in this list (Salehi et al., preprint, currently in open discussion at ESSD). I have tried to judge it with the same yardstick as the others.


What a hydrologist needs from a forcing dataset

Not every good climatological product is a good forcing. For water budgets, these are the requirements I use:

Requirement Why it matters
Daily time step, with the day aligned to discharge records (00–24) Snow, soil moisture and routing run daily; misaligned days shift peaks
Precipitation and temperature from the same network and method Rain–snow partition, melt and ET depend on both; mixing products mixes biases
Tmin and Tmax, or radiation Needed by Hargreaves or Priestley–Taylor ET and by melt and frost thresholds
Resolution close to the model units, about 1 km in Alpine sub-basins Aggregating is exact; disaggregating needs assumptions
Coverage of the whole hydrological district, Swiss and French headwaters included Budgets must close over the basin, not over administrative borders
Uncertainty for each cell and day So that forcing error can be carried into budgets and calibration
Station data and metadata So that users can check, re-interpolate or bias-correct
Documented behaviour with elevation and undercatch High-elevation input errors dominate Alpine budgets
Open licence, persistent identifier, standard format Reuse, citation, reproducibility (the FAIR principles)
Updates after 2020 Operational water-balance and drought monitoring

No product meets all of them.

The datasets

Dataset Variables Period, step Grid Method
ARCIS precipitation (Pavan et al., 2019) P 1961–present, daily (9-to-9 local day) ~5 km Modified Shepard with topographic distance, on 1,048 homogenized series
ARCIS temperature (Pavan et al., 2026) Tmin, Tmax 1991–present, daily, monthly updates ~5 km Piecewise lapse rate, urban and water fraction, in 28 sub-areas; Shepard on residuals
IH-GAR (Manara et al., 2026) P 1951–2023, daily and monthly ~800 m Anomaly method: elevation-based normals, monthly anomalies, daily fractions
APGD (Isotta et al., 2014) P 1971–2008; extended version to 2019 5 km Anomaly method with PRISM-type normals; Alpine part only
Crespi et al. (2018) P normals 1961–1990 climatology ~800 m Local weighted regression on elevation
Crespi et al. (2021) P, mean T 1980–2018, daily 250 m Anomaly method; Trentino–South Tyrol only
Salehi et al. (preprint) P, mean T 1991–2020, daily 1 km Kriging with daily variograms; daily lapse rate for temperature
EMO-1 (Salamon et al., preprint) P, Tmin, Tmax, T, wind, radiation, vapour pressure 1990–2024, daily and 6-hourly ~1.5 km Angular distance weighting
E-OBS P, T, Tmin, Tmax and more 1950–present, daily ~11 km Ensemble interpolation
CERRA-Land P and land variables 1984–present 5.5 km Regional reanalysis
EEAR-Clim (Bongiovanni et al., 2025) Station P, T, Tmin, Tmax to 2020, daily stations Quality-controlled, homogenized series, about 9,000 stations
BIGBANG (ISPRA) Water-balance outputs 1951–2024, monthly 1 km National monthly water-balance model

A few notes on each family.

ARCIS is the work of the regional meteorological services of north-central Italy. Its strengths are care for the data (homogeneity tests, synchronization of 9-to-9 readings) and the fact that it is updated operationally; its temperature companion (Pavan et al., 2026) handles Po Valley inversions with sub-regional, two-slope lapse rates. Its limits for Alpine hydrology are the 5 km grid and the absence of an elevation model for precipitation: Manara et al. (2026) find ARCIS lower than other products above about 750 m.

IH-GAR (Manara et al., 2026) uses the densest network (7,417 stations in its calibration domain, about 2,000 active each year) and the anomaly method, so its normals capture the increase of precipitation with elevation where stations are missing. Its daily values are built from monthly anomalies and interpolated daily fractions; the paper validates normals and monthly anomalies, but I could not find a validation of the daily fields themselves. Temperature has to come from another product.

A caution that applies to all products built from normals. IH-GAR, APGD and Crespi et al. (2021) obtain daily values by scaling station anomalies with elevation-aware normals. A normal is the number of wet days times their intensity, so this scaling can turn a higher frequency of rain at altitude into heavier storms. Monthly totals stay correct; daily wet-day frequency and intensity at altitude are worth checking before using these products as daily forcing.

APGD (Isotta et al., 2014) remains the Alpine reference for daily precipitation and shows the sharpest valley gradients. It covers only the Alpine part of the basin and is not updated.

EMO (Thiemig et al., 2022, and EMO-1) is the most complete in variables, open and updated. It is worth knowing how it is built in the Alps: EMO-5 imports about 5,000 APGD grid points as virtual stations, and its direct Italian station input is small. In the Alpine part of the Po basin it largely re-grids APGD.

E-OBS and CERRA-Land are useful for large-scale consistency, but too coarse, or too model-dependent, for Alpine sub-basins.

Our dataset was designed as hydrological forcing: precipitation and temperature from the same network (1,583 precipitation and 1,555 temperature stations, from the Po River District Authority and EEAR-Clim), on a 1 km grid, over the whole district plus a 20 km buffer. The review it received was useful and sometimes hard. The precipitation field is smoother than ARCIS, IH-GAR and APGD in some Alpine valleys, Valtellina above all. The lapse rate is one per day for the whole domain, so it misses local inversions. The record stops in 2020, and ordinary kriging of daily totals spreads small amounts across the wet/dry boundary. In the revision we are testing, on the gauges and within single events, whether elevation acts on the number of wet days or on storm intensity, and we will build precipitation from occurrence and intensity separately. What it adds is the daily variograms, the daily lapse rates and the per-cell uncertainty, which we will release with the fields.

How many stations, in the same area?

Comparing station totals is misleading, because each product covers a different domain. What matters is how many stations support the field inside the area you model. For the Po River District with a 20 km buffer (about 90,000 km²):

Dataset Stations in the district Basis
Salehi et al., precipitation 472 (1991–2000), 954 (2001–2010), 1,108 (2011–2020) active per day Exact
ARCIS precipitation roughly 500–580 Estimate, scaled by area from about 1,000 series per year
ARCIS temperature roughly 570 (1991) to 930 (after 2013) Estimate, scaled by area from their Fig. 1a
IH-GAR roughly 1,100–1,400 active per year Estimate, from their station density
EMO few direct Italian stations; APGD points in the Alps Thiemig et al. (2022)

The estimates assume uniform station density and should be replaced by real counts. They still show a point that is easy to miss: station support changes a lot over time. Our network more than doubles after 2000, and any network that grows this much makes trends from the gridded series suspect unless the series are homogenized and the network is controlled, as ARCIS and IH-GAR do.

Fitness for water-budget modelling

Dataset P and T, same network Tmin/Tmax ≤ 1.5 km Whole district Per-cell uncertainty P with elevation Homogenized After 2020
ARCIS P + T same agencies, different methods yes no Italian part no no yes yes
IH-GAR P only no yes yes no normals yes to 2023
APGD P only no no Alps only ensemble version on request normals no to 2019
EMO-1 yes yes yes yes yes (EMO-5) limited no yes
E-OBS yes yes no yes ensemble spread no no yes
Salehi et al. yes mean T only yes yes yes, kriging variance and cross-validation tested and rejected no no

My reading, by use:

  • Long-term climate and trends: ARCIS and IH-GAR, which are homogenized and designed for it.
  • Precipitation totals in Alpine basins: IH-GAR, or APGD up to 2019; check ARCIS above 750 m.
  • Operational monitoring: ARCIS precipitation and temperature, updated monthly.
  • Daily forcing for a distributed model of a Po sub-basin: EMO-1 if you need many variables and recent years; our dataset if you want precipitation and temperature from one regional network with their uncertainty, with the caveats above; and in any case a check of the totals against IH-GAR at altitude.

Data availability and FAIR principles

Dataset Identifier and access Licence Station data
ARCIS arcis.it, no DOI check the site no
IH-GAR UNIMI Dataverse, doi:10.13130/RD_UNIMI/CSYYAP check the repository no
APGD MeteoSwiss, doi:10.18751/Climate/Griddata/APGD/1.0, registration non-commercial use no
Crespi et al. (2018) ISAC-CNR CC BY-NC-ND 4.0 no
Crespi et al. (2021) PANGAEA, doi:10.1594/PANGAEA.924502 CC BY 4.0 partly
EMO-1 JRC Data Catalogue CC BY 4.0 no
E-OBS, CERRA-Land Copernicus Climate Data Store open partly (E-OBS)
EEAR-Clim Zenodo, doi:10.5281/zenodo.10951609 CC BY 4.0 yes
Salehi et al. Zenodo, doi:10.5281/zenodo.19207256 CC BY 4.0 no (sources: Po District Authority, EEAR-Clim)

The weakest point is common to all regional grids: none releases the input station series, because they belong to the regional services. EEAR-Clim is the exception and a real step forward. A second gap is code: among these products, only EMO and ours (GEOframe Krigings, GPL-3) point to open interpolation code.

What is still missing

  • A daily product that brings in the elevation dependence of precipitation where it acts, on wet-day frequency, on intensity or both, with an explicit uncertainty for every day and cell.
  • Validation of daily fields at the daily scale, including wet-day frequency and extremes, for products built from monthly components.
  • Independent checks of precipitation at altitude, through water budgets closed on gauged basins with storage and evapotranspiration estimated independently. Snow undercatch cannot be seen by comparing gauges with gauges.
  • Open station data. Without it, every dataset is a black box that can only be compared with other black boxes.

References

  • Bongiovanni, G., et al. (2025). EEAR-Clim: a high-density observational dataset of daily precipitation and air temperature for the extended European Alpine region. Earth Syst. Sci. Data, 17, 1367–1391. doi:10.5194/essd-17-1367-2025
  • Crespi, A., Brunetti, M., Lentini, G., Maugeri, M. (2018). 1961–1990 high-resolution monthly precipitation climatologies for Italy. Int. J. Climatol., 38, 878–895. doi:10.1002/joc.5217
  • Crespi, A., Matiu, M., Bertoldi, G., Petitta, M., Zebisch, M. (2021). A high-resolution gridded dataset of daily temperature and precipitation records (1980–2018) for Trentino-South Tyrol. Earth Syst. Sci. Data, 13, 2801–2818. doi:10.5194/essd-13-2801-2021
  • Isotta, F. A., et al. (2014). The climate of daily precipitation in the Alps. Int. J. Climatol., 34, 1657–1675. doi:10.1002/joc.3794
  • Manara, V., et al. (2026). A new daily high-resolution gridded precipitation dataset for the Italian Greater Alpine Region (1951–2023). J. Hydrol.: Reg. Stud., 67, 103776. doi:10.1016/j.ejrh.2026.103776
  • Pavan, V., et al. (2019). High resolution climate precipitation analysis for north-central Italy, 1961–2015. Clim. Dyn., 52, 3435–3453. doi:10.1007/s00382-018-4337-6
  • Pavan, V., et al. (2026). A new operational dataset of gridded minimum and maximum temperature over north-central Italy 1991 to present. Climate Services, 43, 100689. doi:10.1016/j.cliser.2026.100689
  • Salamon, P., et al. EMO-1: an improved version of the high-resolution multi-variable gridded meteorological dataset for Europe. Earth Syst. Sci. Data Discuss., essd-2025-723
  • Salehi, H., et al. (2026). A 30-year 1-km daily precipitation and air temperature dataset for the Po River District (Italy). Earth Syst. Sci. Data Discuss. doi:10.5194/essd-2026-467
  • Thiemig, V., et al. (2022). EMO-5: a high-resolution multi-variable gridded meteorological dataset for Europe. Earth Syst. Sci. Data, 14, 3249–3272. doi:10.5194/essd-14-3249-2022
  • Copernicus Climate Data Store: E-OBS and CERRA-Land
  • ISPRA, BIGBANG national water balance: workshop presentation, March 2026

Introduction to the Random Forest algorithm (for Hydrologists)

Random forests are among the most used machine-learning tools in hydrology, and among the least understood by the people who use them. This post is a guided reading of how they work, written for hydrologists who want the logic before the library call.

I follow one source closely: Chapter 8, Tree-Based Methods, of An Introduction to Statistical Learning (ISL) by Gareth James, Daniela Witten, Trevor Hastie and Robert Tibshirani, together with the Stanford video lectures in which Hastie and Tibshirani teach that chapter. The book exists in an R edition (2nd ed., 2021) and a Python edition (ISLP, 2023, with Jonathan Taylor); both are free as PDFs from statlearning.com. The chapter numbering and notation below are theirs. Where I depart from them, it is to add a hydrological reading, and I say so. The relevant lectures are embedded section by section; the whole Chapter 8 series is in this YouTube playlist.

The chapter builds in four steps, and so does this post: a single tree, then many trees averaged (bagging), then many decorrelated trees averaged (random forests), then trees grown sequentially (boosting). Each step fixes a weakness of the previous one.


1. A single regression tree (ISL §8.1)

A regression tree cuts the predictor space into \(J\) non-overlapping boxes \(R_1, \dots, R_J\) and predicts, in each box, the mean of the training responses that fall in it. Think of predicting mean annual runoff from basin area, mean elevation, aridity index and forest cover: the tree asks is aridity < 0.8?, then is elevation > 1500 m?, and so on, until each leaf holds a group of similar basins.

The boxes are chosen to minimise the residual sum of squares:

\[ \mathrm{RSS} = \sum_{j=1}^{J} \sum_{i \in R_j} \left( y_i - \hat{y}_{R_j} \right)^2 \]

Finding the best partition is computationally infeasible, so the tree is grown by recursive binary splitting: at each step, take the single predictor \(X_j\) and cutpoint \(s\) that most reduce RSS, split, and repeat inside each half. It is greedy and top-down; it never looks back to see whether an earlier split was a poor choice.

Hastie and Tibshirani, Decision Trees (Stanford Statistical Learning, Ch. 8, 14:37).

A tree grown until each leaf holds a handful of points fits the training data almost perfectly and predicts new data badly. ISL's remedy is cost-complexity pruning: grow a large tree \(T_0\), then for each value of a penalty \(\alpha\) find the subtree \(T\) that minimises

\[ \sum_{m=1}^{|T|} \sum_{i:\, x_i \in R_m} \left( y_i - \hat{y}_{R_m} \right)^2 + \alpha |T| \]

where \(|T|\) is the number of leaves. \(\alpha\) plays the same role as \(\lambda\) in the lasso, and it is chosen by cross-validation.

Pruning a Decision Tree (Ch. 8, 11:45).

For classification the same machinery applies, with the Gini index or cross-entropy replacing RSS; the lecture Classification Trees and Comparison with Linear Models covers it.

Hastie and Tibshirani are frank about the balance sheet. Trees are easy to explain, mirror human decision-making, handle qualitative predictors without dummy variables, and can be drawn. But a single tree is usually less accurate than other methods, and it is non-robust: change the data a little and the tree can change a lot. In statistical language, trees have high variance. Everything that follows in the chapter is a way of killing that variance.

2. Bagging (ISL §8.2.1)

The idea rests on an elementary fact. If \(Z_1, \dots, Z_n\) are independent, each with variance \(\sigma^2\), their mean has variance \(\sigma^2/n\). Averaging reduces variance. If we had \(B\) independent training sets, we could grow \(B\) trees and average their predictions.

We do not have \(B\) training sets, so we fake them with the bootstrap (ISL Chapter 5): draw \(B\) samples of size \(n\), with replacement, from the one training set we have; grow a deep, unpruned tree on each; average:

\[ \hat{f}_{\mathrm{bag}}(x) = \frac{1}{B} \sum_{b=1}^{B} \hat{f}^{*b}(x) \]

For classification, average becomes majority vote. Each tree is deliberately overfitted (low bias, high variance); the averaging removes the variance. \(B\) is not a tuning parameter in the usual sense: a large \(B\) does not overfit, it simply costs time. You stop when the error has stabilised, often a few hundred trees.

Bagging also gives an error estimate for free. Each bootstrap sample leaves out, on average, about one third of the observations (the fraction tends to \(1/e \approx 0.368\)). For each observation, predict it using only the roughly \(B/3\) trees that did not see it. The resulting out-of-bag (OOB) error is a valid test-error estimate, and for large \(B\) it is essentially equivalent to leave-one-out cross-validation, as the authors note in the lecture below.

A caution the book does not need to make, but hydrologists do: the bootstrap assumes the observations are exchangeable. Daily streamflow is not. If neighbouring days land in both the bootstrap sample and the OOB set, the OOB error is optimistic. With time series, a block or year-based hold-out is the honest test.

3. Random forests (ISL §8.2.2)

Random forests improve bagging with one small change: at each split, the tree may only choose among a random subset of \(m\) of the \(p\) predictors, drawn afresh at every split. Typical choices are \(m \approx \sqrt{p}\) for classification and \(m \approx p/3\) for regression; \(m = p\) gives back bagging.

Bootstrap Aggregation (Bagging) and Random Forests (Ch. 8, 13:45): the core lecture for this post.

Why would forbidding a tree from seeing the best predictor help? Because bagged trees are correlated. Suppose one predictor is very strong (in a runoff problem, precipitation almost always is). Every bagged tree will then split on it first, and the trees will look alike. Averaging similar things does not reduce variance much. The arithmetic, given in The Elements of Statistical Learning (§15.2) and implicit in ISL, is the variance of an average of \(B\) identically distributed variables with pairwise correlation \(\rho\):

\[ \mathrm{Var}\!\left( \frac{1}{B}\sum_{b=1}^{B} \hat{f}^{*b} \right) = \rho\,\sigma^2 + \frac{1-\rho}{B}\,\sigma^2 \]

As \(B\) grows the second term vanishes, but the first does not. Bagging attacks the second term; random forests attack \(\rho\). By hiding the strong predictor from most splits, the other predictors get a chance, the trees diversify, and the average becomes more stable. In the lecture Hastie illustrates this on a high-dimensional gene-expression example, where \(m = \sqrt{p}\) clearly beats bagging; the gain is largest when many predictors are correlated.

The practical consequences:

  • Like bagging, a random forest does not overfit by adding trees; \(B\) only needs to be large enough.
  • \(m\) is the one parameter worth tuning, using the OOB error.
  • Trees are grown deep and unpruned. Minimum leaf size (typically 5 for regression) is a secondary control.
  • The price is interpretability: a forest of 500 trees cannot be drawn.

4. Variable importance, and how to misread it

To recover some interpretability, ISL records, for each predictor, the total decrease in RSS (or Gini index) produced by splits on it, averaged over all \(B\) trees. Ranked and plotted, this is the familiar variable-importance chart that ends half the hydrological ML papers I review. The lecture in §5 below discusses it alongside boosting.

Three warnings, the first from ISL's spirit and the others from the later literature:

  1. Importance is predictive, not causal. A high score says the forest found the variable useful for splitting this dataset. It does not say the variable drives the process.
  2. Correlated predictors share or steal credit. Elevation, temperature and snow fraction carry overlapping information; the forest spreads importance among them in ways that depend on \(m\) and on chance.
  3. Impurity-based importance is biased toward continuous predictors and categorical ones with many levels (Strobl et al., 2007). Permutation importance (Breiman, 2001), which measures how much the OOB error grows when one predictor's values are shuffled, is the safer default.

If the question is physical, the variable-importance plot is the beginning of an argument, not its conclusion.

5. The other branch: boosting and BART (ISL §8.2.3–8.2.4)

Chapter 8 does not stop at forests, and a reader should know why. Bagging and random forests grow trees independently and average them. Boosting grows them sequentially: each small tree is fitted to the residuals of the current model, and only a shrunken fraction of it is added:

\[ \hat{f}(x) \leftarrow \hat{f}(x) + \lambda\, \hat{f}^{b}(x), \qquad r_i \leftarrow r_i - \lambda\, \hat{f}^{b}(x_i) \]

The model learns slowly. It has three tuning parameters: the number of trees \(B\) (which, unlike in a forest, can overfit), the shrinkage \(\lambda\) (typically 0.01 or 0.001), and the tree depth \(d\) (often 1 or 2; with \(d = 1\), stumps, the model is additive). Boosting usually edges out random forests in accuracy but needs more care. XGBoost and LightGBM are its modern industrial descendants.

Boosting and Variable Importance (Ch. 8, 12:03).

The 2nd edition of the book adds Bayesian Additive Regression Trees (BART), which mixes both ideas: many trees, each repeatedly perturbed to fit the partial residual left by the others, with the output being a posterior distribution, hence uncertainty bands, at little tuning cost. BART is not in the 2014 video series.

6. A hydrologist's reading

What follows is mine, not the book's. Random forests are excellent at some hydrological jobs and structurally unable to do others, and the reasons follow directly from the construction above.

Where they shine. Regionalisation (predicting signatures or parameters in ungauged basins from catchment attributes); digital soil mapping; land-cover and snow-cover classification; gap-filling of station records; and post-processing, that is, learning the residuals of a process-based model such as one built in GEOframe. In all these cases the predictors are tabular, the relations are non-linear with interactions, and the forest needs almost no tuning.

Where they fail by design.

  • No extrapolation. A forest predicts averages of training responses, so its output is bounded by what it has seen. A flood larger than any in the record, or a climate warmer than the calibration period, is outside its reach. This is the most important single fact about trees for climate-impact work.
  • No conservation laws. Nothing ties predicted runoff, evapotranspiration and storage change to a closed water budget. Each output is fitted separately.
  • No memory. A forest maps inputs to output; dynamics must be put in by hand through lagged predictors, antecedent indices and the like.
  • Dependent data. As noted for OOB error, spatial and temporal autocorrelation make random cross-validation optimistic. Use spatially blocked or leave-basins-out schemes.

Uncertainty. A plain forest gives a point estimate. Quantile regression forests (Meinshausen, 2006) keep the full distribution of responses in each leaf and return predictive quantiles at no extra cost, which is often what a hydrological application actually needs.

My own conclusion is that forests are best used with physics, not instead of it: as a fast, honest benchmark that a process model must beat, and as a tool for learning what the process model gets wrong.

7. Try it: a synthetic Budyko test

The example below generates 500 synthetic basins whose runoff follows Fu's form of the Budyko curve, plus a small forest effect and noise. Elevation is a decoy with no effect. It fits a random forest with \(m = p/3\), reads the OOB score, computes permutation importance, and then asks the forest about a basin wetter than any it was trained on. ISLP's own lab (§8.3) does the same steps on standard datasets, and the R lab is shown in the video below.

import numpy as np
from sklearn.ensemble import RandomForestRegressor
from sklearn.inspection import permutation_importance

rng = np.random.default_rng(42)
n = 500
P   = rng.uniform(400, 2000, n)    # annual precipitation (mm)
PET = rng.uniform(400, 1200, n)    # potential ET (mm)
F   = rng.uniform(0, 1, n)         # forest fraction (-)
Z   = rng.uniform(200, 3000, n)    # mean elevation (m): a decoy
w = 2.6                            # Fu parameter
ET = P * (1 + PET/P - (1 + (PET/P)**w)**(1/w))
Q  = P - ET - 50*F + rng.normal(0, 20, n)
X  = np.column_stack([P, PET, F, Z])
names = ["P", "PET", "forest", "elevation"]

rf = RandomForestRegressor(n_estimators=500, max_features=1/3,
                           min_samples_leaf=5, oob_score=True, random_state=0)
rf.fit(X, Q)
print(f"OOB R^2: {rf.oob_score_:.3f}")

imp = permutation_importance(rf, X, Q, n_repeats=10, random_state=0)
for name, m in sorted(zip(names, imp.importances_mean), key=lambda t: -t[1]):
    print(f"{name:>10s}: {m:.3f}")

# Extrapolation: a basin wetter than any in the training set
x_new = np.array([[3000, 800, 0.5, 1000]])
et_new = 3000 * (1 + 800/3000 - (1 + (800/3000)**w)**(1/w))
print(f"True Q: {3000 - et_new - 25:.0f} mm, RF Q: {rf.predict(x_new)[0]:.0f} mm")

The output (scikit-learn, random_state fixed):

OOB R^2: 0.896
         P: 1.219
       PET: 0.185
    forest: 0.020
 elevation: 0.020
True Q: 2212 mm, RF Q: 918 mm   (max Q in training: 1559 mm)

Three lessons in a few lines. The OOB \(R^2\) of 0.90 is a decent fit obtained with no tuning. The importance ranking recovers precipitation and PET, but the real forest effect is indistinguishable from the decoy: small physical effects drown in noise. And for \(P = 3000\) mm the forest predicts 918 mm against a true 2212 mm, below even the largest runoff in its training set. That is §6's extrapolation warning, in numbers.

The same experiment in Java, with Smile

For those of us whose models live on the JVM, as GEOframe does, Smile (Statistical Machine Intelligence and Learning Engine, by Haifeng Li) offers a random forest that can sit inside the same code base. The defaults match the book: \(m = p/3\) for regression, minimum leaf size 5, OOB metrics computed during training. Add the dependency (Smile 4 and later need Java 21 or newer):

<dependency>
  <groupId>com.github.haifengl</groupId>
  <artifactId>smile-core</artifactId>
  <version>6.3.0</version>
</dependency>
import java.util.Random;
import smile.data.DataFrame;
import smile.data.formula.Formula;
import smile.regression.RandomForest;

public class BudykoForest {

    // Fu's form of the Budyko curve: actual ET from P and PET
    static double fuET(double P, double PET, double w) {
        return P * (1 + PET / P - Math.pow(1 + Math.pow(PET / P, w), 1 / w));
    }

    public static void main(String[] args) {
        int n = 500;
        double w = 2.6;
        Random rng = new Random(42);

        double[][] data = new double[n][];
        double qMax = Double.NEGATIVE_INFINITY;
        for (int i = 0; i < n; i++) {
            double P   = 400 + 1600 * rng.nextDouble();   // annual precipitation (mm)
            double PET = 400 +  800 * rng.nextDouble();   // potential ET (mm)
            double F   = rng.nextDouble();                // forest fraction (-)
            double Z   = 200 + 2800 * rng.nextDouble();   // mean elevation (m): a decoy
            double Q   = P - fuET(P, PET, w) - 50 * F + 20 * rng.nextGaussian();
            data[i] = new double[] {P, PET, F, Z, Q};
            qMax = Math.max(qMax, Q);
        }
        String[] names = {"P", "PET", "forest", "elevation", "Q"};
        DataFrame df = DataFrame.of(data, names);

        // 500 trees; mtry defaults to p/3, nodeSize to 5
        RandomForest rf = RandomForest.fit(Formula.lhs("Q"), df,
                                           new RandomForest.Options(500));

        System.out.printf("OOB R^2: %.3f%n", rf.metrics().r2());

        // Impurity-based importance: total RSS decrease, summed over trees
        double[] imp = rf.importance();
        for (int j = 0; j < imp.length; j++) {
            System.out.printf("%10s: %.3e%n", names[j], imp[j]);
        }

        // Extrapolation: a basin wetter than any in the training set
        DataFrame wet = DataFrame.of(new double[][] {{3000, 800, 0.5, 1000, 0}}, names);
        double qTrue = 3000 - fuET(3000, 800, w) - 25;
        System.out.printf("True Q: %.0f mm, RF Q: %.0f mm (max Q in training: %.0f mm)%n",
                          qTrue, rf.predict(wet.get(0)), qMax);
    }
}

Java's random generator is not NumPy's, so the numbers will differ slightly from the Python run, but the story does not: a high OOB \(R^2\), precipitation dominating, and a wet-basin prediction capped near the training maximum. One difference is instructive. Smile's importance() is the impurity-based measure of §4, not permutation importance, so expect the decoy elevation to receive a visibly non-zero score. That is warning 3 of §4 at work.

Lab: Random Forests and Boosting (Ch. 8, 15:35), in R. A companion Lab: Decision Trees precedes it.

References and lectures

The basis of this post

For going further

  • Hastie, T., Tibshirani, R., Friedman, J. (2009). The Elements of Statistical Learning, 2nd ed. Springer. Chapter 15, Random Forests.
  • Breiman, L. (2001). Random forests. Machine Learning, 45, 5–32.
  • Strobl, C., Boulesteix, A.-L., Zeileis, A., Hothorn, T. (2007). Bias in random forest variable importance measures. BMC Bioinformatics, 8, 25.
  • Meinshausen, N. (2006). Quantile regression forests. Journal of Machine Learning Research, 7, 983–999.

Software

  • Li, H. Smile: Statistical Machine Intelligence and Learning Engine. haifengl.github.io; artifact smile-core on Maven Central.
  • Pedregosa, F. et al. (2011). Scikit-learn: Machine learning in Python. Journal of Machine Learning Research, 12, 2825–2830.