Diffusion and flow matching

Three-space docking initialization and reverse diffusion step

HardRaw PyTorchAbout 30 min1 public example plus private tests

DiffDock

Write and run your solution Sign in

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

Your task

Compute one reverse-diffusion step for ligand translation, rotation and torsions, returning the schedule values, update vectors and updated rigid coordinates. Also construct initial_positions from the independently supplied initial conformer, rotation and translation noise.

Function signature

pose_reverse_diffusion_step(
    activations: dict,
    masks: dict,
    structure: dict,
    mode: str = 'sde',
    no_final_step_noise: bool = False,
    suppress_noise: bool = False,
) -> dict[str, torch.Tensor]

Worked example

A decreasing-time translation step

Consider only the translation-update stage of a movable ligand with valid atoms. Set translation sigma_min=1, sigma_max=2, t=1, dt=0.25, translation_score=(1,0,0) and mode="ode". Then

\sigma=2,\qquad g^2=2\cdot2^2\log2=8\log2,\qquad t_{\mathrm{next}}=0.75.

The translation increment is

\delta=\tfrac12\cdot8\log2\cdot0.25\,(1,0,0)=(\log2,0,0)\approx(0.693147,0,0).

With zero rotation increment, every valid current point shifts by this vector. Noise is ignored in ODE mode; SDE with suppressed noise would use twice this drift for the same stage inputs.

Parameters

ParameterShape and meaning
activationsdictSupplied intermediate tensors.
masksdictSupplied masks. Each field below defines what True includes or permits.
structuredictFields supplied together in this dictionary.
modestrDefault 'sde'Choose "sde" for the stochastic reverse step or "ode" for the deterministic probability-flow update. The score drift factors differ; ODE has no reverse-step noise.
no_final_step_noiseboolDefault FalseSuppress random noise on the terminal step when True.
suppress_noiseboolDefault FalseSuppress supplied reverse-step noise when True.

Return

dict[str, torch.Tensor]

Return exactly the named fields applicable to this operation.

Required behavior

  • Space order is translation,rotation,torsion. t,dt [B,3] satisfy 0\le \mathrm{dt}\le t\le 1; time decreases to t_{\mathrm{next}}=t-\mathrm{dt}. sigma_min,sigma_max [3] satisfy 0<\operatorname{min}<\operatorname{max}.
  • For space j, \sigma_{j}=\mathrm{min\_j}^{1-t_{j}}\cdot \mathrm{max\_j}^{t_{j}}.
  • Use ORIGINAL DiffDock v1.0 coefficients g^{2}=\sigma^{2}\cdot \operatorname{log}(\operatorname{max}/\operatorname{min})\cdot (2,4,2); the rotation factor 4 is intentional and corresponds to its heat kernel exp[-l(l+1)\cdot \sigma^{2}], not the maintained code's changed convention.
  • translation_score,rotation_score [B,3] and torsion_score [B,K] are already physically normalized scores, not raw neural-head outputs.
  • In mode='sde' (default), \delta_{j}=g_{j}^{2}\cdot \mathrm{dt\_j}\cdot \mathrm{score\_j}+g_{j}\cdot \sqrt{\mathrm{dt\_j}}\cdot \mathrm{noise\_j}. 'ode' uses \delta_{j}=0.5\cdot g_{j}^{2}\cdot \mathrm{dt\_j}\cdot \mathrm{score\_j} and ignores all noise; suppress_noise=True in SDE instead drops only noise, not the factor 1 drift.
  • no_final_step_noise=False by default; True suppresses stochastic terms for supplied last_step[B]=True. All noise tensors have the corresponding score shape. At \mathrm{dt\_j}=0 ignore that space's score/noise payloads and return zero increment, without evaluating an unsafe sqrt derivative.
  • Torsion increments are real radians, not wrapped here; directed_bond_torsion_rotation applies them separately. Let c be the mean of valid current positions [B,N,3]. \operatorname{Exp}(\delta_{\mathrm{rotation}}) is a GLOBAL active rotation, so:
  • \mathrm{rigid\_positions}=(\mathrm{positions}-c)\mathbin{@}\operatorname{Exp}(\delta_{\mathrm{rotation}})^{\top}+c+\delta_{\mathrm{translation}}. It is not the local/body right-composition convention of lie_euler.
  • Return the increments and this intermediate rigid pose; a separate torsion action and equal-weight Kabsch complete DiffDock's conformer update.
  • For initialization, initial_conformer [B,N,3] is already torsion-randomized by the separate angular/rotation exercises.
  • \mathrm{initial\_positions}=(\mathrm{initial\_conformer}-\mathrm{its\_valid\_mean})\mathbin{@}\mathrm{initial\_rotation}^{\top}+\sigma_{\mathrm{max}}[0]\cdot \mathrm{initial\_translation\_noise}+\mathrm{reference\_center}.
  • initial_rotation [B,3,3] is a supplied proper rotation (Haar for the original prior), initial_translation_noise and reference_center are [B,3]; original centered-receptor coordinates use \mathrm{reference\_center}=0.
  • Masks: valid_mask [B,N] observed atoms; diffuse_mask [B] whole movable ligand; torsion_mask [B,K] active torsions. Fixed ligands retain their current and initial coordinates, with zero increments and identity rotation_update. An example without valid atoms is inactive; invalid atoms are zero.
  • Inactive scores/noises and initialization transforms may be nonfinite and are ignored. All active payloads and schedule parameters must be finite. B\ge 1,N\ge 0,K\ge 0; no chemistry parsing or denoiser is inside this function.
  • Rodrigues uses a degree-six Taylor branch at squared \mathrm{angle}<10^{-6}, with no re-orthogonalization or angular clipping. keys are mode,suppress_noise,no_final_step_noise; unsupported mode, invalid scales or invalid time bounds raise ValueError.

Why this matters

The three spaces have independent schedules and different diffusion coefficients; the selected SDE or ODE determines how score drift and supplied noise enter.

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 pose_reverse_diffusion_step(
    activations: dict,
    masks: dict,
    structure: dict,
    mode: str = 'sde',
    no_final_step_noise: bool = False,
    suppress_noise: bool = False,
) -> dict[str, torch.Tensor]:
    """Return dict[str, torch.Tensor]:
    
    sigma: (B, 3).
    g: (B, 3).
    t_next: (B, 3).
    translation_update: (B, 3).
    rotation_vector_update: (B, 3).
    torsion_update: (B, K).
    rotation_update: (B, 3, 3).
    rigid_positions: (B, N, 3).
    initial_positions: (B, N, 3)."""
    # Implement the operation. Inputs and test setup are supplied by BioTorch.
    raise NotImplementedError("Implement pose_reverse_diffusion_step")

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.