AntiFold ============================== AntiFold predicts sequences which fit into antibody variable domain structures. The tool outputs residue log-likelihoods in [CSV format](https://github.com/oxpig/AntiFold/blob/master/output/single_pdb/6y1l_imgt.csv), and can sample sequences to a [FASTA format](https://github.com/oxpig/AntiFold/blob/master/output/single_pdb/6y1l_imgt.fasta) directly. Sampled sequences show high structural agreement with experimental structures. AntiFold is based on the ESM-IF1 model and is fine-tuned on solved and predicted antibody structures from SAbDab and OAS. - Paper: [Bioinformatics Advances](https://academic.oup.com/bioinformaticsadvances/article/5/1/vbae202/8090019) - Webserver: [OPIG webserver](https://opig.stats.ox.ac.uk/webapps/antifold/) - Colab: [![Open In Colab](images/colab-badge.svg)](https://colab.research.google.com/drive/1oEDJCHcwxGBeCiYsCm62_OHBXDHnlhb9) - Model: [model.pt](https://github.com/oxpig/AntiFold/releases/download/weights-v1/model.pt) ([OPIG mirror](https://opig.stats.ox.ac.uk/data/downloads/AntiFold/models/model.pt)), downloaded automatically on first run - License: [BSD 3-Clause](https://opig.stats.ox.ac.uk/data/downloads/AntiFold/LICENSE) ## Webserver To try AntiFold without installing it, please see our OPIG webserver: [https://opig.stats.ox.ac.uk/webapps/antifold/](https://opig.stats.ox.ac.uk/webapps/antifold/) ## Features - Antibody (+ antigen) probabilities and sequence sampling - Nanobody (+ antigen) probabilities and sequence sampling - Sampling of residues from specified IMGT regions or individual IMGT positions. Nb: assumes antibody is IMGT numbered! (See --num_seq_per_target and --regions) - Supports use of AntiFold fine-tuned weights and ESM-IF1 pre-trained weights (See --esm_if1_mode) - Extraction of per-residue inverse-folding embeddings (See --extract_embeddings) - GPU accelerated predictions (See --device) ## Input - Input should be either a paired variable domain structure (VH/VL) antibody or nanobody (VHH) (--nanobody_mode) - AntiFold assumes the first PDB chain is the heavy chain, and second the light chain, unless manually specified by the user (See --pdbs_csv, --heavy_chain, --light_chain options) - Antigen chains can optionally be specified. We recommend only including a single, ideally small, antigen chain. (See --pdbs_csv or --antigen_chain options) - Antibody chains are IMGT renumbered with [ANARCII](https://github.com/oxpig/ANARCII) by default, so input need not be IMGT numbered. Chains ANARCII does not recognise as antibody chains (e.g. antigens) are left untouched. Pass --skip_anarcii_numbering to use the input numbering as-is ## Install and run AntiFold #### Download and install from Github source (recommended - latest release) ```bash conda create --name antifold python=3.13 -y && conda activate antifold git clone https://github.com/oxpig/AntiFold && cd AntiFold pip install . ``` GPU only: install using environment.yml ```bash conda env create -f environment.yml python -m pip install . ``` This installs a CUDA build of PyTorch from conda-forge matching your NVIDIA driver, and fails if no GPU driver is found. Detailed instructions on how to correctly install pytorch for your system can be found [here](https://pytorch.org/get-started/locally/) #### Run AntiFold (inverse-folding probabilities, sample sequences on IMGT-numbered PDBs) ```bash # Run AntiFold on single PDB/CIF file # Nb: Assumes first chain heavy, second chain light python antifold/main.py \ --pdb_file data/pdbs/6y1l_imgt.pdb # Antibody-antigen complex python antifold/main.py \ --pdb_file data/antibody_antigen/3hfm.pdb \ --heavy_chain H \ --light_chain L \ --antigen_chain Y # Nanobody or single-chain python antifold/main.py \ --pdb_file data/nanobody/8oi2_imgt.pdb \ --nanobody_chain B # Folder of PDB/CIFs # Nb: Assumes first chain heavy, second light python antifold/main.py \ --pdb_dir data/pdbs # Specify chains to run in a CSV file (e.g. antibody-antigen complex) python antifold/main.py \ --pdb_dir data/antibody_antigen \ --pdbs_csv data/antibody_antigen.csv # Sample sequences 10x (paired VH/VL only) python antifold/main.py \ --pdb_file data/pdbs/6y1l_imgt.pdb \ --heavy_chain H \ --light_chain L \ --num_seq_per_target 10 \ --sampling_temp "0.2" \ --regions "CDR1 CDR2 CDR3" # Sample specific IMGT positions instead of whole regions # Positions take an H: or L: prefix, and mix with region names (e.g. "CDRH3 L:66-70") python antifold/main.py \ --pdb_file data/pdbs/6y1l_imgt.pdb \ --heavy_chain H \ --light_chain L \ --num_seq_per_target 10 \ --sampling_temp "0.2" \ --regions "H:10-12,111-112 L:66-70" # Run all chains with ESM-IF1 model weights python antifold/main.py \ --pdb_dir data/pdbs \ --esm_if1_mode ``` ## Jupyter notebook Notebook: notebook.ipynb Colab: [![Open In Colab](images/colab-badge.svg)](https://colab.research.google.com/drive/1oEDJCHcwxGBeCiYsCm62_OHBXDHnlhb9) ```python import antifold import antifold.main # Load model model = antifold.main.load_model() # PDB directory pdb_dir = "data/pdbs" # Assumes first chain heavy, second chain light pdbs_csv = antifold.main.generate_pdbs_csv(pdb_dir, max_chains=2) # Sample from PDBs df_logits_list = antifold.main.get_pdbs_logits( model=model, pdbs_csv_or_dataframe=pdbs_csv, pdb_dir=pdb_dir, ) # Output log probabilites df_logits_list[0] ``` ## Input parameters Required parameters: ```text Input PDBs should be antibody variable domain structures (IMGT positions 1-128). If no chains are specified, the first two chains will be assumed to be heavy light. If custom_chain_mode is set, all (10) chains will be run. - Option 1: PDB file (--pdb_file). We recommend specifying heavy and light chain (--heavy_chain and --light_chain) - Option 2: PDB folder (--pdb_dir) + CSV file specifying chains (--pdbs_csv) - Option 3: PDB folder, infer 1st chain heavy, 2nd chain light ``` Parameters for generating new sequences: ```text PDBs should be IMGT annotated for the sequence sampling regions to be valid. - Number of sequences to generate (--num_seq_per_target) - Region to mutate (--regions) based on inverse folding probabilities. Select from list in IMGT_dict (e.g. 'CDRH1 CDRH2 CDRH3'), or give chain-prefixed IMGT positions (e.g. 'H:111-112 L:66-70'). The two can be combined (e.g. 'CDRH3 L:66-70'). Positions require an H: or L: prefix, since IMGT numbering repeats across the heavy and light chain, and they include insertion codes, so H:111 also covers 111A and 111B - Design a single chain by naming it in --regions: allH, allL, CDRH, CDRL, the chain-specific names (CDRH1, FWL2 ...) or an H:/L: position prefix - Sampling temperature (--sampling_temp) controls generated sequence diversity, by scaling the inverse folding probabilities before sampling. Temperature = 1 means no change, while temperature ~ 0 only samples the most likely amino-acid at each position (acts as argmax). ``` Optional parameters: ```text - Multi-chain mode for including antigen or other chains (--custom_chain_mode) - Extract latent representations of PDB within model (--extract_embeddings) - Use ESM-IF1 instead of AntiFold model weights (--esm_if1_mode), enables custom_chain_mode ``` ## Example output For example webserver output, see: [https://opig.stats.ox.ac.uk/webapps/antifold/results/example_job/](https://opig.stats.ox.ac.uk/webapps/antifold/results/example_job/) Output CSV with residue log-probabilities: Residue probabilities: 6y1l_imgt.csv - pdb_pos - PDB residue number - pdb_chain - PDB chain - aa_orig - PDB residue (e.g. 112) - aa_pred - Top predicted residue by AntiFold (i.e. argmax) for this position - pdb_posins - PDB residue number with insertion code (e.g. 112A) - perplexity - Inverse folding tolerance (higher is more tolerant) to mutations. See paper for more details. - Amino-acids - Inverse folding scores (log-likelihood) for the given position ```csv pdb_pos,pdb_chain,aa_orig,aa_pred,pdb_posins,perplexity,A,C,D,E,F,G,H,I,K,L,M,N,P,Q,R,S,T,V,W,Y 2,H,V,M,2,1.6488,-4.9963,-6.6117,-6.3181,-6.3243,-6.7570,-4.2518,-6.7514,-5.2540,-6.8067,-5.8619,-0.0904,-6.5493,-4.8639,-6.6316,-6.3084,-5.1900,-5.0988,-3.7295,-8.0480,-7.3236 3,H,Q,Q,3,1.3889,-10.5258,-12.8463,-8.4800,-4.7630,-12.9094,-11.0924,-5.6136,-10.9870,-3.1119,-8.1113,-9.4382,-6.2246,-13.3660,-0.0701,-4.9957,-10.0301,-6.8618,-7.5810,-13.6721,-11.4157 4,H,L,L,4,1.0021,-13.3581,-12.6206,-17.5484,-12.4801,-9.8792,-13.6382,-14.8609,-13.9344,-16.4080,-0.0002,-9.2727,-16.6532,-14.0476,-12.5943,-15.4559,-16.9103,-17.0809,-10.5670,-13.5334,-13.4324 ... ``` Output FASTA file with sampled sequences: 6y1l_imgt.fasta - seqN: sampled sequence number, counting across all temperatures - T: Temperature used for design - score: average log-odds of residues in the sampled region - global_score: average log-odds of all residues (IMGT positions 1-128) - regions: regions selected for design - seq_recovery: fraction of residues identical to the original PDB sequence - mutations: mutations from the original PDB sequence, as chain: ```fasta >6y1l_imgt_HL , score=0.2934, global_score=0.2934, regions=['CDR1', 'CDR2', 'CDRH3'], model_name=AntiFold, seed=42 VQLQESGPGLVKPSETLSLTCAVSGYSISSGYYWGWIRQPPGKGLEWIGSIYHSGSTYYN PSLKSRVTISVDTSKNQFSLKLSSVTAADTAVYYCAGLTQSSHNDANWGQGTLVTVSS/V LTQPPSVSAAPGQKVTISCSGSSSNIGNNYVSWYQQLPGTAPKRLIYDNNKRPSGIPDRF SGSKSGTSATLGITGLQTGDEADYYCGTWDSSLNPVFGGGTKLEIKR >seq1 T=0.20, sample=1, score=0.3978, global_score=0.1869, seq_recovery=0.9469, mutations=H:Y28A,H:S31T,H:G36S,H:H58Y,H:T108Y,H:Q109G,H:S112P,H:H113W,H:N114S,H:D115N,H:A116P,H:N117Y VQLQESGPGLVKPSETLSLTCAVSGASITSSYYWGWIRQPPGKGLEWIGSIYYSGSTYYN PSLKSRVTISVDTSKNQFSLKLSSVTAADTAVYYCAGLYGSPWSNPYWGQGTLVTVSS/V LTQPPSVSAAPGQKVTISCSGSSSNIGNNYVSWYQQLPGTAPKRLIYDNNKRPSGIPDRF SGSKSGTSATLGITGLQTGDEADYYCGTWDSSLNPVFGGGTKLEIKR ... ``` ## Usage ```bash usage: # Predict on example PDBs in folder python antifold/main.py \ --pdb_file data/antibody_antigen/3hfm.pdb \ --heavy_chain H \ --light_chain L \ --antigen_chain Y # Optional Predict antibody variable domain inverse folding probabilities and sample sequences with maintained fold. Antibody chains are IMGT renumbered with ANARCII by default (positions 1-128); pass --skip_anarcii_numbering to use the input numbering as-is. options: -h, --help show this help message and exit --pdb_file PDB_FILE Input PDB file (for single PDB predictions) --heavy_chain HEAVY_CHAIN Ab heavy chain (for single PDB predictions) --light_chain LIGHT_CHAIN Ab light chain (for single PDB predictions) --antigen_chain ANTIGEN_CHAIN Antigen chain (optional) --pdbs_csv PDBS_CSV Input CSV file with PDB names and H/L chains (multi-PDB predictions) --pdb_dir PDB_DIR Directory with input PDB files (multi-PDB predictions) --out_dir OUT_DIR Output directory --regions REGIONS Space-separated regions to mutate. Either IMGT region names (CDR1, CDRH3, allH) or chain-prefixed IMGT positions (H:111, L:66-70, H:10-12,15). Positions include insertion codes, so H:111 also covers 111A and 111B. Default 'CDR1 CDR2 CDR3' --num_seq_per_target NUM_SEQ_PER_TARGET Number of sequences to sample from each antibody PDB (default 0) --sampling_temp SAMPLING_TEMP A string of temperatures e.g. '0.20 0.25 0.50' (default 0.20). Sampling temperature for amino acids. Suggested values 0.10, 0.15, 0.20, 0.25, 0.30. Higher values will lead to more diversity. --limit_variation Limit variation to as many mutations as expected from temperature sampling --extract_embeddings Extract per-residue embeddings from AntiFold / ESM-IF1 --custom_chain_mode Run all specified chains (for antibody-antigen complexes or any combination of chains) --skip_anarcii_numbering Skip IMGT renumbering with ANARCII, using the input numbering as-is --batch_size BATCH_SIZE Batch-size to use --num_threads NUM_THREADS Number of CPU threads to use for parallel processing (0 = all available) --seed SEED Seed for reproducibility --model_path MODEL_PATH Alternative model weights (default models/model.pt). See --esm_if1_mode flag to use ESM-IF1 weights instead of AntiFold --esm_if1_mode Use ESM-IF1 weights instead of AntiFold --device DEVICE Device to run on: cpu, cuda or mps (default: cuda if available, else cpu) --verbose VERBOSE Verbose printing ``` ## IMGT regions dict Used to specify which regions to mutate. Chains are IMGT renumbered with ANARCII before prediction, so these positions are always meaningful. - ANARCII: [https://github.com/oxpig/ANARCII](https://github.com/oxpig/ANARCII) - Read more: [https://www.imgt.org/IMGTScientificChart/Numbering/IMGTIGVLsuperfamily.html](https://www.imgt.org/IMGTScientificChart/Numbering/IMGTIGVLsuperfamily.html) ```python IMGT_dict = { "all": range(1, 128 + 1), "allH": range(1, 128 + 1), "allL": range(1, 128 + 1), "FWH": list(range(1, 26 + 1)) + list(range(39, 55 + 1)) + list(range(66, 104 + 1)) + list(range(118, 128 + 1)), "FWL": list(range(1, 26 + 1)) + list(range(39, 55 + 1)) + list(range(66, 104 + 1)) + list(range(118, 128 + 1)), "CDRH": list(range(27, 38 + 1)) + list(range(56, 65 + 1)) + list(range(105, 117 + 1)), "CDRL": list(range(27, 38 + 1)) + list(range(56, 65 + 1)) + list(range(105, 117 + 1)), "FW1": range(1, 26 + 1), "FWH1": range(1, 26 + 1), "FWL1": range(1, 26 + 1), "CDR1": range(27, 38 + 1), "CDRH1": range(27, 38 + 1), "CDRL1": range(27, 38 + 1), "FW2": range(39, 55 + 1), "FWH2": range(39, 55 + 1), "FWL2": range(39, 55 + 1), "CDR2": range(56, 65 + 1), "CDRH2": range(56, 65 + 1), "CDRL2": range(56, 65 + 1), "FW3": range(66, 104 + 1), "FWH3": range(66, 104 + 1), "FWL3": range(66, 104 + 1), "CDR3": range(105, 117 + 1), "CDRH3": range(105, 117 + 1), "CDRL3": range(105, 117 + 1), "FW4": range(118, 128 + 1), "FWH4": range(118, 128 + 1), "FWL4": range(118, 128 + 1), } ``` ## Benchmarks - [Li, Y., et al. Benchmarking Inverse Folding Models for Antibody CDR Sequence Design, PLOS ONE, 2025](https://doi.org/10.1371/journal.pone.0324566) - [Clifford J.N. et al. (2025). AbEpiTope-1.0: Improved antibody target prediction by use of AlphaFold and inverse folding.](https://doi.org/10.1126/sciadv.adu1823) ## Citing this work The code and data in this package is based on the following paper AntiFold. If you use it, please cite: ```tex @misc{antifold, title={AntiFold: Improved antibody structure-based design using inverse folding}, author={Magnus Haraldson Høie and Alissa Hummer and Tobias H. Olsen and Broncio Aguilar-Sanjuan and Morten Nielsen and Charlotte M. Deane}, year={2024}, eprint={2405.03370}, archivePrefix={arXiv}, primaryClass={q-bio.BM} } ``` Antibody chains are IMGT renumbered with ANARCII (BSD 3-Clause, University of Oxford) unless --skip_anarcii_numbering is passed. If you use AntiFold with renumbering, please also cite: ```tex @article{anarcii, title={ANARCII: A Generalised Language Model for Antigen Receptor Numbering}, author={Alexander Greenshields-Watson and Parth Agarwal and Sarah A Robinson and Benjamin Heathcote Williams and Gemma L Gordon and Henriette L Capel and Yushi Li and Fabian C Spoendlin and Fergus Boyles and Charlotte M Deane}, year={2025}, journal={bioRxiv}, doi={10.1101/2025.04.16.648720} } ```