Geometry and structural losses

Local distance difference test (lDDT)

MediumRaw PyTorchAbout 20 min2 public examples plus private tests

AlphaFold2OpenFoldAlphaFold3Boltz-2Protenix

Write and run your solution Sign in

Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.

Your task

Measure agreement between predicted and target local distances. Use target-defined neighborhoods, score strict error thresholds, and return per-atom and per-structure lDDT scores.

Function signature

lddt(
    pred: torch.Tensor,
    target: torch.Tensor,
    atom_mask: torch.Tensor,
    no_neighbor_score: float = 0.0,
    thresholds: list[float] | tuple[float, ...] = [0.5, 1.0, 2.0, 4.0],
    cutoff: float = 15.0,
) -> dict[str, torch.Tensor]

Worked example

A distance error of exactly one

Take one batch with target=[[0,0,0],[3,0,0]], pred=[[0,0,0],[4,0,0]], atom_mask=[True,True], cutoff=15 and thresholds=[0.5,1,2,4]. Each atom has one eligible neighbor. The distance error is |4−3|=1: it fails 0.5 and 1 but passes 2 and 4. Thus per_atom=[[0.5,0.5]], neighbor_count=[[1,1]] and global_score=[0.5].

Parameters

ParameterShape and meaning
predtorch.Tensor[B, A, 3]Predicted atom coordinates.
targettorch.Tensor[B, A, 3]Reference atom coordinates used to define local neighborhoods.
atom_masktorch.Tensor[B, A]True means valid atom.
no_neighbor_scorefloatDefault 0.0Specified score for a valid atom with no valid neighbors; invalid atoms use zero.
thresholdslist[float] | tuple[float, ...]Default [0.5, 1.0, 2.0, 4.0]Positive distance-error thresholds. Each neighbor contributes the fraction of thresholds its absolute distance error is strictly below.
cutofffloatDefault 15.0Positive target-distance neighborhood radius; self-pairs are excluded and the radius test is strict.

Return

dict[str, torch.Tensor]

Return exactly the named fields applicable to this operation.

Required behavior

  • pred,target [B,A,3] are finite coordinates and atom_mask [B,A] is True for valid atoms; B\ge 1 and A may be zero. Use exact Euclidean distances with no \epsilon.
  • An ordered pair (i,j) is eligible iff i\ne j, both atoms are valid, and TARGET distance is strictly less than config \mathrm{cutoff}>0 (default 15.0 angstrom).
  • For each eligible pair, average indicators \left|d_{\mathrm{pred}}-d_{\mathrm{target}}\right|<\tau over the nonempty positive thresholds sequence (default (0.5,1.0,2.0,4.0) angstrom); all threshold comparisons are STRICT. neighbor_count [B,A] counts eligible partners as int64.
  • per_atom is the exact mean over each atom's eligible partners; a valid atom with no neighbors gets config no_neighbor_score (0.0 by default, alternatively 1.0). Invalid atoms always get zero.
  • global_score is the exact mean over ALL eligible ORDERED pairs, not an unweighted atom-score mean; with no eligible pairs it returns no_neighbor_score. No smoothing, \epsilon pseudocounts or learned confidence head are included. The entire hard metric is nondifferentiable; do not attach a surrogate gradient.

Why this matters

lDDT compares how well nearby target pairs preserve their distances, so it does not require aligning the two structures first.

Starter code

You write the body of this function in the BioTorch workspace. Your code runs in an isolated PyTorch sandbox; Run checks the public examples and Submit grades the full test suite, including gradients.

import torch


def lddt(
    pred: torch.Tensor,  # (B, A, 3)
    target: torch.Tensor,  # (B, A, 3)
    atom_mask: torch.Tensor,  # (B, A)
    no_neighbor_score: float = 0.0,
    thresholds: list[float] | tuple[float, ...] = [0.5, 1.0, 2.0, 4.0],
    cutoff: float = 15.0,
) -> dict[str, torch.Tensor]:
    """Return dict[str, torch.Tensor]:
    
    per_atom: (B, A).
    global_score: (B,).
    neighbor_count: (B, A)."""
    # Implement the operation. Inputs and test setup are supplied by BioTorch.
    raise NotImplementedError("Implement lddt")

Ready to implement it?

3 progressive hints, a solution walkthrough, and grading that checks values, shapes and gradients are waiting in the workspace.

Write and run your solution Sign in

Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.

Sources and further reading

A primitive exercise, not an end-to-end reproduction of the named models. No affiliation or endorsement is implied.