Reference

The algorithm

Every block contributes points by applying its formula to the dataset’s observed values and a published weight. Block totals are mapped to tiers via fixed thresholds; the overall total — raw points × a seasons-adjusted multiplier — gets its own tier.

The general weight

The framework computes a weighting point WP for each input variable as the product of its relevance factor (RF, an integer 1–5 published in the paper’s Tables 1 and 2) and a function of how the variable was actually measured: number of observations, layers, replications, depth, distance from the meteorological station, and elevation difference.

WP  =  RFf(nob,no,d,rep,xyz)\text{WP} \;=\; \text{RF}\cdot f(n_{ob},\, n_o,\, d,\, rep,\, xyz)

For the weather block specifically, two penalties apply when the nearest station is far from the field. A distance penalty reduces the weight proportionally past an optimal cut-off (1 km for precipitation, 5 km for temperature and humidity, 10 km for wind, 20 km for radiation). An altitude penalty kicks in once the station and the field differ by more than 30 m:

WPz  =  max ⁣(RF1ΔZ30,  0)\text{WP}_z \;=\; \max\!\Bigl(\text{RF} - 1\cdot\tfrac{\Delta Z}{30},\; 0\Bigr)

Per-item formulas

Most blocks just sum observations × weight: management, phenology, previous crop, site, and the “observation” state variables (lodging, pests, damages, weeds) work this way.

Three blocks have richer formulas. Initial values rewards both depth and observation count:

p  =  min(d,1.25)    min ⁣(n2,1.2)    wp \;=\; \min(d,\,1.25)\;\cdot\;\min\!\Bigl(\tfrac{n}{2},\,1.2\Bigr)\;\cdot\;w

Soil items split into two methods by depth scope. Full-profile measurements (texture, bulk density, water-retention curve, hydraulic-conductivity curve, field capacity, wilting point) use Method 1 with depth normalised by 1.5 m:

p  =  min ⁣(d1.5,1.25)    min ⁣(L3,1.2)    wp \;=\; \min\!\Bigl(\tfrac{d}{1.5},\,1.25\Bigr)\;\cdot\;\min\!\Bigl(\tfrac{L}{3},\,1.2\Bigr)\;\cdot\;w

Shallow-soil measurements (organic carbon, organic nitrogen, pH) use Method 2 with depth normalised by 0.3 m:

p  =  min ⁣(d0.3,1.25)    min(L,1.2)    wp \;=\; \min\!\Bigl(\tfrac{d}{0.3},\,1.25\Bigr)\;\cdot\;\min(L,\,1.2)\;\cdot\;w

State variables have one bespoke formula per crop / soil / flux item — twenty-three in total. They share a family resemblance — clipped-min terms for layers, observations, and replicates, multiplied by the weight — but each one’s denominator is chosen for the typical measurement frequency of that variable. See backend/engine/scoring.py for the full set.

Tier thresholds

Block totals are cut into tiers at fixed values. The thresholds below are what the shipped 2014 binary uses and what the web port reproduces — see the discrepancy note below the table.

Block Platinum ≥ Gold ≥ Silver ≥ Copper ≥
Management 24 20 17 15
Phenology 13 11 8 5
Previous crop 17 15 12 9
Initial values 10 7 4 1
Soil 28 20 12 5
Site / topography 12 11 8 5
Weather 33 30 22 14
State variables 40 25 10 6
Overall 180 145 90 60

The seasons multiplier

Treatments, sites, and seasons aren’t a tier-classified block of their own — they instead produce a single sum that multiplies the dataset’s raw block total to give an adjusted total. More seasons / treatments increases the multiplier (up to a cap of 1.3); a sparser experiment decreases it. Paper Table 3:

mult  =  1+(SW71)0.1,SW  =  min(w,28)\text{mult} \;=\; 1 + \Bigl(\tfrac{SW}{7} - 1\Bigr)\cdot 0.1, \qquad SW \;=\; \min(\sum w, \, 28)

Discrepancies between paper and shipped binary

The published paper and the shipped 2014 Windows binary disagree in nine places. The web port is faithful to the shipped binary by default (version key 2015-kersebaum in backend/engine/weights.yaml). Listed here so anyone reading both knows which is which:

A paper-faithful weights version is now shipped as 2015-kersebaum-paper. The Müncheberg example shifts from Gold (binary defaults) to Platinum under it — ≈174.4 adjusted total, still comfortably above the paper’s 173 threshold even after dropping soilTemp (−2 raw). To use the paper variant, pick it from the /score page’s weights-version dropdown, or pass weightsVersion: "2015-kersebaum-paper" in the POST /api/score body.

Importing AgMIP / ICASA ACE files

DataRanking accepts uploads in the AgMIP ACE crop-experiment format directly — both raw JSON (.json) and gzipped (.aceb). On the /score page the Upload ACE button does the conversion server-side via POST /api/score/ace and shows you the converted DataRanking dataset alongside the score — you can edit and re-score without re-uploading.

