How I check a strike location with free satellite data, and when I refuse to publish
Contents
A reader asked how we decide whether a claimed strike location holds up. Here's the free toolkit and the actual decision rule. Nothing here needs a paid account.
The free sources
- Sentinel-2 (ESA, optical): 10 m resolution in the visible bands, a new image roughly every 5 days at mid latitudes. Big burn scars, collapsed large buildings, craters in fields. Not cars, not people.
- Sentinel-1 (radar): sees through clouds and at night. Change detection between two passes can show damage when optical is useless. Harder to read, I'm still learning.
- NASA FIRMS: active fire detections from VIIRS (375 m pixels) and MODIS, near real time. A thermal anomaly at the right place and time is supporting evidence. Not proof.
The process
- Pin the claim: exact place, time window, what supposedly happened.
- Geolocate any imagery that came with the claim (Marta has a great post on this in this topic).
- Pull FIRMS detections for the area and window.
- Compare the last clear Sentinel-2 image before with the first clear one after.
- Look for independent sources: local reporting, other footage from different angles, official statements from more than one side.
Step 3 in pandas, from a FIRMS CSV download:
import pandas as pd
lat, lon = 48.0, 37.8 # the claimed location
df = pd.read_csv("firms_viirs.csv")
df["acq"] = pd.to_datetime(
df["acq_date"] + " " + df["acq_time"].astype(str).str.zfill(4),
format="%Y-%m-%d %H%M", utc=True)
window = df[(df["acq"] >= "2026-07-01T00:00Z") & (df["acq"] < "2026-07-03T00:00Z")]
near = window[window["latitude"].between(lat - 0.05, lat + 0.05)
& window["longitude"].between(lon - 0.05, lon + 0.05)]
print(near[["acq", "latitude", "longitude", "frp", "confidence"]])
FIRMS times are UTC, and acq_time comes as an integer like 113 for 01:13, hence the zero padding. That one bit me once.
When I refuse to publish
- One source plus ambiguous imagery. That's an unconfirmed claim, and we say so or we say nothing.
- FIRMS hit but no visible change and no second source. Fires happen for a hundred reasons: industrial flares, field burning, a warehouse.
- Any doubt about the date of the "before" image. Clouds hide a lot, and a two-week gap hides even more.
The free stuff gets you surprisingly far. It also teaches humility: a 10 m pixel is the size of a small house, and most of what matters in a war happens at a smaller scale than that.
Written by
Naomi Feld
Data journalist. I scrape things governments would rather I didn't. Elections, campaign finance, conflict OSINT. Python, pandas, a lot of records requests. Brooklyn.
Get the best of #hack_the_planet weekly
One email each Monday with the most useful posts. No spam; unsubscribe in one click.
Comments
Sign in to join the conversation.
Sign in to comment