$npx -y skills add adaptyvbio/protein-design-skills --skill ipsaeBinder design ranking using ipSAE (interprotein Score from Aligned Errors). Use this skill when: (1) Ranking binder designs for experimental testing, (2) Filtering BindCraft or RFdiffusion outputs, (3) Comparing AF2/AF3/Boltz predictions, (4) Predicting binding success rates, (5)
| 1 | # ipSAE Binder Ranking |
| 2 | |
| 3 | ## Prerequisites |
| 4 | |
| 5 | | Requirement | Minimum | Recommended | |
| 6 | |-------------|---------|-------------| |
| 7 | | Python | 3.8+ | 3.10 | |
| 8 | | NumPy | 1.20+ | Latest | |
| 9 | | RAM | 8GB | 16GB | |
| 10 | |
| 11 | ## Overview |
| 12 | |
| 13 | ipSAE (interprotein Score from Aligned Errors) is a scoring function for ranking protein-protein interactions predicted by AlphaFold2, AlphaFold3, and Boltz1. It separates true from false predicted complexes more reliably than ipTM, which dilutes interface confidence across disordered or accessory regions. In a separate binder meta-analysis (Overath et al. 2025), AF3 ipSAE_min gave a 1.4-fold gain in average precision over the ipAE score that RFdiffusion pipelines commonly filter on. |
| 14 | |
| 15 | **Paper**: Dunbrack, "Rēs ipSAE loquuntur: What's wrong with AlphaFold's ipTM score and how to fix it", [bioRxiv 2025.02.10.637595](https://www.biorxiv.org/content/10.1101/2025.02.10.637595v2) |
| 16 | |
| 17 | ## How to run |
| 18 | |
| 19 | ### Installation |
| 20 | ```bash |
| 21 | git clone https://github.com/DunbrackLab/IPSAE.git |
| 22 | cd IPSAE |
| 23 | pip install numpy |
| 24 | ``` |
| 25 | |
| 26 | ### AlphaFold2 |
| 27 | ```bash |
| 28 | python ipsae.py scores_rank_001.json unrelaxed_rank_001.pdb 15 15 |
| 29 | ``` |
| 30 | |
| 31 | ### AlphaFold3 |
| 32 | ```bash |
| 33 | python ipsae.py fold_model_full_data_0.json fold_model_0.cif 10 10 |
| 34 | ``` |
| 35 | |
| 36 | ### Boltz1 |
| 37 | ```bash |
| 38 | python ipsae.py pae_model_0.npz model_0.cif 10 10 |
| 39 | ``` |
| 40 | |
| 41 | ## Key parameters |
| 42 | |
| 43 | | Parameter | Description | Recommended | |
| 44 | |-----------|-------------|-------------| |
| 45 | | PAE file | JSON (AF2/AF3) or NPZ (Boltz) | Match predictor | |
| 46 | | Structure file | PDB or CIF structure | Match PAE | |
| 47 | | PAE cutoff | Threshold for contacts | 10-15 | |
| 48 | | Distance cutoff | Max CA-CA distance (A) | 10-15 | |
| 49 | |
| 50 | ## Output format |
| 51 | |
| 52 | Two output files are generated: |
| 53 | |
| 54 | **Chain-pair scores** (`_chains.csv`): |
| 55 | ``` |
| 56 | chain_A,chain_B,ipSAE_min,pDockQ,pDockQ2,LIS,n_contacts,interface_dist |
| 57 | A,B,0.72,0.65,0.58,0.45,42,8.5 |
| 58 | ``` |
| 59 | |
| 60 | **Residue-level scores** (`_residues.csv`): |
| 61 | ``` |
| 62 | chain,resnum,pSAE,pLDDT |
| 63 | A,45,0.85,92.3 |
| 64 | A,67,0.78,88.1 |
| 65 | ``` |
| 66 | |
| 67 | ## Sample output |
| 68 | |
| 69 | ### Successful run |
| 70 | ``` |
| 71 | $ python ipsae.py scores_rank_001.json design_0.pdb 10 10 |
| 72 | Processing design_0... |
| 73 | Found 2 chains: A, B |
| 74 | Computing ipSAE scores... |
| 75 | |
| 76 | Results written to: |
| 77 | design_0_chains.csv |
| 78 | design_0_residues.csv |
| 79 | |
| 80 | Summary: |
| 81 | ipSAE_min: 0.72 |
| 82 | pDockQ: 0.65 |
| 83 | LIS: 0.45 |
| 84 | Interface contacts: 42 |
| 85 | ``` |
| 86 | |
| 87 | **What good output looks like:** |
| 88 | - ipSAE_min > 0.61 (primary filter) |
| 89 | - pDockQ > 0.5 (supporting metric) |
| 90 | - Reasonable number of interface contacts (20-100) |
| 91 | |
| 92 | ## Decision tree |
| 93 | |
| 94 | ``` |
| 95 | Should I use ipSAE? |
| 96 | │ |
| 97 | ├─ What are you ranking? |
| 98 | │ ├─ Designed binders → ipSAE ✓ |
| 99 | │ ├─ Natural complexes → ipTM is fine |
| 100 | │ └─ Single proteins → Not applicable |
| 101 | │ |
| 102 | ├─ What predictor did you use? |
| 103 | │ ├─ AlphaFold2 → ipSAE ✓ |
| 104 | │ ├─ AlphaFold3 → ipSAE ✓ |
| 105 | │ ├─ Boltz1 → ipSAE ✓ |
| 106 | │ ├─ Chai → ipSAE (use PAE output) |
| 107 | │ └─ ESMFold → Not applicable (no PAE) |
| 108 | │ |
| 109 | └─ Why ipSAE over ipTM? |
| 110 | ├─ Different length constructs → ipSAE ✓ |
| 111 | ├─ Designs with disordered regions → ipSAE ✓ |
| 112 | └─ Standard complexes → Either works |
| 113 | ``` |
| 114 | |
| 115 | ## Recommended thresholds |
| 116 | |
| 117 | | Metric | Standard | Stringent | Use Case | |
| 118 | |--------|----------|-----------|----------| |
| 119 | | ipSAE_min | > 0.61 | > 0.70 | Primary filter | |
| 120 | | LIS | > 0.35 | > 0.45 | Interface quality | |
| 121 | | pDockQ | > 0.5 | > 0.6 | Supporting | |
| 122 | |
| 123 | ## Batch processing |
| 124 | |
| 125 | ```python |
| 126 | import subprocess |
| 127 | import os |
| 128 | from pathlib import Path |
| 129 | |
| 130 | def score_designs(pae_dir, struct_dir, output_dir): |
| 131 | """Score all designs in a directory.""" |
| 132 | Path(output_dir).mkdir(exist_ok=True) |
| 133 | |
| 134 | for pae_file in Path(pae_dir).glob("*_scores*.json"): |
| 135 | name = pae_file.stem.replace("_scores_rank_001", "") |
| 136 | struct_file = Path(struct_dir) / f"{name}.pdb" |
| 137 | |
| 138 | if struct_file.exists(): |
| 139 | subprocess.run([ |
| 140 | "python", "ipsae.py", |
| 141 | str(pae_file), |
| 142 | str(struct_file), |
| 143 | "10", "10" |
| 144 | ]) |
| 145 | ``` |
| 146 | |
| 147 | --- |
| 148 | |
| 149 | ## Verify |
| 150 | |
| 151 | ```bash |
| 152 | ls *_chains.csv | wc -l # Should match number of predictions |
| 153 | ``` |
| 154 | |
| 155 | --- |
| 156 | |
| 157 | ## Troubleshooting |
| 158 | |
| 159 | **Low scores for good designs**: Check PAE/distance cutoffs |
| 160 | **Missing output**: Verify PAE file format matches predictor |
| 161 | **Inconsistent scores**: Use same cutoffs across all designs |
| 162 | |
| 163 | ### Error interpretation |
| 164 | |
| 165 | | Error | Cause | Fix | |
| 166 | |-------|-------|-----| |
| 167 | | `KeyError: 'pae'` | Wrong PAE format | Check if AF2/AF3/Boltz format | |
| 168 | | `FileNotFoundError` | Structure not found | Verify file paths | |
| 169 | | `ValueError: no contacts` | No interface detected | Check chain IDs, reduce cutoffs | |
| 170 | |
| 171 | --- |
| 172 | |
| 173 | **Next**: Select top designs (ipSAE_min > 0.61) → experimental validation. |