IgFold / scripts /inference.py
wuxing0105's picture
Upload folder using huggingface_hub
1fdc49a verified
Raw
History Blame Contribute Delete
3.05 kB
"""Run IgFold structure prediction from antibody sequences or a FASTA file."""
import argparse
import json
from pathlib import Path
import torch
from igfold import IgFoldRunner
DEFAULT_HEAVY = (
"EVQLVQSGPEVKKPGTSVKVSCKASGFTFMSSAVQWVRQARGQRLEWIGWIVIGSGNTNYAQKF"
"QERVTITRDMSTSTAYMELSSLRSEDTAVYYCAAPYCSSISCNDGFDIWGQGTMVTVS"
)
DEFAULT_LIGHT = (
"DVVMTQTPFSLPVSLGDQASISCRSSQSLVHSNGNTYLHWYLQKPGQSPKLLIYKVSNRFSGV"
"PDRFSGSGSGTDFTLKISRVEAEDLGVYFCSQSTHVPYTFGGGTKLEIK"
)
def parse_args():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--fasta", type=Path, help="Input FASTA containing H/L chains.")
parser.add_argument("--heavy", help="Heavy-chain amino-acid sequence.")
parser.add_argument("--light", help="Light-chain amino-acid sequence.")
parser.add_argument("--output", type=Path, default=Path("output/inference/antibody.pdb"))
parser.add_argument("--num-models", type=int, choices=range(1, 5), default=4)
parser.add_argument("--refine", action="store_true", help="Enable structure refinement.")
parser.add_argument("--openmm", action="store_true", help="Use OpenMM for refinement.")
parser.add_argument("--renum", action="store_true", help="Apply Chothia numbering.")
parser.add_argument("--cpu", action="store_true", help="Force CPU inference.")
return parser.parse_args()
def main():
args = parse_args()
root = Path(__file__).resolve().parents[1]
checkpoints = sorted((root / "weight" / "IgFold").glob("*.ckpt"))[: args.num_models]
if len(checkpoints) != args.num_models:
raise FileNotFoundError(
f"Expected {args.num_models} checkpoints in {root / 'weight' / 'IgFold'}, "
f"found {len(checkpoints)}."
)
if args.fasta is not None:
fasta_file = str(args.fasta.resolve())
sequences = None
else:
fasta_file = None
sequences = {"H": args.heavy or DEFAULT_HEAVY}
light = args.light if args.light is not None else DEFAULT_LIGHT
if light:
sequences["L"] = light
if args.refine and not args.openmm:
from igfold.refine.pyrosetta_ref import init_pyrosetta
init_pyrosetta()
args.output.parent.mkdir(parents=True, exist_ok=True)
runner = IgFoldRunner(
model_ckpts=[str(path) for path in checkpoints],
try_gpu=not args.cpu,
)
output = runner.fold(
str(args.output),
fasta_file=fasta_file,
sequences=sequences,
do_refine=args.refine,
use_openmm=args.openmm,
do_renum=args.renum,
)
result = {
"status": "PASS",
"output_pdb": str(args.output.resolve()),
"models": len(runner.models),
"device": str(next(runner.models[0].parameters()).device),
"torch": torch.__version__,
"coords_shape": list(output.coords.shape),
"prmsd_shape": list(output.prmsd.shape),
}
print("IGFOLD_INFERENCE_RESULT=" + json.dumps(result, sort_keys=True))
if __name__ == "__main__":
main()