春江暮客

春江暮客的个人学习分享网站

RFOptimization: A Practical Guide to Protein Design Refinement

2026-10-08 Technology
RFOptimization: A Practical Guide to Protein Design Refinement

A designed protein can look plausible and still fail a structure-based filter. RFOptimization (RFO) starts with an existing molecular complex and searches for sequence changes that improve its predicted properties. This guide explains the refinement loop, shows how to set up a small trial, and provides a Python checker for completed cycles.

Sources were checked on October 8, 2026. The method comes from Zhang and colleagues’ RFOptimization preprint, first posted in September 2026. The installation and model commands below were checked against the released source; GPU optimization and the paper’s benchmarks were not run for this article. The standalone records checker and its synthetic example were tested locally.

1. What RFOptimization changes

RFO is a training-free refinement framework: it uses pretrained models without fitting a new set of model weights. Sequence optimization can still use gradients. The preprint combines gradient-guided mutation search with structure prediction and MPNN redesign, then uses AlphaFold3 as a separate final evaluator. Its reported improvements concern in silico filtering; they do not establish experimental binding for every passing design. See the original abstract.

In the released workflow, each cycle chooses one of two branches:

Stage Role
RF3 branch Guide sequence optimization with RoseTTAFold3
Boltz branch Predict a structure for the current sequence with Boltz-2
External MPNN Redesign unfixed residues in chain A, then pass the complex to the next cycle
Separate evaluation Assess selected designs independently after optimization

backprop_fraction: 0.5 is a probability for choosing RF3 at each cycle. It does not guarantee alternating branches or an equal split in a short run. Values of 1 and 0 force RF3 and Boltz respectively; MPNN remains part of both branches.

Unlike FlashPPI’s interaction screening, this workflow changes a supplied design. Keep the initial complex so that you can compare the starting sequence, every proposed sequence, and the final candidates under the same evaluation procedure.

2. Prepare the input and model environments

Use a Linux machine with an NVIDIA GPU and a working Conda installation. The driver/RF3, MPNN, and Boltz environments are separate. Keep the commands below in the same shell so their exported paths remain available. The installation guide is the reference for CUDA compatibility and model assets.

The designed protein must be chain A, with standard amino acids and complete N, CA, C, and O backbone atoms. In a two-protein example, chain B is the partner. Check chain IDs and residue completeness before launching; the RF3 branch’s MPNN mask uses contacts with chain B. Paths in the run YAML resolve from the working directory. See the cycling input conventions.

Start with a new working directory. This pins the Foundry source inspected for the tutorial:

mkdir rfo-tutorial
cd rfo-tutorial
export RFO_WORK="$PWD"
git clone https://github.com/RosettaCommons/foundry.git
cd foundry
git checkout 94c78ab125c6ef2cc7d1226de86d1bd578bf8bee

conda create -n rfo-driver python=3.12 -y
conda activate rfo-driver
python -m pip install -e '.[rf3,rfo]'
foundry install rf3
export RF3_CKPT="$HOME/.foundry/checkpoints/rf3_foundry_01_24_latest_remapped.ckpt"
rfo --help

The public RF3 checkpoint must support confidence prediction and include its training configuration. The installation guide notes that historical research configurations used other checkpoints. This recipe is a software trial, not a claim to reproduce the paper’s experiments. Consult the RF3 setup documentation for model-specific resources.

Install the upstream LigandMPNN repository, which supplies the run.py interface used for both ProteinMPNN and LigandMPNN:

cd "$RFO_WORK"
git clone https://github.com/dauparas/LigandMPNN.git
cd LigandMPNN
conda create -n rfo-mpnn python=3.11 -y
conda activate rfo-mpnn
python -m pip install -r requirements.txt
bash get_model_params.sh ./model_params
export MPNN_REPO="$PWD"
export MPNN_PYTHON="$CONDA_PREFIX/bin/python"
export MPNN_MODEL_TYPE=protein_mpnn
"$MPNN_PYTHON" "$MPNN_REPO/run.py" --help
git rev-parse HEAD > "$RFO_WORK/mpnn-commit.txt"
python -m pip freeze > "$RFO_WORK/mpnn-packages.txt"

