Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RADL — Rugby Action Description Language

An open, versioned, per-action record of rugby union matches — the thing cricket has in Cricsheet and football has in StatsBomb open-data, and rugby has nowhere.

One row per action, the same columns whatever the source. A schema strict enough that a corpus built on it stays readable by someone who did not write the producer, and a licence that lets them use it: MIT for the code, CC BY 4.0 for the data, with no requirement to display anyone's logo.

Status: v0.2.2 draft. One producer, one converter, and no real match traced yet. Everything in data/ is synthetic. That is the gap this exists to close, and it is the honest reason to look at the schema now rather than later — the conventions are still cheap to change.

What rugby is missing

football cricket rugby union
open per-action corpus StatsBomb open-data Cricsheet, 15,000+ matches nothing
flat action language SPADL ball-by-ball, by construction nothing
open packages many cricketdata rugbypy — match/player aggregates, not actions

Rugby data exists, but it stops at aggregates or sits behind a commercial feed. There is no free file you can open that says this carry started here, ended there, and gained nine metres.

Use

pip install -e .
radl validate data/events/synthetic-001.json     # conformance, exit code only with -q
radl schema > radl.schema.json                   # JSON Schema, for non-Python readers
import radl

actions = radl.read_match("data/events/synthetic-001.json")
actions[actions.action_type == "carry"].metres_gained.sum()

radl.score(actions)                # {'ENG': 12, 'WAL': 20}
radl.left_to_right(actions)        # SPADL's per-team orientation

read_match returns a pandas DataFrame with the 23 columns in docs/spec-v0.2.md §1. Every vocabulary is closed and enforced: a value outside one raises, naming the row it came from, rather than entering a corpus where it would read as part of the standard.

The CLI and the JSON Schema exist so RADL is checkable from R, JS, or a CI job — most rugby analytics is not written in Python, and a standard only reachable through import pandas is not one.

What's here

path
docs/spec-v0.2.md the schema and the pitch coordinate convention, in enough detail to write a converter from
docs/radl-v0.2.2.schema.json the same thing machine-readable, generated from config.py
docs/governance.md who decides a version, what counts as breaking
docs/rfc-001-tackle.md the open question: rugby's central contest has no row
docs/opta-superscout-mapping.md how the vocabulary lines up against a commercial rugby feed
radl/config.py the closed vocabularies and pitch constants
radl/phase_trace.py the one converter: phase-trace's raw export → an action frame
radl/frame.py the two operations on a frame: left_to_right, score
data/ the seed corpus, StatsBomb layout, currently one synthetic match
tools/ the generator for that synthetic match; not part of the package

Where the schema came from

RADL borrows its shape from three football projects and says, throughout, which one each decision came from. It takes SPADL's middle idea — one row per on-the-ball action, same columns whatever the source — because that is the part which is not sport-specific, and pairs it with StatsBomb's corpus layout. The spec cites each borrowing at the point it is used.

Two places it deliberately goes further than its sources. SPADL's specification is its documentation and config.py; RADL's is a versioned document with a changelog, because a corpus outlives the code that read it. And SPADL does not validate its vocabularies on ingest; RADL refuses the row.

The one converter

phase-trace is the only producer of RADL-shaped rugby data today, so it is the only converter. There is no deserializer layer for providers that do not exist. It reads the match.json written by phase-trace's raw exporter as plain JSON and never imports phase-trace, treating that file as a stable interface.

phase-trace's other export, the momentum-chart JSON, is not a valid input. Its rows bundle a whole possession and carry no coordinates, so it cannot produce one row per action.

Not here, on purpose

No valuation framework: no VAEP, no xT equivalent, no action weights. There is no real corpus to fit or validate one against yet, and a published valuation nobody can check is worse than none. See spec §8.

No tackle. Rugby's central contest is not in the schema, which is the largest honest gap and the reason result is null on nearly every carry. RFC 001 is the open proposal, not a plan.

Develop

pip install -e .[dev]
pytest

Regenerating the synthetic seed needs a phase-trace checkout:

python tools/make_synthetic_match.py ../match-momentum

Licence

Code: MIT (LICENSE). Data: CC BY 4.0 (LICENSE-DATA).

About

Open, versioned, per-action data standard for rugby union — one row per action, closed vocabularies, strict validation. MIT code, CC BY 4.0 data. What Cricsheet is to cricket and SPADL/StatsBomb to football.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages