Source code for the paper ELASTIC: Trajectory-Based Synchronization of Event and Tracking Data in Soccer by Kim et al., CIKM 2026.
ELASTIC (Event-Location-AgnoSTIC synchronizer) is an algorithm for synchronizing event and tracking data in soccer. Unlike prior synchronizers such as ETSY (Van Roy et al., 2023) and DataBallPy (Oonk et al., 2025), it does not rely on human-annotated event locations, which are themselves prone to spatial errors. Instead, it infers the start and end timestamps of each event solely from player and ball trajectories.
To this end, ELASTIC first extracts a sparse set of candidate frames where a ball touch is physically plausible, using motion features such as ball acceleration, player-ball distance, and kick distance. It then aligns the event sequence with the candidate-frame sequence using the Needleman-Wunsch algorithm (Needleman & Wunsch, 1970), preserving the order of events.
As a visual result, the following video compares the raw event timestamps/locations (black "x") and the synchronized event timestamps/locations (orange "★"), alongside player and ball trajectories.
First, clone this repository and install the packages listed in requirements.txt.
Next, download the Sportec Open DFL Dataset (Bassek et al., 2025) and place its XML files under data/sportec/metadata, data/sportec/event, and data/sportec/tracking. See the Data Preparation part of tutorial.ipynb for details.
Then, follow tutorial.ipynb, which applies ELASTIC to that dataset. In particular, the last part of the notebook lets you visualize the three steps of ELASTIC for a given window as follows:
ELASTIC first narrows the search space by keeping only the frames where a ball touch is physically plausible. In the figure below, each colored curve is the distance between the ball and one player in the window. The black dashed lines are the extracted candidate frames, and the red solid lines are the synchronized events, labeled P for a pass and C for a ball control.
Within each in-play segment, ELASTIC scores every (event, candidate frame) pair using features such as ball acceleration, player-ball distance, and kick distance. In the figure below, each cell is the pairwise score between an event (row) and a candidate frame (column), with a darker color indicating a better match.
Finally, the Needleman-Wunsch algorithm picks the highest-scoring assignment that keeps the events in chronological order. In the figure below, each cell of the dynamic programming (DP) table holds the cumulative score and the move that produced it. The optimal path traced back from the bottom-right corner is highlighted in yellow, and the frame IDs it selects are marked in red.
The scripts under experiments/ reproduce the experimental results on the three re-annotated Sportec matches (J03WMX, J03WN1, J03WPY). Run them from the repository root.
Reproducing the experiments needs two inputs:
- Re-annotated event data already contained in
benchmark/of this repository. - Tracking data that can be downloaded from this link, following the Data Preparation part of
tutorial.ipynb. In particular, the tracking XML files should be placed underdata/sportec/tracking.
During the re-annotation process, we removed the false-positive events and inserted the missing ones, so that the evaluation can focus solely on the synchronization performance. The corrected events, with only their timestamps left unsynchronized, are placed in benchmark/unsynced/ and used as the input to the synchronizers.
benchmark/gt/ then holds the same events under the same indexing, with our annotated timestamps attached: frame_id for the moment the event occurs and receive_frame_id for the moment the ball is received.
benchmark.py is the script that built these two files: it reads the per-annotator labels, measures the inter-annotator reliability reported in Table 1, and takes the median of the three annotations as the ground truth. We do not publish the per-annotator labels, so this script is included for reference only.
python experiments/benchmark.pyevaluate.py synchronizes the unsynced events, compares the result against the ground truth, and reports the accuracy metrics in Table 2. It takes the following arguments:
--methodselects the synchronizer amongetsy,biermann,databallpy,elastic_greedy, andelastic_nw.--savecaches the synchronized events tobenchmark/synced/{method}/{match_id}.parquet.--loadreads that cache back instead of running the synchronizer again.databallpyalways does so, since its outputs come from the external DataBallPy package.
python experiments/evaluate.py --method elastic_nw [--save | --load]cand_sweep.py varies the candidate frame detection conditions and thresholds, and reports the resulting candidate frame coverage and the synchronization accuracy in Table 3.
python experiments/cand_sweep.pycoeff_sweep.py varies the weights of per-feature scores (Table 4), and score_sweep.py varies the clipping bounds of the scoring functions and the alignment penalties (Table 5).
python experiments/coeff_sweep.py
python experiments/score_sweep.pyEvery sweep writes one row per (config, match, event category) to experiments/results/{script}_{timestamp}.csv.
If you use this code or the benchmark event data in your research, please consider citing our paper:
@inproceedings{kim2026elastic,
author = {Hyunsung Kim and
Hoyoung Choi and
Kunhee Lee and
Sangwoo Seo and
Tom Boomstra and
Jinsung Yoon and
Chanyoung Park},
title = {{ELASTIC}: Trajectory-Based Synchronization of Event and Tracking Data in Soccer},
booktitle = {Proceedings of the 35th {ACM} International Conference on Information and Knowledge Management},
year = {2026},
doi = {10.1145/3799682.3841035},
}The source code is released under the MPL-2.0 license.
The event data under benchmark/ is derived from the Sportec Open DFL Dataset (Bassek et al., 2025), which is released under CC BY 4.0 with the authorization of the Deutsche Fussball Liga (DFL). We redistribute it under the same license, with the modifications described above (corrected event records and re-annotated timestamps). Please cite the original dataset alongside our paper:
@article{bassek2025integrated,
author = {Manuel Bassek and
Robert Rein and
Hendrik Weber and
Daniel Memmert},
title = {An integrated dataset of spatiotemporal and event data in elite soccer},
journal = {Scientific Data},
volume = {12},
number = {195},
year = {2025},
doi = {10.1038/s41597-025-04505-y},
}