Use the upstream CUDA/PyTorch requirements appropriate to your machine. RFO’s adapter does not use Foundry’s bundled mpnn command. Install Boltz in its own environment, then return to the driver:

conda create -n rfo-boltz python=3.12 -y
conda activate rfo-boltz
python -m pip install 'boltz[cuda]'
export BOLTZ_EXECUTABLE="$CONDA_PREFIX/bin/boltz"
export BOLTZ_CACHE="$HOME/.cache/boltz"
"$BOLTZ_EXECUTABLE" predict --help
python -m pip freeze > "$RFO_WORK/boltz-packages.txt"

conda activate rfo-driver
cd "$RFO_WORK/foundry/models/rfo"
python -m pip freeze > "$RFO_WORK/driver-packages.txt"

These commands record the external MPNN commit and installed package versions; they do not lock the whole dependency graph. Also retain checkpoint filenames and checksums, your input structure, and the actual run configuration. Boltz may download model assets on first use, so allow for that separately from optimization time.

3. Check each branch before a mixed run

From foundry/models/rfo, use the repository’s example complex to exercise the two branches independently:

rfo --config src/rfo/cycling/configs/example.yaml \
    --backprop-fraction 1 --total-cycles 1 \
    --out-dir outputs/smoke-rf3

rfo --config src/rfo/cycling/configs/example.yaml \
    --backprop-fraction 0 --total-cycles 1 \
    --out-dir outputs/smoke-boltz

Use a fresh output directory for each run. The driver implementation initializes the records file at the start; reusing a directory can overwrite records and leave older artifacts alongside newer ones.

After both one-cycle runs succeed, save this as tutorial.yaml in the same directory:

input_structure: ./src/rfo/cycling/examples/example_complex.cif
out_dir: ./outputs/tutorial-mixed
backprop_fraction: 0.5
total_cycles: 3
mpnn_num_seqs: 1
mpnn_temperature: 0.1
seed: 42

Run it and inspect the records:

rfo --config tutorial.yaml
python -m json.tool outputs/tutorial-mixed/example_complex_records.json

The CLI lets command-line flags override YAML settings. Explicit assets: settings override environment variables. This example uses the exported paths and intentionally omits target-specific MSAs and templates. Boltz runs in single-sequence mode without an MSA; a configured target MSA changes the experiment and should be recorded.

This is a three-cycle integration trial. It is not a recommended optimization budget for every protein, and its output is not a benchmark result.

4. Read the output without mixing up stages

For the supplied example, look under outputs/tutorial-mixed/:

Artifact What to inspect
example_complex_records.json Completed cycles, branch names, scores, sequences, and timing
recycle_1/mpnn/mpnn_spec.json Residues fixed during the first MPNN step
recycle_1/mpnn/mpnn_result.json MPNN sequence and handoff information
inputs/example_complex_1.pdb Redesigned complex passed forward after the first cycle
recycle_1/rf3_config.yaml Per-cycle configuration, when the branch is RF3

Records number cycles from 0, while output folders begin at recycle_1. The scores in a record come from the structure/optimization branch before that cycle’s MPNN redesign; mpnn_sequence is the sequence produced afterward. Do not attach those scores to the handoff sequence as though it had already been independently refolded. This ordering is visible in the run loop.

Two other details affect interpretation. Increasing mpnn_num_seqs saves more samples but still carries the first sample forward; the driver does not rank them. Also, an AF3_Status field in the Boltz branch is a legacy label, not evidence that AlphaFold3 ran. Read the method field and the actual model outputs. Independent AF3 filtering is outside this pipeline.

5. Check completed cycles with a small Python script

