Ultra-fast deep learning prediction of single-residue local energetic frustration in proteins. This repo contains the inference code for the preprint FrustraMPNN: An ultra-fast deep learning tool for proteome-scale analysis of deep mutational single-residue local energetic frustration in proteins
FrustraMPNN is a message-passing neural network trained via transfer learning from ProteinMPNN to predict frustration profiles 1,000-4,500x faster than physics-based methods.
pip install frustrampnnWith visualization support:
pip install frustrampnn[viz]With all optional dependencies:
pip install frustrampnn[all]We recommend using uv for development. It is 10-100x faster than pip.
- Install uv (if not already installed):
curl -LsSf https://astral.sh/uv/install.sh | sh- Clone the repository:
git clone https://github.com/schoederlab/frustraMPNN.git
cd frustraMPNN- Create virtual environment and install dependencies:
uv venv --python 3.10
source .venv/bin/activate
uv pip install -e ".[all]"- Verify installation:
python -c "import frustrampnn; print(frustrampnn.__version__)"When using uv with Jupyter notebooks, you need to ensure the notebook uses the correct Python environment. Follow these steps:
cd /path/to/frustraMPNN
source .venv/bin/activate
uv pip install ipykernelRegister the virtual environment as a Jupyter kernel:
python -m ipykernel install --user --name=frustrampnn --display-name="FrustraMPNN"This creates a kernel named "FrustraMPNN" that will appear in Jupyter and VS Code.
In VS Code / Cursor:
- Open the notebook file (
.ipynb) - Click the kernel selector in the top-right corner
- Select "FrustraMPNN" or ".venv (Python 3.10.x)"
In Jupyter Notebook / JupyterLab:
- Open the notebook
- Go to Kernel > Change Kernel
- Select "FrustraMPNN"
From command line:
source .venv/bin/activate
jupyter notebook notebooks/FrustraMPNN_Local.ipynb"No module named X" errors:
If you see import errors, the notebook is likely using the wrong Python environment. Verify by running in a notebook cell:
import sys
print(sys.executable)This should print a path containing .venv, for example:
/path/to/frustraMPNN/.venv/bin/python
If it shows a different path (e.g., /usr/bin/python or a conda environment), select the correct kernel as described above.
Kernel not appearing:
If the "FrustraMPNN" kernel does not appear in the kernel list:
-
Ensure ipykernel is installed in the venv:
source .venv/bin/activate uv pip install ipykernel -
Re-register the kernel:
python -m ipykernel install --user --name=frustrampnn --display-name="FrustraMPNN" -
Restart VS Code / Jupyter
List installed kernels:
jupyter kernelspec listRemove a kernel:
jupyter kernelspec remove frustrampnnFor reproducible environments, use Docker or Singularity:
# Build Docker image
cd docker && bash build_docker.sh
# Run with Docker
bash docker/run_docker.sh predict --pdb protein.pdb --checkpoint model.ckpt
# Build Singularity image (for HPC)
bash docker/build_singu_from_docker.sh
# Run with Singularity
singularity exec --nv frustrampnn.sif frustrampnn predict --pdb protein.pdbfrom frustrampnn import FrustraMPNN
# Load model
model = FrustraMPNN.from_pretrained("checkpoint.ckpt")
# Predict frustration
results = model.predict("protein.pdb", chains=["A"])
# View results
print(results.head())from frustrampnn import FrustraMPNN
# Load pretrained model
model = FrustraMPNN.from_pretrained("checkpoint.ckpt")
# Predict frustration for a single structure
results = model.predict(
"protein.pdb",
chains=["A"], # Specific chains (None = all)
positions=[10, 20, 30], # Specific positions (None = all)
show_progress=True
)
# Batch prediction for multiple structures
results = model.predict_batch(
["protein1.pdb", "protein2.pdb"],
chains=["A"],
show_progress=True
)
# Results DataFrame columns:
# - frustration_pred: Predicted frustration value
# - position: 0-indexed position
# - wildtype: Wild-type amino acid
# - mutation: Mutant amino acid
# - pdb: PDB identifier
# - chain: Chain identifier# Basic prediction
frustrampnn predict --pdb protein.pdb --checkpoint model.ckpt --output results.csv
# Specify chains
frustrampnn predict --pdb protein.pdb --checkpoint model.ckpt --chains A B
# Batch processing
frustrampnn predict --pdb-dir ./structures/ --checkpoint model.ckpt --output batch_results.csv
# Show help
frustrampnn --help
frustrampnn predict --helpFor zero-installation access, use our Google Colab notebook:
The notebook provides:
- One-click installation
- PDB upload or RCSB fetch
- Interactive visualizations
- Results download
from frustrampnn.visualization import (
plot_single_residue,
plot_single_residue_plotly,
plot_frustration_heatmap,
plot_frustration_heatmap_plotly,
)
# Single-residue plot (matplotlib)
fig = plot_single_residue(results, position=72, chain="A")
fig.savefig("position_73.png", dpi=300)
# Single-residue plot (plotly, interactive)
fig = plot_single_residue_plotly(results, position=72, chain="A")
fig.show()
# Heatmap (matplotlib)
fig = plot_frustration_heatmap(results, chain="A")
fig.savefig("heatmap.png", dpi=300)
# Heatmap (plotly, interactive)
fig = plot_frustration_heatmap_plotly(results, chain="A")
fig.show()Color scheme:
- Red: Highly frustrated (frustration index <= -1.0)
- Gray: Neutral (-1.0 < frustration index < 0.58)
- Green: Minimally frustrated (frustration index >= 0.58)
- Blue: Native (wild-type) residue
Compare FrustraMPNN predictions with physics-based frustrapy:
from frustrampnn.validation import compare_with_frustrapy
# Compare at specific positions (frustrapy is slow)
comparison = compare_with_frustrapy(
pdb_path="protein.pdb",
chain="A",
frustrampnn_results=results,
positions=[50, 73, 120],
)
print(f"Spearman: {comparison.spearman:.3f}")
print(f"RMSE: {comparison.rmse:.3f}")
# Plot comparison
fig = comparison.plot()
fig.show()| Protein Size | FrustraMPNN (GPU) | FrustratometeR (CPU) | Speedup |
|---|---|---|---|
| 100 residues | ~20 ms | ~3.4 min | 1,200x |
| 300 residues | ~30 s | ~19 h | 2,300x |
| 500 residues | ~30 s | ~35 h | 4,500x |
If you use FrustraMPNN in your research, please cite:
@article{beining2026frustrampnn,
title={FrustraMPNN: Ultra-fast deep learning prediction of single-residue local energetic frustration},
author={Beining, Max and Engelberger, Felipe and Schoeder, Clara T. and Ram{\'\i}rez-Sarmiento, C{\'e}sar A. and Meiler, Jens},
journal={XXXXXXXXXX},
year={2026},
doi={10.1101/2026.XX.XX.XXXXXX}
}MIT License - see LICENSE for details.
- frustrapy - Python wrapper for FrustratometeR
- ProteinMPNN - Base architecture
- ThermoMPNN - Transfer learning approach