TerraSentinel

Satellite anomaly detection over EU study regions — wildfire, deforestation, cryosphere

Four things worth looking at

Each write-up is generated from a live query, not from prose written once and left to rot. The numbers are read from the serving database when the page renders; the SQL behind each story is shown so you can check it yourself, or open it in the SQL console. Where the two detectors disagree, that is reported rather than smoothed over.

Wildfire · Iberian Peninsula

Three days that outran two years of history

A late-summer cluster put 13,329 fire detections into a single day — roughly 20× the seasonal median for that date.

The Iberian Peninsula burns every summer, and the seasonal baseline expects it. What stands out is not that August had fires but how far the top of the distribution reaches: the busiest day in this window carried 13,329 detections, against a seasonal median of 669.

This is not a single spike. 3 consecutive days sit in the window and 3 of them cleared the anomaly threshold, which is what a sustained fire-weather episode looks like rather than a transient detection artefact.

Large events spread out. Mean intensity reached 59.3 MW per detection and the day's single densest hexagon held only a small share of the total — the signature of a landscape-scale event rather than one concentrated burn.

Caveat. Detection counts are not burned area. One large fire can produce thousands of detections across overpasses, and cloud, smoke and satellite geometry all affect what is seen.

Peak detections in a day (2025-08-15)
13,329
Seasonal median (same day-of-year window)
669
Departure (robust units (median/MAD))
z = 18.7
Days flagged
3 of 3
Mean intensity (per detection)
59.3 MW
SQL behind this story
select observation_date, detection_count, round(zscore,1) as z, severity
from gold_fire_anomalies
where region_id = 'iberia_fire' and observation_date between '2025-08-13' and '2025-08-19'
order by observation_date

Wildfire · out of season

A winter anomaly, and the strongest in the record

Winter fires are rare in Iberia: 1,184 detections against a seasonal median of 67.

This is the largest statistical departure in the whole two-year record — larger than the August megafire cluster — and it happened in winter. The late-February baseline expects almost nothing, so 1,184 detections against a median of 67 produces a departure of z = 22.50.

It outranks August precisely because the baseline is quiet. A big summer day is an amplification of the season; a big winter day is the season behaving incorrectly, and the robust baseline is what makes that difference measurable rather than a matter of opinion.

Night share was 31% on the peak day, below the regional average — daytime-driven burning rather than the overnight smouldering that dominates quiet periods.

Caveat. Agricultural burning plausibly contributes to out-of-season detections and this pipeline cannot distinguish it from wildfire. The anomaly is real; the cause is not established here.

Peak detections (2026-02-25)
1,184
Winter seasonal median
67
Departure (largest in the record)
z = 22.5
Night share
31%
Days flagged
4
SQL behind this story
select observation_date, detection_count, round(zscore,1) as z, severity
from gold_fire_anomalies
where region_id = 'iberia_fire' and observation_date between '2026-02-20' and '2026-03-01'
order by observation_date

Cryosphere · Antarctic

A deficit that does not go away

17.96 × 10⁶ km² expected, 16.41 × 10⁶ km² observed — and it stays there.

Unlike a fire cluster, this is not an event. Antarctic sea-ice extent sat below the 1981–2010 normal for every day in the window, reaching a departure of z = -4.61 on 2026-08-22 and rarely recovering above z = −1.5.

That shape changes how the data should be read. The boolean anomaly flag lights up on 26 of 31 days, which makes it nearly useless here — a threshold is the wrong instrument for a sustained shift. The z-score series is the honest representation, which is why the dashboard charts it rather than badging it.

The baseline is the strongest in the pipeline: a published 30-year per-day-of-year normal with its own standard deviation, so this departure is measured against three decades rather than against our own short record.

Caveat. A threshold on a persistently anomalous series flags most days. Treat `is_anomaly` as uninformative for sea ice and read the departure instead.

Most negative departure (2026-08-22)
z = -4.61
Observed extent
16.41 × 10⁶ km²
1981–2010 normal
17.96 × 10⁶ km²
Days below normal
26 of 31
Baseline
nsidc_climatology
SQL behind this story
select period_start, round(value,2) as extent, round(baseline_mean,2) as normal, round(zscore,2) as z
from gold_ice_extent_trends
where region_id = 'antarctic' order by period_start desc limit 30

Wildfire · Greece, and a disagreement

Where the model and the rule disagree

The statistical baseline calls 2024-09-30 extreme. The model ranks it at percentile 0.915 — high, but below the serving threshold.

This window is kept in the record specifically because the two detectors disagree. The median/MAD rule calls 2024-09-30 extreme at z = 12.55; the Isolation Forest, which sees trailing windows rather than a seasonal baseline, ranks it at percentile 0.915 and does not flag it.

Neither is obviously wrong. A day can be far above its seasonal norm while still sitting inside a run of elevated days, and a model built on recent history will not find that unusual. That is a difference in what the two methods measure, not a bug.

It is reported rather than resolved. A disagreement between a transparent rule and an opaque model is worth more to a reader than a tuned threshold that hides it.

Caveat. The two scores are not competing estimates of one quantity. The z-score compares a day to its season; the model compares it to recent history. Agreement is not expected in every case.

Peak detections (2024-09-30)
808
Statistical z (the rule flags extreme)
12.5
Model percentile (below the 0.975 threshold)
0.915
Days in window
3
SQL behind this story
select a.observation_date, a.detection_count, round(a.zscore,1) as z,
       round(p.anomaly_percentile,3) as model_pct, a.severity
from gold_fire_anomalies a
left join ml_predictions p on p.region_id = a.region_id and p.observation_date = a.observation_date
where a.region_id = 'greece_fire' and a.observation_date between '2024-09-25' and '2024-10-05'
order by a.observation_date

Why there are no deforestation or glacier stories yet

The gap is a missing backfill, not a missing method.

Three of the seven marts depend on Copernicus Sentinel data collected through Google Earth Engine: the deforestation index, the glacier backscatter trend, and the per-hexagon vegetation change layer. The collectors are written and tested; the backfill has not run because Earth Engine needs a service account that is not yet configured.

Rather than hide this, the catalog marks each table as present or awaiting backfill, and ops shows the freshness of everything that is live.