The following checker uses only Python’s standard library. It checks the requested cycle count, contiguous cycle IDs, branch names, standard amino-acid sequences, consistent chain length, and finite nonnegative timings. It does not inspect coordinates or interpret confidence scores.

Download check_rfo_records.py, or save the complete code below:

curl -fL https://www.bobobk.com/downloads/rfoptimization/check_rfo_records.py \
    -o check_rfo_records.py
python3 check_rfo_records.py --help
#!/usr/bin/env python3
"""Audit completed RFO cycles; this does not evaluate molecular quality."""
import argparse
from collections import Counter
import json
import math
from pathlib import Path


def audit(records, expected):
    if expected < 1:
        raise ValueError("expected cycle count must be positive")
    if not isinstance(records, list) or not records:
        raise ValueError("records must be a nonempty JSON list")
    if len(records) != expected:
        raise ValueError(f"expected {expected} cycles, found {len(records)}")
    methods = Counter()
    sequences = []
    seconds = 0.0
    for index, row in enumerate(records):
        if not isinstance(row, dict):
            raise ValueError(f"record {index}: expected an object")
        cycle = row.get("cycle")
        if type(cycle) is not int or cycle != index:
            raise ValueError(f"record {index}: expected zero-based cycle {index}")
        method = row.get("method")
        if method not in ("RF3", "Boltz"):
            raise ValueError(f"cycle {index}: unknown method")
        sequence = row.get("mpnn_sequence")
        if not isinstance(sequence, str) or not sequence:
            raise ValueError(f"cycle {index}: missing MPNN sequence")
        if set(sequence) - set("ACDEFGHIKLMNPQRSTVWY"):
            raise ValueError(f"cycle {index}: nonstandard amino acid")
        if sequences and len(sequence) != len(sequences[0]):
            raise ValueError(f"cycle {index}: chain-A length changed")
        elapsed = row.get("wall_time_sec")
        if (type(elapsed) not in (int, float)
                or not math.isfinite(elapsed) or elapsed < 0):
            raise ValueError(f"cycle {index}: invalid wall_time_sec")
        methods[method] += 1
        sequences.append(sequence)
        seconds += elapsed
    return {
        "completed_cycles": len(records),
        "methods": dict(sorted(methods.items())),
        "chain_a_length": len(sequences[0]),
        "unique_handoff_sequences": len(set(sequences)),
        "recorded_cycle_seconds": round(seconds, 2),
        "quality_evaluated": False,
    }


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("records", type=Path)
    parser.add_argument("--expected-cycles", required=True, type=int)
    args = parser.parse_args()
    try:
        records = json.loads(args.records.read_text(encoding="utf-8"))
        result = audit(records, args.expected_cycles)
    except (OSError, UnicodeError, ValueError) as exc:
        parser.exit(1, f"ERROR: {exc}\n")
    print(json.dumps(result, indent=2, allow_nan=False))


if __name__ == "__main__":
    main()

Try this synthetic fixture first. The sequences and timings are invented solely to demonstrate the checker; they are not RFO predictions or performance measurements.

python3 - <<'PY'
import json
from pathlib import Path

records = [
    {"cycle": 0, "method": "RF3", "mpnn_sequence": "ACDEFG",
     "wall_time_sec": 12.5},
    {"cycle": 1, "method": "Boltz", "mpnn_sequence": "ACDEYG",
     "wall_time_sec": 20.0},
]
Path("synthetic_records.json").write_text(json.dumps(records))
PY
python3 check_rfo_records.py synthetic_records.json --expected-cycles 2

Expected output:

{
  "completed_cycles": 2,
  "methods": {
    "Boltz": 1,
    "RF3": 1
  },
  "chain_a_length": 6,
  "unique_handoff_sequences": 2,
  "recorded_cycle_seconds": 32.5,
  "quality_evaluated": false
}

For the real three-cycle trial, run the checker from foundry/models/rfo, with the script saved there:

