Skip to content

Latest commit

 

History

History
79 lines (59 loc) · 3.02 KB

File metadata and controls

79 lines (59 loc) · 3.02 KB

Steering an OpenFold3 run

A single protein–ligand prediction, run twice: once plain, once with chemical steering. Two files: run_of3_steered.py and query_protein_ligand.json.

What you need

  • OpenFold3 installed in the same environment as foldsteer (pip install -e . from the OF3 checkout, then pip install -e .. here);
  • model parameters under $OPENFOLD_CACHE (setup_openfold --non-interactive);
  • a GPU.

The query runs in single-sequence mode — no MSA server, no template cache, no data root — so nothing else has to be staged. It is PDB 9EHA: a 109-residue SH2 domain plus phosphotyrosine, which has a chiral centre, an aromatic ring and a phosphate, i.e. all three things steering restrains.

Run it

cd examples

# baseline
python run_of3_steered.py --no-steer -- \
    --query-json query_protein_ligand.json \
    --output-dir /tmp/fs_base --num-diffusion-samples 1 --num-model-seeds 1

# steered (guidance only)
python run_of3_steered.py --steer -- \
    --query-json query_protein_ligand.json \
    --output-dir /tmp/fs_steer --num-diffusion-samples 1 --num-model-seeds 1

Everything after -- goes to run_openfold predict unchanged, so the two arms take identical OpenFold3 arguments and only steering differs. Expect a few minutes on one GPU.

Confirming steering actually fired

Steering that finds no ligand is indistinguishable from steering that works, looked at from the outside — so check the counters the script prints at the end:

foldsteer: 1 ligand chain(s); {'n_atoms': 918, 'n_bounds': 231, 'n_chiral': 1, ...}
[foldsteer] targets=1 ligand_chains=1 guided_steps=200

ligand_chains=0 means the chemistry never reached the engine and the run was unsteered; the script warns when that happens. Use --stats-json out.json to keep the per-target breakdown.

Only works in-process

patch_sample_diffusion_class patches the SampleDiffusion class, and Lightning builds the model inside the runner. So the OF3 CLI has to be invoked in the same interpreter — which is what this script does, rather than shelling out to run_openfold. A subprocess would run unsteered, quietly.

Feynman-Kac steering

Guidance only is the default: it is the cheaper half, carries most of the benefit, and leaves the sample count alone. --fk turns on resampling as well, but it reuses OF3's rollout-sample axis as the particle axis, so --num-diffusion-samples must be a multiple of --num-particles (default 3) and each particle group collapses to one survivor — fewer structures come back than were sampled, and per-sample compute goes up.

python run_of3_steered.py --steer --fk --num-particles 3 -- \
    --query-json query_protein_ligand.json \
    --output-dir /tmp/fs_fk --num-diffusion-samples 3 --num-model-seeds 1

Your own targets

Any OF3 query JSON works — see examples/example_inference_inputs/ in the OpenFold3 repo for MSAs, templates, CCD-code ligands and multi-chain complexes. Steering restrains non-polymer chemistry only, so a target with no ligand chain runs unsteered by design.