Multi-experiment. ACE files routinely carry multiple experiments sharing the same weather and soil records. DataRanking scores each experiment separately and returns a list of results. The web UI currently shows only the first; a multi-experiment switcher is on the roadmap.

Best-effort mapping. ACE fields map onto DataRanking sub-items where the alignment is obvious; absent data is silently skipped (block-tier-average classification is the right mode for partial inputs — an absent previousCrop doesn’t score zero, it’s just not counted toward the tier average). High-level mapping:

The data/examples/ace/ directory in the repo ships three BSD-3 demonstration files from the AgMIP json-translation-samples repository — maize Machakos, hard-spring-cereal wheat, rice paddy — that you can upload to see the importer in action.

Two classification methods

Paper p. 404 documents two ways to derive an overall tier from the eight per-block tiers. DataRanking computes both on every score and the /score page displays them side by side — when they disagree, that’s itself informative about how balanced the dataset is.

  1. Total sum (primary — shown as the big tier card on the result page). Block points add up, the seasons multiplier is applied, and the result is bucketed via the overall ladder shown above. This is what the shipped 2014 binary uses.
  2. Block-tier average (the “second-opinion” callout). Per-block tiers are mapped to integers (NA = 0, Copper = 1, Silver = 2, Gold = 3, Platinum = 4), averaged across all eight blocks, then rounded to a final tier via round half up: ≥ 3.5 → Platinum, ≥ 2.5 → Gold, ≥ 1.5 → Silver, ≥ 0.5 → Copper, otherwise NA. The seasons multiplier does not apply here — it’s an average over per-block classifications, not over raw points.

Worked example — Müncheberg under the binary defaults scores Gold by both methods: total sum 176.58, average (4+3+0+3+4+4+3+3)/8 = 3.0 → Gold. Under the paper version it scores Platinum (174.41) by total sum but Gold (3.0) by average — the per-block tiers are unchanged but the overall ladder differs. The disagreement honestly reflects that Müncheberg has three Platinum blocks pulling the total score up while the previousCrop NA pulls the average down.

2026-modern — the v2 extension experimental

2026-modern extends the 2015 framework with three new content blocks, a cross-cutting axis, a calibration-level mapping, and a tier-aware uncertainty band. Critically, it preserves the 2015 verdict: the original 8 blocks are scored byte-identically to 2015-kersebaum, so a dataset's tier_2015 under 2026-modern matches its overallTier under the canonical version. The v2 work adds a parallel tier_2026_composite reported alongside.

New blocks

Remote sensing
Six criteria covering spatial resolution, revisit cadence, cloud-mask quality, ground-truth pairing, variables retrieved (LAI / biomass / canopy), and retrieval-algorithm transparency. Anchored to Levitan, Char & Tucker (2019) and Boote et al. (2016).
In-situ sensor / IoT
Six criteria covering temporal resolution, sensor calibration, gap-filling method, variables captured (soil moisture / soil temperature / ET), spatial sampling, and data accessibility. Anchored to Wallach et al. (2021) and Janssen et al. (2017).
Genetic / cultivar
Four criteria covering cultivar identity (pedigree / SNP accession / name only), canonical model coefficients, genetic data depth, and phenotypic-trial linkage. Anchored to Hoogenboom et al. (2019) and Boote et al. (2016); two sub-criteria still need final citation anchors.

FAIR cross-cutting axis

Every block (original 8 + new 3) carries a FAIR sub-axis scored across Findability, Accessibility, Interoperability, and Reusability (Wilkinson et al. 2016). The block's FAIR tier produces a multiplier (Platinum=1.00, Gold=0.85, Silver=0.70, Copper=0.50, NA=0.50) applied to its raw contribution before the composite total is summed.

Wallach 2024 supportable-groups mapping

Each score also reports which Wallach 2024 calibration groups the dataset can support. Wallach et al. (2024) — the AgMIP Phase IV protocol — defines an 8-step procedure that calibrates variables in groups (phenology, biomass, final values, soil-water, soil-N) rather than a single “level” taxonomy. The dataset-side question the protocol poses is therefore which groups the dataset supports, not which numeric level it has reached.

For each group, the engine evaluates the relevant per-block tiers and checks whether the underlying sub-criteria are populated. The result is a row of supports / does-not-support flags surfaced alongside the tier verdict on /score.

Uncertainty band

Every v2 score includes a tier-aware uncertainty band: 10,000-sample Monte-Carlo resampling of per-block tier verdicts under a Dirichlet prior (concentration 0.85). The result is a p05 / p50 / p95 band around both tier_2015 and tier_2026_composite, so users see where the verdict is robust and where it sits on a tier boundary.

Snapshot URLs and citability

Every v2 score is anchored to an immutable URL of the form /score/{id}/v/{hash} where hash is the SHA256 over (payload ‖ weights_version). Identical inputs always produce the same URL; any revision yields a new one. Major 2026-modern releases are also deposited to Zenodo for a stable DOI.

Full per-criterion citation anchors live in the repo at docs/v2/lit-review/; per-criterion weights and tier-cut thresholds live in backend/engine/weights.yaml under the "2026-modern" key.