python3 check_rfo_records.py \
    outputs/tutorial-mixed/example_complex_records.json --expected-cycles 3

A nonzero exit means the record file did not meet these checks. A successful check establishes record consistency only. recorded_cycle_seconds sums saved completed-cycle durations; it excludes failed attempts that never became records and is not total job wall time. Repeated sequences are counted, not rejected, because an unchanged handoff can be valid.

6. Troubleshooting and evaluation

Symptom Action
MPNN executable or weights missing Check MPNN_REPO/run.py, the absolute MPNN_PYTHON path, and the upstream model_params directory
RF3 checkpoint rejected Set RF3_CKPT to a confidence-enabled checkpoint with its training configuration
Input file not found Run from foundry/models/rfo or replace the relative input path with an absolute path
Fewer records than requested cycles Inspect the failing model logs; directory creation alone does not establish completion
Several MPNN samples but only one next input Inspect saved samples separately; the current driver forwards the first
Scores improve but the handoff sequence is untested Refold the actual saved sequence with the intended partner in a separate evaluation

Choose the evaluation procedure before comparing runs. Preserve the starting candidate, specify which cycles can be selected, and apply the same evaluator and inputs to baseline and refined candidates. Keep failed or missing evaluations visible in the denominator. Computational confidence is useful for prioritization; binding, specificity, stability, and activity still require the corresponding measurements.

For cyclic-peptide work, inspect the implementation separately: cyclic: true is passed to Boltz for chain A, but the RF3 optimizer does not add explicit cyclic bond constraints in this release. The cycling documentation describes this limitation. The protein-complex trial above does not validate cyclic-peptide behavior.

7. Summary

Start with a checked input complex, verify each model branch, and retain every sequence handed to the next cycle. Use the records checker to catch incomplete runs, then evaluate the actual refined sequences independently. RFOptimization’s useful output is a set of candidates with a traceable optimization history; experimental success remains a separate question.

标签

1024 ablang adsense agents.md ai ai-agent ai-agents ai-seo algorithm amp antibodies apparmor argparse automation background backup bash batch-processing binarycif bioinformatics biopython blockchain boltz bootstrapping boxes bubblewrap c-index cca cdn checkpoint cli cloudflare codex cofoldarena copy cpu monitoring cron csv cuda curl data-leakage data-processing data-quality data-validation datascience datavisualization datetime debugging decimal deployment desktop-app devtools disk-space disown dns docker dovecot download economics electron encoding esm esm2 esm3 esmc esmfold2 fable faceswap fasta fastmcp faulthandler ffmpeg file-descriptors file-io flashppi flask folium frontend game generator git github-actions google google-research grep gzip harness hls html http hugo imports indexnow javascript jev json jsonl just k-means kaggle langfuse leecode linux list litellm llm llms.txt logging logs lollipop lsof m3u8 machine-learning macos manacher matplotlib mcp mirror mmcif model-evaluation monitoring mp3 mp4 mpnn multiomics mutation mysql nanobert nanobodies networkx nginx normalize numpy ollama omegatherm pandas password pathlib pdb pep-723 phaser pillow pip postfix preprocessing print probability protein-alignment protein-design protein-embeddings protein-interactions protein-language-models protein-stability protein-structure proxy pydantic pyecharts pyqt python python3 r raincloud reproducibility requests reservoir-sampling rfoptimization rg ripgrep rosettafold3 roundcube rrsi rsi rsync s-tui sampling scale scikit-learn scrapy screen seaborn security seo sequence-identity sha256 shell signals sklearn socket solana somaticsignatures spl sqlite ssh standardize static-site subprocess symlink sysadmin system-one tarfile tcp tensorflow tkinter tls toml trade tron tronpy troubleshooting turtle typesafe-ai ubuntu unicode usdt utf-8 uv vhhbert vite wallet webp wordcloud wordpress workflow yaml zipfile zoneinfo 迅雷解析

友情链接

其它