readme.md

March 19, 2026 · View on GitHub

Pixel-Wise T-Test

A New Algorithm for Battle Damage Detection using Sentinel-1 Imagery

The generation of public information regarding buildings damaged by conflict has become particularly important in the context of recent, highly destructive wars in Gaza and Ukraine. This paper develops the Pixelwise T-Test (PWTT), a new algorithm for open-access battle damage estimation that is accurate, lightweight, and generalizable. The PWTT addresses many of the problems associated with expense, coverage consistency, and domain shift that affect deep-learning based approaches to building damage detection, and outperforms the state of the art deep learning model on unseen areas.

How it Works

The PWTT utilizes Synthetic Aperture Radar imagery from the Sentinel-1 satellite. The figure below demonstrates the change in backscatter amplitude (i.e., the "loudness" of the signal's echo) for a destroyed building in Mariupol, Ukraine, before and after its destruction. The corresponding Sentinel-1 pixel has a low standard deviation in both the pre-and post-war periods, but experiences a large change in mean amplitude. The T-Test is a simple signal-to-noise ratio that measures the difference between the means of two samples adjusted by the standard deviation within each sample.

The green dashed line and shaded area represent the pixel's mean backscatter amplitude ±\pm 1 standard deviation prior to the invasion, while the red line and shaded area represent these statistics following the building's destruction.

Installation

pip install pwtt

This installs the pwtt package and its dependencies (earthengine-api, geemap).

Python Quickstart

First, import the Google Earth Engine python API and authenticate using your credentials and cloud project name.

import ee
import pwtt

project_name='<YOUR PROJECT NAME>'
ee.Authenticate()
ee.Initialize(project=project_name)

The PWTT can be deployed in one line of code. The example below conducts a damage assessment over Gaza for July 2024.

gaza = ee.Geometry.Rectangle([34.21,31.21,34.57,31.60])

pwtt.detect_damage(aoi=gaza, # the area of interest as a bounding box
                   war_start='2023-10-10', # the start of the war
                   inference_start='2024-07-01', # the beginning of the inference window
                   pre_interval=12, # the number of months before the war to use as a reference period 
                   post_interval=1, # the number of months after the war to use as an inference period 
                   viz=True) # visualize the results

By simply modifying the location, war_start date and inference_start dates, damage assessment can be carried out on a new area; below is another example for Bakhmut, Ukraine:

bakhmut = ee.Geometry.Rectangle([37.949421, 48.556181, 38.043834, 48.621584])

pwtt.detect_damage(aoi=bakhmut,
                   war_start='2022-02-22',
                   inference_start='2024-07-01',
                   pre_interval=12,
                   post_interval=1,
                   viz=True)

Choosing a Threshold

The detect_damage function returns a continuous T_statistic band and a binary damage band (default threshold T > 3.3). The choice of threshold controls the precision-recall tradeoff and should be guided by the use case. The figure below shows how precision, recall, and F1 vary across thresholds, using UNOSAT-labeled building footprints from Gaza and Ukraine(click for interactive version).

1-month inference window (interactive)

ThresholdPrecisionRecallF1Use case
T > 239.2%97.6%55.9%Maximum sensitivity / screening. Useful when missing damage is more costly than false alarms.
T > 3.370.0%82.4%75.7%Balanced (default). Good tradeoff between precision and recall across most cities.
T > 477.7%62.8%69.5%High confidence. Fewer false positives, but misses less severe damage.
T > 582.4%31.9%46.0%Very high confidence. Detects only the most severe damage.

Precision-recall considerations

Precision is the fraction of buildings flagged as damaged that are actually damaged (i.e. how trustworthy is a positive prediction). Recall is the fraction of actually damaged buildings that the algorithm successfully detects (i.e. how much damage does it miss). Raising the threshold increases precision but decreases recall; lowering it does the opposite.

Precision and recall vary significantly across cities, largely driven by the proportion of damaged buildings (class imbalance). In cities with low damage rates, even a highly discriminative model produces low precision because the vast majority of buildings are undamaged. AUC is the best metric for comparing algorithm performance across cities as it is insensitive to class imbalance.

IMPORTANT: This algorithm measures significant changes in urban environments following the onset of conflict. It remains an assumption that this change corresponds to damage.

  • Damage counts and humanitarian response: use the default threshold (T > 3.3). The algorithm tends toward higher recall than precision, meaning it is more likely to over-count than under-count.
  • High-precision applications (e.g. legal evidence, journalism): raise the threshold to T > 4 or higher to minimize false positives.
  • Rapid response / early warning: lower the threshold to T > 2 for maximum coverage. The algorithm works with as few as one post-event image, with approximately a 6% reduction in AUC compared to a 1-month window.
  • Aggregate statistics: even when building-level precision is moderate, aggregate damage counts at the neighborhood or city level are robust due to error cancellation.

Validation Data

Accuracy assessments are carried out using an original dataset of 700,500 annotated building footprints, spanning 12 cities in four different countries. This dataset was compiled by spatially joining damage annotations from the United Nations Satellite Centre (UNOSAT) with data on building footprints. The dataset can be downloaded here.

Benchmark Dataset

CountryCityFootprintsPercent DamagedAnnotation Date
PalestineGaza22872857.49%2024-05-03
UkraineRubizhne889933.67%2022-07-09
UkraineMariupol1844631.42%2022-05-12
UkraineSievierodonetsk597024.32%2022-07-27
UkraineHostomel417514.04%2022-03-31
UkraineIrpin724211.28%2022-03-31
UkraineAvdiivka72628.7%2022-09-20
UkraineLysychansk202467.42%2022-09-21
UkraineMakariv35144.01%2022-03-16
UkraineChernihiv299293.25%2022-03-22
UkraineShchastia12931.93%2022-07-07
UkraineBucha57391.6%2022-03-31
UkraineKharkiv1079760.85%2022-06-15
UkraineTrostianets89130.72%2022-03-25
UkraineOkhtyrka159050.4%2022-03-25
UkraineMykolaiv604670.34%2022-07-21
UkraineMelitopol323730.23%2022-08-02
UkraineKramatorsk218800.22%2022-07-24
UkraineKremenchuk274970.11%2022-06-29
UkraineSumy282650.08%2022-07-08
SyriaRaqqa2468944.67%2017-10-21
SyriaAleppo6587026.65%2016-09-18
IraqMosul13779411.51%2017-08-04
AllAll87307212.39%

Building footprint data is sourced from the Microsoft Building Footprints dataset, which consists of over 1 billion building footprints derived from high resolution satellite imagery around the world. A building footprint is labeled as damaged if it intersects with a UNOSAT damage annotation point, and labeled undamaged otherwise. UNOSAT annotations are generated manually on the basis of high resolution optical satellite imagery.

Accuracy Assessment

The table below reports the accuracy statistics for the PWTT algorithm in 12 cities, assessed using the benchmark dataset above.

CountryCityAUCAccuracyF1PrecisionRecallN
PalestineGaza83.3275.4178.270.4287.91228728
UkraineKremenchuk92.5698.822.732.682.7727497
UkraineBucha90.1998.1971.998.2756.685739
UkraineOkhtyrka89.2898.953.1476.2840.7715905
UkraineKramatorsk88.2497.167.9211.995.9121880
UkraineTrostianets86.6398.4467.680.5858.238913
UkraineChernihiv86.6194.4748.2953.4844.0329929
UkraineHostomel84.9980.4468.1163.8772.954175
UkraineIrpin83.8182.9356.7552.8361.37242
UkraineKharkiv83.7897.2429.3730.4428.36107976
UkraineMykolaiv83.2898.1821.6118.7125.5760467
UkraineMakariv82.8790.3740.6934.8848.823514
UkraineLysychansk77.9182.5950.1447.3853.2420246
UkraineRubizhne77.8171.3866.4262.1471.338899
UkraineMariupol73.8566.1771.0860.7885.5718446
UkraineShchastia73.3996.6938.3147.1232.281293
UkraineSumy69.6399.514.264.364.1628265
UkraineSievierodonetsk69.1859.362.5350.7181.545970
UkraineMelitopol66.8496.772.671.785.3332373
UkraineAvdiivka66.5160.6439.828.0568.57262
SyriaRaqqa75.666.2673.8763.2188.8724689
SyriaAleppo71.7661.4958.8246.2880.6765870
IraqMosul74.9181.1641.1835.1849.64137794
AllAll84.1776.458.248.0473.82873072

Receiver-Operating Characteristic (ROC) curves for each country are also provided below.

Citation

@article{ballinger2025pwtt,
  title={Open access battle damage detection via Pixel-Wise T-Test on Sentinel-1 imagery},
  author={Ballinger, Ollie},
  journal={Remote Sensing of Environment},
  volume={331},
  pages={115025},
  year={2025},
  publisher={Elsevier},
  doi={10.1016/j.rse.2025.115025}
}

The diagram below displays the full PWTT process: