Upload folder using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitattributes +28 -9
- .gitignore +171 -0
- .gitmodules +4 -0
- CODE_OF_CONDUCT.md +127 -0
- CONTRIBUTING.md +61 -0
- LICENSE +201 -0
- README.md +520 -0
- conf/examples/5o45.cif +0 -0
- conf/examples/PDL1_quick_start.yaml +16 -0
- conf/examples/msa/PDL1/0/non_pairing.a3m +0 -0
- conf/examples/msa/PDL1/0/pairing.a3m +0 -0
- configuration.json +39 -0
- model/PXDesignBench/.gitignore +168 -0
- model/PXDesignBench/CODE_OF_CONDUCT.md +127 -0
- model/PXDesignBench/CONTRIBUTING.md +61 -0
- model/PXDesignBench/ColabDesign/.github/workflows/python-publish.yml +39 -0
- model/PXDesignBench/ColabDesign/.gitignore +2 -0
- model/PXDesignBench/ColabDesign/LICENSE.txt +8 -0
- model/PXDesignBench/ColabDesign/MANIFEST.in +4 -0
- model/PXDesignBench/ColabDesign/README.md +29 -0
- model/PXDesignBench/ColabDesign/af/LICENSE.txt +8 -0
- model/PXDesignBench/ColabDesign/af/README.md +336 -0
- model/PXDesignBench/ColabDesign/af/contrib/README.md +1 -0
- model/PXDesignBench/ColabDesign/af/design.ipynb +452 -0
- model/PXDesignBench/ColabDesign/af/examples/AF2Rank.ipynb +0 -0
- model/PXDesignBench/ColabDesign/af/examples/RSO.ipynb +1297 -0
- model/PXDesignBench/ColabDesign/af/examples/af2cycler.ipynb +741 -0
- model/PXDesignBench/ColabDesign/af/examples/af_cyc_design.ipynb +320 -0
- model/PXDesignBench/ColabDesign/af/examples/af_pseudo_diffusion.ipynb +266 -0
- model/PXDesignBench/ColabDesign/af/examples/af_pseudo_diffusion_dgram.ipynb +376 -0
- model/PXDesignBench/ColabDesign/af/examples/af_pseudo_diffusion_recycle.ipynb +329 -0
- model/PXDesignBench/ColabDesign/af/examples/af_relax_design.ipynb +400 -0
- model/PXDesignBench/ColabDesign/af/examples/af_single_sequential.ipynb +164 -0
- model/PXDesignBench/ColabDesign/af/examples/afdesign_hotspot_test.ipynb +247 -0
- model/PXDesignBench/ColabDesign/af/examples/binder_hallucination.ipynb +42 -0
- model/PXDesignBench/ColabDesign/af/examples/disulfide_design.ipynb +348 -0
- model/PXDesignBench/ColabDesign/af/examples/hallucination.ipynb +193 -0
- model/PXDesignBench/ColabDesign/af/examples/hallucination_custom_loss.ipynb +260 -0
- model/PXDesignBench/ColabDesign/af/examples/partial_hallucination_rewire.ipynb +161 -0
- model/PXDesignBench/ColabDesign/af/examples/peptide_binder_design.ipynb +319 -0
- model/PXDesignBench/ColabDesign/af/examples/use_esm_1b_bias.ipynb +329 -0
- model/PXDesignBench/ColabDesign/af_design_tutorial.ipynb +43 -0
- model/PXDesignBench/ColabDesign/colabdesign/__init__.py +16 -0
- model/PXDesignBench/ColabDesign/colabdesign/af/README.md +6 -0
- model/PXDesignBench/ColabDesign/colabdesign/af/__init__.py +13 -0
- model/PXDesignBench/ColabDesign/colabdesign/af/alphafold/__init__.py +14 -0
- model/PXDesignBench/ColabDesign/colabdesign/af/alphafold/common/__init__.py +14 -0
- model/PXDesignBench/ColabDesign/colabdesign/af/alphafold/common/confidence.py +169 -0
- model/PXDesignBench/ColabDesign/colabdesign/af/alphafold/common/protein.py +229 -0
- model/PXDesignBench/ColabDesign/colabdesign/af/alphafold/common/residue_constants.py +911 -0
.gitattributes
CHANGED
|
@@ -1,35 +1,54 @@
|
|
| 1 |
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
*.bin filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 4 |
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
-
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bin.* filter=lfs diff=lfs merge=lfs -text
|
| 5 |
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 6 |
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 11 |
*.model filter=lfs diff=lfs merge=lfs -text
|
| 12 |
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
| 13 |
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 14 |
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 15 |
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 16 |
*.pb filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
| 17 |
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 18 |
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 19 |
*.rar filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 20 |
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 21 |
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 22 |
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 23 |
*.tgz filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 24 |
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 25 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
*.zstandard filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.db* filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.ark* filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
**/*ckpt*data* filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
**/*ckpt*.meta filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
**/*ckpt*.index filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*.gguf* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
*.ggml filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
*.llamafile* filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
*.pt2 filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 44 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 45 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 46 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 47 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 48 |
+
weight/release_data/ccd_cache/components.v20240608.cif filter=lfs diff=lfs merge=lfs -text
|
| 49 |
+
model/PXDesignBench/pxdbench/metrics/TMalign filter=lfs diff=lfs merge=lfs -text
|
| 50 |
+
model/Protenix-pxd/Protenix_Technical_Report.pdf filter=lfs diff=lfs merge=lfs -text
|
| 51 |
+
model/Protenix-pxd/assets/constraint_metrics.png filter=lfs diff=lfs merge=lfs -text
|
| 52 |
+
model/Protenix-pxd/assets/mini_performance.png filter=lfs diff=lfs merge=lfs -text
|
| 53 |
+
model/Protenix-pxd/assets/protenix_predictions.gif filter=lfs diff=lfs merge=lfs -text
|
| 54 |
+
model/Protenix-pxd/assets/v0.5.0_metrics.png filter=lfs diff=lfs merge=lfs -text
|
.gitignore
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Byte-compiled / optimized / DLL files
|
| 2 |
+
*__pycache__/
|
| 3 |
+
*.py[cod]
|
| 4 |
+
*$py.class
|
| 5 |
+
|
| 6 |
+
# C extensions
|
| 7 |
+
*.so
|
| 8 |
+
*.o
|
| 9 |
+
*.obj
|
| 10 |
+
*.d
|
| 11 |
+
# ninjia relate
|
| 12 |
+
*ninja*
|
| 13 |
+
lock
|
| 14 |
+
# Distribution / packaging
|
| 15 |
+
.Python
|
| 16 |
+
.vscode
|
| 17 |
+
build/
|
| 18 |
+
develop-eggs/
|
| 19 |
+
dist/
|
| 20 |
+
downloads/
|
| 21 |
+
eggs/
|
| 22 |
+
.eggs/
|
| 23 |
+
lib/
|
| 24 |
+
lib64/
|
| 25 |
+
parts/
|
| 26 |
+
sdist/
|
| 27 |
+
var/
|
| 28 |
+
wheels/
|
| 29 |
+
share/python-wheels/
|
| 30 |
+
*.egg-info/
|
| 31 |
+
.installed.cfg
|
| 32 |
+
*.egg
|
| 33 |
+
MANIFEST
|
| 34 |
+
|
| 35 |
+
# PyInstaller
|
| 36 |
+
# Usually these files are written by a python script from a template
|
| 37 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
| 38 |
+
*.manifest
|
| 39 |
+
*.spec
|
| 40 |
+
|
| 41 |
+
# Installer logs
|
| 42 |
+
pip-log.txt
|
| 43 |
+
pip-delete-this-directory.txt
|
| 44 |
+
|
| 45 |
+
# Unit test / coverage reports
|
| 46 |
+
.tox/
|
| 47 |
+
.nox/
|
| 48 |
+
.coverage
|
| 49 |
+
.coverage.*
|
| 50 |
+
.cache
|
| 51 |
+
*.cover
|
| 52 |
+
*.py,cover
|
| 53 |
+
.hypothesis/
|
| 54 |
+
.pytest_cache/
|
| 55 |
+
|
| 56 |
+
# Translations
|
| 57 |
+
*.mo
|
| 58 |
+
*.pot
|
| 59 |
+
|
| 60 |
+
# Django stuff:
|
| 61 |
+
*.log
|
| 62 |
+
local_settings.py
|
| 63 |
+
db.sqlite3
|
| 64 |
+
db.sqlite3-journal
|
| 65 |
+
|
| 66 |
+
# Flask stuff:
|
| 67 |
+
instance/
|
| 68 |
+
.webassets-cache
|
| 69 |
+
|
| 70 |
+
# Scrapy stuff:
|
| 71 |
+
.scrapy
|
| 72 |
+
|
| 73 |
+
# Sphinx documentation
|
| 74 |
+
docs/_build/
|
| 75 |
+
|
| 76 |
+
# PyBuilder
|
| 77 |
+
.pybuilder/
|
| 78 |
+
target/
|
| 79 |
+
|
| 80 |
+
# Jupyter Notebook
|
| 81 |
+
.ipynb_checkpoints
|
| 82 |
+
|
| 83 |
+
# IPython
|
| 84 |
+
profile_default/
|
| 85 |
+
ipython_config.py
|
| 86 |
+
|
| 87 |
+
# data cache and checkpoints
|
| 88 |
+
data_cache/
|
| 89 |
+
checkpoints/
|
| 90 |
+
|
| 91 |
+
# pyenv
|
| 92 |
+
# For a library or package, you might want to ignore these files since the code is
|
| 93 |
+
# intended to run in multiple environments; otherwise, check them in:
|
| 94 |
+
# .python-version
|
| 95 |
+
|
| 96 |
+
# pipenv
|
| 97 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
| 98 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
| 99 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
| 100 |
+
# install all needed dependencies.
|
| 101 |
+
#Pipfile.lock
|
| 102 |
+
|
| 103 |
+
# poetry
|
| 104 |
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
| 105 |
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
| 106 |
+
# commonly ignored for libraries.
|
| 107 |
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
| 108 |
+
#poetry.lock
|
| 109 |
+
|
| 110 |
+
# pdm
|
| 111 |
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
| 112 |
+
#pdm.lock
|
| 113 |
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
| 114 |
+
# in version control.
|
| 115 |
+
# https://pdm.fming.dev/#use-with-ide
|
| 116 |
+
.pdm.toml
|
| 117 |
+
|
| 118 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
| 119 |
+
__pypackages__/
|
| 120 |
+
|
| 121 |
+
# Celery stuff
|
| 122 |
+
celerybeat-schedule
|
| 123 |
+
celerybeat.pid
|
| 124 |
+
|
| 125 |
+
# SageMath parsed files
|
| 126 |
+
*.sage.py
|
| 127 |
+
|
| 128 |
+
# Environments
|
| 129 |
+
.env
|
| 130 |
+
.venv
|
| 131 |
+
env/
|
| 132 |
+
venv/
|
| 133 |
+
ENV/
|
| 134 |
+
env.bak/
|
| 135 |
+
venv.bak/
|
| 136 |
+
|
| 137 |
+
# Spyder project settings
|
| 138 |
+
.spyderproject
|
| 139 |
+
.spyproject
|
| 140 |
+
|
| 141 |
+
# Rope project settings
|
| 142 |
+
.ropeproject
|
| 143 |
+
|
| 144 |
+
# mkdocs documentation
|
| 145 |
+
/site
|
| 146 |
+
|
| 147 |
+
# mypy
|
| 148 |
+
.mypy_cache/
|
| 149 |
+
.dmypy.json
|
| 150 |
+
dmypy.json
|
| 151 |
+
|
| 152 |
+
# Pyre type checker
|
| 153 |
+
.pyre/
|
| 154 |
+
|
| 155 |
+
# pytype static type analyzer
|
| 156 |
+
.pytype/
|
| 157 |
+
|
| 158 |
+
# Cython debug symbols
|
| 159 |
+
cython_debug/
|
| 160 |
+
|
| 161 |
+
# PyCharm
|
| 162 |
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
| 163 |
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
| 164 |
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
| 165 |
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
| 166 |
+
#.idea/
|
| 167 |
+
|
| 168 |
+
wandb/
|
| 169 |
+
output*/
|
| 170 |
+
release_data/
|
| 171 |
+
tool_weights/
|
.gitmodules
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[submodule "eval_design"]
|
| 2 |
+
path = eval_design
|
| 3 |
+
url = https://github.com/bytedance/PXDesignBench.git
|
| 4 |
+
branch = master
|
CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Contributor Covenant Code of Conduct
|
| 2 |
+
|
| 3 |
+
## Our Pledge
|
| 4 |
+
|
| 5 |
+
We as members, contributors, and leaders pledge to make participation in our
|
| 6 |
+
community a harassment-free experience for everyone, regardless of age, body
|
| 7 |
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
| 8 |
+
identity and expression, level of experience, education, socio-economic status,
|
| 9 |
+
nationality, personal appearance, race, religion, or sexual identity
|
| 10 |
+
and orientation.
|
| 11 |
+
|
| 12 |
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
| 13 |
+
diverse, inclusive, and healthy community.
|
| 14 |
+
|
| 15 |
+
## Our Standards
|
| 16 |
+
|
| 17 |
+
Examples of behavior that contributes to a positive environment for our
|
| 18 |
+
community include:
|
| 19 |
+
|
| 20 |
+
* Demonstrating empathy and kindness toward other people
|
| 21 |
+
* Being respectful of differing opinions, viewpoints, and experiences
|
| 22 |
+
* Giving and gracefully accepting constructive feedback
|
| 23 |
+
* Accepting responsibility and apologizing to those affected by our mistakes,
|
| 24 |
+
and learning from the experience
|
| 25 |
+
* Focusing on what is best not just for us as individuals, but for the
|
| 26 |
+
overall community
|
| 27 |
+
|
| 28 |
+
Examples of unacceptable behavior include:
|
| 29 |
+
|
| 30 |
+
* The use of sexualized language or imagery, and sexual attention or
|
| 31 |
+
advances of any kind
|
| 32 |
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
| 33 |
+
* Public or private harassment
|
| 34 |
+
* Publishing others' private information, such as a physical or email
|
| 35 |
+
address, without their explicit permission
|
| 36 |
+
* Other conduct which could reasonably be considered inappropriate in a
|
| 37 |
+
professional setting
|
| 38 |
+
|
| 39 |
+
## Enforcement Responsibilities
|
| 40 |
+
|
| 41 |
+
Community leaders are responsible for clarifying and enforcing our standards of
|
| 42 |
+
acceptable behavior and will take appropriate and fair corrective action in
|
| 43 |
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
| 44 |
+
or harmful.
|
| 45 |
+
|
| 46 |
+
Community leaders have the right and responsibility to remove, edit, or reject
|
| 47 |
+
comments, commits, code, wiki edits, issues, and other contributions that are
|
| 48 |
+
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
| 49 |
+
decisions when appropriate.
|
| 50 |
+
|
| 51 |
+
## Scope
|
| 52 |
+
|
| 53 |
+
This Code of Conduct applies within all community spaces, and also applies when
|
| 54 |
+
an individual is officially representing the community in public spaces.
|
| 55 |
+
Examples of representing our community include using an official e-mail address,
|
| 56 |
+
posting via an official social media account, or acting as an appointed
|
| 57 |
+
representative at an online or offline event.
|
| 58 |
+
|
| 59 |
+
## Enforcement
|
| 60 |
+
|
| 61 |
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
| 62 |
+
reported to the community leaders responsible for enforcement.
|
| 63 |
+
All complaints will be reviewed and investigated promptly and fairly.
|
| 64 |
+
|
| 65 |
+
All community leaders are obligated to respect the privacy and security of the
|
| 66 |
+
reporter of any incident.
|
| 67 |
+
|
| 68 |
+
## Enforcement Guidelines
|
| 69 |
+
|
| 70 |
+
Community leaders will follow these Community Impact Guidelines in determining
|
| 71 |
+
the consequences for any action they deem in violation of this Code of Conduct:
|
| 72 |
+
|
| 73 |
+
### 1. Correction
|
| 74 |
+
|
| 75 |
+
**Community Impact**: Use of inappropriate language or other behavior deemed
|
| 76 |
+
unprofessional or unwelcome in the community.
|
| 77 |
+
|
| 78 |
+
**Consequence**: A private, written warning from community leaders, providing
|
| 79 |
+
clarity around the nature of the violation and an explanation of why the
|
| 80 |
+
behavior was inappropriate. A public apology may be requested.
|
| 81 |
+
|
| 82 |
+
### 2. Warning
|
| 83 |
+
|
| 84 |
+
**Community Impact**: A violation through a single incident or series
|
| 85 |
+
of actions.
|
| 86 |
+
|
| 87 |
+
**Consequence**: A warning with consequences for continued behavior. No
|
| 88 |
+
interaction with the people involved, including unsolicited interaction with
|
| 89 |
+
those enforcing the Code of Conduct, for a specified period of time. This
|
| 90 |
+
includes avoiding interactions in community spaces as well as external channels
|
| 91 |
+
like social media. Violating these terms may lead to a temporary or
|
| 92 |
+
permanent ban.
|
| 93 |
+
|
| 94 |
+
### 3. Temporary Ban
|
| 95 |
+
|
| 96 |
+
**Community Impact**: A serious violation of community standards, including
|
| 97 |
+
sustained inappropriate behavior.
|
| 98 |
+
|
| 99 |
+
**Consequence**: A temporary ban from any sort of interaction or public
|
| 100 |
+
communication with the community for a specified period of time. No public or
|
| 101 |
+
private interaction with the people involved, including unsolicited interaction
|
| 102 |
+
with those enforcing the Code of Conduct, is allowed during this period.
|
| 103 |
+
Violating these terms may lead to a permanent ban.
|
| 104 |
+
|
| 105 |
+
### 4. Permanent Ban
|
| 106 |
+
|
| 107 |
+
**Community Impact**: Demonstrating a pattern of violation of community
|
| 108 |
+
standards, including sustained inappropriate behavior, harassment of an
|
| 109 |
+
individual, or aggression toward or disparagement of classes of individuals.
|
| 110 |
+
|
| 111 |
+
**Consequence**: A permanent ban from any sort of public interaction within
|
| 112 |
+
the community.
|
| 113 |
+
|
| 114 |
+
## Attribution
|
| 115 |
+
|
| 116 |
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
| 117 |
+
version 2.0, available at
|
| 118 |
+
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
| 119 |
+
|
| 120 |
+
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
| 121 |
+
enforcement ladder](https://github.com/mozilla/diversity).
|
| 122 |
+
|
| 123 |
+
[homepage]: https://www.contributor-covenant.org
|
| 124 |
+
|
| 125 |
+
For answers to common questions about this code of conduct, see the FAQ at
|
| 126 |
+
https://www.contributor-covenant.org/faq. Translations are available at
|
| 127 |
+
https://www.contributor-covenant.org/translations.
|
CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Contributing
|
| 2 |
+
|
| 3 |
+
Thank you for investing your time in contributing to <NAME> project!
|
| 4 |
+
|
| 5 |
+
Read our [Code of Coduct](./CODE_OF_CONDUCT.md) to keep our community approachable and respectable.
|
| 6 |
+
|
| 7 |
+
This guide details how to use issues and pull requests to improve <NAME> project.
|
| 8 |
+
|
| 9 |
+
## General Guidelines
|
| 10 |
+
|
| 11 |
+
### Pull Requests
|
| 12 |
+
|
| 13 |
+
Make sure to keep Pull Requests small and functional to make them easier to review, understand, and look up in commit history. This repository uses "Squash and Commit" to keep our history clean and make it easier to revert changes based on PR.
|
| 14 |
+
|
| 15 |
+
Adding the appropriate documentation, unit tests and e2e tests as part of a feature is the responsibility of the feature owner, whether it is done in the same Pull Request or not.
|
| 16 |
+
|
| 17 |
+
Pull Requests should follow the "subject: message" format, where the subject describes what part of the code is being modified.
|
| 18 |
+
|
| 19 |
+
Refer to the template for more information on what goes into a PR description.
|
| 20 |
+
|
| 21 |
+
### Design Docs
|
| 22 |
+
|
| 23 |
+
A contributor proposes a design with a PR on the repository to allow for revisions and discussions. If a design needs to be discussed before formulating a document for it, make use of Google doc and GitHub issue to involve the community on the discussion.
|
| 24 |
+
|
| 25 |
+
### GitHub Issues
|
| 26 |
+
|
| 27 |
+
GitHub Issues are used to file bugs, work items, and feature requests with actionable items/issues (Please refer to the "Reporting Bugs/Feature Requests" section below for more information).
|
| 28 |
+
|
| 29 |
+
### Reporting Bugs/Feature Requests
|
| 30 |
+
|
| 31 |
+
We welcome you to use the GitHub issue tracker to report bugs or suggest features that have actionable items/issues (as opposed to introducing a feature request on GitHub Discussions).
|
| 32 |
+
|
| 33 |
+
When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
|
| 34 |
+
|
| 35 |
+
- A reproducible test case or series of steps
|
| 36 |
+
- The version of the code being used
|
| 37 |
+
- Any modifications you've made relevant to the bug
|
| 38 |
+
- Anything unusual about your environment or deployment
|
| 39 |
+
|
| 40 |
+
## Contributing via Pull Requests
|
| 41 |
+
|
| 42 |
+
### Find interesting issue
|
| 43 |
+
|
| 44 |
+
If you spot a problem with the problem, [search if an issue already exists](https://github.com/bytedance/<NAME>/issues). If a related issue doesn't exist, you can open a new issue using [issue template](https://github.com/bytedance/<NAME>/issues/new/choose).
|
| 45 |
+
|
| 46 |
+
### Solve an issue
|
| 47 |
+
|
| 48 |
+
Please check `DEVELOPMENT.md` in sub folder to get familar with running and testing codes.
|
| 49 |
+
|
| 50 |
+
### Open a Pull request.
|
| 51 |
+
|
| 52 |
+
When you're done making the changes, open a pull request and fill PR template so we can better review your PR. The template helps reviewers understand your changes and the purpose of your pull request.
|
| 53 |
+
|
| 54 |
+
Don't forget to link PR to issue if you are solving one.
|
| 55 |
+
|
| 56 |
+
If you run into any merge issues, checkout this [git tutorial](https://lab.github.com/githubtraining/managing-merge-conflicts) to help you resolve merge conflicts and other issues.
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
## Finding contributions to work on
|
| 60 |
+
|
| 61 |
+
Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' and 'good first issue' issues are a great place to start.
|
LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Apache License
|
| 2 |
+
Version 2.0, January 2004
|
| 3 |
+
http://www.apache.org/licenses/
|
| 4 |
+
|
| 5 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
| 6 |
+
|
| 7 |
+
1. Definitions.
|
| 8 |
+
|
| 9 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
| 10 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
| 11 |
+
|
| 12 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
| 13 |
+
the copyright owner that is granting the License.
|
| 14 |
+
|
| 15 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
| 16 |
+
other entities that control, are controlled by, or are under common
|
| 17 |
+
control with that entity. For the purposes of this definition,
|
| 18 |
+
"control" means (i) the power, direct or indirect, to cause the
|
| 19 |
+
direction or management of such entity, whether by contract or
|
| 20 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
| 21 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
| 22 |
+
|
| 23 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
| 24 |
+
exercising permissions granted by this License.
|
| 25 |
+
|
| 26 |
+
"Source" form shall mean the preferred form for making modifications,
|
| 27 |
+
including but not limited to software source code, documentation
|
| 28 |
+
source, and configuration files.
|
| 29 |
+
|
| 30 |
+
"Object" form shall mean any form resulting from mechanical
|
| 31 |
+
transformation or translation of a Source form, including but
|
| 32 |
+
not limited to compiled object code, generated documentation,
|
| 33 |
+
and conversions to other media types.
|
| 34 |
+
|
| 35 |
+
"Work" shall mean the work of authorship, whether in Source or
|
| 36 |
+
Object form, made available under the License, as indicated by a
|
| 37 |
+
copyright notice that is included in or attached to the work
|
| 38 |
+
(an example is provided in the Appendix below).
|
| 39 |
+
|
| 40 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
| 41 |
+
form, that is based on (or derived from) the Work and for which the
|
| 42 |
+
editorial revisions, annotations, elaborations, or other modifications
|
| 43 |
+
represent, as a whole, an original work of authorship. For the purposes
|
| 44 |
+
of this License, Derivative Works shall not include works that remain
|
| 45 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
| 46 |
+
the Work and Derivative Works thereof.
|
| 47 |
+
|
| 48 |
+
"Contribution" shall mean any work of authorship, including
|
| 49 |
+
the original version of the Work and any modifications or additions
|
| 50 |
+
to that Work or Derivative Works thereof, that is intentionally
|
| 51 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
| 52 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
| 53 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
| 54 |
+
means any form of electronic, verbal, or written communication sent
|
| 55 |
+
to the Licensor or its representatives, including but not limited to
|
| 56 |
+
communication on electronic mailing lists, source code control systems,
|
| 57 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
| 58 |
+
Licensor for the purpose of discussing and improving the Work, but
|
| 59 |
+
excluding communication that is conspicuously marked or otherwise
|
| 60 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
| 61 |
+
|
| 62 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
| 63 |
+
on behalf of whom a Contribution has been received by Licensor and
|
| 64 |
+
subsequently incorporated within the Work.
|
| 65 |
+
|
| 66 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
| 67 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 68 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 69 |
+
copyright license to reproduce, prepare Derivative Works of,
|
| 70 |
+
publicly display, publicly perform, sublicense, and distribute the
|
| 71 |
+
Work and such Derivative Works in Source or Object form.
|
| 72 |
+
|
| 73 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
| 74 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 75 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 76 |
+
(except as stated in this section) patent license to make, have made,
|
| 77 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
| 78 |
+
where such license applies only to those patent claims licensable
|
| 79 |
+
by such Contributor that are necessarily infringed by their
|
| 80 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
| 81 |
+
with the Work to which such Contribution(s) was submitted. If You
|
| 82 |
+
institute patent litigation against any entity (including a
|
| 83 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
| 84 |
+
or a Contribution incorporated within the Work constitutes direct
|
| 85 |
+
or contributory patent infringement, then any patent licenses
|
| 86 |
+
granted to You under this License for that Work shall terminate
|
| 87 |
+
as of the date such litigation is filed.
|
| 88 |
+
|
| 89 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
| 90 |
+
Work or Derivative Works thereof in any medium, with or without
|
| 91 |
+
modifications, and in Source or Object form, provided that You
|
| 92 |
+
meet the following conditions:
|
| 93 |
+
|
| 94 |
+
(a) You must give any other recipients of the Work or
|
| 95 |
+
Derivative Works a copy of this License; and
|
| 96 |
+
|
| 97 |
+
(b) You must cause any modified files to carry prominent notices
|
| 98 |
+
stating that You changed the files; and
|
| 99 |
+
|
| 100 |
+
(c) You must retain, in the Source form of any Derivative Works
|
| 101 |
+
that You distribute, all copyright, patent, trademark, and
|
| 102 |
+
attribution notices from the Source form of the Work,
|
| 103 |
+
excluding those notices that do not pertain to any part of
|
| 104 |
+
the Derivative Works; and
|
| 105 |
+
|
| 106 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
| 107 |
+
distribution, then any Derivative Works that You distribute must
|
| 108 |
+
include a readable copy of the attribution notices contained
|
| 109 |
+
within such NOTICE file, excluding those notices that do not
|
| 110 |
+
pertain to any part of the Derivative Works, in at least one
|
| 111 |
+
of the following places: within a NOTICE text file distributed
|
| 112 |
+
as part of the Derivative Works; within the Source form or
|
| 113 |
+
documentation, if provided along with the Derivative Works; or,
|
| 114 |
+
within a display generated by the Derivative Works, if and
|
| 115 |
+
wherever such third-party notices normally appear. The contents
|
| 116 |
+
of the NOTICE file are for informational purposes only and
|
| 117 |
+
do not modify the License. You may add Your own attribution
|
| 118 |
+
notices within Derivative Works that You distribute, alongside
|
| 119 |
+
or as an addendum to the NOTICE text from the Work, provided
|
| 120 |
+
that such additional attribution notices cannot be construed
|
| 121 |
+
as modifying the License.
|
| 122 |
+
|
| 123 |
+
You may add Your own copyright statement to Your modifications and
|
| 124 |
+
may provide additional or different license terms and conditions
|
| 125 |
+
for use, reproduction, or distribution of Your modifications, or
|
| 126 |
+
for any such Derivative Works as a whole, provided Your use,
|
| 127 |
+
reproduction, and distribution of the Work otherwise complies with
|
| 128 |
+
the conditions stated in this License.
|
| 129 |
+
|
| 130 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
| 131 |
+
any Contribution intentionally submitted for inclusion in the Work
|
| 132 |
+
by You to the Licensor shall be under the terms and conditions of
|
| 133 |
+
this License, without any additional terms or conditions.
|
| 134 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
| 135 |
+
the terms of any separate license agreement you may have executed
|
| 136 |
+
with Licensor regarding such Contributions.
|
| 137 |
+
|
| 138 |
+
6. Trademarks. This License does not grant permission to use the trade
|
| 139 |
+
names, trademarks, service marks, or product names of the Licensor,
|
| 140 |
+
except as required for reasonable and customary use in describing the
|
| 141 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
| 142 |
+
|
| 143 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
| 144 |
+
agreed to in writing, Licensor provides the Work (and each
|
| 145 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
| 146 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
| 147 |
+
implied, including, without limitation, any warranties or conditions
|
| 148 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
| 149 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
| 150 |
+
appropriateness of using or redistributing the Work and assume any
|
| 151 |
+
risks associated with Your exercise of permissions under this License.
|
| 152 |
+
|
| 153 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
| 154 |
+
whether in tort (including negligence), contract, or otherwise,
|
| 155 |
+
unless required by applicable law (such as deliberate and grossly
|
| 156 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
| 157 |
+
liable to You for damages, including any direct, indirect, special,
|
| 158 |
+
incidental, or consequential damages of any character arising as a
|
| 159 |
+
result of this License or out of the use or inability to use the
|
| 160 |
+
Work (including but not limited to damages for loss of goodwill,
|
| 161 |
+
work stoppage, computer failure or malfunction, or any and all
|
| 162 |
+
other commercial damages or losses), even if such Contributor
|
| 163 |
+
has been advised of the possibility of such damages.
|
| 164 |
+
|
| 165 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
| 166 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
| 167 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
| 168 |
+
or other liability obligations and/or rights consistent with this
|
| 169 |
+
License. However, in accepting such obligations, You may act only
|
| 170 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
| 171 |
+
of any other Contributor, and only if You agree to indemnify,
|
| 172 |
+
defend, and hold each Contributor harmless for any liability
|
| 173 |
+
incurred by, or claims asserted against, such Contributor by reason
|
| 174 |
+
of your accepting any such warranty or additional liability.
|
| 175 |
+
|
| 176 |
+
END OF TERMS AND CONDITIONS
|
| 177 |
+
|
| 178 |
+
APPENDIX: How to apply the Apache License to your work.
|
| 179 |
+
|
| 180 |
+
To apply the Apache License to your work, attach the following
|
| 181 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
| 182 |
+
replaced with your own identifying information. (Don't include
|
| 183 |
+
the brackets!) The text should be enclosed in the appropriate
|
| 184 |
+
comment syntax for the file format. We also recommend that a
|
| 185 |
+
file or class name and description of purpose be included on the
|
| 186 |
+
same "printed page" as the copyright notice for easier
|
| 187 |
+
identification within third-party archives.
|
| 188 |
+
|
| 189 |
+
Copyright [yyyy] [name of copyright owner]
|
| 190 |
+
|
| 191 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 192 |
+
you may not use this file except in compliance with the License.
|
| 193 |
+
You may obtain a copy of the License at
|
| 194 |
+
|
| 195 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 196 |
+
|
| 197 |
+
Unless required by applicable law or agreed to in writing, software
|
| 198 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 199 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 200 |
+
See the License for the specific language governing permissions and
|
| 201 |
+
limitations under the License.
|
README.md
ADDED
|
@@ -0,0 +1,520 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
language:
|
| 4 |
+
- en
|
| 5 |
+
- zh
|
| 6 |
+
tags:
|
| 7 |
+
- OneScience
|
| 8 |
+
- life-science
|
| 9 |
+
- protein-design
|
| 10 |
+
- protein-binder
|
| 11 |
+
- PXDesign
|
| 12 |
+
- Protenix
|
| 13 |
+
frameworks: PyTorch
|
| 14 |
+
---
|
| 15 |
+
|
| 16 |
+
<p align="center">
|
| 17 |
+
<strong>
|
| 18 |
+
<span style="font-size: 30px;">PXDesign</span>
|
| 19 |
+
</strong>
|
| 20 |
+
</p>
|
| 21 |
+
|
| 22 |
+
# Model Introduction
|
| 23 |
+
|
| 24 |
+
PXDesign is an open-source suite from the ByteDance team for de novo protein binder design. Given a target protein structure, it generates candidate binders and further filters candidate structures through structure prediction and confidence evaluation workflows.
|
| 25 |
+
|
| 26 |
+
The complete PXDesign workflow consists of the PXDesign diffusion generation model, ProteinMPNN sequence design, AF2-IG evaluation, and Protenix evaluation. The official implementation provides three primary modes, generation-only, preview, and extended, covering use cases from quick validation to complete candidate screening.
|
| 27 |
+
|
| 28 |
+
Paper:
|
| 29 |
+
> **PXDesign: Fast, Modular, and Accurate De Novo Design of Protein Binders**
|
| 30 |
+
> https://www.biorxiv.org/content/10.1101/2025.08.15.670647v1
|
| 31 |
+
|
| 32 |
+
# Model Description
|
| 33 |
+
|
| 34 |
+
The core task of PXDesign is to generate new protein binders from a target protein structure and specified design regions.
|
| 35 |
+
|
| 36 |
+
The typical workflow is:
|
| 37 |
+
```text
|
| 38 |
+
Target protein structure and design constraints
|
| 39 |
+
-> PXDesign-d diffusion model
|
| 40 |
+
-> Binder Backbone Generation
|
| 41 |
+
-> ProteinMPNN sequence design
|
| 42 |
+
-> AF2-IG structure prediction and filtering
|
| 43 |
+
-> Protenix structure prediction and filtering (extended mode)
|
| 44 |
+
-> summary.csv
|
| 45 |
+
-> Filtered high-confidence binders
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
Where:
|
| 49 |
+
- **PXDesign-d**: Generates candidate binder backbones from the target protein structure, hotspots, binder length, and other conditions.
|
| 50 |
+
- **ProteinMPNN**: Designs amino acid sequences for the generated protein backbones.
|
| 51 |
+
- **AF2-IG**: Predicts structures and applies quality filters to candidate binder-target complexes.
|
| 52 |
+
- **Protenix**: Provides additional structure prediction and confidence evaluation in extended mode.
|
| 53 |
+
- **summary.csv**: Summarizes AF2-IG, Protenix, and other evaluation metrics for candidate structures, along with the pass status of each filter.
|
| 54 |
+
|
| 55 |
+
# Use Cases
|
| 56 |
+
|
| 57 |
+
| Use case | Description |
|
| 58 |
+
| --- | --- |
|
| 59 |
+
| De novo protein binder design | Generate new candidate binders from a given target protein structure |
|
| 60 |
+
| Interface-guided design | Use hotspots to specify target residues that the binder should preferentially bind |
|
| 61 |
+
| Rapid validation of protein design workflows | Use preview mode to quickly evaluate whether the design task and parameters are reasonable |
|
| 62 |
+
| High-quality candidate screening | Use extended mode with AF2-IG and Protenix for multistage filtering |
|
| 63 |
+
| Structure generation research | Use `pxdesign infer` to run only the PXDesign generation stage |
|
| 64 |
+
|
| 65 |
+
# Usage
|
| 66 |
+
|
| 67 |
+
## 1. Using OneCode
|
| 68 |
+
|
| 69 |
+
Experience intelligent one-click AI4S programming in the OneCode online environment:
|
| 70 |
+
[Try intelligent one-click AI4S programming](https://web-2069360198568017922-iaaj.ksai.scnet.cn:58043/home)
|
| 71 |
+
|
| 72 |
+
## 2. Manual Installation and Usage
|
| 73 |
+
|
| 74 |
+
### Hardware Requirements
|
| 75 |
+
|
| 76 |
+
- A GPU/DCU is recommended for the PXDesign backbone generation stage; complete inference typically requires substantial GPU memory.
|
| 77 |
+
- MSA generation and preparation primarily use the CPU. You can prepare MSAs in advance with `prepare-msa` or by precomputing them.
|
| 78 |
+
- The ProteinMPNN, AF2-IG, and Protenix prediction and screening stages depend on deep learning frameworks such as PyTorch and JAX; a GPU/DCU is recommended.
|
| 79 |
+
- If GPU/DCU resources are limited, prepare the MSA separately on the CPU first, then run the PXDesign generation, ProteinMPNN, AF2-IG, and Protenix evaluation stages.
|
| 80 |
+
|
| 81 |
+
### Set Up the Runtime Environment
|
| 82 |
+
|
| 83 |
+
#### DCU Environment
|
| 84 |
+
|
| 85 |
+
```bash
|
| 86 |
+
# Activate DTK and CONDA first
|
| 87 |
+
conda create -n onescience311 python=3.11 -y
|
| 88 |
+
conda activate onescience311
|
| 89 |
+
|
| 90 |
+
# Install with uv support
|
| 91 |
+
pip install onescience[bio] -i http://mirrors.onescience.ai:3141/pypi/simple/ --trusted-host mirrors.onescience.ai
|
| 92 |
+
```
|
| 93 |
+
|
| 94 |
+
#### Environment Notes
|
| 95 |
+
|
| 96 |
+
- If you encounter missing dependencies or version issues during execution, install additional dependencies according to the versions specified in `requirements.txt`.
|
| 97 |
+
- Enter the project root and activate the environment:
|
| 98 |
+
|
| 99 |
+
```bash
|
| 100 |
+
cd /path/to/PXDesign-main
|
| 101 |
+
conda activate your_env
|
| 102 |
+
```
|
| 103 |
+
|
| 104 |
+
Install PXDesign in the current environment:
|
| 105 |
+
|
| 106 |
+
```bash
|
| 107 |
+
python -m pip install -e model
|
| 108 |
+
```
|
| 109 |
+
|
| 110 |
+
Verify the installation:
|
| 111 |
+
|
| 112 |
+
```bash
|
| 113 |
+
which pxdesign
|
| 114 |
+
pxdesign --help
|
| 115 |
+
pxdesign pipeline --help
|
| 116 |
+
```
|
| 117 |
+
|
| 118 |
+
### Environment Variables
|
| 119 |
+
|
| 120 |
+
After entering the PXDesign root directory, configure the following variables together:
|
| 121 |
+
```bash
|
| 122 |
+
export PXDESIGN_ROOT=$PWD
|
| 123 |
+
export TOOL_WEIGHTS_ROOT=$PWD/weight/tool_weights
|
| 124 |
+
export PROTENIX_DATA_ROOT_DIR=$PWD/weight/release_data/ccd_cache
|
| 125 |
+
```
|
| 126 |
+
|
| 127 |
+
Check them with:
|
| 128 |
+
```bash
|
| 129 |
+
echo $PXDESIGN_ROOT
|
| 130 |
+
echo $TOOL_WEIGHTS_ROOT
|
| 131 |
+
echo $PROTENIX_DATA_ROOT_DIR
|
| 132 |
+
```
|
| 133 |
+
|
| 134 |
+
to confirm the configuration.
|
| 135 |
+
|
| 136 |
+
## Prepare Weights and Data
|
| 137 |
+
|
| 138 |
+
The complete PXDesign workflow depends on PXDesign and Protenix model weights, as well as AlphaFold2, ProteinMPNN, and the CCD cache. This model repository already includes the CCD cache and PXDesign/Protenix checkpoints; users only need to prepare the `tool_weights/` portion separately. The complete preparation process is as follows:
|
| 139 |
+
|
| 140 |
+
### 1) External Tool Weights and CCD Cache
|
| 141 |
+
|
| 142 |
+
PXDesign provides an official download script:
|
| 143 |
+
```bash
|
| 144 |
+
bash scripts/download_tool_weights.sh
|
| 145 |
+
```
|
| 146 |
+
|
| 147 |
+
The script uses the official default directories and generates `tool_weights/` and `release_data/ccd_cache/` in the current directory when run directly. This project has been reorganized under a `weight/` directory, so it is recommended to organize or symlink the existing weights and cache to the locations below.
|
| 148 |
+
|
| 149 |
+
In the current reorganized project structure, place the external tool weights as follows:
|
| 150 |
+
```text
|
| 151 |
+
weight/
|
| 152 |
+
├── tool_weights/
|
| 153 |
+
│ ├── af2/ # AlphaFold2 weights
|
| 154 |
+
│ └── mpnn/ # ProteinMPNN weights
|
| 155 |
+
└── release_data/
|
| 156 |
+
└── ccd_cache/ # Protenix CCD cache
|
| 157 |
+
```
|
| 158 |
+
|
| 159 |
+
- The recommended default location for the CCD cache is:
|
| 160 |
+
|
| 161 |
+
```text
|
| 162 |
+
weight/release_data/ccd_cache/
|
| 163 |
+
```
|
| 164 |
+
|
| 165 |
+
To specify another location, set:
|
| 166 |
+
|
| 167 |
+
```bash
|
| 168 |
+
export PROTENIX_DATA_ROOT_DIR=/path/to/ccd_cache
|
| 169 |
+
```
|
| 170 |
+
|
| 171 |
+
### 2) PXDesign and Protenix Checkpoints
|
| 172 |
+
|
| 173 |
+
The following model weights are downloaded on demand during the first run, or can be downloaded to the corresponding locations in advance:
|
| 174 |
+
```text
|
| 175 |
+
PXDesign diffusion checkpoint
|
| 176 |
+
|
| 177 |
+
Protenix checkpoints:
|
| 178 |
+
├── base
|
| 179 |
+
├── mini
|
| 180 |
+
└── mini_tmpl
|
| 181 |
+
```
|
| 182 |
+
|
| 183 |
+
The recommended location in the reorganized structure is:
|
| 184 |
+
|
| 185 |
+
```text
|
| 186 |
+
weight/release_data/checkpoint/
|
| 187 |
+
```
|
| 188 |
+
|
| 189 |
+
The required files include:
|
| 190 |
+
```text
|
| 191 |
+
pxdesign_v0.1.0.pt
|
| 192 |
+
protenix_base_default_v0.5.0.pt
|
| 193 |
+
protenix_mini_default_v0.5.0.pt
|
| 194 |
+
protenix_mini_tmpl_v0.5.0.pt
|
| 195 |
+
```
|
| 196 |
+
|
| 197 |
+
### 3) Check the Installation
|
| 198 |
+
|
| 199 |
+
After preparation is complete, run:
|
| 200 |
+
```bash
|
| 201 |
+
ls weight/tool_weights/af2/
|
| 202 |
+
ls weight/tool_weights/mpnn/
|
| 203 |
+
ls weight/release_data/ccd_cache/
|
| 204 |
+
ls weight/release_data/checkpoint/*.pt
|
| 205 |
+
```
|
| 206 |
+
to confirm that the required weights and data are ready.
|
| 207 |
+
|
| 208 |
+
## 3. Quick Start
|
| 209 |
+
|
| 210 |
+
### Download the Model Package
|
| 211 |
+
|
| 212 |
+
```bash
|
| 213 |
+
hf download OneScience-Group/PXDesign --local-dir ./PXDesign
|
| 214 |
+
cd PXDesign
|
| 215 |
+
```
|
| 216 |
+
|
| 217 |
+
- PXDesign additionally depends on Protenix and PXDesignBench; the corresponding dependency source code is included in this model repository, so separate downloads are not required.
|
| 218 |
+
- The complete PXDesign workflow also depends on AlphaFold2, ProteinMPNN, and the CCD cache required by Protenix. Prepare these resources as described in "Prepare Weights and Data" first.
|
| 219 |
+
|
| 220 |
+
### Quick Verification
|
| 221 |
+
|
| 222 |
+
First, verify that the command is available:
|
| 223 |
+
```bash
|
| 224 |
+
pxdesign --help
|
| 225 |
+
```
|
| 226 |
+
|
| 227 |
+
To save the results to `runs/` as in the examples below, first create the output directory:
|
| 228 |
+
```bash
|
| 229 |
+
mkdir -p runs
|
| 230 |
+
```
|
| 231 |
+
|
| 232 |
+
Then check the official example YAML:
|
| 233 |
+
```bash
|
| 234 |
+
pxdesign check-input \
|
| 235 |
+
--yaml conf/examples/PDL1_quick_start.yaml
|
| 236 |
+
```
|
| 237 |
+
|
| 238 |
+
On success, the output should be:
|
| 239 |
+
```text
|
| 240 |
+
YAML file is valid.
|
| 241 |
+
```
|
| 242 |
+
|
| 243 |
+
### Example Data
|
| 244 |
+
|
| 245 |
+
The current project provides:
|
| 246 |
+
```text
|
| 247 |
+
conf/examples/
|
| 248 |
+
├── PDL1_quick_start.yaml
|
| 249 |
+
├── 5o45.cif
|
| 250 |
+
└── msa/
|
| 251 |
+
└── PDL1/
|
| 252 |
+
└── 0/
|
| 253 |
+
```
|
| 254 |
+
|
| 255 |
+
`PDL1_quick_start.yaml` defines the PDL1 binder design task.
|
| 256 |
+
|
| 257 |
+
The typical YAML format is:
|
| 258 |
+
```yaml
|
| 259 |
+
target:
|
| 260 |
+
file: "./conf/examples/5o45.cif"
|
| 261 |
+
chains:
|
| 262 |
+
A:
|
| 263 |
+
crop: ["1-116"]
|
| 264 |
+
hotspots: [40, 99, 107]
|
| 265 |
+
msa: "./conf/examples/msa/PDL1/0"
|
| 266 |
+
|
| 267 |
+
binder_length: 80
|
| 268 |
+
```
|
| 269 |
+
|
| 270 |
+
Key fields:
|
| 271 |
+
| Field | Description |
|
| 272 |
+
| --- | --- |
|
| 273 |
+
| `target.file` | Target protein structure file; mmCIF or PDB can be used |
|
| 274 |
+
| `target.chains` | Target chains involved in the design |
|
| 275 |
+
| `crop` | Residue range retained from the target chain |
|
| 276 |
+
| `hotspots` | Target residues used to guide binder interface generation |
|
| 277 |
+
| `msa` | Path to the precomputed MSA for the target chain |
|
| 278 |
+
| `binder_length` | Amino acid length of the binder to be designed |
|
| 279 |
+
|
| 280 |
+
PXDesign primarily uses the mmCIF `label_seq_id` as the standard residue index internally. For custom tasks, mmCIF files are recommended, and `parse-target` should be used to check that crop and hotspot specifications point to the intended positions.
|
| 281 |
+
|
| 282 |
+
### Input Checking and Target Parsing
|
| 283 |
+
|
| 284 |
+
#### 1) Check the YAML
|
| 285 |
+
|
| 286 |
+
Run the following before formally executing a design task:
|
| 287 |
+
|
| 288 |
+
```bash
|
| 289 |
+
pxdesign check-input \
|
| 290 |
+
--yaml conf/examples/PDL1_quick_start.yaml
|
| 291 |
+
```
|
| 292 |
+
|
| 293 |
+
#### 2) Parse the Target and Generate Visualization Debug Files
|
| 294 |
+
```bash
|
| 295 |
+
pxdesign parse-target \
|
| 296 |
+
--yaml conf/examples/PDL1_quick_start.yaml \
|
| 297 |
+
-o runs/debug_target
|
| 298 |
+
```
|
| 299 |
+
|
| 300 |
+
This step is useful for checking the following before running a large-scale design:
|
| 301 |
+
|
| 302 |
+
- whether the crop is correct;
|
| 303 |
+
- whether the hotspots correspond to the intended residues;
|
| 304 |
+
- whether the structure chains and residue numbering are correct.
|
| 305 |
+
|
| 306 |
+
## Inference Examples
|
| 307 |
+
|
| 308 |
+
PXDesign primarily provides three execution modes:
|
| 309 |
+
```text
|
| 310 |
+
Generation Only
|
| 311 |
+
-> Generate only the PXDesign binder backbone
|
| 312 |
+
|
| 313 |
+
Preview Pipeline
|
| 314 |
+
-> PXDesign + ProteinMPNN + AF2-IG
|
| 315 |
+
|
| 316 |
+
Extended Pipeline
|
| 317 |
+
-> PXDesign + ProteinMPNN + AF2-IG + Protenix
|
| 318 |
+
```
|
| 319 |
+
|
| 320 |
+
### 1. Generation Only: Run PXDesign Generation Only
|
| 321 |
+
|
| 322 |
+
#### Quick Smoke Test
|
| 323 |
+
|
| 324 |
+
To first verify that the model, weights, and GPU/DCU work correctly, use a smaller number of steps:
|
| 325 |
+
```bash
|
| 326 |
+
pxdesign infer \
|
| 327 |
+
-i conf/examples/PDL1_quick_start.yaml \
|
| 328 |
+
-o runs/test_infer \
|
| 329 |
+
--load_checkpoint_dir weight/release_data/checkpoint \
|
| 330 |
+
--N_sample 1 \
|
| 331 |
+
--N_step 20 \
|
| 332 |
+
--dtype bf16 \
|
| 333 |
+
--sample_diffusion_chunk_size 1
|
| 334 |
+
```
|
| 335 |
+
|
| 336 |
+
#### Full-Step Generation Test
|
| 337 |
+
|
| 338 |
+
```bash
|
| 339 |
+
pxdesign infer \
|
| 340 |
+
-i conf/examples/PDL1_quick_start.yaml \
|
| 341 |
+
-o runs/test_infer_full \
|
| 342 |
+
--load_checkpoint_dir weight/release_data/checkpoint \
|
| 343 |
+
--N_sample 10 \
|
| 344 |
+
--N_step 400 \
|
| 345 |
+
--dtype bf16
|
| 346 |
+
```
|
| 347 |
+
|
| 348 |
+
This mode only generates binders and does not provide complete AF2/Protenix filtering results.
|
| 349 |
+
|
| 350 |
+
### 2. Preview Pipeline
|
| 351 |
+
|
| 352 |
+
Preview mode runs:
|
| 353 |
+
```text
|
| 354 |
+
PXDesign generation
|
| 355 |
+
-> ProteinMPNN sequence design
|
| 356 |
+
-> AF2-IG filtering
|
| 357 |
+
```
|
| 358 |
+
|
| 359 |
+
```bash
|
| 360 |
+
pxdesign pipeline \
|
| 361 |
+
--preset preview \
|
| 362 |
+
-i conf/examples/PDL1_quick_start.yaml \
|
| 363 |
+
-o runs/test_preview \
|
| 364 |
+
--load_checkpoint_dir weight/release_data/checkpoint \
|
| 365 |
+
--N_sample 2 \
|
| 366 |
+
--N_step 100 \
|
| 367 |
+
--dtype bf16 \
|
| 368 |
+
--use_fast_ln False \
|
| 369 |
+
--use_deepspeed_evo_attention False
|
| 370 |
+
```
|
| 371 |
+
|
| 372 |
+
Preview mode is suitable for:
|
| 373 |
+
- initial validation of the complete pipeline;
|
| 374 |
+
- checking whether the hotspot/crop settings are reasonable;
|
| 375 |
+
- assessing the difficulty of the current design task;
|
| 376 |
+
- running a small pilot experiment before a large-scale Extended task.
|
| 377 |
+
|
| 378 |
+
### 3. Extended Pipeline
|
| 379 |
+
|
| 380 |
+
Extended mode is the official PXDesign workflow for complete evaluation:
|
| 381 |
+
|
| 382 |
+
```text
|
| 383 |
+
PXDesign generation
|
| 384 |
+
-> ProteinMPNN
|
| 385 |
+
-> AF2-IG
|
| 386 |
+
-> Protenix
|
| 387 |
+
-> summary.csv
|
| 388 |
+
```
|
| 389 |
+
|
| 390 |
+
#### Small-Scale Validation
|
| 391 |
+
```bash
|
| 392 |
+
pxdesign pipeline \
|
| 393 |
+
--preset extended \
|
| 394 |
+
-i conf/examples/PDL1_quick_start.yaml \
|
| 395 |
+
-o runs/test_extended \
|
| 396 |
+
--load_checkpoint_dir weight/release_data/checkpoint \
|
| 397 |
+
--N_sample 2 \
|
| 398 |
+
--N_step 100 \
|
| 399 |
+
--dtype bf16 \
|
| 400 |
+
--use_fast_ln False \
|
| 401 |
+
--use_deepspeed_evo_attention False
|
| 402 |
+
```
|
| 403 |
+
|
| 404 |
+
#### Quick Start Scale
|
| 405 |
+
|
| 406 |
+
The official Quick Start example uses:
|
| 407 |
+
```text
|
| 408 |
+
N_sample = 10
|
| 409 |
+
N_step = 400
|
| 410 |
+
```
|
| 411 |
+
|
| 412 |
+
```bash
|
| 413 |
+
pxdesign pipeline \
|
| 414 |
+
--preset extended \
|
| 415 |
+
-i conf/examples/PDL1_quick_start.yaml \
|
| 416 |
+
-o runs/test_extended_N10 \
|
| 417 |
+
--load_checkpoint_dir weight/release_data/checkpoint \
|
| 418 |
+
--N_sample 10 \
|
| 419 |
+
--N_step 400 \
|
| 420 |
+
--dtype bf16 \
|
| 421 |
+
--use_fast_ln False \
|
| 422 |
+
--use_deepspeed_evo_attention False
|
| 423 |
+
```
|
| 424 |
+
|
| 425 |
+
## Output Description
|
| 426 |
+
|
| 427 |
+
The core results from Extended mode are typically located at:
|
| 428 |
+
```text
|
| 429 |
+
<OUT_DIR>/
|
| 430 |
+
└── design_outputs/
|
| 431 |
+
└── <task_name>/
|
| 432 |
+
├── summary.csv
|
| 433 |
+
├── task_info.json
|
| 434 |
+
├── server_extended_mode.png
|
| 435 |
+
├── orig_designed/
|
| 436 |
+
├── passing-AF2-IG-easy/
|
| 437 |
+
└── passing-Protenix-basic/
|
| 438 |
+
```
|
| 439 |
+
|
| 440 |
+
If no designs pass the corresponding filters, the `passing-AF2-IG-easy/` or `passing-Protenix-basic/` directories may not be generated. This is normal for small-sample tests.
|
| 441 |
+
|
| 442 |
+
# Official OneScience Information
|
| 443 |
+
|
| 444 |
+
| Platform | Main OneScience repository | Skills repository |
|
| 445 |
+
| --- | --- | --- |
|
| 446 |
+
| Gitee | https://gitee.com/onescience-ai/onescience | https://gitee.com/onescience-ai/oneskills |
|
| 447 |
+
| GitHub | https://github.com/onescience-ai/OneScience | https://github.com/onescience-ai/oneskills |
|
| 448 |
+
|
| 449 |
+
|
| 450 |
+
# Citation and License
|
| 451 |
+
|
| 452 |
+
If you use PXDesign in research, cite the official PXDesign paper:
|
| 453 |
+
```bibtex
|
| 454 |
+
@article{ren2025pxdesign,
|
| 455 |
+
title={PXDesign: Fast, Modular, and Accurate De Novo Design of Protein Binders},
|
| 456 |
+
author={Ren, Milong and Sun, Jinyuan and Guan, Jiaqi and Liu, Cong and
|
| 457 |
+
Gong, Chengyue and Wang, Yuzhe and Wang, Lan and Cai, Qixu and
|
| 458 |
+
Chen, Xinshi and Xiao, Wenzhi},
|
| 459 |
+
journal={bioRxiv},
|
| 460 |
+
pages={2025--08},
|
| 461 |
+
year={2025},
|
| 462 |
+
publisher={Cold Spring Harbor Laboratory}
|
| 463 |
+
}
|
| 464 |
+
```
|
| 465 |
+
|
| 466 |
+
The complete PXDesign pipeline also depends on methods such as Protenix, ProteinMPNN, and AF2-IG. If you use these modules in research, also cite the corresponding original works as described in the official PXDesign README.
|
| 467 |
+
|
| 468 |
+
Protenix:
|
| 469 |
+
```bibtex
|
| 470 |
+
@article{bytedance2025protenix,
|
| 471 |
+
title={Protenix - Advancing Structure Prediction Through a Comprehensive AlphaFold3 Reproduction},
|
| 472 |
+
author={ByteDance AML AI4Science Team and Chen, Xinshi and Zhang, Yuxuan
|
| 473 |
+
and Lu, Chan and Ma, Wenzhi and Guan, Jiaqi and Gong, Chengyue
|
| 474 |
+
and Yang, Jincai and Zhang, Hanyu and Zhang, Ke and Wu, Shenghao
|
| 475 |
+
and Zhou, Kuangqi and Yang, Yanping and Liu, Zhenyu and Wang, Lan
|
| 476 |
+
and Shi, Bo and Shi, Shaochen and Xiao, Wenzhi},
|
| 477 |
+
year={2025},
|
| 478 |
+
journal={bioRxiv},
|
| 479 |
+
publisher={Cold Spring Harbor Laboratory},
|
| 480 |
+
doi={10.1101/2025.01.08.631967}
|
| 481 |
+
}
|
| 482 |
+
```
|
| 483 |
+
|
| 484 |
+
ProteinMPNN:
|
| 485 |
+
```bibtex
|
| 486 |
+
@article{dauparas2022robust,
|
| 487 |
+
title={Robust deep learning--based protein sequence design using ProteinMPNN},
|
| 488 |
+
author={Dauparas, Justas and Anishchenko, Ivan and Bennett, Nathaniel
|
| 489 |
+
and Bai, Hua and Ragotte, Robert J and Milles, Lukas and others},
|
| 490 |
+
journal={Science},
|
| 491 |
+
volume={378},
|
| 492 |
+
number={6615},
|
| 493 |
+
pages={49--56},
|
| 494 |
+
year={2022}
|
| 495 |
+
}
|
| 496 |
+
```
|
| 497 |
+
|
| 498 |
+
AF2-IG:
|
| 499 |
+
```bibtex
|
| 500 |
+
@article{bennett2023improving,
|
| 501 |
+
title={Improving de novo protein binder design with deep learning},
|
| 502 |
+
author={Bennett, Nathaniel R and Coventry, Brian and Goreshnik, Inna
|
| 503 |
+
and Huang, Buwei and Allen, Aza and Vafeados, Dionne and others},
|
| 504 |
+
journal={Nature Communications},
|
| 505 |
+
volume={14},
|
| 506 |
+
number={1},
|
| 507 |
+
pages={2625},
|
| 508 |
+
year={2023}
|
| 509 |
+
}
|
| 510 |
+
```
|
| 511 |
+
|
| 512 |
+
The official PXDesign repository is released under the **Apache License 2.0**. According to the official README, this license permits academic research and commercial use. Use, modification, and redistribution of the code must comply with the specific terms in this project's `LICENSE`.
|
| 513 |
+
|
| 514 |
+
In addition:
|
| 515 |
+
- AlphaFold2/AF2 weights and related resources are subject to their respective licenses and terms of use.
|
| 516 |
+
- ProteinMPNN is subject to the license of its official repository.
|
| 517 |
+
- Protenix is subject to the license of its official repository.
|
| 518 |
+
- Models and data resources reused through SCNet shared directories remain subject to the authorization conditions of their respective original resources.
|
| 519 |
+
|
| 520 |
+
For papers, reports, or public releases, also cite PXDesign, Protenix, ProteinMPNN, AF2-IG, and any other third-party models and data resources actually used.
|
conf/examples/5o45.cif
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
conf/examples/PDL1_quick_start.yaml
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
target:
|
| 2 |
+
# Path to the target structure (PDB or CIF)
|
| 3 |
+
file: "./conf/examples/5o45.cif"
|
| 4 |
+
# Specify the target chain(s)
|
| 5 |
+
chains:
|
| 6 |
+
# Configuration for Target Chain A
|
| 7 |
+
A:
|
| 8 |
+
# Crop regions (Optional)
|
| 9 |
+
crop: ["1-116"]
|
| 10 |
+
# Binding hotspot residues (Optional)
|
| 11 |
+
hotspots: [40, 99, 107]
|
| 12 |
+
# Path to pre-computed MSA (Optional but recommended)
|
| 13 |
+
msa: "./conf/examples/msa/PDL1/0"
|
| 14 |
+
|
| 15 |
+
# Number of amino acids of the binder to be designed
|
| 16 |
+
binder_length: 80
|
conf/examples/msa/PDL1/0/non_pairing.a3m
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
conf/examples/msa/PDL1/0/pairing.a3m
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
configuration.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"project": "PXDesign-main",
|
| 3 |
+
"layout": {
|
| 4 |
+
"conf": "Configuration files, example inputs, license files, and reproduction notes.",
|
| 5 |
+
"model": "PXDesign source code, bundled Protenix/PXDesignBench source trees, original README, and assets.",
|
| 6 |
+
"scripts": "Installation, dependency, Docker, and download scripts.",
|
| 7 |
+
"weight": "Model checkpoints, CCD cache, AF2/ProteinMPNN external tool weights, and MSA cache."
|
| 8 |
+
},
|
| 9 |
+
"paths": {
|
| 10 |
+
"pxdesign_package": "model/pxdesign",
|
| 11 |
+
"protenix_source": "model/Protenix-pxd",
|
| 12 |
+
"pxdesignbench_source": "model/PXDesignBench",
|
| 13 |
+
"example_yaml": "conf/examples/PDL1_quick_start.yaml",
|
| 14 |
+
"checkpoint_dir": "weight/release_data/checkpoint",
|
| 15 |
+
"ccd_cache_dir": "weight/release_data/ccd_cache",
|
| 16 |
+
"tool_weights_root": "weight/tool_weights",
|
| 17 |
+
"af2_weights": "weight/tool_weights/af2",
|
| 18 |
+
"mpnn_weights": "weight/tool_weights/mpnn",
|
| 19 |
+
"reproduction_notes": "conf/PXDESIGN_REPRODUCTION_NOTES.md",
|
| 20 |
+
"original_readme": "model/README.md"
|
| 21 |
+
},
|
| 22 |
+
"environment": {
|
| 23 |
+
"conda_env_used": "model_bio",
|
| 24 |
+
"tool_weights_root_env": "TOOL_WEIGHTS_ROOT=$PWD/weight/tool_weights",
|
| 25 |
+
"protenix_data_root_env": "PROTENIX_DATA_ROOT_DIR=$PWD/weight/release_data/ccd_cache"
|
| 26 |
+
},
|
| 27 |
+
"validated_tasks": [
|
| 28 |
+
"pxdesign check-input",
|
| 29 |
+
"pxdesign parse-target",
|
| 30 |
+
"pxdesign infer",
|
| 31 |
+
"pxdesign pipeline --preset preview",
|
| 32 |
+
"pxdesign pipeline --preset extended"
|
| 33 |
+
],
|
| 34 |
+
"hpc_runtime_overrides": {
|
| 35 |
+
"use_fast_ln": false,
|
| 36 |
+
"use_deepspeed_evo_attention": false,
|
| 37 |
+
"reason": "The DTK/HIP environment failed to build fastfold_layer_norm_cuda with CUDA compiler flags."
|
| 38 |
+
}
|
| 39 |
+
}
|
model/PXDesignBench/.gitignore
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Byte-compiled / optimized / DLL files
|
| 2 |
+
*__pycache__/
|
| 3 |
+
*.py[cod]
|
| 4 |
+
*$py.class
|
| 5 |
+
|
| 6 |
+
# C extensions
|
| 7 |
+
*.so
|
| 8 |
+
*.o
|
| 9 |
+
*.obj
|
| 10 |
+
*.d
|
| 11 |
+
# ninjia relate
|
| 12 |
+
*ninja*
|
| 13 |
+
lock
|
| 14 |
+
# Distribution / packaging
|
| 15 |
+
.Python
|
| 16 |
+
.vscode
|
| 17 |
+
build/
|
| 18 |
+
develop-eggs/
|
| 19 |
+
dist/
|
| 20 |
+
downloads/
|
| 21 |
+
eggs/
|
| 22 |
+
.eggs/
|
| 23 |
+
lib/
|
| 24 |
+
lib64/
|
| 25 |
+
parts/
|
| 26 |
+
sdist/
|
| 27 |
+
var/
|
| 28 |
+
wheels/
|
| 29 |
+
share/python-wheels/
|
| 30 |
+
*.egg-info/
|
| 31 |
+
.installed.cfg
|
| 32 |
+
*.egg
|
| 33 |
+
MANIFEST
|
| 34 |
+
|
| 35 |
+
# PyInstaller
|
| 36 |
+
# Usually these files are written by a python script from a template
|
| 37 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
| 38 |
+
*.manifest
|
| 39 |
+
*.spec
|
| 40 |
+
|
| 41 |
+
# Installer logs
|
| 42 |
+
pip-log.txt
|
| 43 |
+
pip-delete-this-directory.txt
|
| 44 |
+
|
| 45 |
+
# Unit test / coverage reports
|
| 46 |
+
.tox/
|
| 47 |
+
.nox/
|
| 48 |
+
.coverage
|
| 49 |
+
.coverage.*
|
| 50 |
+
.cache
|
| 51 |
+
*.cover
|
| 52 |
+
*.py,cover
|
| 53 |
+
.hypothesis/
|
| 54 |
+
.pytest_cache/
|
| 55 |
+
|
| 56 |
+
# Translations
|
| 57 |
+
*.mo
|
| 58 |
+
*.pot
|
| 59 |
+
|
| 60 |
+
# Django stuff:
|
| 61 |
+
*.log
|
| 62 |
+
local_settings.py
|
| 63 |
+
db.sqlite3
|
| 64 |
+
db.sqlite3-journal
|
| 65 |
+
|
| 66 |
+
# Flask stuff:
|
| 67 |
+
instance/
|
| 68 |
+
.webassets-cache
|
| 69 |
+
|
| 70 |
+
# Scrapy stuff:
|
| 71 |
+
.scrapy
|
| 72 |
+
|
| 73 |
+
# Sphinx documentation
|
| 74 |
+
docs/_build/
|
| 75 |
+
|
| 76 |
+
# PyBuilder
|
| 77 |
+
.pybuilder/
|
| 78 |
+
target/
|
| 79 |
+
|
| 80 |
+
# Jupyter Notebook
|
| 81 |
+
.ipynb_checkpoints
|
| 82 |
+
|
| 83 |
+
# IPython
|
| 84 |
+
profile_default/
|
| 85 |
+
ipython_config.py
|
| 86 |
+
|
| 87 |
+
# data cache and checkpoints
|
| 88 |
+
data_cache/
|
| 89 |
+
checkpoints/
|
| 90 |
+
|
| 91 |
+
# pyenv
|
| 92 |
+
# For a library or package, you might want to ignore these files since the code is
|
| 93 |
+
# intended to run in multiple environments; otherwise, check them in:
|
| 94 |
+
# .python-version
|
| 95 |
+
|
| 96 |
+
# pipenv
|
| 97 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
| 98 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
| 99 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
| 100 |
+
# install all needed dependencies.
|
| 101 |
+
#Pipfile.lock
|
| 102 |
+
|
| 103 |
+
# poetry
|
| 104 |
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
| 105 |
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
| 106 |
+
# commonly ignored for libraries.
|
| 107 |
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
| 108 |
+
#poetry.lock
|
| 109 |
+
|
| 110 |
+
# pdm
|
| 111 |
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
| 112 |
+
#pdm.lock
|
| 113 |
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
| 114 |
+
# in version control.
|
| 115 |
+
# https://pdm.fming.dev/#use-with-ide
|
| 116 |
+
.pdm.toml
|
| 117 |
+
|
| 118 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
| 119 |
+
__pypackages__/
|
| 120 |
+
|
| 121 |
+
# Celery stuff
|
| 122 |
+
celerybeat-schedule
|
| 123 |
+
celerybeat.pid
|
| 124 |
+
|
| 125 |
+
# SageMath parsed files
|
| 126 |
+
*.sage.py
|
| 127 |
+
|
| 128 |
+
# Environments
|
| 129 |
+
.env
|
| 130 |
+
.venv
|
| 131 |
+
env/
|
| 132 |
+
venv/
|
| 133 |
+
ENV/
|
| 134 |
+
env.bak/
|
| 135 |
+
venv.bak/
|
| 136 |
+
|
| 137 |
+
# Spyder project settings
|
| 138 |
+
.spyderproject
|
| 139 |
+
.spyproject
|
| 140 |
+
|
| 141 |
+
# Rope project settings
|
| 142 |
+
.ropeproject
|
| 143 |
+
|
| 144 |
+
# mkdocs documentation
|
| 145 |
+
/site
|
| 146 |
+
|
| 147 |
+
# mypy
|
| 148 |
+
.mypy_cache/
|
| 149 |
+
.dmypy.json
|
| 150 |
+
dmypy.json
|
| 151 |
+
|
| 152 |
+
# Pyre type checker
|
| 153 |
+
.pyre/
|
| 154 |
+
|
| 155 |
+
# pytype static type analyzer
|
| 156 |
+
.pytype/
|
| 157 |
+
|
| 158 |
+
# Cython debug symbols
|
| 159 |
+
cython_debug/
|
| 160 |
+
|
| 161 |
+
# PyCharm
|
| 162 |
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
| 163 |
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
| 164 |
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
| 165 |
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
| 166 |
+
#.idea/
|
| 167 |
+
|
| 168 |
+
output*/
|
model/PXDesignBench/CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Contributor Covenant Code of Conduct
|
| 2 |
+
|
| 3 |
+
## Our Pledge
|
| 4 |
+
|
| 5 |
+
We as members, contributors, and leaders pledge to make participation in our
|
| 6 |
+
community a harassment-free experience for everyone, regardless of age, body
|
| 7 |
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
| 8 |
+
identity and expression, level of experience, education, socio-economic status,
|
| 9 |
+
nationality, personal appearance, race, religion, or sexual identity
|
| 10 |
+
and orientation.
|
| 11 |
+
|
| 12 |
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
| 13 |
+
diverse, inclusive, and healthy community.
|
| 14 |
+
|
| 15 |
+
## Our Standards
|
| 16 |
+
|
| 17 |
+
Examples of behavior that contributes to a positive environment for our
|
| 18 |
+
community include:
|
| 19 |
+
|
| 20 |
+
* Demonstrating empathy and kindness toward other people
|
| 21 |
+
* Being respectful of differing opinions, viewpoints, and experiences
|
| 22 |
+
* Giving and gracefully accepting constructive feedback
|
| 23 |
+
* Accepting responsibility and apologizing to those affected by our mistakes,
|
| 24 |
+
and learning from the experience
|
| 25 |
+
* Focusing on what is best not just for us as individuals, but for the
|
| 26 |
+
overall community
|
| 27 |
+
|
| 28 |
+
Examples of unacceptable behavior include:
|
| 29 |
+
|
| 30 |
+
* The use of sexualized language or imagery, and sexual attention or
|
| 31 |
+
advances of any kind
|
| 32 |
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
| 33 |
+
* Public or private harassment
|
| 34 |
+
* Publishing others' private information, such as a physical or email
|
| 35 |
+
address, without their explicit permission
|
| 36 |
+
* Other conduct which could reasonably be considered inappropriate in a
|
| 37 |
+
professional setting
|
| 38 |
+
|
| 39 |
+
## Enforcement Responsibilities
|
| 40 |
+
|
| 41 |
+
Community leaders are responsible for clarifying and enforcing our standards of
|
| 42 |
+
acceptable behavior and will take appropriate and fair corrective action in
|
| 43 |
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
| 44 |
+
or harmful.
|
| 45 |
+
|
| 46 |
+
Community leaders have the right and responsibility to remove, edit, or reject
|
| 47 |
+
comments, commits, code, wiki edits, issues, and other contributions that are
|
| 48 |
+
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
| 49 |
+
decisions when appropriate.
|
| 50 |
+
|
| 51 |
+
## Scope
|
| 52 |
+
|
| 53 |
+
This Code of Conduct applies within all community spaces, and also applies when
|
| 54 |
+
an individual is officially representing the community in public spaces.
|
| 55 |
+
Examples of representing our community include using an official e-mail address,
|
| 56 |
+
posting via an official social media account, or acting as an appointed
|
| 57 |
+
representative at an online or offline event.
|
| 58 |
+
|
| 59 |
+
## Enforcement
|
| 60 |
+
|
| 61 |
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
| 62 |
+
reported to the community leaders responsible for enforcement.
|
| 63 |
+
All complaints will be reviewed and investigated promptly and fairly.
|
| 64 |
+
|
| 65 |
+
All community leaders are obligated to respect the privacy and security of the
|
| 66 |
+
reporter of any incident.
|
| 67 |
+
|
| 68 |
+
## Enforcement Guidelines
|
| 69 |
+
|
| 70 |
+
Community leaders will follow these Community Impact Guidelines in determining
|
| 71 |
+
the consequences for any action they deem in violation of this Code of Conduct:
|
| 72 |
+
|
| 73 |
+
### 1. Correction
|
| 74 |
+
|
| 75 |
+
**Community Impact**: Use of inappropriate language or other behavior deemed
|
| 76 |
+
unprofessional or unwelcome in the community.
|
| 77 |
+
|
| 78 |
+
**Consequence**: A private, written warning from community leaders, providing
|
| 79 |
+
clarity around the nature of the violation and an explanation of why the
|
| 80 |
+
behavior was inappropriate. A public apology may be requested.
|
| 81 |
+
|
| 82 |
+
### 2. Warning
|
| 83 |
+
|
| 84 |
+
**Community Impact**: A violation through a single incident or series
|
| 85 |
+
of actions.
|
| 86 |
+
|
| 87 |
+
**Consequence**: A warning with consequences for continued behavior. No
|
| 88 |
+
interaction with the people involved, including unsolicited interaction with
|
| 89 |
+
those enforcing the Code of Conduct, for a specified period of time. This
|
| 90 |
+
includes avoiding interactions in community spaces as well as external channels
|
| 91 |
+
like social media. Violating these terms may lead to a temporary or
|
| 92 |
+
permanent ban.
|
| 93 |
+
|
| 94 |
+
### 3. Temporary Ban
|
| 95 |
+
|
| 96 |
+
**Community Impact**: A serious violation of community standards, including
|
| 97 |
+
sustained inappropriate behavior.
|
| 98 |
+
|
| 99 |
+
**Consequence**: A temporary ban from any sort of interaction or public
|
| 100 |
+
communication with the community for a specified period of time. No public or
|
| 101 |
+
private interaction with the people involved, including unsolicited interaction
|
| 102 |
+
with those enforcing the Code of Conduct, is allowed during this period.
|
| 103 |
+
Violating these terms may lead to a permanent ban.
|
| 104 |
+
|
| 105 |
+
### 4. Permanent Ban
|
| 106 |
+
|
| 107 |
+
**Community Impact**: Demonstrating a pattern of violation of community
|
| 108 |
+
standards, including sustained inappropriate behavior, harassment of an
|
| 109 |
+
individual, or aggression toward or disparagement of classes of individuals.
|
| 110 |
+
|
| 111 |
+
**Consequence**: A permanent ban from any sort of public interaction within
|
| 112 |
+
the community.
|
| 113 |
+
|
| 114 |
+
## Attribution
|
| 115 |
+
|
| 116 |
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
| 117 |
+
version 2.0, available at
|
| 118 |
+
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
| 119 |
+
|
| 120 |
+
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
| 121 |
+
enforcement ladder](https://github.com/mozilla/diversity).
|
| 122 |
+
|
| 123 |
+
[homepage]: https://www.contributor-covenant.org
|
| 124 |
+
|
| 125 |
+
For answers to common questions about this code of conduct, see the FAQ at
|
| 126 |
+
https://www.contributor-covenant.org/faq. Translations are available at
|
| 127 |
+
https://www.contributor-covenant.org/translations.
|
model/PXDesignBench/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Contributing
|
| 2 |
+
|
| 3 |
+
Thank you for investing your time in contributing to PXDesignBench project!
|
| 4 |
+
|
| 5 |
+
Read our [Code of Conduct](./CODE_OF_CONDUCT.md) to keep our community approachable and respectable.
|
| 6 |
+
|
| 7 |
+
This guide details how to use issues and pull requests to improve PXDesignBench project.
|
| 8 |
+
|
| 9 |
+
## General Guidelines
|
| 10 |
+
|
| 11 |
+
### Pull Requests
|
| 12 |
+
|
| 13 |
+
Make sure to keep Pull Requests small and functional to make them easier to review, understand, and look up in commit history. This repository uses "Squash and Commit" to keep our history clean and make it easier to revert changes based on PR.
|
| 14 |
+
|
| 15 |
+
Adding the appropriate documentation, unit tests and e2e tests as part of a feature is the responsibility of the feature owner, whether it is done in the same Pull Request or not.
|
| 16 |
+
|
| 17 |
+
Pull Requests should follow the "subject: message" format, where the subject describes what part of the code is being modified.
|
| 18 |
+
|
| 19 |
+
Refer to the template for more information on what goes into a PR description.
|
| 20 |
+
|
| 21 |
+
### Design Docs
|
| 22 |
+
|
| 23 |
+
A contributor proposes a design with a PR on the repository to allow for revisions and discussions. If a design needs to be discussed before formulating a document for it, make use of Google doc and GitHub issue to involve the community on the discussion.
|
| 24 |
+
|
| 25 |
+
### GitHub Issues
|
| 26 |
+
|
| 27 |
+
GitHub Issues are used to file bugs, work items, and feature requests with actionable items/issues (Please refer to the "Reporting Bugs/Feature Requests" section below for more information).
|
| 28 |
+
|
| 29 |
+
### Reporting Bugs/Feature Requests
|
| 30 |
+
|
| 31 |
+
We welcome you to use the GitHub issue tracker to report bugs or suggest features that have actionable items/issues (as opposed to introducing a feature request on GitHub Discussions).
|
| 32 |
+
|
| 33 |
+
When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
|
| 34 |
+
|
| 35 |
+
- A reproducible test case or series of steps
|
| 36 |
+
- The version of the code being used
|
| 37 |
+
- Any modifications you've made relevant to the bug
|
| 38 |
+
- Anything unusual about your environment or deployment
|
| 39 |
+
|
| 40 |
+
## Contributing via Pull Requests
|
| 41 |
+
|
| 42 |
+
### Find interesting issue
|
| 43 |
+
|
| 44 |
+
If you spot a problem with the problem, [search if an issue already exists](https://github.com/bytedance/PXDesignBench/issues). If a related issue doesn't exist, you can open a new issue using [issue template](https://github.com/bytedance/PXDesignBench/issues/new/choose).
|
| 45 |
+
|
| 46 |
+
### Solve an issue
|
| 47 |
+
|
| 48 |
+
Please check `DEVELOPMENT.md` in sub folder to get familiar with running and testing codes.
|
| 49 |
+
|
| 50 |
+
### Open a Pull request.
|
| 51 |
+
|
| 52 |
+
When you're done making the changes, open a pull request and fill PR template so we can better review your PR. The template helps reviewers understand your changes and the purpose of your pull request.
|
| 53 |
+
|
| 54 |
+
Don't forget to link PR to the issue if you are solving one.
|
| 55 |
+
|
| 56 |
+
If you run into any merge issues, checkout this [git tutorial](https://lab.github.com/githubtraining/managing-merge-conflicts) to help you resolve merge conflicts and other issues.
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
## Finding contributions to work on
|
| 60 |
+
|
| 61 |
+
Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' and 'good first issue' issues are a great place to start.
|
model/PXDesignBench/ColabDesign/.github/workflows/python-publish.yml
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This workflow will upload a Python Package using Twine when a release is created
|
| 2 |
+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
|
| 3 |
+
|
| 4 |
+
# This workflow uses actions that are not certified by GitHub.
|
| 5 |
+
# They are provided by a third-party and are governed by
|
| 6 |
+
# separate terms of service, privacy policy, and support
|
| 7 |
+
# documentation.
|
| 8 |
+
|
| 9 |
+
name: Upload Python Package
|
| 10 |
+
|
| 11 |
+
on:
|
| 12 |
+
release:
|
| 13 |
+
types: [published]
|
| 14 |
+
|
| 15 |
+
permissions:
|
| 16 |
+
contents: read
|
| 17 |
+
|
| 18 |
+
jobs:
|
| 19 |
+
deploy:
|
| 20 |
+
|
| 21 |
+
runs-on: ubuntu-latest
|
| 22 |
+
|
| 23 |
+
steps:
|
| 24 |
+
- uses: actions/checkout@v3
|
| 25 |
+
- name: Set up Python
|
| 26 |
+
uses: actions/setup-python@v3
|
| 27 |
+
with:
|
| 28 |
+
python-version: '3.x'
|
| 29 |
+
- name: Install dependencies
|
| 30 |
+
run: |
|
| 31 |
+
python -m pip install --upgrade pip
|
| 32 |
+
pip install build
|
| 33 |
+
- name: Build package
|
| 34 |
+
run: python -m build
|
| 35 |
+
- name: Publish package
|
| 36 |
+
uses: pypa/gh-action-pypi-publish@release/v1
|
| 37 |
+
with:
|
| 38 |
+
user: __token__
|
| 39 |
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
model/PXDesignBench/ColabDesign/.gitignore
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
**/.DS_Store
|
| 2 |
+
*.pyc
|
model/PXDesignBench/ColabDesign/LICENSE.txt
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* ----------------------------------------------------------------------------
|
| 3 |
+
* "THE BEER-WARE LICENSE" (Revision 42):
|
| 4 |
+
* <so3@mit.edu> wrote this file. As long as you retain this notice you
|
| 5 |
+
* can do whatever you want with this stuff. If we meet some day, and you think
|
| 6 |
+
* this stuff is worth it, you can buy me a beer in return. Sergey Ovchinnikov
|
| 7 |
+
* ----------------------------------------------------------------------------
|
| 8 |
+
*/
|
model/PXDesignBench/ColabDesign/MANIFEST.in
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
include colabdesign/mpnn/weights/*.pkl
|
| 2 |
+
include colabdesign/mpnn/weights_soluble/*.pkl
|
| 3 |
+
include colabdesign/tr/weights/*.npy
|
| 4 |
+
include colabdesign/af/weights/*.npy
|
model/PXDesignBench/ColabDesign/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ColabDesign
|
| 2 |
+
### Making Protein Design accessible to all via Google Colab!
|
| 3 |
+
- P(structure | sequence)
|
| 4 |
+
- [TrDesign](/tr) - using TrRosetta for design
|
| 5 |
+
- [AfDesign](/af) - using AlphaFold for design
|
| 6 |
+
- [WIP] [RfDesign](https://github.com/RosettaCommons/RFDesign) - using RoseTTAFold for design
|
| 7 |
+
- P(sequence | structure)
|
| 8 |
+
- [ProteinMPNN](/mpnn)
|
| 9 |
+
- [WIP] TrMRF
|
| 10 |
+
- P(sequence)
|
| 11 |
+
- [WIP] [MSA_transformer](/esm_msa)
|
| 12 |
+
- [WIP] [SEQ](/seq) - (GREMLIN, mfDCA, arDCA, plmDCA, bmDCA, etc)
|
| 13 |
+
- P(structure)
|
| 14 |
+
- [Rfdiffusion](/rf)
|
| 15 |
+
|
| 16 |
+
### Where can I chat with other ColabDesign users?
|
| 17 |
+
- See our [Discord](https://discord.gg/gna8maru7d) channel!
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
### Presentations
|
| 21 |
+
[Slides](https://docs.google.com/presentation/d/1Zy7lf_LBK0_G3e7YQLSPP5aj_-AR5I131fTsxJrLdg4/)
|
| 22 |
+
[Talk](https://www.youtube.com/watch?v=2HmXwlKWMVs)
|
| 23 |
+
|
| 24 |
+
### Contributors:
|
| 25 |
+
- Sergey Ovchinnikov [@sokrypton](https://github.com/sokrypton)
|
| 26 |
+
- Shihao Feng [@JeffSHF](https://github.com/JeffSHF)
|
| 27 |
+
- Justas Dauparas [@dauparas](https://github.com/dauparas)
|
| 28 |
+
- Weikun.Wu [@guyujun](https://github.com/guyujun) (from [Levinthal.bio](http://levinthal.bio/en/))
|
| 29 |
+
- Christopher Frank [@chris-kafka](https://github.com/chris-kafka)
|
model/PXDesignBench/ColabDesign/af/LICENSE.txt
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* ----------------------------------------------------------------------------
|
| 3 |
+
* "THE BEER-WARE LICENSE" (Revision 42):
|
| 4 |
+
* <so3@mit.edu> wrote this file. As long as you retain this notice you
|
| 5 |
+
* can do whatever you want with this stuff. If we meet some day, and you think
|
| 6 |
+
* this stuff is worth it, you can buy me a beer in return. Sergey Ovchinnikov
|
| 7 |
+
* ----------------------------------------------------------------------------
|
| 8 |
+
*/
|
model/PXDesignBench/ColabDesign/af/README.md
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# AfDesign (v1.1.1)
|
| 2 |
+
### Google Colab
|
| 3 |
+
<a href="https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/design.ipynb">
|
| 4 |
+
<img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/>
|
| 5 |
+
</a>
|
| 6 |
+
|
| 7 |
+
# Updates
|
| 8 |
+
- Jump to [Previous Updates](#previous-updates)
|
| 9 |
+
- **15Oct2022** - v1.1.0
|
| 10 |
+
- integrating proteinMPNN!
|
| 11 |
+
- bugfix for sidechain loss
|
| 12 |
+
- **17Nov2022**
|
| 13 |
+
- updating pae/plddt loss calculation to be consistent with pae/plddt outputs
|
| 14 |
+
- **24Dec2022** - v1.1.1
|
| 15 |
+
- adding af_pseudo_diffusion examples
|
| 16 |
+
- updating to alphafold-multimer v2.3.0
|
| 17 |
+
- enabling fused_triangle_multiplication by default
|
| 18 |
+
- **21Jan2023**
|
| 19 |
+
- add support for bfloat16 (enabled by default
|
| 20 |
+
- **01Mar2023**
|
| 21 |
+
- adding support for [RfDiffusion](/rf)
|
| 22 |
+
### setup
|
| 23 |
+
first install jax (with GPU support)
|
| 24 |
+
```bash
|
| 25 |
+
pip install "jax[cuda]" -f https://storage.googleapis.com/jax-releases/jax_cuda_releases.html
|
| 26 |
+
```
|
| 27 |
+
second install colabdesign
|
| 28 |
+
```bash
|
| 29 |
+
pip install git+https://github.com/sokrypton/ColabDesign.git@v1.1.1
|
| 30 |
+
|
| 31 |
+
# download alphafold weights
|
| 32 |
+
mkdir params
|
| 33 |
+
curl -fsSL https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar | tar x -C params
|
| 34 |
+
```
|
| 35 |
+
By default `mk_afdesign_model()` assumes alphafold "params" are saved in the run directory (`data_dir="."`). To override:
|
| 36 |
+
```python
|
| 37 |
+
model = mk_afdesign_model(..., data_dir="/location/of")
|
| 38 |
+
```
|
| 39 |
+
### import
|
| 40 |
+
```python
|
| 41 |
+
import numpy as np
|
| 42 |
+
from IPython.display import HTML
|
| 43 |
+
from colabdesign import mk_afdesign_model, clear_mem
|
| 44 |
+
```
|
| 45 |
+
### fixed backbone design
|
| 46 |
+
For a given protein backbone, generate/design a new sequence that AlphaFold thinks folds into that conformation
|
| 47 |
+
```python
|
| 48 |
+
model = mk_afdesign_model(protocol="fixbb")
|
| 49 |
+
model.prep_inputs(pdb_filename="1TEN.pdb", chain="A")
|
| 50 |
+
model.design_3stage()
|
| 51 |
+
```
|
| 52 |
+
### hallucination
|
| 53 |
+
For a given length, generate/hallucinate a protein sequence that AlphaFold thinks folds into a well structured
|
| 54 |
+
protein (high plddt, low pae, many contacts).
|
| 55 |
+
```python
|
| 56 |
+
model = mk_afdesign_model(protocol="hallucination")
|
| 57 |
+
model.prep_inputs(length=100)
|
| 58 |
+
model.set_seq(mode="gumbel")
|
| 59 |
+
model.design_soft(50)
|
| 60 |
+
model.set_seq(model.aux["seq"]["pseudo"])
|
| 61 |
+
model.design_3stage(50,50,10)
|
| 62 |
+
```
|
| 63 |
+
### binder hallucination
|
| 64 |
+
For a given protein target and protein binder length, generate/hallucinate a protein binder sequence AlphaFold
|
| 65 |
+
thinks will bind to the target structure. To do this, we minimize PAE and maximize number of contacts at the
|
| 66 |
+
interface and within the binder, and we maximize pLDDT of the binder.
|
| 67 |
+
```python
|
| 68 |
+
model = mk_afdesign_model(protocol="binder")
|
| 69 |
+
model.prep_inputs(pdb_filename="4MZK.pdb", chain="A", binder_len=19)
|
| 70 |
+
model.design_3stage(100, 100, 10)
|
| 71 |
+
```
|
| 72 |
+
Instead of hallucination, you can redesign an existing binder:
|
| 73 |
+
```python
|
| 74 |
+
model.prep_inputs(pdb_filename="4MZK.pdb", chain="A", binder_chain="T")
|
| 75 |
+
```
|
| 76 |
+
|
| 77 |
+
### partial hallucination
|
| 78 |
+
If you have a motif (binding motif, or functional motif) and you want to hallucinate a new scaffold around it,
|
| 79 |
+
you can use partial hallucination. Or you have a protein and you want to extend one of the loops.
|
| 80 |
+
```python
|
| 81 |
+
af_model = mk_afdesign_model(protocol="partial")
|
| 82 |
+
af_model.prep_inputs(pdb_filename="6MRR.pdb", chain="A", pos="3-30,33-68", length=100)
|
| 83 |
+
af_model.rewire(loops=[36])
|
| 84 |
+
```
|
| 85 |
+
# FAQ
|
| 86 |
+
|
| 87 |
+
#### Can I reuse the same model without needing to recompile?
|
| 88 |
+
```python
|
| 89 |
+
model.restart()
|
| 90 |
+
```
|
| 91 |
+
#### How do I change the loss weights?
|
| 92 |
+
This can be done using the provided function:
|
| 93 |
+
```python
|
| 94 |
+
model.set_weights(pae=0.0, plddt=1.0)
|
| 95 |
+
```
|
| 96 |
+
or the dictionary directly:
|
| 97 |
+
```python
|
| 98 |
+
model.opt["weights"]["pae"] = 0.0
|
| 99 |
+
```
|
| 100 |
+
#### How do I control number of recycles used during design?
|
| 101 |
+
```python
|
| 102 |
+
model = mk_afdesign_model(num_recycles=1, recycle_mode="average")
|
| 103 |
+
# if recycle_mode in ["average",last","sample","first"] the number of recycles can change during optimization
|
| 104 |
+
model.set_opt(num_recycles=1)
|
| 105 |
+
```
|
| 106 |
+
- `num_recycles` - number of recycles to use during design (for denovo proteins we find 0 is often enough)
|
| 107 |
+
- `recycle_mode` - optimizing across all recycles can be tricky, we experiment with a couple of ways:
|
| 108 |
+
- *last* - use loss from last recycle. (Default)
|
| 109 |
+
- *average* - compute loss at each recycle and average gradients. (Previous default from v.1.0.5)
|
| 110 |
+
- *sample* - Same as *last* but each iteration a different number of recycles are used.
|
| 111 |
+
- *first* - use loss from first recycle.
|
| 112 |
+
- *add_prev* - average the outputs (dgram, plddt, pae) across all recycles before computing loss.
|
| 113 |
+
- *backprop* - use loss from last recycle, but backprop through all recycles.
|
| 114 |
+
|
| 115 |
+
#### How do I control which model params are used during design?
|
| 116 |
+
By default all five models are used during optimization. If `num_models` > 1, then multiple params are evaluated at each iteration and the gradients/losses are averaged. Each iteration a random set of model params are used unless `sample_models=False`.
|
| 117 |
+
```python
|
| 118 |
+
model = mk_afdesign_model(num_models=1, sample_models=True)
|
| 119 |
+
# or
|
| 120 |
+
model.set_opt(num_models=1, sample_models=True)
|
| 121 |
+
```
|
| 122 |
+
- `num_models` - number of model params to use at each iteration.
|
| 123 |
+
- `sample_models`:
|
| 124 |
+
- *True* - randomly select models params to use. (Recommended)
|
| 125 |
+
- *False* - use the same model params each iteration.
|
| 126 |
+
You can also specify exactly which models are used during any of the design protocols:
|
| 127 |
+
```python
|
| 128 |
+
model.design_(num_models=1, sample_models=True, models=[0,2,3])
|
| 129 |
+
# or
|
| 130 |
+
model.design_(num_models=2, sample_models=False, models=["model_1_ptm","model_3_ptm"])
|
| 131 |
+
```
|
| 132 |
+
#### Can I use OpenFold model params for design instead of AlphaFold?
|
| 133 |
+
You may need to download them:
|
| 134 |
+
```bash
|
| 135 |
+
for W in openfold_model_ptm_1 openfold_model_ptm_2 openfold_model_no_templ_ptm_1
|
| 136 |
+
do wget -qnc https://files.ipd.uw.edu/krypton/openfold/${W}.npz -P params; done
|
| 137 |
+
```
|
| 138 |
+
Once downloaded:
|
| 139 |
+
```python
|
| 140 |
+
model = mk_afdesign_model(use_openfold=True, use_alphafold=False)
|
| 141 |
+
```
|
| 142 |
+
#### For binder hallucination, can I specify the site I want to bind?
|
| 143 |
+
```python
|
| 144 |
+
model.prep_inputs(..., hotspot="1-10,15,3")
|
| 145 |
+
```
|
| 146 |
+
#### Can I input more than one chain?
|
| 147 |
+
```python
|
| 148 |
+
model.prep_inputs(..., chain="A,B")
|
| 149 |
+
```
|
| 150 |
+
#### For fixed backbone design, how do I force the sequence to be the same for homo-dimer optimization?
|
| 151 |
+
```python
|
| 152 |
+
model.prep_inputs(pdb_filename="6Q40.pdb", chain="A,B", copies=2, homooligomer=True)
|
| 153 |
+
```
|
| 154 |
+
WARNING, this functionality assumes the input chains are of equal length.
|
| 155 |
+
#### How do I disable certain amino acids?
|
| 156 |
+
```python
|
| 157 |
+
model.restart(rm_aa="C,W")
|
| 158 |
+
```
|
| 159 |
+
#### How do I set the random seed for reproducibility?
|
| 160 |
+
```python
|
| 161 |
+
model.restart(seed=0)
|
| 162 |
+
```
|
| 163 |
+
#### What are all the different `design_???` methods?
|
| 164 |
+
- For **design** we provide 5 different functions:
|
| 165 |
+
- `design_logits()` - optimize *logits* inputs (continious)
|
| 166 |
+
- `design_soft()` - optimize *softmax(logits)* inputs (probabilities)
|
| 167 |
+
- `design_hard()` - optimize *one_hot(logits)* inputs (discrete)
|
| 168 |
+
|
| 169 |
+
- For complex topologies, we find directly optimizing one_hot encoded sequence `design_hard()` to be very challenging.
|
| 170 |
+
To get around this problem, we propose optimizing in 3 stages or first learning logits then switching to semigreedy optimization.
|
| 171 |
+
- `design_3stage()` - gradient based optimization (GD) (logits → soft → hard)
|
| 172 |
+
- `design_semigreedy(tries=X)` - tries X random mutations, accepts those that decrease loss
|
| 173 |
+
- `design_pssm_semigreey(tries=X)` - uses GD to get a sequence profile (PSSM), then uses the PSSM to bias semigreedy opt. (Recommended)
|
| 174 |
+
|
| 175 |
+
#### What are all the different losses being optimized?
|
| 176 |
+
- general losses
|
| 177 |
+
- *pae* - minimizes the predicted alignment error
|
| 178 |
+
- *plddt* - maximizes the predicted LDDT
|
| 179 |
+
- *pae* and *plddt* values are between 0 and 1 (where lower is better for both)
|
| 180 |
+
|
| 181 |
+
- fixbb specific losses
|
| 182 |
+
- *dgram_cce* - minimizes the categorical-crossentropy between predicted distogram and one extracted from pdb.
|
| 183 |
+
- *fape* - minimize difference between coordinates (see AlphaFold paper)
|
| 184 |
+
- we find *dgram_cce* loss to be more stable for design (compared to *fape*)
|
| 185 |
+
|
| 186 |
+
- hallucination specific losses
|
| 187 |
+
- *con* - maximize `1` contacts per position. `model.set_opt("con",num=1)`
|
| 188 |
+
|
| 189 |
+
- binder specific losses
|
| 190 |
+
- *pae* - minimize PAE at interface and within binder
|
| 191 |
+
- *con* - - maximize `2` contacts per binder position, within binder. `model.set_opt("con",num=2)`
|
| 192 |
+
- *i_con* - maximize `1` contacts per binder position `model.set_opt("i_con",num=1)`
|
| 193 |
+
|
| 194 |
+
- partial hallucination specific losses
|
| 195 |
+
- *sc_fape* - sidechain-specific fape
|
| 196 |
+
|
| 197 |
+
#### How is contact defined? How do I change it?
|
| 198 |
+
By default, 2 [con]tacts per positions are optimized to be within cβ-cβ < 14.0Å and sequence seperation ≥ 9. This can be changed with:
|
| 199 |
+
```python
|
| 200 |
+
model.set_opt(con=dict(cutoff=8, seqsep=5, num=1))
|
| 201 |
+
```
|
| 202 |
+
For interface:
|
| 203 |
+
```python
|
| 204 |
+
model.set_opt(i_con=dict(...))
|
| 205 |
+
```
|
| 206 |
+
|
| 207 |
+
#### Optax Optimizers
|
| 208 |
+
By default, we use stochastic gradient descent `set_optimizer(optimizer="sgd", learning_rate=0.1, norm_seq_grad=True)` for optimization. This seems to work quite well for the default problems. But if you want to try other optimizers, ColabDesign is now fully integrated with all [Optax optimizers](https://optax.readthedocs.io/en/latest/api.html).
|
| 209 |
+
Example how to change optimizer. Note the default learning_rate of 0.1 was calibrated for sgd with gradient normalization. A different learning_rate may be more optimal for other optimization settings.
|
| 210 |
+
```python
|
| 211 |
+
model = mk_afdesign_model(optimizer="adam", learning_rate=0.01)
|
| 212 |
+
```
|
| 213 |
+
Or for more control (or to change settings after model initialization), use:
|
| 214 |
+
```python
|
| 215 |
+
model.set_optimizer(optimizer="adam", learning_rate=0.01, b1=0.9, b2=0.999)
|
| 216 |
+
```
|
| 217 |
+
By default, the gradients for the sequence parameters are normalized. We find this helps with convergence. To disable:
|
| 218 |
+
```python
|
| 219 |
+
model.set_opt(norm_seq_grad=False)
|
| 220 |
+
```
|
| 221 |
+
|
| 222 |
+
# Advanced FAQ
|
| 223 |
+
#### loss during Gradient descent is too jumpy, can I do some kind of greedy search towards the end?
|
| 224 |
+
Gradient descent updates multiple positions each iteration, which can be a little too aggressive during hard (discrete) mode.
|
| 225 |
+
Instead, one can try (`tries`) a few random mutations and accept one with lowest loss. If `use_plddt=True` the random mutations will be biased towards positions with low pLDDT.
|
| 226 |
+
```python
|
| 227 |
+
model.design_3stage(hard_iters=0)
|
| 228 |
+
# set number of model params to evaluate at each iteration
|
| 229 |
+
num_models = 2 if model.args["use_templates"] else 5
|
| 230 |
+
model.design_semigreedy(iters=10, tries=20, num_models=num_models, use_plddt=True)
|
| 231 |
+
```
|
| 232 |
+
#### I was getting better results before the major update (19June2022), how do I revert back to the old settings?
|
| 233 |
+
We are actively trying to find the best weights `model.opt["weights"]`, settings `model.opt` for each protocol.
|
| 234 |
+
Please send us a note if you find something better! To revert back to old settings do this after prepping the model:
|
| 235 |
+
- fixbb:
|
| 236 |
+
```python
|
| 237 |
+
model.set_weights(dgram_cce=1, pae=0.1, plddt=0.1)
|
| 238 |
+
model.design_3stage()
|
| 239 |
+
```
|
| 240 |
+
- hallucination:
|
| 241 |
+
```python
|
| 242 |
+
model.set_seq(mode="gumbel")
|
| 243 |
+
model.set_weights(pae=1, plddt=1, con=0.5)
|
| 244 |
+
model.set_opt("con", binary=True, cutoff=21.6875, num=model._len, seqsep=0)
|
| 245 |
+
model.design_2stage(100, 100, 10)
|
| 246 |
+
```
|
| 247 |
+
- binder hallucination:
|
| 248 |
+
```python
|
| 249 |
+
model.set_weights(plddt=0.1, pae=0.1, i_pae=1.0, con=0.1, i_con=0.5)
|
| 250 |
+
model.set_opt("con", binary=True, cutoff=21.6875, num=model._binder_len, seqsep=0)
|
| 251 |
+
model.set_opt("i_con", binary=True, cutoff=21.6875, num=model._target_len)
|
| 252 |
+
model.design_3stage(100, 100, 10)
|
| 253 |
+
```
|
| 254 |
+
#### I don't like your design_??? function, can I write my own with more detailed control?
|
| 255 |
+
```python
|
| 256 |
+
def design_custom(self):
|
| 257 |
+
# set options
|
| 258 |
+
self.set_opt(dropout=True, soft=False, hard=False)
|
| 259 |
+
# set number of recycles
|
| 260 |
+
self.set_opt(num_recycles=0)
|
| 261 |
+
# take 100 steps
|
| 262 |
+
for _ in range(100): self.step()
|
| 263 |
+
# increase weight for plddt
|
| 264 |
+
self.set_weights(plddt=2.0)
|
| 265 |
+
# take another 100 steps
|
| 266 |
+
for _ in range(100): self.step()
|
| 267 |
+
# increase number of recycles
|
| 268 |
+
self.set_opt(num_recycles=1)
|
| 269 |
+
# take another 100 steps
|
| 270 |
+
for _ in range(100): self.step()
|
| 271 |
+
# etc...
|
| 272 |
+
|
| 273 |
+
model = mk_afdesign_model()
|
| 274 |
+
design_custom(model)
|
| 275 |
+
```
|
| 276 |
+
|
| 277 |
+
#### custom callback examples
|
| 278 |
+
Looking for more control over afdesign? The callback functions have gotten much smarter. Based on your input arguments, it will automatically fetch the variable of interest. You can now define your own custom losses, params to optimize, modify inputs before alphafold is run, and modify auxiliary outputs.
|
| 279 |
+
```python
|
| 280 |
+
def custom_pre_callback(inputs, aux, opt, key):
|
| 281 |
+
inputs["aatype"] = inputs["aatype"].at[:].set(0)
|
| 282 |
+
aux["pre"] = opt["pre"] + jax.random.randint(key,[],0,10)
|
| 283 |
+
|
| 284 |
+
def custom_post_callback(outputs, aux):
|
| 285 |
+
aux["post"] = outputs["structure_module"]
|
| 286 |
+
|
| 287 |
+
def custom_loss_callback(outputs, params):
|
| 288 |
+
loss = jnp.square(outputs["structure_module"]["final_atom14_positions"] + params["custom_param"]).mean()
|
| 289 |
+
return {"custom_loss":loss}
|
| 290 |
+
|
| 291 |
+
af_model = mk_afdesign_model(protocol="fixbb",
|
| 292 |
+
pre_callback=custom_pre_callback,
|
| 293 |
+
post_callback=custom_post_callback,
|
| 294 |
+
loss_callback=custom_loss_callback)
|
| 295 |
+
af_model._params["custom_param"] = 1.0
|
| 296 |
+
af_model.opt["weights"]["custom_loss"] = 0.1
|
| 297 |
+
af_model.opt["pre"] = 100
|
| 298 |
+
|
| 299 |
+
af_model.prep_inputs(pdb_filename=get_pdb("1TEN"), chain="A")
|
| 300 |
+
```
|
| 301 |
+
|
| 302 |
+
# Previous Updates
|
| 303 |
+
- **24Feb2022** - "Beta" branch started. Refactoring code to allow homooligomeric hallucination/design and averaging gradients across recycles (which is now the default).
|
| 304 |
+
Minor changes changes include renaming intra_pae/inter_con to pae/con and inter_pae/inter_con to i_pae/i_con for clarity.
|
| 305 |
+
- **28Feb2022** - We find backprop through structure module to be unstable, all functions have been updated to only use distogram by default. The definition of contact has changed to minimize entropy within distance cutoff.
|
| 306 |
+
- **02May2022** - The `design.py` code has been split up into multiple python files under `src/`
|
| 307 |
+
- **14May2022** - Adding support for partial hallucination (if you want to constrain one part and generate structure/sequence for rest).
|
| 308 |
+
- **19June2022** - "Beta" branch is now the "Main" branch. WARNING: Lots of default settings and weights were changed. [Click here](#i-was-getting-better-results-before-the-major-update-19june2022-how-do-i-revert-back-to-the-old-settings) for info on how to revert back to old settings.
|
| 309 |
+
- **28June2022** - v1.0.1 - Major code reorganization/refactoring to add support for callbacks (to allow integration w/ other tools during design) and to avoid clashes with existing trrosetta/alphafold installations. (eg. `af → colabdesign`, `af.src → colabdesign.af` and `alphafold → colabdesign.af.alphafold`).
|
| 310 |
+
- **05July2022** - v1.0.2 - Major code cleanup, removing duplicate code. Adding support for custom loss functions.
|
| 311 |
+
- **11July2022** - v1.0.3 - Improved homo-oligomeric support. RMSD and dgram losses have been refactored to automatically save aligned coordinates. Multimeric coordinates now saved with chain identifiers.
|
| 312 |
+
- **23July2022** - v1.0.4 - Adding support for openfold weights. To enable set `mk_afdesign_model(..., use_openfold=True)`.
|
| 313 |
+
- **31July2022** - v1.0.5 - Refactoring to add support for swapping batch features without recompile. Allowing for implementation of [AF2Rank](https://github.com/sokrypton/ColabDesign/blob/main/af/examples/AF2Rank.ipynb)!
|
| 314 |
+
- **09Sept2022** - v1.0.6
|
| 315 |
+
- support for alphafold-multimer `model = mk_afdesign_model(..., use_multimer=True)`
|
| 316 |
+
- support for experimentally resolved loss `model.set_weights(exp_res=1)`
|
| 317 |
+
- support for multichain design/hallucination for fixbb, hallucination and partial protocols: `model.prep_inputs(..., copies=2)`
|
| 318 |
+
- support to fix the sequence for certain positions `model.prep_inputs(..., fix_pos="1-10")` (supported in protocols "fixbb" and "partial")
|
| 319 |
+
- binder protocol improved, prior protocol would try to optimize number of contacts per target, new default is to optimize number of contacts per binder position. Number of contacts per binder position can be controlled with `model.set_opt("i_con",num=1)` and number of positions that should be contact with `model.set_opt("i_con",num_pos=5)`
|
| 320 |
+
- implementing David Jones'-like protocol for semi-greedy optimization, where positions are selected based on plddt, and after 20 tries, the mutation that decreasing loss the most is accepted. `model.design_semigreedy()`
|
| 321 |
+
- WARNING: the returned pLDDT is now in the "correct" direction (higher is better)
|
| 322 |
+
- removing recycle dimension from the input features (to standardize with multimer inputs)
|
| 323 |
+
- removing all dependence on TensorFlow
|
| 324 |
+
- **14Sept2022** - v1.0.7
|
| 325 |
+
- refactoring design.py to add `design_pssm_semigreedy()` protocol, which is a wrapper around `design_semigreedy(seq_logits=)`, and can be used to input/learn PSSM for biased optimization.
|
| 326 |
+
- adding example [peptide_binder_design.ipynb](https://colab.research.google.com/github/sokrypton/ColabDesign/blob/main/af/examples/peptide_binder_design.ipynb) targeted for peptide binder hallucination/design.
|
| 327 |
+
- adding [finer control](#how-do-i-control-which-model-params-are-used-during-design) over what models are used during optimization.
|
| 328 |
+
- fixing RAM memory leaks, `clear_mem()` now also does garbage collection
|
| 329 |
+
- fixing integration with TrDesign that got broken in v1.0.6
|
| 330 |
+
- **22Sept2022** - v1.0.8
|
| 331 |
+
- [custom callback functions](#custom-callback-examples) (\[pre|loss|pos\]_callback) have been refactored to be more flexible.
|
| 332 |
+
- Supported input arguments include: ["inputs", "outputs", "params", "opt", "seq", "aux", "key"].
|
| 333 |
+
- The pre_callback function can be used to modify inputs before prediction, loss_callback to add cutstom loss.
|
| 334 |
+
- adding support for [Optax optimizers](#optax-optimizers)
|
| 335 |
+
- **24Sept2022** - v1.0.9
|
| 336 |
+
- adding [contrib section](/af/contrib) where user contributed modifications and protocols will go.
|
model/PXDesignBench/ColabDesign/af/contrib/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
WIP
|
model/PXDesignBench/ColabDesign/af/design.ipynb
ADDED
|
@@ -0,0 +1,452 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/design.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "markdown",
|
| 15 |
+
"metadata": {
|
| 16 |
+
"id": "OA2k3sAYuiXe"
|
| 17 |
+
},
|
| 18 |
+
"source": [
|
| 19 |
+
"#AfDesign (v1.1.1)\n",
|
| 20 |
+
"Backprop through AlphaFold for protein design.\n",
|
| 21 |
+
"\n",
|
| 22 |
+
"**WARNING**\n",
|
| 23 |
+
"1. This notebook is in active development and was designed for demonstration purposes only.\n",
|
| 24 |
+
"2. Using AfDesign as the only \"loss\" function for design might be a bad idea, you may find adversarial sequences (aka. sequences that trick AlphaFold)."
|
| 25 |
+
]
|
| 26 |
+
},
|
| 27 |
+
{
|
| 28 |
+
"cell_type": "code",
|
| 29 |
+
"execution_count": null,
|
| 30 |
+
"metadata": {
|
| 31 |
+
"cellView": "form",
|
| 32 |
+
"id": "-AXy0s_4cKaK"
|
| 33 |
+
},
|
| 34 |
+
"outputs": [],
|
| 35 |
+
"source": [
|
| 36 |
+
"#@title setup\n",
|
| 37 |
+
"%%time\n",
|
| 38 |
+
"import os\n",
|
| 39 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 40 |
+
" # get code\n",
|
| 41 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git@v1.1.1\")\n",
|
| 42 |
+
" # for debugging\n",
|
| 43 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 44 |
+
" # download params\n",
|
| 45 |
+
" os.system(\"mkdir params\")\n",
|
| 46 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 47 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar\")\n",
|
| 48 |
+
" os.system(\"tar -xf alphafold_params_2022-12-06.tar -C params\")\n",
|
| 49 |
+
"\n",
|
| 50 |
+
"import warnings\n",
|
| 51 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 52 |
+
"\n",
|
| 53 |
+
"import os\n",
|
| 54 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 55 |
+
"from IPython.display import HTML\n",
|
| 56 |
+
"from google.colab import files\n",
|
| 57 |
+
"import numpy as np\n",
|
| 58 |
+
"\n",
|
| 59 |
+
"def get_pdb(pdb_code=\"\"):\n",
|
| 60 |
+
" if pdb_code is None or pdb_code == \"\":\n",
|
| 61 |
+
" upload_dict = files.upload()\n",
|
| 62 |
+
" pdb_string = upload_dict[list(upload_dict.keys())[0]]\n",
|
| 63 |
+
" with open(\"tmp.pdb\",\"wb\") as out: out.write(pdb_string)\n",
|
| 64 |
+
" return \"tmp.pdb\"\n",
|
| 65 |
+
" elif os.path.isfile(pdb_code):\n",
|
| 66 |
+
" return pdb_code\n",
|
| 67 |
+
" elif len(pdb_code) == 4:\n",
|
| 68 |
+
" os.system(f\"wget -qnc https://files.rcsb.org/view/{pdb_code}.pdb\")\n",
|
| 69 |
+
" return f\"{pdb_code}.pdb\"\n",
|
| 70 |
+
" else:\n",
|
| 71 |
+
" os.system(f\"wget -qnc https://alphafold.ebi.ac.uk/files/AF-{pdb_code}-F1-model_v3.pdb\")\n",
|
| 72 |
+
" return f\"AF-{pdb_code}-F1-model_v3.pdb\""
|
| 73 |
+
]
|
| 74 |
+
},
|
| 75 |
+
{
|
| 76 |
+
"cell_type": "markdown",
|
| 77 |
+
"metadata": {
|
| 78 |
+
"id": "UUfKrOzT0gOS"
|
| 79 |
+
},
|
| 80 |
+
"source": [
|
| 81 |
+
"# fixed backbone design (fixbb)\n",
|
| 82 |
+
"For a given protein backbone, generate/design a new sequence that AlphaFold thinks folds into that conformation. "
|
| 83 |
+
]
|
| 84 |
+
},
|
| 85 |
+
{
|
| 86 |
+
"cell_type": "code",
|
| 87 |
+
"execution_count": null,
|
| 88 |
+
"metadata": {
|
| 89 |
+
"id": "qLd1DsnKzxBJ"
|
| 90 |
+
},
|
| 91 |
+
"outputs": [],
|
| 92 |
+
"source": [
|
| 93 |
+
"clear_mem()\n",
|
| 94 |
+
"af_model = mk_afdesign_model(protocol=\"fixbb\")\n",
|
| 95 |
+
"af_model.prep_inputs(pdb_filename=get_pdb(\"1TEN\"), chain=\"A\")\n",
|
| 96 |
+
"\n",
|
| 97 |
+
"print(\"length\", af_model._len)\n",
|
| 98 |
+
"print(\"weights\", af_model.opt[\"weights\"])"
|
| 99 |
+
]
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"cell_type": "code",
|
| 103 |
+
"source": [
|
| 104 |
+
"af_model.restart()\n",
|
| 105 |
+
"af_model.design_3stage()"
|
| 106 |
+
],
|
| 107 |
+
"metadata": {
|
| 108 |
+
"id": "u0AwskJ84NGx"
|
| 109 |
+
},
|
| 110 |
+
"execution_count": null,
|
| 111 |
+
"outputs": []
|
| 112 |
+
},
|
| 113 |
+
{
|
| 114 |
+
"cell_type": "code",
|
| 115 |
+
"source": [
|
| 116 |
+
"af_model.plot_traj() "
|
| 117 |
+
],
|
| 118 |
+
"metadata": {
|
| 119 |
+
"id": "8FB1v7dn1LL6"
|
| 120 |
+
},
|
| 121 |
+
"execution_count": null,
|
| 122 |
+
"outputs": []
|
| 123 |
+
},
|
| 124 |
+
{
|
| 125 |
+
"cell_type": "code",
|
| 126 |
+
"execution_count": null,
|
| 127 |
+
"metadata": {
|
| 128 |
+
"id": "YEApO8YzBoS0"
|
| 129 |
+
},
|
| 130 |
+
"outputs": [],
|
| 131 |
+
"source": [
|
| 132 |
+
"af_model.save_pdb(f\"{af_model.protocol}.pdb\")\n",
|
| 133 |
+
"af_model.plot_pdb()"
|
| 134 |
+
]
|
| 135 |
+
},
|
| 136 |
+
{
|
| 137 |
+
"cell_type": "code",
|
| 138 |
+
"execution_count": null,
|
| 139 |
+
"metadata": {
|
| 140 |
+
"id": "cW1KQiHKJpfp"
|
| 141 |
+
},
|
| 142 |
+
"outputs": [],
|
| 143 |
+
"source": [
|
| 144 |
+
"HTML(af_model.animate())"
|
| 145 |
+
]
|
| 146 |
+
},
|
| 147 |
+
{
|
| 148 |
+
"cell_type": "code",
|
| 149 |
+
"source": [
|
| 150 |
+
"af_model.get_seqs()"
|
| 151 |
+
],
|
| 152 |
+
"metadata": {
|
| 153 |
+
"id": "YDrChASGVUUx"
|
| 154 |
+
},
|
| 155 |
+
"execution_count": null,
|
| 156 |
+
"outputs": []
|
| 157 |
+
},
|
| 158 |
+
{
|
| 159 |
+
"cell_type": "markdown",
|
| 160 |
+
"source": [
|
| 161 |
+
"# hallucination\n",
|
| 162 |
+
"For a given length, generate/hallucinate a protein sequence that AlphaFold thinks folds into a well structured protein (high plddt, low pae, many contacts)."
|
| 163 |
+
],
|
| 164 |
+
"metadata": {
|
| 165 |
+
"id": "qLwS2s_xcjRI"
|
| 166 |
+
}
|
| 167 |
+
},
|
| 168 |
+
{
|
| 169 |
+
"cell_type": "code",
|
| 170 |
+
"execution_count": null,
|
| 171 |
+
"metadata": {
|
| 172 |
+
"id": "sZnYfCbfEvol"
|
| 173 |
+
},
|
| 174 |
+
"outputs": [],
|
| 175 |
+
"source": [
|
| 176 |
+
"clear_mem()\n",
|
| 177 |
+
"af_model = mk_afdesign_model(protocol=\"hallucination\")\n",
|
| 178 |
+
"af_model.prep_inputs(length=100)\n",
|
| 179 |
+
"\n",
|
| 180 |
+
"print(\"length\",af_model._len)\n",
|
| 181 |
+
"print(\"weights\",af_model.opt[\"weights\"])"
|
| 182 |
+
]
|
| 183 |
+
},
|
| 184 |
+
{
|
| 185 |
+
"cell_type": "code",
|
| 186 |
+
"source": [
|
| 187 |
+
"# pre-design with gumbel initialization and softmax activation\n",
|
| 188 |
+
"af_model.restart(mode=\"gumbel\")\n",
|
| 189 |
+
"af_model.design_soft(50)\n",
|
| 190 |
+
"\n",
|
| 191 |
+
"# three stage design \n",
|
| 192 |
+
"af_model.set_seq(af_model.aux[\"seq\"][\"pseudo\"])\n",
|
| 193 |
+
"af_model.design_3stage(50,50,10)"
|
| 194 |
+
],
|
| 195 |
+
"metadata": {
|
| 196 |
+
"id": "f76xqCkw0vj9"
|
| 197 |
+
},
|
| 198 |
+
"execution_count": null,
|
| 199 |
+
"outputs": []
|
| 200 |
+
},
|
| 201 |
+
{
|
| 202 |
+
"cell_type": "code",
|
| 203 |
+
"execution_count": null,
|
| 204 |
+
"metadata": {
|
| 205 |
+
"id": "A1GxeLZdTTya"
|
| 206 |
+
},
|
| 207 |
+
"outputs": [],
|
| 208 |
+
"source": [
|
| 209 |
+
"af_model.save_pdb(f\"{af_model.protocol}.pdb\")\n",
|
| 210 |
+
"af_model.plot_pdb()"
|
| 211 |
+
]
|
| 212 |
+
},
|
| 213 |
+
{
|
| 214 |
+
"cell_type": "code",
|
| 215 |
+
"execution_count": null,
|
| 216 |
+
"metadata": {
|
| 217 |
+
"id": "L2E9Tn2Acchj"
|
| 218 |
+
},
|
| 219 |
+
"outputs": [],
|
| 220 |
+
"source": [
|
| 221 |
+
"HTML(af_model.animate())"
|
| 222 |
+
]
|
| 223 |
+
},
|
| 224 |
+
{
|
| 225 |
+
"cell_type": "code",
|
| 226 |
+
"execution_count": null,
|
| 227 |
+
"metadata": {
|
| 228 |
+
"id": "YSKWYu0_GlUH"
|
| 229 |
+
},
|
| 230 |
+
"outputs": [],
|
| 231 |
+
"source": [
|
| 232 |
+
"af_model.get_seqs()"
|
| 233 |
+
]
|
| 234 |
+
},
|
| 235 |
+
{
|
| 236 |
+
"cell_type": "markdown",
|
| 237 |
+
"metadata": {
|
| 238 |
+
"id": "dXfm4B8ISLuL"
|
| 239 |
+
},
|
| 240 |
+
"source": [
|
| 241 |
+
"# binder hallucination\n",
|
| 242 |
+
"For a given protein target and protein binder length, generate/hallucinate a protein binder sequence AlphaFold thinks will bind to the target structure.\n",
|
| 243 |
+
"To do this, we minimize PAE and maximize number of contacts at the interface and within the binder, and we maximize pLDDT of the binder.\n",
|
| 244 |
+
"By default, AlphaFold-ptm with residue index offset hack is used. To enable AlphaFold-multimer set: mk_afdesign_model(use_multimer=True).\n"
|
| 245 |
+
]
|
| 246 |
+
},
|
| 247 |
+
{
|
| 248 |
+
"cell_type": "code",
|
| 249 |
+
"execution_count": null,
|
| 250 |
+
"metadata": {
|
| 251 |
+
"id": "3XLJPiRKx5Mw"
|
| 252 |
+
},
|
| 253 |
+
"outputs": [],
|
| 254 |
+
"source": [
|
| 255 |
+
"clear_mem()\n",
|
| 256 |
+
"af_model = mk_afdesign_model(protocol=\"binder\")\n",
|
| 257 |
+
"af_model.prep_inputs(pdb_filename=get_pdb(\"4MZK\"), chain=\"A\", binder_len=19)\n",
|
| 258 |
+
"\n",
|
| 259 |
+
"print(\"target_length\",af_model._target_len)\n",
|
| 260 |
+
"print(\"binder_length\",af_model._binder_len)\n",
|
| 261 |
+
"print(\"weights\",af_model.opt[\"weights\"])"
|
| 262 |
+
]
|
| 263 |
+
},
|
| 264 |
+
{
|
| 265 |
+
"cell_type": "code",
|
| 266 |
+
"execution_count": null,
|
| 267 |
+
"metadata": {
|
| 268 |
+
"id": "u6VxjuinyCZa"
|
| 269 |
+
},
|
| 270 |
+
"outputs": [],
|
| 271 |
+
"source": [
|
| 272 |
+
"af_model.restart()\n",
|
| 273 |
+
"af_model.design_3stage(100,100,10)"
|
| 274 |
+
]
|
| 275 |
+
},
|
| 276 |
+
{
|
| 277 |
+
"cell_type": "code",
|
| 278 |
+
"source": [
|
| 279 |
+
"af_model.save_pdb(f\"{af_model.protocol}.pdb\")\n",
|
| 280 |
+
"af_model.plot_pdb()"
|
| 281 |
+
],
|
| 282 |
+
"metadata": {
|
| 283 |
+
"id": "sTlS7_L8Zfwf"
|
| 284 |
+
},
|
| 285 |
+
"execution_count": null,
|
| 286 |
+
"outputs": []
|
| 287 |
+
},
|
| 288 |
+
{
|
| 289 |
+
"cell_type": "code",
|
| 290 |
+
"execution_count": null,
|
| 291 |
+
"metadata": {
|
| 292 |
+
"id": "9cARoviGyIKb"
|
| 293 |
+
},
|
| 294 |
+
"outputs": [],
|
| 295 |
+
"source": [
|
| 296 |
+
"HTML(af_model.animate())"
|
| 297 |
+
]
|
| 298 |
+
},
|
| 299 |
+
{
|
| 300 |
+
"cell_type": "code",
|
| 301 |
+
"source": [
|
| 302 |
+
"af_model.get_seqs()"
|
| 303 |
+
],
|
| 304 |
+
"metadata": {
|
| 305 |
+
"id": "RzE137NDZdZc"
|
| 306 |
+
},
|
| 307 |
+
"execution_count": null,
|
| 308 |
+
"outputs": []
|
| 309 |
+
},
|
| 310 |
+
{
|
| 311 |
+
"cell_type": "markdown",
|
| 312 |
+
"source": [
|
| 313 |
+
"#**ADVANCED**"
|
| 314 |
+
],
|
| 315 |
+
"metadata": {
|
| 316 |
+
"id": "SK0IJLoen_EC"
|
| 317 |
+
}
|
| 318 |
+
},
|
| 319 |
+
{
|
| 320 |
+
"cell_type": "markdown",
|
| 321 |
+
"source": [
|
| 322 |
+
"## partial hallucination + custom Radius of Gyration (rg) loss\n",
|
| 323 |
+
"mix supervised (fixbb) and unsupervised (hallucination) losses to constrain the halluciation process."
|
| 324 |
+
],
|
| 325 |
+
"metadata": {
|
| 326 |
+
"id": "zl6JGTUzXRnk"
|
| 327 |
+
}
|
| 328 |
+
},
|
| 329 |
+
{
|
| 330 |
+
"cell_type": "code",
|
| 331 |
+
"source": [
|
| 332 |
+
"import jax\n",
|
| 333 |
+
"import jax.numpy as jnp\n",
|
| 334 |
+
"from colabdesign.af.alphafold.common import residue_constants\n",
|
| 335 |
+
"\n",
|
| 336 |
+
"# first off, let's implement a custom Radius of Gyration loss function\n",
|
| 337 |
+
"def rg_loss(inputs, outputs):\n",
|
| 338 |
+
" positions = outputs[\"structure_module\"][\"final_atom_positions\"]\n",
|
| 339 |
+
" ca = positions[:,residue_constants.atom_order[\"CA\"]]\n",
|
| 340 |
+
" center = ca.mean(0)\n",
|
| 341 |
+
" rg = jnp.sqrt(jnp.square(ca - center).sum(-1).mean() + 1e-8)\n",
|
| 342 |
+
" rg_th = 2.38 * ca.shape[0] ** 0.365\n",
|
| 343 |
+
" rg = jax.nn.elu(rg - rg_th)\n",
|
| 344 |
+
" return {\"rg\":rg}"
|
| 345 |
+
],
|
| 346 |
+
"metadata": {
|
| 347 |
+
"id": "spec3m8BlGer"
|
| 348 |
+
},
|
| 349 |
+
"execution_count": null,
|
| 350 |
+
"outputs": []
|
| 351 |
+
},
|
| 352 |
+
{
|
| 353 |
+
"cell_type": "code",
|
| 354 |
+
"source": [
|
| 355 |
+
"clear_mem()\n",
|
| 356 |
+
"af_model = mk_afdesign_model(protocol=\"partial\",\n",
|
| 357 |
+
" loss_callback=rg_loss, # add rg_loss\n",
|
| 358 |
+
" use_templates=False) # set True to constrain positions using template input\n",
|
| 359 |
+
"\n",
|
| 360 |
+
"af_model.opt[\"weights\"][\"rg\"] = 0.1 # optional: specify weight for rg_loss\n",
|
| 361 |
+
"\n",
|
| 362 |
+
"af_model.prep_inputs(pdb_filename=get_pdb(\"6MRR\"),\n",
|
| 363 |
+
" chain=\"A\",\n",
|
| 364 |
+
" pos=\"3-30,33-68\", # define positions to contrain\n",
|
| 365 |
+
" length=100) # total length if different from input pdb\n",
|
| 366 |
+
"\n",
|
| 367 |
+
"af_model.rewire(loops=[36]) # set loop length between segments "
|
| 368 |
+
],
|
| 369 |
+
"metadata": {
|
| 370 |
+
"id": "h_BvzwbAKo6V"
|
| 371 |
+
},
|
| 372 |
+
"execution_count": null,
|
| 373 |
+
"outputs": []
|
| 374 |
+
},
|
| 375 |
+
{
|
| 376 |
+
"cell_type": "code",
|
| 377 |
+
"source": [
|
| 378 |
+
"# initialize with wildtype seq, fill in the rest with soft_gumbel distribution\n",
|
| 379 |
+
"af_model.restart(mode=[\"soft\",\"gumbel\",\"wildtype\"])\n",
|
| 380 |
+
"af_model.design_3stage(100, 100, 10)"
|
| 381 |
+
],
|
| 382 |
+
"metadata": {
|
| 383 |
+
"id": "5Unr9u2GYKRD"
|
| 384 |
+
},
|
| 385 |
+
"execution_count": null,
|
| 386 |
+
"outputs": []
|
| 387 |
+
},
|
| 388 |
+
{
|
| 389 |
+
"cell_type": "code",
|
| 390 |
+
"source": [
|
| 391 |
+
"af_model.save_pdb(f\"{af_model.protocol}.pdb\")\n",
|
| 392 |
+
"af_model.plot_pdb()"
|
| 393 |
+
],
|
| 394 |
+
"metadata": {
|
| 395 |
+
"id": "BFweaqNWYuF0"
|
| 396 |
+
},
|
| 397 |
+
"execution_count": null,
|
| 398 |
+
"outputs": []
|
| 399 |
+
},
|
| 400 |
+
{
|
| 401 |
+
"cell_type": "code",
|
| 402 |
+
"source": [
|
| 403 |
+
"HTML(af_model.animate())"
|
| 404 |
+
],
|
| 405 |
+
"metadata": {
|
| 406 |
+
"id": "GSu2lB9HYw-t"
|
| 407 |
+
},
|
| 408 |
+
"execution_count": null,
|
| 409 |
+
"outputs": []
|
| 410 |
+
},
|
| 411 |
+
{
|
| 412 |
+
"cell_type": "code",
|
| 413 |
+
"source": [
|
| 414 |
+
"af_model.get_seqs()"
|
| 415 |
+
],
|
| 416 |
+
"metadata": {
|
| 417 |
+
"id": "2EG2t2_KY4Td"
|
| 418 |
+
},
|
| 419 |
+
"execution_count": null,
|
| 420 |
+
"outputs": []
|
| 421 |
+
},
|
| 422 |
+
{
|
| 423 |
+
"cell_type": "code",
|
| 424 |
+
"source": [],
|
| 425 |
+
"metadata": {
|
| 426 |
+
"id": "rTGKbhsI0t8k"
|
| 427 |
+
},
|
| 428 |
+
"execution_count": null,
|
| 429 |
+
"outputs": []
|
| 430 |
+
}
|
| 431 |
+
],
|
| 432 |
+
"metadata": {
|
| 433 |
+
"accelerator": "GPU",
|
| 434 |
+
"colab": {
|
| 435 |
+
"collapsed_sections": [
|
| 436 |
+
"q4qiU9I0QHSz"
|
| 437 |
+
],
|
| 438 |
+
"name": "design.ipynb",
|
| 439 |
+
"provenance": [],
|
| 440 |
+
"include_colab_link": true
|
| 441 |
+
},
|
| 442 |
+
"kernelspec": {
|
| 443 |
+
"display_name": "Python 3",
|
| 444 |
+
"name": "python3"
|
| 445 |
+
},
|
| 446 |
+
"language_info": {
|
| 447 |
+
"name": "python"
|
| 448 |
+
}
|
| 449 |
+
},
|
| 450 |
+
"nbformat": 4,
|
| 451 |
+
"nbformat_minor": 0
|
| 452 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/AF2Rank.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
model/PXDesignBench/ColabDesign/af/examples/RSO.ipynb
ADDED
|
@@ -0,0 +1,1297 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/main/af/examples/RSO.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "markdown",
|
| 15 |
+
"metadata": {
|
| 16 |
+
"id": "OA2k3sAYuiXe"
|
| 17 |
+
},
|
| 18 |
+
"source": [
|
| 19 |
+
"\n",
|
| 20 |
+
"\n",
|
| 21 |
+
"\n",
|
| 22 |
+
"#Protein Design using Relaxed Sequence Optimization\n",
|
| 23 |
+
"\n",
|
| 24 |
+
"\n",
|
| 25 |
+
"**Scalable protein design using optimization in a relaxed sequence space**\n",
|
| 26 |
+
"\n",
|
| 27 |
+
"\n",
|
| 28 |
+
"\n",
|
| 29 |
+
"\n",
|
| 30 |
+
"Christopher Frank, Ali Khoshouei, Lara Fuß, Lara Weber Dominik Schiewitz,Zhixuan Zhao, Motoyuki Hattori, Yosta de Stigter, Shihao Feng, Sergey Ovchinnikov and Hendrik Dietz\n",
|
| 31 |
+
"\n",
|
| 32 |
+
"\n",
|
| 33 |
+
"This notebook contains code to run relaxed sequence optimisation for de novo protein design as described in the manuscript. There are additional options to modify the pipeline according to ones needs\n",
|
| 34 |
+
"\n",
|
| 35 |
+
"We recommend using at least an L4 GPU to run this notebook, as the free T4 GPU struggles with larger proteins\n",
|
| 36 |
+
"\n",
|
| 37 |
+
"Alternativly a local installation of ColabDesign is strongly recommendet, especially for the design of larger proteins.\n",
|
| 38 |
+
"\n",
|
| 39 |
+
"For questions feel free to reach out to the authors\n"
|
| 40 |
+
]
|
| 41 |
+
},
|
| 42 |
+
{
|
| 43 |
+
"cell_type": "code",
|
| 44 |
+
"execution_count": null,
|
| 45 |
+
"metadata": {
|
| 46 |
+
"cellView": "form",
|
| 47 |
+
"id": "-AXy0s_4cKaK"
|
| 48 |
+
},
|
| 49 |
+
"outputs": [],
|
| 50 |
+
"source": [
|
| 51 |
+
"#@title setup\n",
|
| 52 |
+
"%%time\n",
|
| 53 |
+
"import os\n",
|
| 54 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 55 |
+
" # get code\n",
|
| 56 |
+
" os.system(\"pip -q install pyppeteer nest_asyncio\")\n",
|
| 57 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git\")\n",
|
| 58 |
+
" # for debugging\n",
|
| 59 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 60 |
+
" # download params\n",
|
| 61 |
+
" os.system(\"mkdir params\")\n",
|
| 62 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 63 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar\")\n",
|
| 64 |
+
" os.system(\"tar -xf alphafold_params_2022-12-06.tar -C params\")\n",
|
| 65 |
+
"\n",
|
| 66 |
+
"import warnings\n",
|
| 67 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 68 |
+
"\n",
|
| 69 |
+
"import os\n",
|
| 70 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 71 |
+
"from colabdesign.mpnn import mk_mpnn_model\n",
|
| 72 |
+
"\n",
|
| 73 |
+
"from IPython.display import HTML\n",
|
| 74 |
+
"from google.colab import files\n",
|
| 75 |
+
"import numpy as np\n",
|
| 76 |
+
"\n",
|
| 77 |
+
"import requests, time\n",
|
| 78 |
+
"if not os.path.isfile(\"TMscore\"):\n",
|
| 79 |
+
" os.system(\"wget -qnc https://zhanggroup.org/TM-score/TMscore.cpp\")\n",
|
| 80 |
+
" os.system(\"g++ -static -O3 -ffast-math -lm -o TMscore TMscore.cpp\")\n",
|
| 81 |
+
"def tmscore(x,y):\n",
|
| 82 |
+
" # pass to TMscore\n",
|
| 83 |
+
" output = os.popen(f'./TMscore {x} {y}')\n",
|
| 84 |
+
" # parse outputs\n",
|
| 85 |
+
" parse_float = lambda x: float(x.split(\"=\")[1].split()[0])\n",
|
| 86 |
+
" o = {}\n",
|
| 87 |
+
" for line in output:\n",
|
| 88 |
+
" line = line.rstrip()\n",
|
| 89 |
+
" if line.startswith(\"RMSD\"): o[\"rms\"] = parse_float(line)\n",
|
| 90 |
+
" if line.startswith(\"TM-score\"): o[\"tms\"] = parse_float(line)\n",
|
| 91 |
+
" if line.startswith(\"GDT-TS-score\"): o[\"gdt\"] = parse_float(line)\n",
|
| 92 |
+
" return o\n",
|
| 93 |
+
"\n",
|
| 94 |
+
"import asyncio\n",
|
| 95 |
+
"import nest_asyncio\n",
|
| 96 |
+
"from pyppeteer import launch\n",
|
| 97 |
+
"import base64\n",
|
| 98 |
+
"\n",
|
| 99 |
+
"# Apply nest_asyncio to enable nested event loops\n",
|
| 100 |
+
"nest_asyncio.apply()\n",
|
| 101 |
+
"\n",
|
| 102 |
+
"async def fetch_blob_content(page, blob_url):\n",
|
| 103 |
+
" blob_to_base64 = \"\"\"\n",
|
| 104 |
+
" async (blobUrl) => {\n",
|
| 105 |
+
" const blob = await fetch(blobUrl).then(r => r.blob());\n",
|
| 106 |
+
" return new Promise((resolve) => {\n",
|
| 107 |
+
" const reader = new FileReader();\n",
|
| 108 |
+
" reader.onloadend = () => resolve(reader.result);\n",
|
| 109 |
+
" reader.readAsDataURL(blob);\n",
|
| 110 |
+
" });\n",
|
| 111 |
+
" }\n",
|
| 112 |
+
" \"\"\"\n",
|
| 113 |
+
" base64_data = await page.evaluate(blob_to_base64, blob_url)\n",
|
| 114 |
+
" _, encoded = base64_data.split(',', 1)\n",
|
| 115 |
+
" return base64.b64decode(encoded)\n",
|
| 116 |
+
"\n",
|
| 117 |
+
"async def extract_pdb_file_download_link_and_content(url):\n",
|
| 118 |
+
" browser = await launch(headless=True, args=['--no-sandbox', '--disable-setuid-sandbox'])\n",
|
| 119 |
+
" page = await browser.newPage()\n",
|
| 120 |
+
" await page.goto(url, {'waitUntil': 'networkidle0'})\n",
|
| 121 |
+
" elements = await page.querySelectorAll('a.btn.bg-purple')\n",
|
| 122 |
+
" for element in elements:\n",
|
| 123 |
+
" href = await page.evaluate('(element) => element.getAttribute(\"href\")', element)\n",
|
| 124 |
+
" if 'blob:https://esmatlas.com/' in href:\n",
|
| 125 |
+
" content = await fetch_blob_content(page, href)\n",
|
| 126 |
+
" await browser.close()\n",
|
| 127 |
+
" return href, content\n",
|
| 128 |
+
" await browser.close()\n",
|
| 129 |
+
" return \"No PDB file link found.\", None\n",
|
| 130 |
+
"\n",
|
| 131 |
+
"def esmfold_api(sequence):\n",
|
| 132 |
+
" url = f'https://esmatlas.com/resources/fold/result?fasta_header=%3Eunnamed&sequence={sequence}'\n",
|
| 133 |
+
" result = asyncio.get_event_loop().run_until_complete(extract_pdb_file_download_link_and_content(url))\n",
|
| 134 |
+
" if result[1]:\n",
|
| 135 |
+
" pdb_str = result[1].decode('utf-8')\n",
|
| 136 |
+
" return pdb_str\n",
|
| 137 |
+
" else:\n",
|
| 138 |
+
" return \"Failed to retrieve PDB content.\"\n",
|
| 139 |
+
"\n",
|
| 140 |
+
"import jax\n",
|
| 141 |
+
"import jax.numpy as jnp\n",
|
| 142 |
+
"from colabdesign.af.alphafold.common import residue_constants"
|
| 143 |
+
]
|
| 144 |
+
},
|
| 145 |
+
{
|
| 146 |
+
"cell_type": "code",
|
| 147 |
+
"execution_count": null,
|
| 148 |
+
"metadata": {
|
| 149 |
+
"id": "sZnYfCbfEvol",
|
| 150 |
+
"cellView": "form"
|
| 151 |
+
},
|
| 152 |
+
"outputs": [],
|
| 153 |
+
"source": [
|
| 154 |
+
"#@title # Unconditional Generation (Custom)\n",
|
| 155 |
+
"#@markdown For a given length, generate/hallucinate a protein sequence that AlphaFold thinks folds into a well structured protein (high plddt, low pae, many contacts).\n",
|
| 156 |
+
"LENGTH = 100 #@param {type:\"integer\"}\n",
|
| 157 |
+
"#@markdown With copies you can specify the number of identical sequences design, resulting in homo oligomers. Copies = 1 is the standard, resulting in a monomer\n",
|
| 158 |
+
"\n",
|
| 159 |
+
"COPIES = 1 #@param [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"] {type:\"raw\"}\n",
|
| 160 |
+
"MODE = \"manuscript\"\n",
|
| 161 |
+
"\n",
|
| 162 |
+
"#@markdown Select the losses you want to use. For unconditional generation as reported in the manuscript use all the losses. To increase the diversity of designes remove confidence losses and/or increase the weight of the helix loss.\n",
|
| 163 |
+
"\n",
|
| 164 |
+
"use_rg_loss = True #@param {type:\"boolean\"}\n",
|
| 165 |
+
"#@markdown A too strong rg loss can lead to problems and clashes. Use 0.1 for backbones smaller then 600 AA and 0.01 for larger proteins (0.001 for 1000 AA).\n",
|
| 166 |
+
"rg_weight = 0.1 #@param {type:\"raw\"}\n",
|
| 167 |
+
"use_helix_loss = True #@param {type:\"boolean\"}\n",
|
| 168 |
+
"use_con_loss = True #@param {type:\"boolean\"}\n",
|
| 169 |
+
"use_confidence_loss = True #@param {type:\"boolean\"}\n",
|
| 170 |
+
"#@markdown How many halluicnation iteration you want to perform. The standard in the manuscript is 100.\n",
|
| 171 |
+
"\n",
|
| 172 |
+
"iters = 50 #@param [\"100\", \"50\", \"30\"] {type:\"raw\"}\n",
|
| 173 |
+
"\n",
|
| 174 |
+
"\n",
|
| 175 |
+
"#@markdown Select if you want to use the 'standard\" ProteinMPNN weights or the soluble ones. The soluble ones usually result in higher in silico as well as experimental sucess, but will increase the negative net charge of the protein which sould potentially interfer with certain protein design problems. The manuscript settings are soluble MPNN\n",
|
| 176 |
+
"\n",
|
| 177 |
+
"use_solubleMPNN = True #@param {type:\"boolean\"}\n",
|
| 178 |
+
"#@markdown Select this to use an experimental ProteinMPNN loss, also backpropagating through ProteinMPNN. This was not used in the manuscript\n",
|
| 179 |
+
"\n",
|
| 180 |
+
"use_mpnn_loss = False #@param {type:\"boolean\"}\n",
|
| 181 |
+
"#@markdown\n",
|
| 182 |
+
"\n",
|
| 183 |
+
"def add_rg_loss(self, weight=0.1):\n",
|
| 184 |
+
" '''add radius of gyration loss'''\n",
|
| 185 |
+
" def loss_fn(inputs, outputs):\n",
|
| 186 |
+
" xyz = outputs[\"structure_module\"]\n",
|
| 187 |
+
" ca = xyz[\"final_atom_positions\"][:,residue_constants.atom_order[\"CA\"]]\n",
|
| 188 |
+
" if self.protocol == \"binder\":\n",
|
| 189 |
+
" ca = ca[-self._binder_len:]\n",
|
| 190 |
+
" #This uses a scaled version of the rg loss, only looking at every 5th residue\n",
|
| 191 |
+
" if MODE == \"manuscript\":\n",
|
| 192 |
+
" ca = ca[::5]\n",
|
| 193 |
+
" rg = jnp.sqrt(jnp.square(ca - ca.mean(0)).sum(-1).mean() + 1e-8)\n",
|
| 194 |
+
"\n",
|
| 195 |
+
" if MODE == \"original\":\n",
|
| 196 |
+
" rg_th = 2.38 * ca.shape[0] ** 0.365\n",
|
| 197 |
+
" rg = jax.nn.elu(rg - rg_th)\n",
|
| 198 |
+
" return {\"rg\":rg}\n",
|
| 199 |
+
" self._callbacks[\"model\"][\"loss\"].append(loss_fn)\n",
|
| 200 |
+
" self.opt[\"weights\"][\"rg\"] = weight\n",
|
| 201 |
+
"\n",
|
| 202 |
+
"def add_mpnn_loss(self, mpnn=0.1, mpnn_seq=0.0):\n",
|
| 203 |
+
" '''\n",
|
| 204 |
+
" add mpnn loss\n",
|
| 205 |
+
" mpnn = maximize confidence of proteinmpnn\n",
|
| 206 |
+
" mpnn_seq = push designed sequence to match proteinmpnn logits\n",
|
| 207 |
+
" '''\n",
|
| 208 |
+
"\n",
|
| 209 |
+
" self._mpnn = mk_mpnn_model(weights = \"soluble\" if use_solubleMPNN else \"original\")\n",
|
| 210 |
+
" def loss_fn(inputs, outputs, aux, key):\n",
|
| 211 |
+
"\n",
|
| 212 |
+
" # get structure\n",
|
| 213 |
+
" atom_idx = tuple(residue_constants.atom_order[k] for k in [\"N\",\"CA\",\"C\",\"O\"])\n",
|
| 214 |
+
" I = {\"S\": inputs[\"aatype\"],\n",
|
| 215 |
+
" \"residue_idx\": inputs[\"residue_index\"],\n",
|
| 216 |
+
" \"chain_idx\": inputs[\"asym_id\"],\n",
|
| 217 |
+
" \"X\": outputs[\"structure_module\"][\"final_atom_positions\"][:,atom_idx],\n",
|
| 218 |
+
" \"mask\": outputs[\"structure_module\"][\"final_atom_mask\"][:,1],\n",
|
| 219 |
+
" \"lengths\": self._lengths,\n",
|
| 220 |
+
" \"key\": key}\n",
|
| 221 |
+
"\n",
|
| 222 |
+
" if \"offset\" in inputs:\n",
|
| 223 |
+
" I[\"offset\"] = inputs[\"offset\"]\n",
|
| 224 |
+
"\n",
|
| 225 |
+
" # set autoregressive mask\n",
|
| 226 |
+
" L = sum(self._lengths)\n",
|
| 227 |
+
" if self.protocol == \"binder\":\n",
|
| 228 |
+
" I[\"ar_mask\"] = 1 - np.eye(L)\n",
|
| 229 |
+
" I[\"ar_mask\"][-self._len:,-self._len:] = 0\n",
|
| 230 |
+
" else:\n",
|
| 231 |
+
" I[\"ar_mask\"] = np.zeros((L,L))\n",
|
| 232 |
+
"\n",
|
| 233 |
+
" # get logits\n",
|
| 234 |
+
" logits = self._mpnn._score(**I)[\"logits\"][:,:20]\n",
|
| 235 |
+
" if self.protocol == \"binder\":\n",
|
| 236 |
+
" logits = logits[-self._len:]\n",
|
| 237 |
+
" else:\n",
|
| 238 |
+
" logits = logits[:self._len]\n",
|
| 239 |
+
" aux[\"mpnn_logits\"] = logits\n",
|
| 240 |
+
"\n",
|
| 241 |
+
" # compute loss\n",
|
| 242 |
+
" log_q = jax.nn.log_softmax(logits)\n",
|
| 243 |
+
" p = inputs[\"seq\"][\"hard\"]\n",
|
| 244 |
+
" q = jax.nn.softmax(logits)\n",
|
| 245 |
+
" losses = {}\n",
|
| 246 |
+
" losses[\"mpnn\"] = -log_q.max(-1).mean()\n",
|
| 247 |
+
" losses[\"mpnn_seq\"] = -(p * jax.lax.stop_gradient(log_q)).sum(-1).mean()\n",
|
| 248 |
+
" return losses\n",
|
| 249 |
+
"\n",
|
| 250 |
+
" self._callbacks[\"model\"][\"loss\"].append(loss_fn)\n",
|
| 251 |
+
" self.opt[\"weights\"][\"mpnn\"] = mpnn\n",
|
| 252 |
+
" self.opt[\"weights\"][\"mpnn_seq\"] = mpnn_seq\n",
|
| 253 |
+
"\n",
|
| 254 |
+
"clear_mem()\n",
|
| 255 |
+
"af_model = mk_afdesign_model(protocol=\"hallucination\")\n",
|
| 256 |
+
"af_model.prep_inputs(length=LENGTH, copies=COPIES)\n",
|
| 257 |
+
"\n",
|
| 258 |
+
"# add extra losses\n",
|
| 259 |
+
"\n",
|
| 260 |
+
"if use_mpnn_loss: add_mpnn_loss(af_model)\n",
|
| 261 |
+
"\n",
|
| 262 |
+
"print(\"length\",af_model._lengths)\n",
|
| 263 |
+
"print(\"weights\",af_model.opt[\"weights\"])"
|
| 264 |
+
]
|
| 265 |
+
},
|
| 266 |
+
{
|
| 267 |
+
"cell_type": "code",
|
| 268 |
+
"source": [
|
| 269 |
+
"#This cell runs the design loop. Run this in a for loop for design of multiple proteins\n",
|
| 270 |
+
"\n",
|
| 271 |
+
"af_model.restart()\n",
|
| 272 |
+
"af_model.set_seq(mode=[\"gumbel\",\"soft\"])\n",
|
| 273 |
+
"if use_rg_loss: add_rg_loss(af_model,rg_weight)\n",
|
| 274 |
+
"if use_helix_loss : af_model.set_weights(helix=-0.2)\n",
|
| 275 |
+
"if use_con_loss : af_model.set_weights(con=1.0)\n",
|
| 276 |
+
"if use_confidence_loss : af_model.set_weights(plddt=0.5, pae=0.5)\n",
|
| 277 |
+
"print(\"weights\",af_model.opt[\"weights\"])\n",
|
| 278 |
+
"af_model.design_logits(iters-10)\n",
|
| 279 |
+
"af_model.design_logits(10, save_best=True)"
|
| 280 |
+
],
|
| 281 |
+
"metadata": {
|
| 282 |
+
"id": "f76xqCkw0vj9"
|
| 283 |
+
},
|
| 284 |
+
"execution_count": null,
|
| 285 |
+
"outputs": []
|
| 286 |
+
},
|
| 287 |
+
{
|
| 288 |
+
"cell_type": "code",
|
| 289 |
+
"execution_count": null,
|
| 290 |
+
"metadata": {
|
| 291 |
+
"id": "A1GxeLZdTTya"
|
| 292 |
+
},
|
| 293 |
+
"outputs": [],
|
| 294 |
+
"source": [
|
| 295 |
+
"#This cell plots and saves the results as a pdb file\n",
|
| 296 |
+
"af_model.save_pdb(f\"{af_model.protocol}.pdb\")\n",
|
| 297 |
+
"af_model.plot_pdb()"
|
| 298 |
+
]
|
| 299 |
+
},
|
| 300 |
+
{
|
| 301 |
+
"cell_type": "code",
|
| 302 |
+
"execution_count": null,
|
| 303 |
+
"metadata": {
|
| 304 |
+
"id": "L2E9Tn2Acchj"
|
| 305 |
+
},
|
| 306 |
+
"outputs": [],
|
| 307 |
+
"source": [
|
| 308 |
+
"HTML(af_model.animate())"
|
| 309 |
+
]
|
| 310 |
+
},
|
| 311 |
+
{
|
| 312 |
+
"cell_type": "code",
|
| 313 |
+
"execution_count": null,
|
| 314 |
+
"metadata": {
|
| 315 |
+
"id": "YSKWYu0_GlUH"
|
| 316 |
+
},
|
| 317 |
+
"outputs": [],
|
| 318 |
+
"source": [
|
| 319 |
+
"af_model.get_seqs()"
|
| 320 |
+
]
|
| 321 |
+
},
|
| 322 |
+
{
|
| 323 |
+
"cell_type": "code",
|
| 324 |
+
"source": [
|
| 325 |
+
"import pandas as pd\n",
|
| 326 |
+
"#@title # Designability test\n",
|
| 327 |
+
"#@markdown Test the designability of the backbone, taking in the backbone, generating sequences with solubleMPNN and predicting the sequence with AF2 in single sequence mode.\n",
|
| 328 |
+
"#@markdown Use Initial Guess (IG) and All Atom Initialisation (AA) for larger proteins\n",
|
| 329 |
+
"\n",
|
| 330 |
+
"AA = False #@param {type:\"boolean\"}\n",
|
| 331 |
+
"IG = False #@param {type:\"boolean\"}\n",
|
| 332 |
+
"#@markdown NOTE: we remove cysteines from all designed proteins. Additionally for large proteins we also exclude methions to reduce the number of internal start codons\n",
|
| 333 |
+
"\n",
|
| 334 |
+
"def designability_test(af_model_test, mpnn_model_test,\n",
|
| 335 |
+
" num_seqs=8, sampling_temp=0.1, num_recycles=3,\n",
|
| 336 |
+
" model_num=4, best_metric=\"rmsd\",\n",
|
| 337 |
+
" in_pdb=\"init.pdb\", out_pdb=\"final.pdb\",\n",
|
| 338 |
+
" verbose=False):\n",
|
| 339 |
+
" alphafold_model = f\"model_{model_num}_ptm\"\n",
|
| 340 |
+
"\n",
|
| 341 |
+
" af_model_test.prep_inputs(in_pdb)\n",
|
| 342 |
+
" af_model_test.restart(rm_aa=\"C,M\")\n",
|
| 343 |
+
" af_model_test._args[\"best_metric\"] = best_metric\n",
|
| 344 |
+
" L = sum(af_model_test._lengths)\n",
|
| 345 |
+
" mpnn_model_test.get_af_inputs(af_model_test)\n",
|
| 346 |
+
" out = mpnn_model_test.sample(num=num_seqs // 8, batch=8,\n",
|
| 347 |
+
" temperature=sampling_temp)\n",
|
| 348 |
+
"\n",
|
| 349 |
+
" af_terms = [\"plddt\", \"ptm\", \"pae\", \"rmsd\", \"dgram_cce\"]\n",
|
| 350 |
+
" for k in af_terms: out[k] = []\n",
|
| 351 |
+
"\n",
|
| 352 |
+
" for n in range(num_seqs):\n",
|
| 353 |
+
" seq = out[\"seq\"][n]\n",
|
| 354 |
+
" af_model_test.predict(seq=seq,\n",
|
| 355 |
+
" num_recycles=num_recycles,\n",
|
| 356 |
+
" num_models=1,\n",
|
| 357 |
+
" verbose=False,\n",
|
| 358 |
+
" models=alphafold_model)\n",
|
| 359 |
+
"\n",
|
| 360 |
+
" for k in af_terms: out[k].append(af_model_test.aux[\"log\"][k])\n",
|
| 361 |
+
" out[\"pae\"][-1] = out[\"pae\"][-1] * 31\n",
|
| 362 |
+
" af_model_test._save_results(save_best=True, verbose=verbose)\n",
|
| 363 |
+
" af_model_test._k += 1\n",
|
| 364 |
+
"\n",
|
| 365 |
+
" af_model_test.save_pdb(out_pdb)\n",
|
| 366 |
+
" labels = [\"score\"] + af_terms + [\"seq\"]\n",
|
| 367 |
+
" data = [[out[k][n] for k in labels] for n in range(num_seqs)]\n",
|
| 368 |
+
" labels[0] = \"mpnn\"\n",
|
| 369 |
+
" df = pd.DataFrame(data, columns=labels)\n",
|
| 370 |
+
" return df\n",
|
| 371 |
+
"\n",
|
| 372 |
+
"af_model_test = mk_afdesign_model(protocol=\"fixbb\",best_metric=\"rmsd\",use_initial_guess=IG,use_initial_atom_pos=AA,use_templates=False)\n",
|
| 373 |
+
"mpnn_model_test = mk_mpnn_model(weights=\"soluble\")\n",
|
| 374 |
+
"\n",
|
| 375 |
+
"\n",
|
| 376 |
+
"lowest_rmsd = float('inf')\n",
|
| 377 |
+
"lowest_rmsd_data = None\n",
|
| 378 |
+
"\n",
|
| 379 |
+
"in_pdb = f\"{af_model.protocol}.pdb\"\n",
|
| 380 |
+
"out_pdb = f\"{af_model.protocol}_out.pdb\"\n",
|
| 381 |
+
"\n",
|
| 382 |
+
"\n",
|
| 383 |
+
"out = designability_test(af_model_test, mpnn_model_test,\n",
|
| 384 |
+
" num_seqs=8, sampling_temp=0.1, num_recycles=3,\n",
|
| 385 |
+
" model_num=4, best_metric=\"rmsd\",\n",
|
| 386 |
+
" in_pdb=in_pdb, out_pdb=out_pdb,\n",
|
| 387 |
+
" verbose=True)\n",
|
| 388 |
+
"\n"
|
| 389 |
+
],
|
| 390 |
+
"metadata": {
|
| 391 |
+
"cellView": "form",
|
| 392 |
+
"id": "Y_-8_Ya4Q8oo"
|
| 393 |
+
},
|
| 394 |
+
"execution_count": null,
|
| 395 |
+
"outputs": []
|
| 396 |
+
},
|
| 397 |
+
{
|
| 398 |
+
"cell_type": "code",
|
| 399 |
+
"source": [
|
| 400 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 401 |
+
"from colabdesign.af.alphafold.common import residue_constants\n",
|
| 402 |
+
"import jax\n",
|
| 403 |
+
"import jax.numpy as jnp\n",
|
| 404 |
+
"#@title # OPTIONAL Unconditional Generation (Manuscript Code)\n",
|
| 405 |
+
"\n",
|
| 406 |
+
"#@markdown This code generates a sample of 10 unconditional proteins for lengths between 100 and 800 AA exactly as in the manuscript. For larger proteins CUDA_UNIFIED_MEMORY is needed. This can be done by localy running the code on a CUDA capeable GPU with sufficient memory (A100 80GB e.g.) and running the code with the environment variables XLA_PYTHON_CLIENT_MEM_FRACTION=100.0 TF_FORCE_UNIFIED_MEMORY=1\n",
|
| 407 |
+
"def rg_loss(inputs, outputs):\n",
|
| 408 |
+
" positions = outputs[\"structure_module\"][\"final_atom_positions\"]\n",
|
| 409 |
+
" ca = positions[::5,residue_constants.atom_order[\"CA\"]]\n",
|
| 410 |
+
" center = ca.mean(0)\n",
|
| 411 |
+
" rg = jnp.sqrt(jnp.square(ca - center).sum(-1).mean() + 1e-8)\n",
|
| 412 |
+
" rg_th = 2.38 * ca.shape[0] ** 0.365\n",
|
| 413 |
+
" rg = jax.nn.elu(rg - rg_th)\n",
|
| 414 |
+
" return {\"rg\":rg}\n",
|
| 415 |
+
"\n",
|
| 416 |
+
"\n",
|
| 417 |
+
"\n",
|
| 418 |
+
"\n",
|
| 419 |
+
"for length in [100,200,300,400,500,600,700,800]:\n",
|
| 420 |
+
" model = mk_afdesign_model(protocol=\"hallucination\",loss_callback=rg_loss)\n",
|
| 421 |
+
" model.prep_inputs(length=length)\n",
|
| 422 |
+
" print(\"weights\",model.opt[\"weights\"])\n",
|
| 423 |
+
" print('Starting up and compiling JAX model....')\n",
|
| 424 |
+
"\n",
|
| 425 |
+
" for i in range(10):\n",
|
| 426 |
+
" model.restart(mode=[\"gumbel\", \"soft\"],rm_aa=\"C\")\n",
|
| 427 |
+
" model.opt[\"weights\"][\"rg\"] = 0.1\n",
|
| 428 |
+
" if length > 600:\n",
|
| 429 |
+
" model.opt[\"weights\"][\"rg\"] = 0.01\n",
|
| 430 |
+
" #model.opt[\"weights\"]['helix'] = -0.1\n",
|
| 431 |
+
" model.opt[\"weights\"]['plddt'] = 1.0\n",
|
| 432 |
+
" model.opt[\"weights\"]['pae'] = 1.0\n",
|
| 433 |
+
" model.opt[\"weights\"]['helix'] = -0.1\n",
|
| 434 |
+
" print(\"weights\", model.opt[\"weights\"])\n",
|
| 435 |
+
" model.design_logits(100)\n",
|
| 436 |
+
"\n",
|
| 437 |
+
" #change the output path for local execution\n",
|
| 438 |
+
" model.save_pdb(f\"Hallo_{i}.pdb\")"
|
| 439 |
+
],
|
| 440 |
+
"metadata": {
|
| 441 |
+
"cellView": "form",
|
| 442 |
+
"id": "gPby7oP25b5i"
|
| 443 |
+
},
|
| 444 |
+
"execution_count": null,
|
| 445 |
+
"outputs": []
|
| 446 |
+
},
|
| 447 |
+
{
|
| 448 |
+
"cell_type": "code",
|
| 449 |
+
"source": [
|
| 450 |
+
"#@markdown #Redesign with ProteinMPNN for ESMFold prediction\n",
|
| 451 |
+
"#@markdown The standard manuscript settings were 8 sequences, 0.1 sampling temperature and the removal of cysteines\n",
|
| 452 |
+
"import pickle\n",
|
| 453 |
+
"num_seqs = 8 #@param [\"8\", \"16\", \"32\", \"64\"] {type:\"raw\"}\n",
|
| 454 |
+
"mpnn_sampling_temp = 0.1 #@param [\"0.0001\", \"0.1\", \"0.15\", \"0.2\", \"0.25\", \"0.3\", \"0.5\", \"1.0\"] {type:\"raw\"}\n",
|
| 455 |
+
"rm_aa = \"C\" #@param {type:\"string\"}\n",
|
| 456 |
+
"use_solubleMPNN = False #@param {type:\"boolean\"}\n",
|
| 457 |
+
"#@markdown - `mpnn_sampling_temp` - control diversity of sampled sequences. (higher = more diverse).\n",
|
| 458 |
+
"#@markdown - `rm_aa='C'` - do not use [C]ysteines.\n",
|
| 459 |
+
"#@markdown - `use_solubleMPNN` - use weights trained only on soluble proteins.\n",
|
| 460 |
+
"#@markdown\n",
|
| 461 |
+
"\n",
|
| 462 |
+
"from colabdesign.shared.protein import alphabet_list as chain_list\n",
|
| 463 |
+
"mpnn_model = mk_mpnn_model()\n",
|
| 464 |
+
"mpnn_model.prep_inputs(pdb_filename=f\"{af_model.protocol}.pdb\",\n",
|
| 465 |
+
" chain=\",\".join(chain_list[:COPIES]),\n",
|
| 466 |
+
" homooligmer=COPIES>1,\n",
|
| 467 |
+
" rm_aa=rm_aa,\n",
|
| 468 |
+
" weights = \"soluble\" if use_solubleMPNN else\"original\")\n",
|
| 469 |
+
"out = mpnn_model.sample(num=num_seqs//8,\n",
|
| 470 |
+
" batch=8,\n",
|
| 471 |
+
" temperature=mpnn_sampling_temp)\n",
|
| 472 |
+
"for seq,score in zip(out[\"seq\"],out[\"score\"]):\n",
|
| 473 |
+
" print(score,seq.split(\"/\")[0])\n",
|
| 474 |
+
"df = pd.DataFrame(out[\"seq\"])\n",
|
| 475 |
+
"\n",
|
| 476 |
+
"# Define the output path for saving the sequences as a .pkl file\n",
|
| 477 |
+
"output_pkl_file = \"redesigned_sequences.pkl\"\n",
|
| 478 |
+
"\n",
|
| 479 |
+
"# Save the DataFrame to a .pkl file\n",
|
| 480 |
+
"with open(output_pkl_file, 'wb') as f:\n",
|
| 481 |
+
" pickle.dump(df, f)"
|
| 482 |
+
],
|
| 483 |
+
"metadata": {
|
| 484 |
+
"id": "m2qAYsDsCfqJ",
|
| 485 |
+
"cellView": "form"
|
| 486 |
+
},
|
| 487 |
+
"execution_count": null,
|
| 488 |
+
"outputs": []
|
| 489 |
+
},
|
| 490 |
+
{
|
| 491 |
+
"cell_type": "code",
|
| 492 |
+
"source": [
|
| 493 |
+
"#@markdown #Run ESMFold to test designability\n",
|
| 494 |
+
"#@markdown This cells runs ESMFold from huggingface and automatically calculates the RMSD to the designed backbone\n",
|
| 495 |
+
"#@markdown NOTE: GPU memory can be a big problem here. If you get memory errors please restart the runtime and run this cell again. It should be self contained. Additionally, after finish the ESMFold prediction rerun the setup cell\n",
|
| 496 |
+
"\n",
|
| 497 |
+
"import os\n",
|
| 498 |
+
"import pandas as pd\n",
|
| 499 |
+
"from Bio.PDB import PDBParser, Superimposer\n",
|
| 500 |
+
"import pickle\n",
|
| 501 |
+
"import torch\n",
|
| 502 |
+
"import numpy as np\n",
|
| 503 |
+
"from transformers import AutoTokenizer, EsmForProteinFolding\n",
|
| 504 |
+
"from transformers.models.esm.openfold_utils.protein import to_pdb, Protein as OFProtein\n",
|
| 505 |
+
"from transformers.models.esm.openfold_utils.feats import atom14_to_atom37\n",
|
| 506 |
+
"output_pkl_file = \"redesigned_sequences.pkl\"\n",
|
| 507 |
+
"\n",
|
| 508 |
+
"with open(output_pkl_file, 'rb') as f:\n",
|
| 509 |
+
" seq = pickle.load(f)\n",
|
| 510 |
+
"seq_list = []\n",
|
| 511 |
+
"for i in np.asarray(seq):\n",
|
| 512 |
+
" seq_list.append(i[0])\n",
|
| 513 |
+
"\n",
|
| 514 |
+
"pdb_file = \"hallucination.pdb\"\n",
|
| 515 |
+
"print(seq_list)\n",
|
| 516 |
+
"\n",
|
| 517 |
+
"\n",
|
| 518 |
+
"tokenizer = AutoTokenizer.from_pretrained(\"facebook/esmfold_v1\")\n",
|
| 519 |
+
"model = EsmForProteinFolding.from_pretrained(\"facebook/esmfold_v1\", low_cpu_mem_usage=True)\n",
|
| 520 |
+
"\n",
|
| 521 |
+
"device = 'cuda:0'\n",
|
| 522 |
+
"model = model.cuda(device)\n",
|
| 523 |
+
"model.esm = model.esm.half()\n",
|
| 524 |
+
"model.trunk.set_chunk_size(64)\n",
|
| 525 |
+
"torch.backends.cuda.matmul.allow_tf32 = True\n",
|
| 526 |
+
"\n",
|
| 527 |
+
"def convert_outputs_to_pdb(outputs):\n",
|
| 528 |
+
" final_atom_positions = atom14_to_atom37(outputs[\"positions\"][-1], outputs)\n",
|
| 529 |
+
" outputs = {k: v.to(\"cpu\").numpy() for k, v in outputs.items()}\n",
|
| 530 |
+
" final_atom_positions = final_atom_positions.cpu().numpy()\n",
|
| 531 |
+
" final_atom_mask = outputs[\"atom37_atom_exists\"]\n",
|
| 532 |
+
" pdbs = []\n",
|
| 533 |
+
" for i in range(outputs[\"aatype\"].shape[0]):\n",
|
| 534 |
+
" aa = outputs[\"aatype\"][i]\n",
|
| 535 |
+
" pred_pos = final_atom_positions[i]\n",
|
| 536 |
+
" mask = final_atom_mask[i]\n",
|
| 537 |
+
" resid = outputs[\"residue_index\"][i] + 1\n",
|
| 538 |
+
" pred = OFProtein(\n",
|
| 539 |
+
" aatype=aa,\n",
|
| 540 |
+
" atom_positions=pred_pos,\n",
|
| 541 |
+
" atom_mask=mask,\n",
|
| 542 |
+
" residue_index=resid,\n",
|
| 543 |
+
" b_factors=outputs[\"plddt\"][i],\n",
|
| 544 |
+
" chain_index=outputs[\"chain_index\"][i] if \"chain_index\" in outputs else None,\n",
|
| 545 |
+
" )\n",
|
| 546 |
+
" pdbs.append(to_pdb(pred))\n",
|
| 547 |
+
" return pdbs\n",
|
| 548 |
+
"\n",
|
| 549 |
+
"def calculate_ca_rmsd(pdb_file1, pdb_file2):\n",
|
| 550 |
+
" parser = PDBParser(QUIET=True)\n",
|
| 551 |
+
"\n",
|
| 552 |
+
" structure1 = parser.get_structure(\"Protein1\", pdb_file1)\n",
|
| 553 |
+
" structure2 = parser.get_structure(\"Protein2\", pdb_file2)\n",
|
| 554 |
+
"\n",
|
| 555 |
+
" ca_atoms1 = [atom for atom in structure1.get_atoms() if atom.get_name() == \"CA\"]\n",
|
| 556 |
+
" ca_atoms2 = [atom for atom in structure2.get_atoms() if atom.get_name() == \"CA\"]\n",
|
| 557 |
+
"\n",
|
| 558 |
+
" super_imposer = Superimposer()\n",
|
| 559 |
+
" super_imposer.set_atoms(ca_atoms1, ca_atoms2)\n",
|
| 560 |
+
" super_imposer.apply(structure2.get_atoms())\n",
|
| 561 |
+
" rmsd = super_imposer.rms\n",
|
| 562 |
+
" return rmsd\n",
|
| 563 |
+
"\n",
|
| 564 |
+
"def process_sequences(seq_list, pdb_file):\n",
|
| 565 |
+
" lowest_rmsd = float('inf')\n",
|
| 566 |
+
" lowest_rmsd_data = None\n",
|
| 567 |
+
" out_ss_path = \"./output\"\n",
|
| 568 |
+
"\n",
|
| 569 |
+
" if not os.path.exists(out_ss_path):\n",
|
| 570 |
+
" os.mkdir(out_ss_path)\n",
|
| 571 |
+
"\n",
|
| 572 |
+
" for test_protein in seq_list:\n",
|
| 573 |
+
" data = {}\n",
|
| 574 |
+
" tokenized_input = tokenizer([test_protein], return_tensors=\"pt\", add_special_tokens=False)['input_ids']\n",
|
| 575 |
+
" tokenized_input = tokenized_input.cuda(device)\n",
|
| 576 |
+
"\n",
|
| 577 |
+
" with torch.no_grad():\n",
|
| 578 |
+
" output = model(tokenized_input)\n",
|
| 579 |
+
"\n",
|
| 580 |
+
" data['out'] = output\n",
|
| 581 |
+
" data[\"plddt\"] = torch.mean(output['plddt']).item()\n",
|
| 582 |
+
" data['pae'] = torch.mean(output['predicted_aligned_error']).item()\n",
|
| 583 |
+
"\n",
|
| 584 |
+
" pdb_data = convert_outputs_to_pdb(output)\n",
|
| 585 |
+
" tmp_pdb_file = os.path.join(out_ss_path, \"TMP.pdb\")\n",
|
| 586 |
+
"\n",
|
| 587 |
+
" with open(tmp_pdb_file, 'w') as file:\n",
|
| 588 |
+
" for line in pdb_data:\n",
|
| 589 |
+
" file.write(line)\n",
|
| 590 |
+
"\n",
|
| 591 |
+
" data['rmsd'] = calculate_ca_rmsd(tmp_pdb_file, pdb_file)\n",
|
| 592 |
+
" print(f'Sequence: {test_protein}, plddt: {data[\"plddt\"]}, PAE: {data[\"pae\"]}, RMSD: {data[\"rmsd\"]}')\n",
|
| 593 |
+
"\n",
|
| 594 |
+
" if data['rmsd'] < lowest_rmsd:\n",
|
| 595 |
+
" lowest_rmsd = data['rmsd']\n",
|
| 596 |
+
" lowest_rmsd_data = data\n",
|
| 597 |
+
"\n",
|
| 598 |
+
" if lowest_rmsd_data is not None:\n",
|
| 599 |
+
" print(f'Lowest RMSD: {lowest_rmsd}')\n",
|
| 600 |
+
" best_pdb_data = convert_outputs_to_pdb(lowest_rmsd_data['out'])\n",
|
| 601 |
+
" best_pdb_file = os.path.join(out_ss_path, \"best_structure.pdb\")\n",
|
| 602 |
+
"\n",
|
| 603 |
+
" with open(best_pdb_file, 'w') as file:\n",
|
| 604 |
+
" for line in best_pdb_data:\n",
|
| 605 |
+
" file.write(line)\n",
|
| 606 |
+
"\n",
|
| 607 |
+
" original_dict = lowest_rmsd_data\n",
|
| 608 |
+
" key_to_exclude = 'out'\n",
|
| 609 |
+
" data_out = {k: v for k, v in original_dict.items() if k != key_to_exclude}\n",
|
| 610 |
+
"\n",
|
| 611 |
+
" with open(os.path.join(out_ss_path, \"best_structure_data.pkl\"), 'wb') as f:\n",
|
| 612 |
+
" pickle.dump(data_out, f)\n",
|
| 613 |
+
"\n",
|
| 614 |
+
" return lowest_rmsd, best_pdb_file, data_out\n",
|
| 615 |
+
"\n",
|
| 616 |
+
" return None, None, None\n",
|
| 617 |
+
"\n",
|
| 618 |
+
"\n",
|
| 619 |
+
"\n",
|
| 620 |
+
"lowest_rmsd, best_pdb_file, best_data = process_sequences(seq_list, pdb_file)\n",
|
| 621 |
+
"if lowest_rmsd is not None:\n",
|
| 622 |
+
" print(f\"Lowest RMSD: {lowest_rmsd}, Best PDB file: {best_pdb_file}\")\n",
|
| 623 |
+
"else:\n",
|
| 624 |
+
" print(\"No valid result found.\")\n"
|
| 625 |
+
],
|
| 626 |
+
"metadata": {
|
| 627 |
+
"id": "Ey29NmNAFtK0",
|
| 628 |
+
"cellView": "form"
|
| 629 |
+
},
|
| 630 |
+
"execution_count": null,
|
| 631 |
+
"outputs": []
|
| 632 |
+
},
|
| 633 |
+
{
|
| 634 |
+
"cell_type": "code",
|
| 635 |
+
"source": [
|
| 636 |
+
"#@title # Heterodimer Design Prep\n",
|
| 637 |
+
"#@markdown Design a set of heterodimeric proteins with two chains making a complex. The settings are excatly the ones used in the manuscript to design the heterodimer binders.\n",
|
| 638 |
+
"LENGTH1 = 100 #@param {type:\"integer\"}\n",
|
| 639 |
+
"LENGTH2 = 100 #@param {type:\"integer\"}\n",
|
| 640 |
+
"\n",
|
| 641 |
+
"#@markdown ProteinMPNN Settings\n",
|
| 642 |
+
"use_solubleMPNN = True #@param {type:\"boolean\"}\n",
|
| 643 |
+
"#@markdown\n",
|
| 644 |
+
"\n",
|
| 645 |
+
"\n",
|
| 646 |
+
"from colabdesign.af.alphafold.common import residue_constants\n",
|
| 647 |
+
"import jax\n",
|
| 648 |
+
"import jax.numpy as jnp\n",
|
| 649 |
+
"\n",
|
| 650 |
+
"def hd_loss(inputs, outputs):\n",
|
| 651 |
+
" positions = outputs[\"structure_module\"][\"final_atom_positions\"]\n",
|
| 652 |
+
" ca1 = positions[:LENGTH1, residue_constants.atom_order[\"CA\"]]\n",
|
| 653 |
+
" center1 = ca1.mean(0)\n",
|
| 654 |
+
" rg1 = jnp.sqrt(jnp.square(ca1 - center1).sum(-1).mean() + 1e-8)\n",
|
| 655 |
+
" rg_th = 2.38 * ca1.shape[0] ** 0.365\n",
|
| 656 |
+
" rg1 = jax.nn.elu(rg1 - rg_th)\n",
|
| 657 |
+
"\n",
|
| 658 |
+
"\n",
|
| 659 |
+
" ca2 = positions[LENGTH2:, residue_constants.atom_order[\"CA\"]]\n",
|
| 660 |
+
" center2 = ca2.mean(0)\n",
|
| 661 |
+
" rg2 = jnp.sqrt(jnp.square(ca2 - center2).sum(-1).mean() + 1e-8)\n",
|
| 662 |
+
" rg_th = 2.38 * ca2.shape[0] ** 0.365\n",
|
| 663 |
+
" rg2 = jax.nn.elu(rg2 - rg_th)\n",
|
| 664 |
+
"\n",
|
| 665 |
+
"\n",
|
| 666 |
+
"\n",
|
| 667 |
+
" return {\"hd\":rg1+rg2}\n",
|
| 668 |
+
"\n",
|
| 669 |
+
"total_length = LENGTH1 + LENGTH2\n",
|
| 670 |
+
"clear_mem()\n",
|
| 671 |
+
"af_model = mk_afdesign_model(protocol=\"hallucination\", loss_callback=hd_loss)\n",
|
| 672 |
+
"af_model.prep_inputs(length=total_length)\n",
|
| 673 |
+
"af_model._inputs['residue_index'][LENGTH1:] = np.arange(LENGTH2) + 50 + LENGTH1\n",
|
| 674 |
+
"# add extra losses\n",
|
| 675 |
+
"af_model.restart(mode=[\"gumbel\", \"soft\"])\n",
|
| 676 |
+
"af_model.opt[\"weights\"][\"hd\"] = 0.1\n",
|
| 677 |
+
"af_model.opt[\"weights\"]['plddt'] = 1.0\n",
|
| 678 |
+
"af_model.opt[\"weights\"]['pae'] = 1.0\n",
|
| 679 |
+
"af_model.opt[\"weights\"]['helix'] = -0.5\n",
|
| 680 |
+
"print(\"weights\", af_model.opt[\"weights\"])\n",
|
| 681 |
+
"print('Starting up and compiling JAX model....')\n"
|
| 682 |
+
],
|
| 683 |
+
"metadata": {
|
| 684 |
+
"id": "88HCs0ID6CGc",
|
| 685 |
+
"cellView": "form"
|
| 686 |
+
},
|
| 687 |
+
"execution_count": null,
|
| 688 |
+
"outputs": []
|
| 689 |
+
},
|
| 690 |
+
{
|
| 691 |
+
"cell_type": "code",
|
| 692 |
+
"source": [
|
| 693 |
+
"#@title # Run Design\n",
|
| 694 |
+
"af_model.design_logits(100)\n",
|
| 695 |
+
"af_model.save_pdb(\"Heterodimer.pdb\")"
|
| 696 |
+
],
|
| 697 |
+
"metadata": {
|
| 698 |
+
"id": "5KVtj6LM7RQ4"
|
| 699 |
+
},
|
| 700 |
+
"execution_count": null,
|
| 701 |
+
"outputs": []
|
| 702 |
+
},
|
| 703 |
+
{
|
| 704 |
+
"cell_type": "code",
|
| 705 |
+
"source": [
|
| 706 |
+
"af_model.save_pdb(\"Heterodimer.pdb\")\n",
|
| 707 |
+
"af_model.plot_pdb()"
|
| 708 |
+
],
|
| 709 |
+
"metadata": {
|
| 710 |
+
"id": "qfOEMo4qpWfm"
|
| 711 |
+
},
|
| 712 |
+
"execution_count": null,
|
| 713 |
+
"outputs": []
|
| 714 |
+
},
|
| 715 |
+
{
|
| 716 |
+
"cell_type": "code",
|
| 717 |
+
"source": [
|
| 718 |
+
"#@title # Design Sequence using Homooligomer Filter\n",
|
| 719 |
+
"#@markdown We first test if the two protomers are predictd to fold into a high confidence protein on their own, removing proteins that are not likely to be expressed on their own. Then we predict the heterodimer using the AF multimer model. Generally the AF multimer model has a hard time predicting de novo designed proteins. This is why we use templates and remove any interchain information. Finally we predict each individual protomer with a copy of itself, testing for homooligomerisation.\n",
|
| 720 |
+
"\n",
|
| 721 |
+
"\n",
|
| 722 |
+
"file_path =\"Heterodimer.pdb\"\n",
|
| 723 |
+
"\n",
|
| 724 |
+
"folder_path = \"/content/\"\n",
|
| 725 |
+
"\n",
|
| 726 |
+
"######## make A - B chain file\n",
|
| 727 |
+
"\n",
|
| 728 |
+
"from Bio.PDB import PDBParser, PDBIO, Chain\n",
|
| 729 |
+
"\n",
|
| 730 |
+
"# Set the input and output PDB file names\n",
|
| 731 |
+
"input_pdb_file = file_path\n",
|
| 732 |
+
"if not os.path.exists(os.path.join(folder_path, 'AB')):\n",
|
| 733 |
+
" os.mkdir(os.path.join(folder_path, 'AB'))\n",
|
| 734 |
+
"output_pdb_file = os.path.join(folder_path, 'AB',\"Heterodimer.pdb\")\n",
|
| 735 |
+
"\n",
|
| 736 |
+
"# Create a PDB parser and read the input PDB file\n",
|
| 737 |
+
"parser = PDBParser()\n",
|
| 738 |
+
"structure = parser.get_structure(\"input_structure\", input_pdb_file)\n",
|
| 739 |
+
"\n",
|
| 740 |
+
"# Find the initial chain id\n",
|
| 741 |
+
"initial_chain_id = None\n",
|
| 742 |
+
"for chain in structure[0]:\n",
|
| 743 |
+
" initial_chain_id = chain.get_id()\n",
|
| 744 |
+
" break\n",
|
| 745 |
+
"\n",
|
| 746 |
+
"# Create new chains A and B\n",
|
| 747 |
+
"chain_A = Chain.Chain(\"A\")\n",
|
| 748 |
+
"chain_B = Chain.Chain(\"B\")\n",
|
| 749 |
+
"\n",
|
| 750 |
+
"# Iterate over the residues in the original chain\n",
|
| 751 |
+
"for residue in structure[0][initial_chain_id]:\n",
|
| 752 |
+
" res_id = residue.get_id()[1]\n",
|
| 753 |
+
"\n",
|
| 754 |
+
" # Add residues 1-200 to chain A\n",
|
| 755 |
+
" if 1 <= res_id <= 100:\n",
|
| 756 |
+
" chain_A.add(residue.copy())\n",
|
| 757 |
+
"\n",
|
| 758 |
+
" # Add residues 201-400 to chain B\n",
|
| 759 |
+
" elif 151 <= res_id <= 450:\n",
|
| 760 |
+
" chain_B.add(residue.copy())\n",
|
| 761 |
+
"\n",
|
| 762 |
+
"# Remove the existing chain\n",
|
| 763 |
+
"for model in structure:\n",
|
| 764 |
+
" model.detach_child(initial_chain_id)\n",
|
| 765 |
+
"\n",
|
| 766 |
+
"# Add the new chains to the model\n",
|
| 767 |
+
"structure[0].add(chain_A)\n",
|
| 768 |
+
"structure[0].add(chain_B)\n",
|
| 769 |
+
"\n",
|
| 770 |
+
"# Save the modified structure to a new PDB file\n",
|
| 771 |
+
"io = PDBIO()\n",
|
| 772 |
+
"io.set_structure(structure)\n",
|
| 773 |
+
"io.save(output_pdb_file)\n",
|
| 774 |
+
"\n",
|
| 775 |
+
"\n",
|
| 776 |
+
"clear_mem()\n",
|
| 777 |
+
"he_model = mk_afdesign_model(protocol=\"fixbb\", use_templates=True, use_multimer=True)\n",
|
| 778 |
+
"\n",
|
| 779 |
+
"\n",
|
| 780 |
+
"ho_model = mk_afdesign_model(protocol=\"hallucination\")\n",
|
| 781 |
+
"ho_model.prep_inputs(length=LENGTH1, copies=2)\n",
|
| 782 |
+
"\n",
|
| 783 |
+
"ho_model.set_weights(i_pae=1.0)\n",
|
| 784 |
+
"s_model = mk_afdesign_model(protocol=\"hallucination\")\n",
|
| 785 |
+
"s_model.prep_inputs(length=LENGTH2)\n",
|
| 786 |
+
"mpnn_model = mk_mpnn_model(weights=\"soluble\")\n",
|
| 787 |
+
"\n",
|
| 788 |
+
"\n",
|
| 789 |
+
"mpnn_model.prep_inputs(pdb_filename=output_pdb_file, chain='A,B',rm_aa=\"C\")\n",
|
| 790 |
+
"samples = mpnn_model.sample_parallel(8)\n",
|
| 791 |
+
"\n",
|
| 792 |
+
"he_model.prep_inputs(pdb_filename=output_pdb_file, chain='A,B',rm_template_ic=True)\n",
|
| 793 |
+
"he_model._inputs['residue_index'][LENGTH1:] = np.arange(LENGTH2) + 50 + LENGTH1\n",
|
| 794 |
+
"\n",
|
| 795 |
+
"k = 0\n",
|
| 796 |
+
"for seq in samples['seq']:\n",
|
| 797 |
+
" print('Predicting Protomer 1...')\n",
|
| 798 |
+
" s_model.predict(seq=seq[:LENGTH1], num_recycles=3)\n",
|
| 799 |
+
" plddt1 = s_model.aux['losses']['plddt']\n",
|
| 800 |
+
" print('Predicting Protomer 2...')\n",
|
| 801 |
+
" s_model.predict(seq=seq[LENGTH1+1:], num_recycles=3)\n",
|
| 802 |
+
" plddt2 = s_model.aux['losses']['plddt']\n",
|
| 803 |
+
" k = k + 1\n",
|
| 804 |
+
" if plddt1 < 0.20 and plddt2 < 0.20:\n",
|
| 805 |
+
" print('Passed Protomer Check! Predicting Heterodimer...')\n",
|
| 806 |
+
" he_model.predict(seq=''.join([seq[:LENGTH1], seq[LENGTH1+1:]]), num_recycles=3)\n",
|
| 807 |
+
"\n",
|
| 808 |
+
" if he_model.aux['losses']['plddt'] < 0.15 and he_model.aux['losses']['rmsd'] < 2.0:\n",
|
| 809 |
+
" print('Passed Heterodimer Check! Predicting Homodimer 1...')\n",
|
| 810 |
+
" ho_model.predict(seq=seq[:LENGTH1],num_recycles=3)\n",
|
| 811 |
+
" print('Predicting Homodimer 2...')\n",
|
| 812 |
+
" ipae1 = ho_model.aux['losses']['i_pae']\n",
|
| 813 |
+
" ho_model.predict(seq=seq[LENGTH1+1:],num_recycles=3)\n",
|
| 814 |
+
" ipae2 = ho_model.aux['losses']['i_pae']\n",
|
| 815 |
+
" if ipae1 > 0.8 and ipae2 > 0.8:\n",
|
| 816 |
+
" print('Passed Homodimer check!')\n",
|
| 817 |
+
" he_model.save_pdb(f'Heterodimer_seq_{k}.pdb')\n",
|
| 818 |
+
"\n"
|
| 819 |
+
],
|
| 820 |
+
"metadata": {
|
| 821 |
+
"id": "mII01sjwhAqX",
|
| 822 |
+
"cellView": "form"
|
| 823 |
+
},
|
| 824 |
+
"execution_count": null,
|
| 825 |
+
"outputs": []
|
| 826 |
+
},
|
| 827 |
+
{
|
| 828 |
+
"cell_type": "code",
|
| 829 |
+
"source": [
|
| 830 |
+
"def get_pdb(pdb_code=\"\"):\n",
|
| 831 |
+
" if pdb_code is None or pdb_code == \"\":\n",
|
| 832 |
+
" upload_dict = files.upload()\n",
|
| 833 |
+
" pdb_string = upload_dict[list(upload_dict.keys())[0]]\n",
|
| 834 |
+
" with open(\"tmp.pdb\",\"wb\") as out: out.write(pdb_string)\n",
|
| 835 |
+
" return \"tmp.pdb\"\n",
|
| 836 |
+
" elif os.path.isfile(pdb_code):\n",
|
| 837 |
+
" return pdb_code\n",
|
| 838 |
+
" elif len(pdb_code) == 4:\n",
|
| 839 |
+
" os.system(f\"wget -qnc https://files.rcsb.org/view/{pdb_code}.pdb\")\n",
|
| 840 |
+
" return f\"{pdb_code}.pdb\"\n",
|
| 841 |
+
" else:\n",
|
| 842 |
+
" os.system(f\"wget -qnc https://alphafold.ebi.ac.uk/files/AF-{pdb_code}-F1-model_v3.pdb\")\n",
|
| 843 |
+
" return f\"AF-{pdb_code}-F1-model_v3.pdb\"\n",
|
| 844 |
+
"\n",
|
| 845 |
+
"def add_rg_loss(self, weight=0.1):\n",
|
| 846 |
+
" '''add radius of gyration loss'''\n",
|
| 847 |
+
" def loss_fn(inputs, outputs):\n",
|
| 848 |
+
" xyz = outputs[\"structure_module\"]\n",
|
| 849 |
+
" ca = xyz[\"final_atom_positions\"][:,residue_constants.atom_order[\"CA\"]]\n",
|
| 850 |
+
"\n",
|
| 851 |
+
" ca = ca[-self._binder_len:]\n",
|
| 852 |
+
"\n",
|
| 853 |
+
" rg = jnp.sqrt(jnp.square(ca - ca.mean(0)).sum(-1).mean() + 1e-8)\n",
|
| 854 |
+
" rg_th = 2.38 * ca.shape[0] ** 0.365\n",
|
| 855 |
+
" rg = jax.nn.elu(rg - rg_th)\n",
|
| 856 |
+
" return {\"rg\":rg}\n",
|
| 857 |
+
" self._callbacks[\"model\"][\"loss\"].append(loss_fn)\n",
|
| 858 |
+
" self.opt[\"weights\"][\"rg\"] = weight\n",
|
| 859 |
+
"\n",
|
| 860 |
+
"\n",
|
| 861 |
+
"\n",
|
| 862 |
+
"#@title # Binder Design\n",
|
| 863 |
+
"#@markdown For a given length, generate/hallucinate a protein sequence that AlphaFold thinks folds into a well structured protein (high plddt, low pae, many contacts).\n",
|
| 864 |
+
"LENGTH = 100 #@param {type:\"integer\"}\n",
|
| 865 |
+
"binder_pdb = '5NGV' #@param {type:\"string\"}\n",
|
| 866 |
+
"binder_chain ='A' #@param {type:\"string\"}\n",
|
| 867 |
+
"hotspot ='' #@param {type:\"string\"}\n",
|
| 868 |
+
"if hotspot == \"\": hotspot = None\n",
|
| 869 |
+
"#@markdown ProteinMPNN Settings\n",
|
| 870 |
+
"use_solubleMPNN = True #@param {type:\"boolean\"}\n",
|
| 871 |
+
"#@markdown\n",
|
| 872 |
+
"\n",
|
| 873 |
+
"clear_mem()\n",
|
| 874 |
+
"af_model = mk_afdesign_model(protocol=\"binder\")\n",
|
| 875 |
+
"add_rg_loss(af_model)\n",
|
| 876 |
+
"af_model.prep_inputs(pdb_filename=get_pdb(binder_pdb), chain=binder_chain,hotspot=hotspot, binder_len=LENGTH)\n",
|
| 877 |
+
"\n",
|
| 878 |
+
"\n",
|
| 879 |
+
"af_model.restart(mode=[\"gumbel\", \"soft\"])\n",
|
| 880 |
+
"\n",
|
| 881 |
+
"af_model.opt[\"weights\"][\"rg\"] = 0.5\n",
|
| 882 |
+
"\n",
|
| 883 |
+
"af_model.opt[\"weights\"]['helix'] = -0.2\n",
|
| 884 |
+
"af_model.opt[\"weights\"]['plddt'] = 0.1\n",
|
| 885 |
+
"af_model.opt[\"weights\"]['pae'] = 0.1\n",
|
| 886 |
+
"af_model.opt[\"weights\"]['i_pae'] = 0.1\n",
|
| 887 |
+
"af_model.opt[\"weights\"]['i_con'] = 2.0\n",
|
| 888 |
+
"\n",
|
| 889 |
+
"print(\"weights\", af_model.opt[\"weights\"])\n",
|
| 890 |
+
"print('Starting up and compiling JAX model....')\n"
|
| 891 |
+
],
|
| 892 |
+
"metadata": {
|
| 893 |
+
"id": "H4WqduyJ785H",
|
| 894 |
+
"cellView": "form"
|
| 895 |
+
},
|
| 896 |
+
"execution_count": null,
|
| 897 |
+
"outputs": []
|
| 898 |
+
},
|
| 899 |
+
{
|
| 900 |
+
"cell_type": "code",
|
| 901 |
+
"source": [
|
| 902 |
+
"af_model.design_logits(100)\n",
|
| 903 |
+
"af_model.save_pdb(\"Binder.pdb\")"
|
| 904 |
+
],
|
| 905 |
+
"metadata": {
|
| 906 |
+
"id": "bS83MeVd99FN"
|
| 907 |
+
},
|
| 908 |
+
"execution_count": null,
|
| 909 |
+
"outputs": []
|
| 910 |
+
},
|
| 911 |
+
{
|
| 912 |
+
"cell_type": "code",
|
| 913 |
+
"source": [
|
| 914 |
+
"af_model.plot_pdb()"
|
| 915 |
+
],
|
| 916 |
+
"metadata": {
|
| 917 |
+
"id": "UQMYKLCNZK2L"
|
| 918 |
+
},
|
| 919 |
+
"execution_count": null,
|
| 920 |
+
"outputs": []
|
| 921 |
+
},
|
| 922 |
+
{
|
| 923 |
+
"cell_type": "code",
|
| 924 |
+
"source": [
|
| 925 |
+
"\n",
|
| 926 |
+
"#@title # Binder Sequence Design with AF Multimer filtering\n",
|
| 927 |
+
"#@markdown Use this to generate sequences for the binder candidate generated in the previous step\n",
|
| 928 |
+
"\n",
|
| 929 |
+
"#@markdown First we use the AF2 PTM model to predict the binder without receptor, acting as a fast pre filter. Then we use the AF Multimer model to predict the Receptor Binder complex. Again we use a template for the binder to help AF Multimer predicting the de novo designed protein\n",
|
| 930 |
+
"\n",
|
| 931 |
+
"binder_model = mk_afdesign_model(protocol=\"binder\",use_multimer=True,use_initial_guess=True)\n",
|
| 932 |
+
"hall_model = mk_afdesign_model(protocol=\"fixbb\")\n",
|
| 933 |
+
"\n",
|
| 934 |
+
"\n",
|
| 935 |
+
"binder_model.set_weights(i_pae=1.0)\n",
|
| 936 |
+
"\n",
|
| 937 |
+
"\n",
|
| 938 |
+
"mpnn_model = mk_mpnn_model(weights=\"soluble\")\n",
|
| 939 |
+
"mpnn_model.prep_inputs(pdb_filename=\"Binder.pdb\", chain='A,B', fix_pos='A',rm_aa=\"C\")\n",
|
| 940 |
+
"\n",
|
| 941 |
+
"samples = mpnn_model.sample_parallel(8,temperature=0.01)\n",
|
| 942 |
+
"hall_model.prep_inputs(pdb_filename=\"Binder.pdb\", chain='B')\n",
|
| 943 |
+
"binder_model.prep_inputs(pdb_filename=\"Binder.pdb\", chain='A', binder_chain='B',use_binder_template=True,rm_template_ic=True)\n",
|
| 944 |
+
"k=0\n",
|
| 945 |
+
"for seq in samples['seq']:\n",
|
| 946 |
+
" print(\"Predicting binder only\")\n",
|
| 947 |
+
" hall_model.predict(seq=seq[-LENGTH:], num_recycles=3)\n",
|
| 948 |
+
" if hall_model.aux['losses']['rmsd'] < 2.0 :\n",
|
| 949 |
+
" print(\"Passed! Predicting binder with receptor using AF Multimer\")\n",
|
| 950 |
+
" binder_model.predict(seq=seq[-LENGTH:], num_recycles=3)\n",
|
| 951 |
+
" plddt1 = binder_model.aux['losses']['plddt']\n",
|
| 952 |
+
" i_pae = binder_model.aux['losses']['i_pae']\n",
|
| 953 |
+
" if plddt1 < 0.15 and i_pae < 0.4:\n",
|
| 954 |
+
" print(f\"Passed! Final I_PAE is {i_pae*31}\")\n",
|
| 955 |
+
" binder_model.save_pdb(f'Binder_seq_{k}.pdb')\n",
|
| 956 |
+
" binder_model.plot_pdb()\n",
|
| 957 |
+
"\n",
|
| 958 |
+
" k = k + 1"
|
| 959 |
+
],
|
| 960 |
+
"metadata": {
|
| 961 |
+
"id": "QfrRhvwTAyK-",
|
| 962 |
+
"cellView": "form"
|
| 963 |
+
},
|
| 964 |
+
"execution_count": null,
|
| 965 |
+
"outputs": []
|
| 966 |
+
},
|
| 967 |
+
{
|
| 968 |
+
"cell_type": "code",
|
| 969 |
+
"source": [
|
| 970 |
+
"#@title # Site scaffolding example\n",
|
| 971 |
+
"#@markdown This cell provides the code to perform the site scaffolding in bulk.\n",
|
| 972 |
+
"#@markdown Just go to the commented section with names, contigs and length to insert the desired PDB identifier, contigs and final size and start designing.\n",
|
| 973 |
+
"#@markdown Num_designs controls how many backbones one designes per PDB file\n",
|
| 974 |
+
"\n",
|
| 975 |
+
"num_designs = 1 #@param {type:\"integer\"}\n",
|
| 976 |
+
"\n",
|
| 977 |
+
"\n",
|
| 978 |
+
"def get_pdb(pdb_code=\"\"):\n",
|
| 979 |
+
" if pdb_code is None or pdb_code == \"\":\n",
|
| 980 |
+
" upload_dict = files.upload()\n",
|
| 981 |
+
" pdb_string = upload_dict[list(upload_dict.keys())[0]]\n",
|
| 982 |
+
" with open(\"tmp.pdb\",\"wb\") as out: out.write(pdb_string)\n",
|
| 983 |
+
" return \"tmp.pdb\"\n",
|
| 984 |
+
" elif os.path.isfile(pdb_code):\n",
|
| 985 |
+
" return pdb_code\n",
|
| 986 |
+
" elif len(pdb_code) == 4:\n",
|
| 987 |
+
" os.system(f\"wget -qnc https://files.rcsb.org/view/{pdb_code}.pdb\")\n",
|
| 988 |
+
" return f\"{pdb_code}.pdb\"\n",
|
| 989 |
+
" else:\n",
|
| 990 |
+
" os.system(f\"wget -qnc https://alphafold.ebi.ac.uk/files/AF-{pdb_code}-F1-model_v3.pdb\")\n",
|
| 991 |
+
" return f\"AF-{pdb_code}-F1-model_v3.pdb\"\n",
|
| 992 |
+
"\n",
|
| 993 |
+
"\n",
|
| 994 |
+
"\n",
|
| 995 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 996 |
+
"import contextlib\n",
|
| 997 |
+
"\n",
|
| 998 |
+
"from colabdesign.af.alphafold.common import residue_constants\n",
|
| 999 |
+
"import jax\n",
|
| 1000 |
+
"import jax.numpy as jnp\n",
|
| 1001 |
+
"import pickle\n",
|
| 1002 |
+
"from colabdesign.mpnn import mk_mpnn_model\n",
|
| 1003 |
+
"\n",
|
| 1004 |
+
"import re\n",
|
| 1005 |
+
"import os\n",
|
| 1006 |
+
"\n",
|
| 1007 |
+
"\n",
|
| 1008 |
+
"#Add the names of the PDB files for the scaffolding problem here\n",
|
| 1009 |
+
"names = [\n",
|
| 1010 |
+
" \"1PRW\"\n",
|
| 1011 |
+
"]\n",
|
| 1012 |
+
"print(len(names))\n",
|
| 1013 |
+
"#Add the design contigs here\n",
|
| 1014 |
+
"\n",
|
| 1015 |
+
"inputs = [\n",
|
| 1016 |
+
" \"5-20,A16-35,10-25,A52-71,5-20\"\n",
|
| 1017 |
+
"]\n",
|
| 1018 |
+
"#Add the total length here. We only use the maximum length specified\n",
|
| 1019 |
+
"lengths = [\n",
|
| 1020 |
+
" \"60-105\"\n",
|
| 1021 |
+
"]\n",
|
| 1022 |
+
"\n",
|
| 1023 |
+
"\n",
|
| 1024 |
+
"def rg_loss(inputs, outputs):\n",
|
| 1025 |
+
" positions = outputs[\"structure_module\"][\"final_atom_positions\"]\n",
|
| 1026 |
+
" ca = positions[::5, residue_constants.atom_order[\"CA\"]]\n",
|
| 1027 |
+
" center = ca.mean(0)\n",
|
| 1028 |
+
" rg = jnp.sqrt(jnp.square(ca - center).sum(-1).mean() + 1e-8)\n",
|
| 1029 |
+
" rg_th = 2.38 * ca.shape[0] ** 0.365\n",
|
| 1030 |
+
" rg = jax.nn.elu(rg - rg_th)\n",
|
| 1031 |
+
" return {\"rg\": rg}\n",
|
| 1032 |
+
"\n",
|
| 1033 |
+
"\n",
|
| 1034 |
+
"clear_mem()\n",
|
| 1035 |
+
"\n",
|
| 1036 |
+
"for _name, _input, _length in zip(\n",
|
| 1037 |
+
" names, inputs, lengths\n",
|
| 1038 |
+
"):\n",
|
| 1039 |
+
" print(f\"Starting on {_name}\")\n",
|
| 1040 |
+
" _input = _input.replace(\" \", \"\")\n",
|
| 1041 |
+
" __name = _name.split(\"_\")[0]\n",
|
| 1042 |
+
" model = mk_afdesign_model(\n",
|
| 1043 |
+
" protocol=\"partial\"\n",
|
| 1044 |
+
" )\n",
|
| 1045 |
+
" wire_loop_repr = [\"l\" if re.search(\"[A-Z]\", x) else \"w\" for x in _input.split(\",\")]\n",
|
| 1046 |
+
"\n",
|
| 1047 |
+
" _lengths = []\n",
|
| 1048 |
+
" for _id, rep in zip(wire_loop_repr, _input.split(\",\")):\n",
|
| 1049 |
+
" if \"-\" in rep: # loop or range\n",
|
| 1050 |
+
" if _id == \"l\": # loop\n",
|
| 1051 |
+
" rep = rep[1:]\n",
|
| 1052 |
+
" _len = int(rep.split(\"-\")[1]) - int(rep.split(\"-\")[0]) + 1\n",
|
| 1053 |
+
" else: # range\n",
|
| 1054 |
+
" _len = int(rep.split(\"-\")[1])\n",
|
| 1055 |
+
" else:\n",
|
| 1056 |
+
" if _id == \"l\":\n",
|
| 1057 |
+
" rep = rep[1:]\n",
|
| 1058 |
+
" _len = int(1)\n",
|
| 1059 |
+
" _lengths.append(_len)\n",
|
| 1060 |
+
"\n",
|
| 1061 |
+
" overall_length = sum(_lengths)\n",
|
| 1062 |
+
" print(overall_length)\n",
|
| 1063 |
+
" old_pos = list(filter(lambda x: re.search(\"[A-Z]\", x), _input.split(\",\")))\n",
|
| 1064 |
+
" order = list(range(len(old_pos)))\n",
|
| 1065 |
+
" old_pos = \",\".join(old_pos)\n",
|
| 1066 |
+
" wires = list(filter(lambda x: not re.search(\"[A-Z]\", x), _input.split(\",\")))\n",
|
| 1067 |
+
" wires = [\n",
|
| 1068 |
+
" int(wire) if \"-\" not in wire else int(wire.split(\"-\")[1]) for wire in wires\n",
|
| 1069 |
+
" ]\n",
|
| 1070 |
+
" offset = wires[0] if not wire_loop_repr[0] == \"l\" else 0\n",
|
| 1071 |
+
" if wire_loop_repr[0] == \"w\":\n",
|
| 1072 |
+
" wires = wires[1:]\n",
|
| 1073 |
+
" if wire_loop_repr[-1] == \"w\":\n",
|
| 1074 |
+
" wires = wires[:-1]\n",
|
| 1075 |
+
"\n",
|
| 1076 |
+
" chain = re.findall(\"[A-Z]\", _input)\n",
|
| 1077 |
+
" chain = list(set(chain))\n",
|
| 1078 |
+
" assert len(chain) == 1\n",
|
| 1079 |
+
" chain = chain[0]\n",
|
| 1080 |
+
" if \"-\" in _length:\n",
|
| 1081 |
+
" _length = _length.split(\"-\")[1]\n",
|
| 1082 |
+
" _length = int(_length)\n",
|
| 1083 |
+
" if _length < overall_length:\n",
|
| 1084 |
+
" _length = overall_length\n",
|
| 1085 |
+
"\n",
|
| 1086 |
+
" debug = False\n",
|
| 1087 |
+
" if debug:\n",
|
| 1088 |
+
" print(\"chain \" + str(chain))\n",
|
| 1089 |
+
" print(\"old_pos \" + str(old_pos))\n",
|
| 1090 |
+
" print(\"wires \" + str(wires))\n",
|
| 1091 |
+
" print(\"offset \" + str(offset))\n",
|
| 1092 |
+
" print(\"_length \" + str(_length))\n",
|
| 1093 |
+
" print(\"order \" + str(order))\n",
|
| 1094 |
+
" print(_name)\n",
|
| 1095 |
+
" pdb_file = get_pdb(_name)\n",
|
| 1096 |
+
" model.prep_inputs(\n",
|
| 1097 |
+
" pdb_file,\n",
|
| 1098 |
+
" chain=chain,\n",
|
| 1099 |
+
" pos=old_pos,\n",
|
| 1100 |
+
" length=_length,\n",
|
| 1101 |
+
" fix_seq=True,\n",
|
| 1102 |
+
" )\n",
|
| 1103 |
+
"\n",
|
| 1104 |
+
"\n",
|
| 1105 |
+
" model.rewire(\n",
|
| 1106 |
+
" order=order, # set order of segments\n",
|
| 1107 |
+
" loops=wires, # change loop length inbetween segments\n",
|
| 1108 |
+
" offset=offset,\n",
|
| 1109 |
+
" ) # essentially loop length at the N term\n",
|
| 1110 |
+
"\n",
|
| 1111 |
+
" print(\" Starting up and compiling JAX model....\")\n",
|
| 1112 |
+
"\n",
|
| 1113 |
+
" for i in range(num_designs):\n",
|
| 1114 |
+
" print(f\" Iteration {i} of 100\")\n",
|
| 1115 |
+
" model.restart(mode=[\"gumbel\", \"soft\"], rm_aa=\"C\")\n",
|
| 1116 |
+
" model.opt[\"weights\"][\"rg\"] = 0.1\n",
|
| 1117 |
+
" model.opt[\"weights\"][\"dgram_cce\"] = 2.0\n",
|
| 1118 |
+
" model.opt[\"weights\"][\"plddt\"] = 0.1\n",
|
| 1119 |
+
" model.opt[\"weights\"][\"pae\"] = 0.1\n",
|
| 1120 |
+
" model.opt[\"weights\"][\"rmsd\"] = 1.0\n",
|
| 1121 |
+
" model.opt[\"weights\"]['sc_rmsd'] = 1.0\n",
|
| 1122 |
+
" # model.opt[\"weights\"]['fape'] = 1.0\n",
|
| 1123 |
+
"\n",
|
| 1124 |
+
" model.design_logits(190)\n",
|
| 1125 |
+
" model.design_logits(10, save_best=True)\n",
|
| 1126 |
+
" outfile = f\"out_sc/{_name}_resesigned/{_name}_redesigned_{i}.pdb\"\n",
|
| 1127 |
+
" os.makedirs(os.path.dirname(outfile), exist_ok=True)\n",
|
| 1128 |
+
" model.save_pdb(outfile)\n",
|
| 1129 |
+
" mpnn_model = mk_mpnn_model()\n",
|
| 1130 |
+
"\n",
|
| 1131 |
+
" p = (\n",
|
| 1132 |
+
" []\n",
|
| 1133 |
+
" ) # [homo if not n in _interfaceFixturesIndexSecChain else hetero for n, (homo, hetero) in enumerate(zip(list(ho2), list(he[-len(ho2):])))]\n",
|
| 1134 |
+
" for k in model.opt[\"pos\"]:\n",
|
| 1135 |
+
" p.append(str(k + 1)) # Might be wrong\n",
|
| 1136 |
+
" p.append(\",\")\n",
|
| 1137 |
+
" posf = \"\".join(p[:-1])\n",
|
| 1138 |
+
"\n",
|
| 1139 |
+
" repredictionModel = mk_afdesign_model(\n",
|
| 1140 |
+
" protocol=\"fixbb\", use_templates=False\n",
|
| 1141 |
+
" )\n",
|
| 1142 |
+
" os.makedirs(os.path.dirname('out_sc_Redesigned/'), exist_ok=True)\n",
|
| 1143 |
+
"\n",
|
| 1144 |
+
" for j in range(num_designs):\n",
|
| 1145 |
+
" print(f\" Reprediction Iteration {j} of 100\")\n",
|
| 1146 |
+
" repredictionModel.prep_inputs(\n",
|
| 1147 |
+
" f\"out_sc/{_name}_resesigned/{_name}_redesigned_{j}.pdb\"\n",
|
| 1148 |
+
" )\n",
|
| 1149 |
+
"\n",
|
| 1150 |
+
" mpnn_model.prep_inputs(\n",
|
| 1151 |
+
" pdb_filename=f\"out_sc/{_name}_resesigned/{_name}_redesigned_{j}.pdb\",\n",
|
| 1152 |
+
" chain=\"A\",\n",
|
| 1153 |
+
" fix_pos=posf,\n",
|
| 1154 |
+
" rm_aa=\"C\",\n",
|
| 1155 |
+
" )\n",
|
| 1156 |
+
" out = mpnn_model.sample(num=1, batch=8, temperature=0.1)\n",
|
| 1157 |
+
"\n",
|
| 1158 |
+
" for n, i in enumerate(out[\"seq\"]):\n",
|
| 1159 |
+
"\n",
|
| 1160 |
+
" repredictionModel.predict(seq=i, num_recycles=3)\n",
|
| 1161 |
+
" if (\n",
|
| 1162 |
+
" repredictionModel.aux[\"log\"][\"rmsd\"] < 2.0\n",
|
| 1163 |
+
" and repredictionModel.aux[\"log\"][\"plddt\"] > 0.85\n",
|
| 1164 |
+
" ):\n",
|
| 1165 |
+
" filename = f'out_sc_Redesigned/{_name}_resesigned/{_name}_redesigned-{j}_num-{n}_rmsd-{int(repredictionModel.aux[\"log\"][\"rmsd\"]*100)}.pdb'\n",
|
| 1166 |
+
" os.makedirs(os.path.dirname(filename), exist_ok=True)\n",
|
| 1167 |
+
" repredictionModel.save_pdb(filename)\n",
|
| 1168 |
+
"\n",
|
| 1169 |
+
"for _name, _input, _length in zip(\n",
|
| 1170 |
+
" names, inputs, lengths\n",
|
| 1171 |
+
"):\n",
|
| 1172 |
+
" print(f\"Starting on {_name}\")\n",
|
| 1173 |
+
" clear_mem()\n",
|
| 1174 |
+
"\n",
|
| 1175 |
+
" _input = _input.replace(\" \", \"\")\n",
|
| 1176 |
+
" __name = _name.split(\"_\")[0]\n",
|
| 1177 |
+
"\n",
|
| 1178 |
+
" test_model = mk_afdesign_model(protocol='fixbb')\n",
|
| 1179 |
+
" model = mk_afdesign_model(\n",
|
| 1180 |
+
" protocol=\"partial\", use_templates=False\n",
|
| 1181 |
+
" ) # set True to constrain positions using template input\n",
|
| 1182 |
+
" # define positions we want to constrain (input PDB numbering)\n",
|
| 1183 |
+
"\n",
|
| 1184 |
+
" wire_loop_repr = [\"l\" if re.search(\"[A-Z]\", x) else \"w\" for x in _input.split(\",\")]\n",
|
| 1185 |
+
"\n",
|
| 1186 |
+
" _lengths = []\n",
|
| 1187 |
+
" for _id, rep in zip(wire_loop_repr, _input.split(\",\")):\n",
|
| 1188 |
+
" if \"-\" in rep: # loop or range\n",
|
| 1189 |
+
" if _id == \"l\": # loop\n",
|
| 1190 |
+
" rep = rep[1:]\n",
|
| 1191 |
+
" _len = int(rep.split(\"-\")[1]) - int(rep.split(\"-\")[0]) + 1\n",
|
| 1192 |
+
" else: # range\n",
|
| 1193 |
+
" _len = int(rep.split(\"-\")[1])\n",
|
| 1194 |
+
" else:\n",
|
| 1195 |
+
" if _id == \"l\":\n",
|
| 1196 |
+
" rep = rep[1:]\n",
|
| 1197 |
+
" _len = 1\n",
|
| 1198 |
+
" _lengths.append(_len)\n",
|
| 1199 |
+
"\n",
|
| 1200 |
+
" overall_length = sum(_lengths)\n",
|
| 1201 |
+
"\n",
|
| 1202 |
+
" old_pos = list(filter(lambda x: re.search(\"[A-Z]\", x), _input.split(\",\")))\n",
|
| 1203 |
+
" order = list(range(len(old_pos)))\n",
|
| 1204 |
+
" old_pos = \",\".join(old_pos)\n",
|
| 1205 |
+
" wires = list(filter(lambda x: not re.search(\"[A-Z]\", x), _input.split(\",\")))\n",
|
| 1206 |
+
" wires = [\n",
|
| 1207 |
+
" int(wire) if \"-\" not in wire else int(wire.split(\"-\")[1]) for wire in wires\n",
|
| 1208 |
+
" ]\n",
|
| 1209 |
+
" offset = wires[0] if not wire_loop_repr[0] == \"l\" else 0\n",
|
| 1210 |
+
" if wire_loop_repr[0] == \"w\":\n",
|
| 1211 |
+
" wires = wires[1:]\n",
|
| 1212 |
+
" if wire_loop_repr[-1] == \"w\":\n",
|
| 1213 |
+
" wires = wires[:-1]\n",
|
| 1214 |
+
"\n",
|
| 1215 |
+
" chain = re.findall(\"[A-Z]\", _input)\n",
|
| 1216 |
+
" chain = list(set(chain))\n",
|
| 1217 |
+
" assert len(chain) == 1\n",
|
| 1218 |
+
" chain = chain[0]\n",
|
| 1219 |
+
" if \"-\" in _length:\n",
|
| 1220 |
+
" _length = _length.split(\"-\")[1]\n",
|
| 1221 |
+
" _length = int(_length)\n",
|
| 1222 |
+
" if _length < overall_length:\n",
|
| 1223 |
+
" _length = overall_length\n",
|
| 1224 |
+
"\n",
|
| 1225 |
+
"\n",
|
| 1226 |
+
" print(_name)\n",
|
| 1227 |
+
" pdb_file = get_pdb(_name)\n",
|
| 1228 |
+
"\n",
|
| 1229 |
+
"\n",
|
| 1230 |
+
"\n",
|
| 1231 |
+
" model.prep_inputs(\n",
|
| 1232 |
+
" pdb_file,\n",
|
| 1233 |
+
" chain=chain,\n",
|
| 1234 |
+
" pos=old_pos, # define positions to contrain\n",
|
| 1235 |
+
" length=_length, # define if the desired length is different from input PDB\n",
|
| 1236 |
+
" fix_seq=True,\n",
|
| 1237 |
+
" ) # set True to constrain the sequence\n",
|
| 1238 |
+
"\n",
|
| 1239 |
+
" # set positions (if different from PDB)\n",
|
| 1240 |
+
" # reorder the segments,\n",
|
| 1241 |
+
" model.rewire(\n",
|
| 1242 |
+
" order=order, # set order of segments\n",
|
| 1243 |
+
" loops=wires, # change loop length inbetween segments\n",
|
| 1244 |
+
" offset=offset,\n",
|
| 1245 |
+
" ) # essentially loop length at the N term\n",
|
| 1246 |
+
"\n",
|
| 1247 |
+
" in_files = os.listdir(f'out_sc_Redesigned/{_name}_resesigned/')\n",
|
| 1248 |
+
" if not os.path.exists(f'out_sc_Redesigned/{_name}_resesigned/out/'):\n",
|
| 1249 |
+
" os.mkdir(f'out_sc_Redesigned/{_name}_resesigned/out/')\n",
|
| 1250 |
+
" for ii in in_files:\n",
|
| 1251 |
+
" if ii[-1] == 'b':\n",
|
| 1252 |
+
" test_model.prep_inputs(pdb_filename=f'out_sc_Redesigned/{_name}_resesigned/{ii}')\n",
|
| 1253 |
+
" seq = test_model._inputs['batch'][\"aatype\"]\n",
|
| 1254 |
+
" #print(seq)\n",
|
| 1255 |
+
" model.predict(seq=seq, num_recycles=3)\n",
|
| 1256 |
+
" if model.aux[\"losses\"][\"rmsd\"] < 1.0:\n",
|
| 1257 |
+
" model.save_pdb(f'out_sc_Redesigned/{_name}_resesigned/out/{ii}')\n",
|
| 1258 |
+
" with open(f'out_sc_Redesigned/{_name}_resesigned/out/{ii[:-4]}_data.pkl', 'wb') as f:\n",
|
| 1259 |
+
" pickle.dump(model.aux[\"losses\"][\"rmsd\"], f)\n",
|
| 1260 |
+
"\n"
|
| 1261 |
+
],
|
| 1262 |
+
"metadata": {
|
| 1263 |
+
"id": "8sLixVvGGJ47",
|
| 1264 |
+
"cellView": "form"
|
| 1265 |
+
},
|
| 1266 |
+
"execution_count": null,
|
| 1267 |
+
"outputs": []
|
| 1268 |
+
},
|
| 1269 |
+
{
|
| 1270 |
+
"cell_type": "code",
|
| 1271 |
+
"source": [],
|
| 1272 |
+
"metadata": {
|
| 1273 |
+
"id": "QHFiJeHjB4sM"
|
| 1274 |
+
},
|
| 1275 |
+
"execution_count": null,
|
| 1276 |
+
"outputs": []
|
| 1277 |
+
}
|
| 1278 |
+
],
|
| 1279 |
+
"metadata": {
|
| 1280 |
+
"accelerator": "GPU",
|
| 1281 |
+
"colab": {
|
| 1282 |
+
"provenance": [],
|
| 1283 |
+
"machine_shape": "hm",
|
| 1284 |
+
"gpuType": "L4",
|
| 1285 |
+
"include_colab_link": true
|
| 1286 |
+
},
|
| 1287 |
+
"kernelspec": {
|
| 1288 |
+
"display_name": "Python 3",
|
| 1289 |
+
"name": "python3"
|
| 1290 |
+
},
|
| 1291 |
+
"language_info": {
|
| 1292 |
+
"name": "python"
|
| 1293 |
+
}
|
| 1294 |
+
},
|
| 1295 |
+
"nbformat": 4,
|
| 1296 |
+
"nbformat_minor": 0
|
| 1297 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/af2cycler.ipynb
ADDED
|
@@ -0,0 +1,741 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"nbformat": 4,
|
| 3 |
+
"nbformat_minor": 0,
|
| 4 |
+
"metadata": {
|
| 5 |
+
"colab": {
|
| 6 |
+
"provenance": [],
|
| 7 |
+
"machine_shape": "hm",
|
| 8 |
+
"gpuType": "L4",
|
| 9 |
+
"include_colab_link": true
|
| 10 |
+
},
|
| 11 |
+
"kernelspec": {
|
| 12 |
+
"name": "python3",
|
| 13 |
+
"display_name": "Python 3"
|
| 14 |
+
},
|
| 15 |
+
"language_info": {
|
| 16 |
+
"name": "python"
|
| 17 |
+
},
|
| 18 |
+
"accelerator": "GPU"
|
| 19 |
+
},
|
| 20 |
+
"cells": [
|
| 21 |
+
{
|
| 22 |
+
"cell_type": "markdown",
|
| 23 |
+
"metadata": {
|
| 24 |
+
"id": "view-in-github",
|
| 25 |
+
"colab_type": "text"
|
| 26 |
+
},
|
| 27 |
+
"source": [
|
| 28 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/main/af/examples/af2cycler.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 29 |
+
]
|
| 30 |
+
},
|
| 31 |
+
{
|
| 32 |
+
"cell_type": "markdown",
|
| 33 |
+
"source": [
|
| 34 |
+
"# The AF2cycler\n",
|
| 35 |
+
"This notebook contains the code to run the af2cycler and use for improvement of suboptimal designed protein backbones.\n",
|
| 36 |
+
"Based on:\n",
|
| 37 |
+
"\n",
|
| 38 |
+
"**Alphafold2 refinement improves designability of large de novo proteins**\n",
|
| 39 |
+
"\n",
|
| 40 |
+
"Christopher Frank, Dominik Schiwietz, Lara Fuß, Sergey Ovchinnikov and Hendrik Dietz\n",
|
| 41 |
+
"\n",
|
| 42 |
+
"We recommend to run this Notebook with at leat a L4 or better a A100 GPU as the GPU memeory needed for ESMFold is quite significant\n",
|
| 43 |
+
"\n"
|
| 44 |
+
],
|
| 45 |
+
"metadata": {
|
| 46 |
+
"id": "wsji9enfo8aM"
|
| 47 |
+
}
|
| 48 |
+
},
|
| 49 |
+
{
|
| 50 |
+
"cell_type": "code",
|
| 51 |
+
"execution_count": null,
|
| 52 |
+
"metadata": {
|
| 53 |
+
"cellView": "form",
|
| 54 |
+
"id": "yv2S1XouoxZF"
|
| 55 |
+
},
|
| 56 |
+
"outputs": [],
|
| 57 |
+
"source": [
|
| 58 |
+
"#@title setup\n",
|
| 59 |
+
"%%time\n",
|
| 60 |
+
"import os\n",
|
| 61 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 62 |
+
" # get code\n",
|
| 63 |
+
" os.system(\"pip -q install pyppeteer nest_asyncio\")\n",
|
| 64 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git\")\n",
|
| 65 |
+
" # for debugging\n",
|
| 66 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 67 |
+
" # download params\n",
|
| 68 |
+
" os.system(\"mkdir params\")\n",
|
| 69 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 70 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar\")\n",
|
| 71 |
+
" os.system(\"tar -xf alphafold_params_2022-12-06.tar -C params\")\n",
|
| 72 |
+
"\n",
|
| 73 |
+
"import warnings\n",
|
| 74 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 75 |
+
"\n",
|
| 76 |
+
"import os\n",
|
| 77 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 78 |
+
"from colabdesign.mpnn import mk_mpnn_model\n",
|
| 79 |
+
"\n",
|
| 80 |
+
"from IPython.display import HTML\n",
|
| 81 |
+
"from google.colab import files\n",
|
| 82 |
+
"import numpy as np\n",
|
| 83 |
+
"\n",
|
| 84 |
+
"import requests, time\n",
|
| 85 |
+
"if not os.path.isfile(\"TMscore\"):\n",
|
| 86 |
+
" os.system(\"wget -qnc https://zhanggroup.org/TM-score/TMscore.cpp\")\n",
|
| 87 |
+
" os.system(\"g++ -static -O3 -ffast-math -lm -o TMscore TMscore.cpp\")\n",
|
| 88 |
+
"def tmscore(x,y):\n",
|
| 89 |
+
" # pass to TMscore\n",
|
| 90 |
+
" output = os.popen(f'./TMscore {x} {y}')\n",
|
| 91 |
+
" # parse outputs\n",
|
| 92 |
+
" parse_float = lambda x: float(x.split(\"=\")[1].split()[0])\n",
|
| 93 |
+
" o = {}\n",
|
| 94 |
+
" for line in output:\n",
|
| 95 |
+
" line = line.rstrip()\n",
|
| 96 |
+
" if line.startswith(\"RMSD\"): o[\"rms\"] = parse_float(line)\n",
|
| 97 |
+
" if line.startswith(\"TM-score\"): o[\"tms\"] = parse_float(line)\n",
|
| 98 |
+
" if line.startswith(\"GDT-TS-score\"): o[\"gdt\"] = parse_float(line)\n",
|
| 99 |
+
" return o\n",
|
| 100 |
+
"\n",
|
| 101 |
+
"import asyncio\n",
|
| 102 |
+
"import nest_asyncio\n",
|
| 103 |
+
"from pyppeteer import launch\n",
|
| 104 |
+
"import base64\n",
|
| 105 |
+
"\n",
|
| 106 |
+
"# Apply nest_asyncio to enable nested event loops\n",
|
| 107 |
+
"nest_asyncio.apply()\n",
|
| 108 |
+
"\n",
|
| 109 |
+
"async def fetch_blob_content(page, blob_url):\n",
|
| 110 |
+
" blob_to_base64 = \"\"\"\n",
|
| 111 |
+
" async (blobUrl) => {\n",
|
| 112 |
+
" const blob = await fetch(blobUrl).then(r => r.blob());\n",
|
| 113 |
+
" return new Promise((resolve) => {\n",
|
| 114 |
+
" const reader = new FileReader();\n",
|
| 115 |
+
" reader.onloadend = () => resolve(reader.result);\n",
|
| 116 |
+
" reader.readAsDataURL(blob);\n",
|
| 117 |
+
" });\n",
|
| 118 |
+
" }\n",
|
| 119 |
+
" \"\"\"\n",
|
| 120 |
+
" base64_data = await page.evaluate(blob_to_base64, blob_url)\n",
|
| 121 |
+
" _, encoded = base64_data.split(',', 1)\n",
|
| 122 |
+
" return base64.b64decode(encoded)\n",
|
| 123 |
+
"\n",
|
| 124 |
+
"async def extract_pdb_file_download_link_and_content(url):\n",
|
| 125 |
+
" browser = await launch(headless=True, args=['--no-sandbox', '--disable-setuid-sandbox'])\n",
|
| 126 |
+
" page = await browser.newPage()\n",
|
| 127 |
+
" await page.goto(url, {'waitUntil': 'networkidle0'})\n",
|
| 128 |
+
" elements = await page.querySelectorAll('a.btn.bg-purple')\n",
|
| 129 |
+
" for element in elements:\n",
|
| 130 |
+
" href = await page.evaluate('(element) => element.getAttribute(\"href\")', element)\n",
|
| 131 |
+
" if 'blob:https://esmatlas.com/' in href:\n",
|
| 132 |
+
" content = await fetch_blob_content(page, href)\n",
|
| 133 |
+
" await browser.close()\n",
|
| 134 |
+
" return href, content\n",
|
| 135 |
+
" await browser.close()\n",
|
| 136 |
+
" return \"No PDB file link found.\", None\n",
|
| 137 |
+
"\n",
|
| 138 |
+
"def esmfold_api(sequence):\n",
|
| 139 |
+
" url = f'https://esmatlas.com/resources/fold/result?fasta_header=%3Eunnamed&sequence={sequence}'\n",
|
| 140 |
+
" result = asyncio.get_event_loop().run_until_complete(extract_pdb_file_download_link_and_content(url))\n",
|
| 141 |
+
" if result[1]:\n",
|
| 142 |
+
" pdb_str = result[1].decode('utf-8')\n",
|
| 143 |
+
" return pdb_str\n",
|
| 144 |
+
" else:\n",
|
| 145 |
+
" return \"Failed to retrieve PDB content.\"\n",
|
| 146 |
+
"\n",
|
| 147 |
+
"import jax\n",
|
| 148 |
+
"import jax.numpy as jnp\n",
|
| 149 |
+
"from colabdesign.af.alphafold.common import residue_constants\n",
|
| 150 |
+
"\n",
|
| 151 |
+
"if not os.path.exists('/content/in/'):\n",
|
| 152 |
+
" os.mkdir('/content/in/')\n",
|
| 153 |
+
"\n",
|
| 154 |
+
"import py3Dmol\n",
|
| 155 |
+
"\n",
|
| 156 |
+
"def visualize_pdb_overlay(pdb1_path, pdb2_path):\n",
|
| 157 |
+
" viewer = py3Dmol.view(width=800, height=600)\n",
|
| 158 |
+
"\n",
|
| 159 |
+
" with open(pdb1_path, 'r') as f:\n",
|
| 160 |
+
" pdb1_data = f.read()\n",
|
| 161 |
+
" viewer.addModel(pdb1_data, 'pdb')\n",
|
| 162 |
+
" viewer.setStyle({'model': 0}, {'cartoon': {'color': 'grey'}})\n",
|
| 163 |
+
"\n",
|
| 164 |
+
" with open(pdb2_path, 'r') as f:\n",
|
| 165 |
+
" pdb2_data = f.read()\n",
|
| 166 |
+
" viewer.addModel(pdb2_data, 'pdb')\n",
|
| 167 |
+
" viewer.setStyle({'model': 1}, {'cartoon': {'color' : 'red'}})\n",
|
| 168 |
+
"\n",
|
| 169 |
+
" viewer.zoomTo()\n",
|
| 170 |
+
" viewer.show()\n",
|
| 171 |
+
"\n",
|
| 172 |
+
"\n"
|
| 173 |
+
]
|
| 174 |
+
},
|
| 175 |
+
{
|
| 176 |
+
"cell_type": "code",
|
| 177 |
+
"source": [],
|
| 178 |
+
"metadata": {
|
| 179 |
+
"id": "bxL_tvmGqg-S"
|
| 180 |
+
},
|
| 181 |
+
"execution_count": null,
|
| 182 |
+
"outputs": []
|
| 183 |
+
},
|
| 184 |
+
{
|
| 185 |
+
"cell_type": "markdown",
|
| 186 |
+
"source": [
|
| 187 |
+
"# Chroma Design\n",
|
| 188 |
+
"\n",
|
| 189 |
+
"On the start of this pipeline is the creation of draft backbones using Chroma or any other design method you want to use. We suggest you check out this two notebooks on Chroma to generate your desired proteins:\n",
|
| 190 |
+
"**Chroma Quickstart**\n",
|
| 191 |
+
"https://colab.research.google.com/github/generatebio/chroma/blob/main/notebooks/ChromaDemo.ipynb\n",
|
| 192 |
+
"\n",
|
| 193 |
+
"**Chroma API Tutorial**\n",
|
| 194 |
+
"https://colab.research.google.com/github/generatebio/chroma/blob/main/notebooks/ChromaAPI.ipynb\n",
|
| 195 |
+
"\n",
|
| 196 |
+
"If you have your PDB files please upload them into the **in/** folder and proceed\n"
|
| 197 |
+
],
|
| 198 |
+
"metadata": {
|
| 199 |
+
"id": "WMpjGEyGqgSH"
|
| 200 |
+
}
|
| 201 |
+
},
|
| 202 |
+
{
|
| 203 |
+
"cell_type": "code",
|
| 204 |
+
"source": [
|
| 205 |
+
"#@title Monomer af2cycling\n",
|
| 206 |
+
"#@markdown The af2cycler takes in the Chroma design and returns a new pdb file with improved structure\n",
|
| 207 |
+
"iterations = 10 #@param {type:\"integer\"}\n",
|
| 208 |
+
"#@markdown The af2cycled model is shown in red, while the chroma model is shown in grey\n",
|
| 209 |
+
"\n",
|
| 210 |
+
"\n",
|
| 211 |
+
"\n",
|
| 212 |
+
"import numpy as np\n",
|
| 213 |
+
"import warnings\n",
|
| 214 |
+
"\n",
|
| 215 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 216 |
+
"\n",
|
| 217 |
+
"import os, re\n",
|
| 218 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 219 |
+
"from colabdesign.mpnn import mk_mpnn_model\n",
|
| 220 |
+
"\n",
|
| 221 |
+
"import os, re\n",
|
| 222 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 223 |
+
"from colabdesign.mpnn import mk_mpnn_model\n",
|
| 224 |
+
"\n",
|
| 225 |
+
"import numpy as np\n",
|
| 226 |
+
"\n",
|
| 227 |
+
"def sample_gumbel(shape, eps=1e-20):\n",
|
| 228 |
+
" \"\"\"Sample from Gumbel(0, 1)\"\"\"\n",
|
| 229 |
+
" U = np.random.uniform(size=shape)\n",
|
| 230 |
+
" return -np.log(-np.log(U + eps) + eps)\n",
|
| 231 |
+
"\n",
|
| 232 |
+
"\n",
|
| 233 |
+
"clear_mem()\n",
|
| 234 |
+
"\n",
|
| 235 |
+
"iters = iterations\n",
|
| 236 |
+
"in_path = '/content/in/'\n",
|
| 237 |
+
"out_path = 'out/'\n",
|
| 238 |
+
"if not os.path.exists('/content/in/out/'):\n",
|
| 239 |
+
" os.mkdir('/content/in/out/')\n",
|
| 240 |
+
"\n",
|
| 241 |
+
"\n",
|
| 242 |
+
"starting_seq = \"\"\n",
|
| 243 |
+
"starting_seq = re.sub(\"[^A-Z]\", \"\", starting_seq.upper())\n",
|
| 244 |
+
"\n",
|
| 245 |
+
"\n",
|
| 246 |
+
"file_list = os.listdir(in_path)\n",
|
| 247 |
+
"\n",
|
| 248 |
+
"clear_mem()\n",
|
| 249 |
+
"mpnn_model = mk_mpnn_model()\n",
|
| 250 |
+
"af_model = mk_afdesign_model(protocol=\"fixbb\",use_templates=True,use_initial_atom_pos=True,use_initial_guess=True)\n",
|
| 251 |
+
"\n",
|
| 252 |
+
"for file_name in file_list:\n",
|
| 253 |
+
" if file_name[-1] == 'b':\n",
|
| 254 |
+
"\n",
|
| 255 |
+
" in_pdb = in_path + file_name\n",
|
| 256 |
+
" out_pdb = in_path + out_path + 'Out_' + file_name\n",
|
| 257 |
+
"\n",
|
| 258 |
+
"\n",
|
| 259 |
+
"\n",
|
| 260 |
+
"\n",
|
| 261 |
+
" af_model.prep_inputs(pdb_filename=in_pdb, chain='A')\n",
|
| 262 |
+
"\n",
|
| 263 |
+
" starting_seq = af_model._inputs['batch'][\"aatype\"]\n",
|
| 264 |
+
"\n",
|
| 265 |
+
" iterations = iters\n",
|
| 266 |
+
"\n",
|
| 267 |
+
" use_dropout = True\n",
|
| 268 |
+
" num_recycles = 0\n",
|
| 269 |
+
"\n",
|
| 270 |
+
" mpnn_mode = \"conditional\"\n",
|
| 271 |
+
" cmap_seqsep = 9\n",
|
| 272 |
+
"\n",
|
| 273 |
+
" cmap_num = 2\n",
|
| 274 |
+
" #cmap_cutoff = 14\n",
|
| 275 |
+
" L = sum(af_model._lengths)\n",
|
| 276 |
+
" af_model.restart(mode=\"gumbel\")\n",
|
| 277 |
+
" af_model._args[\"clear_prev\"] = False\n",
|
| 278 |
+
" #af_model.set_opt(cmap_cutoff=cmap_cutoff)\n",
|
| 279 |
+
" af_model.set_weights(helix=1e-8)\n",
|
| 280 |
+
" # gather info about inputs\n",
|
| 281 |
+
" if \"offset\" in af_model._inputs:\n",
|
| 282 |
+
" offset = af_model._inputs\n",
|
| 283 |
+
" else:\n",
|
| 284 |
+
" idx = af_model._inputs[\"residue_index\"]\n",
|
| 285 |
+
" offset = idx[:, None] - idx[None, :]\n",
|
| 286 |
+
" # initialize sequence\n",
|
| 287 |
+
" if len(starting_seq) > 1:\n",
|
| 288 |
+
" af_model.set_seq(seq=starting_seq)\n",
|
| 289 |
+
" # initialize coordinates\n",
|
| 290 |
+
" af_model._inputs.pop(\"prev\", None)\n",
|
| 291 |
+
" init = af_model._inputs[\"batch\"]['all_atom_positions'].copy()\n",
|
| 292 |
+
"\n",
|
| 293 |
+
" save_best = False\n",
|
| 294 |
+
" for k in range(iterations):\n",
|
| 295 |
+
"\n",
|
| 296 |
+
" if k > (iterations - 10):\n",
|
| 297 |
+
" use_dropout = False\n",
|
| 298 |
+
" save_best = True\n",
|
| 299 |
+
"\n",
|
| 300 |
+
" # denoise\n",
|
| 301 |
+
" aux = af_model.predict(return_aux=True, verbose=False,\n",
|
| 302 |
+
" dropout=use_dropout,\n",
|
| 303 |
+
" num_recycles=num_recycles)\n",
|
| 304 |
+
"\n",
|
| 305 |
+
" #af_model._inputs[\"prev\"] = aux[\"prev\"]\n",
|
| 306 |
+
" #af_model._inputs[\"prev\"][\"prev_msa_first_row\"] *= 0\n",
|
| 307 |
+
" #af_model._inputs[\"prev\"][\"prev_pos\"] *= 0\n",
|
| 308 |
+
"\n",
|
| 309 |
+
" cmap = aux[\"cmap\"] * (np.abs(offset) > cmap_seqsep)\n",
|
| 310 |
+
" conf = np.sort(cmap)[:, -cmap_num:].mean(-1)\n",
|
| 311 |
+
"\n",
|
| 312 |
+
" plddt = aux[\"plddt\"]\n",
|
| 313 |
+
" seq = aux[\"seq\"][\"hard\"][0].argmax(-1)\n",
|
| 314 |
+
" xyz = aux[\"atom_positions\"].copy()\n",
|
| 315 |
+
" # update inputs\n",
|
| 316 |
+
" af_model._inputs[\"batch\"][\"aatype\"] = seq\n",
|
| 317 |
+
" af_model._inputs[\"batch\"][\"all_atom_positions\"] = xyz\n",
|
| 318 |
+
"\n",
|
| 319 |
+
" if mpnn_mode != \"none\":\n",
|
| 320 |
+
"\n",
|
| 321 |
+
" mpnn_model.get_af_inputs(af_model)\n",
|
| 322 |
+
" opt = {\"mask\": np.sqrt(conf)}\n",
|
| 323 |
+
" if mpnn_mode == \"unconditional\":\n",
|
| 324 |
+
" opt[\"ar_mask\"] = np.zeros((L, L))\n",
|
| 325 |
+
" mpnn_out = mpnn_model.score(**opt)\n",
|
| 326 |
+
" mpnn_logits = mpnn_out[\"logits\"][:, :20]\n",
|
| 327 |
+
" aux[\"log\"][\"mpnn\"] = mpnn_out[\"score\"]\n",
|
| 328 |
+
"\n",
|
| 329 |
+
" c = conf[:, None]\n",
|
| 330 |
+
"\n",
|
| 331 |
+
" new_logits = (1 - c) * sample_gumbel(mpnn_logits.shape) + c * mpnn_logits\n",
|
| 332 |
+
"\n",
|
| 333 |
+
" af_model._params[\"seq\"] = 0.9 * af_model._params[\"seq\"] + 0.1 * new_logits\n",
|
| 334 |
+
"\n",
|
| 335 |
+
" # save results\n",
|
| 336 |
+
" af_model._save_results(aux, save_best=save_best)\n",
|
| 337 |
+
" af_model._k += 1\n",
|
| 338 |
+
"\n",
|
| 339 |
+
" af_model.save_pdb(out_pdb)\n",
|
| 340 |
+
" visualize_pdb_overlay(in_pdb, out_pdb)\n",
|
| 341 |
+
"\n"
|
| 342 |
+
],
|
| 343 |
+
"metadata": {
|
| 344 |
+
"cellView": "form",
|
| 345 |
+
"id": "KeWmENFFqf1S"
|
| 346 |
+
},
|
| 347 |
+
"execution_count": null,
|
| 348 |
+
"outputs": []
|
| 349 |
+
},
|
| 350 |
+
{
|
| 351 |
+
"cell_type": "code",
|
| 352 |
+
"source": [
|
| 353 |
+
"HTML(af_model.animate())"
|
| 354 |
+
],
|
| 355 |
+
"metadata": {
|
| 356 |
+
"id": "HtpnTpvZtHi6"
|
| 357 |
+
},
|
| 358 |
+
"execution_count": null,
|
| 359 |
+
"outputs": []
|
| 360 |
+
},
|
| 361 |
+
{
|
| 362 |
+
"cell_type": "code",
|
| 363 |
+
"source": [
|
| 364 |
+
"#@markdown #Redesign with solubleMPNN for ESMFold prediction\n",
|
| 365 |
+
"#@markdown The standard manuscript settings were 8 sequences, 0.1 sampling temperature and the removal of cysteines\n",
|
| 366 |
+
"import pickle\n",
|
| 367 |
+
"import pandas as pd\n",
|
| 368 |
+
"in_path = '/content/in/out/'\n",
|
| 369 |
+
"out_path = 'out_sMPNN/'\n",
|
| 370 |
+
"if not os.path.exists(out_path):\n",
|
| 371 |
+
" os.mkdir(out_path)\n",
|
| 372 |
+
"\n",
|
| 373 |
+
"file_list = os.listdir(in_path)\n",
|
| 374 |
+
"\n",
|
| 375 |
+
"\n",
|
| 376 |
+
"num_seqs = 8 #@param [\"8\", \"16\", \"32\", \"64\"] {type:\"raw\"}\n",
|
| 377 |
+
"mpnn_sampling_temp = 0.1 #@param [\"0.0001\", \"0.1\", \"0.15\", \"0.2\", \"0.25\", \"0.3\", \"0.5\", \"1.0\"] {type:\"raw\"}\n",
|
| 378 |
+
"rm_aa = \"C\" #@param {type:\"string\"}\n",
|
| 379 |
+
"use_solubleMPNN = True #@param {type:\"boolean\"}\n",
|
| 380 |
+
"#@markdown - `mpnn_sampling_temp` - control diversity of sampled sequences. (higher = more diverse).\n",
|
| 381 |
+
"#@markdown - `rm_aa='C'` - do not use [C]ysteines.\n",
|
| 382 |
+
"#@markdown - `use_solubleMPNN` - use weights trained only on soluble proteins.\n",
|
| 383 |
+
"#@markdown\n",
|
| 384 |
+
"\n",
|
| 385 |
+
"from colabdesign.shared.protein import alphabet_list as chain_list\n",
|
| 386 |
+
"mpnn_model = mk_mpnn_model()\n",
|
| 387 |
+
"\n",
|
| 388 |
+
"\n",
|
| 389 |
+
"for file in file_list:\n",
|
| 390 |
+
" if file[-4:] == '.pdb':\n",
|
| 391 |
+
"\n",
|
| 392 |
+
" in_file1 = in_path + file\n",
|
| 393 |
+
" mpnn_model.prep_inputs(pdb_filename=in_file1,\n",
|
| 394 |
+
" chain='A',\n",
|
| 395 |
+
" rm_aa=rm_aa,weights = \"soluble\")\n",
|
| 396 |
+
" out = mpnn_model.sample(num=num_seqs//8,\n",
|
| 397 |
+
" batch=8,\n",
|
| 398 |
+
" temperature=mpnn_sampling_temp)\n",
|
| 399 |
+
" for seq,score in zip(out[\"seq\"],out[\"score\"]):\n",
|
| 400 |
+
" print(score,seq.split(\"/\")[0])\n",
|
| 401 |
+
" df = pd.DataFrame(out[\"seq\"])\n",
|
| 402 |
+
"\n",
|
| 403 |
+
" # Define the output path for saving the sequences as a .pkl file\n",
|
| 404 |
+
" output_pkl_file = out_path + file[:-4] + \"_sequences.pkl\"\n",
|
| 405 |
+
"\n",
|
| 406 |
+
" # Save the DataFrame to a .pkl file\n",
|
| 407 |
+
" with open(output_pkl_file, 'wb') as f:\n",
|
| 408 |
+
" pickle.dump(df, f)"
|
| 409 |
+
],
|
| 410 |
+
"metadata": {
|
| 411 |
+
"cellView": "form",
|
| 412 |
+
"id": "KNcTvB5XzG-X"
|
| 413 |
+
},
|
| 414 |
+
"execution_count": null,
|
| 415 |
+
"outputs": []
|
| 416 |
+
},
|
| 417 |
+
{
|
| 418 |
+
"cell_type": "code",
|
| 419 |
+
"source": [
|
| 420 |
+
"#@markdown #Run ESMFold to test designability\n",
|
| 421 |
+
"\n",
|
| 422 |
+
"#@markdown **This cell is a little bit tricky. The problem is the compatibility between the JAX and PYTORCH frameworks between ColabDesign and ESMFold and GPU memory requirements**\n",
|
| 423 |
+
"\n",
|
| 424 |
+
"#@markdown Go to *Runtime* >> *Restart Session*\n",
|
| 425 |
+
"\n",
|
| 426 |
+
"#@markdown then Run this cell\n",
|
| 427 |
+
"\n",
|
| 428 |
+
"#@markdown Runtime 2-5 min\n",
|
| 429 |
+
"\n",
|
| 430 |
+
"#@markdown This cells runs ESMFold from huggingface and automatically calculates the RMSD to the designed backbone\n",
|
| 431 |
+
"#@markdown NOTE: GPU memory can be a big problem here. If you get memory errors please restart the runtime and run this cell again. It should be self contained. Additionally, after finish the ESMFold prediction rerun the setup cell\n",
|
| 432 |
+
"\n",
|
| 433 |
+
"import os\n",
|
| 434 |
+
"import pandas as pd\n",
|
| 435 |
+
"from Bio.PDB import PDBParser, Superimposer\n",
|
| 436 |
+
"import pickle\n",
|
| 437 |
+
"import torch\n",
|
| 438 |
+
"import numpy as np\n",
|
| 439 |
+
"from transformers import AutoTokenizer, EsmForProteinFolding\n",
|
| 440 |
+
"from transformers.models.esm.openfold_utils.protein import to_pdb, Protein as OFProtein\n",
|
| 441 |
+
"from transformers.models.esm.openfold_utils.feats import atom14_to_atom37\n",
|
| 442 |
+
"\n",
|
| 443 |
+
"import py3Dmol\n",
|
| 444 |
+
"\n",
|
| 445 |
+
"def visualize_pdb_overlay(pdb1_path, pdb2_path):\n",
|
| 446 |
+
" viewer = py3Dmol.view(width=800, height=600)\n",
|
| 447 |
+
"\n",
|
| 448 |
+
" with open(pdb1_path, 'r') as f:\n",
|
| 449 |
+
" pdb1_data = f.read()\n",
|
| 450 |
+
" viewer.addModel(pdb1_data, 'pdb')\n",
|
| 451 |
+
" viewer.setStyle({'model': 0}, {'cartoon': {'color': 'grey'}})\n",
|
| 452 |
+
"\n",
|
| 453 |
+
" with open(pdb2_path, 'r') as f:\n",
|
| 454 |
+
" pdb2_data = f.read()\n",
|
| 455 |
+
" viewer.addModel(pdb2_data, 'pdb')\n",
|
| 456 |
+
" viewer.setStyle({'model': 1}, {'cartoon': {'color' : 'red'}})\n",
|
| 457 |
+
"\n",
|
| 458 |
+
" viewer.zoomTo()\n",
|
| 459 |
+
" viewer.show()\n",
|
| 460 |
+
"\n",
|
| 461 |
+
"\n",
|
| 462 |
+
"\n",
|
| 463 |
+
"\n",
|
| 464 |
+
"\n",
|
| 465 |
+
"tokenizer = AutoTokenizer.from_pretrained(\"facebook/esmfold_v1\")\n",
|
| 466 |
+
"model = EsmForProteinFolding.from_pretrained(\"facebook/esmfold_v1\", low_cpu_mem_usage=True)\n",
|
| 467 |
+
"\n",
|
| 468 |
+
"device = 'cuda:0'\n",
|
| 469 |
+
"model = model.cuda(device)\n",
|
| 470 |
+
"model.esm = model.esm.half()\n",
|
| 471 |
+
"model.trunk.set_chunk_size(64)\n",
|
| 472 |
+
"torch.backends.cuda.matmul.allow_tf32 = True\n",
|
| 473 |
+
"\n",
|
| 474 |
+
"def convert_outputs_to_pdb(outputs):\n",
|
| 475 |
+
" final_atom_positions = atom14_to_atom37(outputs[\"positions\"][-1], outputs)\n",
|
| 476 |
+
" outputs = {k: v.to(\"cpu\").numpy() for k, v in outputs.items()}\n",
|
| 477 |
+
" final_atom_positions = final_atom_positions.cpu().numpy()\n",
|
| 478 |
+
" final_atom_mask = outputs[\"atom37_atom_exists\"]\n",
|
| 479 |
+
" pdbs = []\n",
|
| 480 |
+
" for i in range(outputs[\"aatype\"].shape[0]):\n",
|
| 481 |
+
" aa = outputs[\"aatype\"][i]\n",
|
| 482 |
+
" pred_pos = final_atom_positions[i]\n",
|
| 483 |
+
" mask = final_atom_mask[i]\n",
|
| 484 |
+
" resid = outputs[\"residue_index\"][i] + 1\n",
|
| 485 |
+
" pred = OFProtein(\n",
|
| 486 |
+
" aatype=aa,\n",
|
| 487 |
+
" atom_positions=pred_pos,\n",
|
| 488 |
+
" atom_mask=mask,\n",
|
| 489 |
+
" residue_index=resid,\n",
|
| 490 |
+
" b_factors=outputs[\"plddt\"][i],\n",
|
| 491 |
+
" chain_index=outputs[\"chain_index\"][i] if \"chain_index\" in outputs else None,\n",
|
| 492 |
+
" )\n",
|
| 493 |
+
" pdbs.append(to_pdb(pred))\n",
|
| 494 |
+
" return pdbs\n",
|
| 495 |
+
"\n",
|
| 496 |
+
"def calculate_ca_rmsd(pdb_file1, pdb_file2):\n",
|
| 497 |
+
" parser = PDBParser(QUIET=True)\n",
|
| 498 |
+
"\n",
|
| 499 |
+
" structure1 = parser.get_structure(\"Protein1\", pdb_file1)\n",
|
| 500 |
+
" structure2 = parser.get_structure(\"Protein2\", pdb_file2)\n",
|
| 501 |
+
"\n",
|
| 502 |
+
" ca_atoms1 = [atom for atom in structure1.get_atoms() if atom.get_name() == \"CA\"]\n",
|
| 503 |
+
" ca_atoms2 = [atom for atom in structure2.get_atoms() if atom.get_name() == \"CA\"]\n",
|
| 504 |
+
"\n",
|
| 505 |
+
" super_imposer = Superimposer()\n",
|
| 506 |
+
" super_imposer.set_atoms(ca_atoms1, ca_atoms2)\n",
|
| 507 |
+
" super_imposer.apply(structure2.get_atoms())\n",
|
| 508 |
+
" rmsd = super_imposer.rms\n",
|
| 509 |
+
" return rmsd\n",
|
| 510 |
+
"\n",
|
| 511 |
+
"def process_sequences(seq_list, pdb_file,in_path_pdb):\n",
|
| 512 |
+
" lowest_rmsd = float('inf')\n",
|
| 513 |
+
" lowest_rmsd_data = None\n",
|
| 514 |
+
" pdb_id = pdb_file[16:-4]\n",
|
| 515 |
+
" out_ss_path = in_path_pdb + \"output/\"\n",
|
| 516 |
+
"\n",
|
| 517 |
+
" if not os.path.exists(out_ss_path):\n",
|
| 518 |
+
" os.mkdir(out_ss_path)\n",
|
| 519 |
+
"\n",
|
| 520 |
+
" for test_protein in seq_list:\n",
|
| 521 |
+
" data = {}\n",
|
| 522 |
+
" tokenized_input = tokenizer([test_protein], return_tensors=\"pt\", add_special_tokens=False)['input_ids']\n",
|
| 523 |
+
" tokenized_input = tokenized_input.cuda(device)\n",
|
| 524 |
+
"\n",
|
| 525 |
+
" with torch.no_grad():\n",
|
| 526 |
+
" output = model(tokenized_input)\n",
|
| 527 |
+
"\n",
|
| 528 |
+
" data['out'] = output\n",
|
| 529 |
+
" data[\"plddt\"] = torch.mean(output['plddt']).item()\n",
|
| 530 |
+
" data['pae'] = torch.mean(output['predicted_aligned_error']).item()\n",
|
| 531 |
+
"\n",
|
| 532 |
+
" pdb_data = convert_outputs_to_pdb(output)\n",
|
| 533 |
+
" tmp_pdb_file = os.path.join(out_ss_path, \"TMP.pdb\")\n",
|
| 534 |
+
"\n",
|
| 535 |
+
" with open(tmp_pdb_file, 'w') as file:\n",
|
| 536 |
+
" for line in pdb_data:\n",
|
| 537 |
+
" file.write(line)\n",
|
| 538 |
+
"\n",
|
| 539 |
+
" data['rmsd'] = calculate_ca_rmsd(tmp_pdb_file, pdb_file)\n",
|
| 540 |
+
" print(f'Sequence: {test_protein}, plddt: {data[\"plddt\"]}, PAE: {data[\"pae\"]}, RMSD: {data[\"rmsd\"]}')\n",
|
| 541 |
+
"\n",
|
| 542 |
+
" if data['rmsd'] < lowest_rmsd:\n",
|
| 543 |
+
" lowest_rmsd = data['rmsd']\n",
|
| 544 |
+
" lowest_rmsd_data = data\n",
|
| 545 |
+
"\n",
|
| 546 |
+
" if lowest_rmsd_data is not None:\n",
|
| 547 |
+
" print(f'Lowest RMSD: {lowest_rmsd}')\n",
|
| 548 |
+
" best_pdb_data = convert_outputs_to_pdb(lowest_rmsd_data['out'])\n",
|
| 549 |
+
" best_pdb_file = os.path.join(out_ss_path, f\"{pdb_id}_best_structure.pdb\")\n",
|
| 550 |
+
"\n",
|
| 551 |
+
" with open(best_pdb_file, 'w') as file:\n",
|
| 552 |
+
" for line in best_pdb_data:\n",
|
| 553 |
+
" file.write(line)\n",
|
| 554 |
+
"\n",
|
| 555 |
+
" original_dict = lowest_rmsd_data\n",
|
| 556 |
+
" key_to_exclude = 'out'\n",
|
| 557 |
+
" data_out = {k: v for k, v in original_dict.items() if k != key_to_exclude}\n",
|
| 558 |
+
"\n",
|
| 559 |
+
" with open(os.path.join(out_ss_path, f\"{pdb_id}_best_structure_data.pkl\"), 'wb') as f:\n",
|
| 560 |
+
" pickle.dump(data_out, f)\n",
|
| 561 |
+
"\n",
|
| 562 |
+
" return lowest_rmsd, best_pdb_file, data_out\n",
|
| 563 |
+
"\n",
|
| 564 |
+
" return None, None, None\n",
|
| 565 |
+
"\n",
|
| 566 |
+
"\n",
|
| 567 |
+
"in_path= '/content/out_sMPNN/'\n",
|
| 568 |
+
"file_list = os.listdir(in_path)\n",
|
| 569 |
+
"\n",
|
| 570 |
+
"for file in file_list:\n",
|
| 571 |
+
" if file[-1] =='l':\n",
|
| 572 |
+
"\n",
|
| 573 |
+
"\n",
|
| 574 |
+
"\n",
|
| 575 |
+
" output_pkl_file = in_path + file\n",
|
| 576 |
+
"\n",
|
| 577 |
+
" with open(output_pkl_file, 'rb') as f:\n",
|
| 578 |
+
" seq = pickle.load(f)\n",
|
| 579 |
+
" seq_list = []\n",
|
| 580 |
+
" for i in np.asarray(seq):\n",
|
| 581 |
+
" seq_list.append(i[0])\n",
|
| 582 |
+
"\n",
|
| 583 |
+
" pdb_file = \"/content/in/out/\" + file[:-14] + '.pdb'\n",
|
| 584 |
+
" print(seq_list)\n",
|
| 585 |
+
"\n",
|
| 586 |
+
"\n",
|
| 587 |
+
"\n",
|
| 588 |
+
"\n",
|
| 589 |
+
"\n",
|
| 590 |
+
"\n",
|
| 591 |
+
"\n",
|
| 592 |
+
" lowest_rmsd, best_pdb_file, best_data = process_sequences(seq_list, pdb_file,in_path)\n",
|
| 593 |
+
" if lowest_rmsd is not None:\n",
|
| 594 |
+
" print(f\"Lowest RMSD: {lowest_rmsd}, Best PDB file: {best_pdb_file}\")\n",
|
| 595 |
+
" else:\n",
|
| 596 |
+
" print(\"No valid result found.\")\n",
|
| 597 |
+
" #visualize_pdb_overlay(pdb_file, best_pdb_file)\n"
|
| 598 |
+
],
|
| 599 |
+
"metadata": {
|
| 600 |
+
"cellView": "form",
|
| 601 |
+
"collapsed": true,
|
| 602 |
+
"id": "Ctyijhvu0UVe"
|
| 603 |
+
},
|
| 604 |
+
"execution_count": null,
|
| 605 |
+
"outputs": []
|
| 606 |
+
},
|
| 607 |
+
{
|
| 608 |
+
"cell_type": "code",
|
| 609 |
+
"source": [
|
| 610 |
+
"#@markdown #Optional: Run AF2 based designability test\n",
|
| 611 |
+
"\n",
|
| 612 |
+
"\n",
|
| 613 |
+
"#@markdown Rerun **setup cell** if you tested ESMFold prediction before!\n",
|
| 614 |
+
"\n",
|
| 615 |
+
"#@markdown This cell predicts the solubleMPNN generated seuqneces with AF2 with Initial Guess & All atom initialisation\n",
|
| 616 |
+
"import re\n",
|
| 617 |
+
"clear_mem()\n",
|
| 618 |
+
"\n",
|
| 619 |
+
"in_path = '/content/in/'\n",
|
| 620 |
+
"out_path = 'out/'\n",
|
| 621 |
+
"if not os.path.exists('/content/in/out/'):\n",
|
| 622 |
+
" os.mkdir('/content/in/out/')\n",
|
| 623 |
+
"\n",
|
| 624 |
+
"\n",
|
| 625 |
+
"starting_seq = \"\"\n",
|
| 626 |
+
"starting_seq = re.sub(\"[^A-Z]\", \"\", starting_seq.upper())\n",
|
| 627 |
+
"\n",
|
| 628 |
+
"\n",
|
| 629 |
+
"file_list = os.listdir(in_path)\n",
|
| 630 |
+
"\n",
|
| 631 |
+
"clear_mem()\n",
|
| 632 |
+
"\n",
|
| 633 |
+
"af_model = mk_afdesign_model(protocol=\"fixbb\",use_initial_atom_pos=True,use_initial_guess=True)\n",
|
| 634 |
+
"\n",
|
| 635 |
+
"\n",
|
| 636 |
+
"def process_sequences(seq_list, pdb_file,in_path_pdb):\n",
|
| 637 |
+
" lowest_rmsd = float('inf')\n",
|
| 638 |
+
" lowest_rmsd_data = None\n",
|
| 639 |
+
" pdb_id = pdb_file[16:-4]\n",
|
| 640 |
+
" out_ss_path = in_path_pdb + \"output_AF2/\"\n",
|
| 641 |
+
"\n",
|
| 642 |
+
" if not os.path.exists(out_ss_path):\n",
|
| 643 |
+
" os.mkdir(out_ss_path)\n",
|
| 644 |
+
" kk=0\n",
|
| 645 |
+
" for test_protein in seq_list:\n",
|
| 646 |
+
" data = {}\n",
|
| 647 |
+
" af_model.prep_inputs(pdb_filename=pdb_file, chain='A')\n",
|
| 648 |
+
" af_model.predict(seq=test_protein,num_recycles=3)\n",
|
| 649 |
+
"\n",
|
| 650 |
+
"\n",
|
| 651 |
+
"\n",
|
| 652 |
+
" data[\"plddt\"] = af_model.aux['losses']['plddt']\n",
|
| 653 |
+
" data['pae'] = af_model.aux['losses']['pae']*31\n",
|
| 654 |
+
" data['rmsd'] = af_model.aux['losses']['rmsd']\n",
|
| 655 |
+
" af_model.save_pdb(f'{out_ss_path}{pdb_id}_{kk}.pdb')\n",
|
| 656 |
+
" print(f'Sequence: {test_protein}, plddt: {data[\"plddt\"]}, PAE: {data[\"pae\"]}, RMSD: {data[\"rmsd\"]}')\n",
|
| 657 |
+
"\n",
|
| 658 |
+
" if data['rmsd'] < lowest_rmsd:\n",
|
| 659 |
+
" lowest_rmsd = data['rmsd']\n",
|
| 660 |
+
" lowest_rmsd_data = data\n",
|
| 661 |
+
"\n",
|
| 662 |
+
" if lowest_rmsd_data is not None:\n",
|
| 663 |
+
" print(f'Lowest RMSD: {lowest_rmsd}')\n",
|
| 664 |
+
"\n",
|
| 665 |
+
" best_pdb_file = os.path.join(out_ss_path, f\"{pdb_id}_best_structure.pdb\")\n",
|
| 666 |
+
"\n",
|
| 667 |
+
" return lowest_rmsd, best_pdb_file\n",
|
| 668 |
+
"\n",
|
| 669 |
+
" return None, None, None\n",
|
| 670 |
+
"\n",
|
| 671 |
+
"\n",
|
| 672 |
+
"in_path= '/content/out_sMPNN/'\n",
|
| 673 |
+
"file_list = os.listdir(in_path)\n",
|
| 674 |
+
"\n",
|
| 675 |
+
"for file in file_list:\n",
|
| 676 |
+
" if file[-1] =='l':\n",
|
| 677 |
+
"\n",
|
| 678 |
+
"\n",
|
| 679 |
+
"\n",
|
| 680 |
+
" output_pkl_file = in_path + file\n",
|
| 681 |
+
"\n",
|
| 682 |
+
" with open(output_pkl_file, 'rb') as f:\n",
|
| 683 |
+
" seq = pickle.load(f)\n",
|
| 684 |
+
" seq_list = []\n",
|
| 685 |
+
" for i in np.asarray(seq):\n",
|
| 686 |
+
" seq_list.append(i[0])\n",
|
| 687 |
+
"\n",
|
| 688 |
+
" pdb_file = \"/content/in/out/\" + file[:-14] + '.pdb'\n",
|
| 689 |
+
" print(seq_list)\n",
|
| 690 |
+
"\n",
|
| 691 |
+
"\n",
|
| 692 |
+
"\n",
|
| 693 |
+
"\n",
|
| 694 |
+
"\n",
|
| 695 |
+
"\n",
|
| 696 |
+
"\n",
|
| 697 |
+
" lowest_rmsd, best_pdb_file = process_sequences(seq_list, pdb_file,in_path)\n",
|
| 698 |
+
" if lowest_rmsd is not None:\n",
|
| 699 |
+
" print(f\"Lowest RMSD: {lowest_rmsd}, Best PDB file: {best_pdb_file}\")\n",
|
| 700 |
+
" else:\n",
|
| 701 |
+
" print(\"No valid result found.\")\n",
|
| 702 |
+
" #visualize_pdb_overlay(pdb_file, best_pdb_file)\n",
|
| 703 |
+
"\n",
|
| 704 |
+
"\n"
|
| 705 |
+
],
|
| 706 |
+
"metadata": {
|
| 707 |
+
"cellView": "form",
|
| 708 |
+
"id": "s1EVl7Ee8ne-"
|
| 709 |
+
},
|
| 710 |
+
"execution_count": null,
|
| 711 |
+
"outputs": []
|
| 712 |
+
},
|
| 713 |
+
{
|
| 714 |
+
"cell_type": "code",
|
| 715 |
+
"source": [],
|
| 716 |
+
"metadata": {
|
| 717 |
+
"id": "ZQljfnQl8oTc"
|
| 718 |
+
},
|
| 719 |
+
"execution_count": null,
|
| 720 |
+
"outputs": []
|
| 721 |
+
},
|
| 722 |
+
{
|
| 723 |
+
"cell_type": "code",
|
| 724 |
+
"source": [],
|
| 725 |
+
"metadata": {
|
| 726 |
+
"id": "16XTY0u9YyxP"
|
| 727 |
+
},
|
| 728 |
+
"execution_count": null,
|
| 729 |
+
"outputs": []
|
| 730 |
+
},
|
| 731 |
+
{
|
| 732 |
+
"cell_type": "code",
|
| 733 |
+
"source": [],
|
| 734 |
+
"metadata": {
|
| 735 |
+
"id": "u6mCraHrdqM3"
|
| 736 |
+
},
|
| 737 |
+
"execution_count": null,
|
| 738 |
+
"outputs": []
|
| 739 |
+
}
|
| 740 |
+
]
|
| 741 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/af_cyc_design.ipynb
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/main/af/examples/af_cyc_design.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "markdown",
|
| 15 |
+
"metadata": {
|
| 16 |
+
"id": "OA2k3sAYuiXe"
|
| 17 |
+
},
|
| 18 |
+
"source": [
|
| 19 |
+
"#af_cyc_design\n",
|
| 20 |
+
"\n",
|
| 21 |
+
"**Cyclic peptide structure prediction and design using AlphaFold**\n",
|
| 22 |
+
"\n",
|
| 23 |
+
"Stephen Rettie, Katelyn Campbell, Asim Bera, Alex Kang, Simon Kozlov, Joshmyn De La Cruz, Victor Adebomi, Guangfeng Zhou, Frank DiMaio, Sergey Ovchinnikov, Gaurav Bhardwaj\n",
|
| 24 |
+
"\n",
|
| 25 |
+
"doi: https://doi.org/10.1101/2023.02.25.529956\n"
|
| 26 |
+
]
|
| 27 |
+
},
|
| 28 |
+
{
|
| 29 |
+
"cell_type": "code",
|
| 30 |
+
"execution_count": null,
|
| 31 |
+
"metadata": {
|
| 32 |
+
"cellView": "form",
|
| 33 |
+
"id": "-AXy0s_4cKaK"
|
| 34 |
+
},
|
| 35 |
+
"outputs": [],
|
| 36 |
+
"source": [
|
| 37 |
+
"#@title setup (~2 minutes)\n",
|
| 38 |
+
"%%time\n",
|
| 39 |
+
"import os\n",
|
| 40 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 41 |
+
" # get code\n",
|
| 42 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git@v1.1.1\")\n",
|
| 43 |
+
" # for debugging\n",
|
| 44 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 45 |
+
" # download params\n",
|
| 46 |
+
" os.system(\"mkdir params\")\n",
|
| 47 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 48 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar\")\n",
|
| 49 |
+
" os.system(\"tar -xf alphafold_params_2022-12-06.tar -C params\")\n",
|
| 50 |
+
"\n",
|
| 51 |
+
"import warnings\n",
|
| 52 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 53 |
+
"\n",
|
| 54 |
+
"import os\n",
|
| 55 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 56 |
+
"from IPython.display import HTML\n",
|
| 57 |
+
"from google.colab import files\n",
|
| 58 |
+
"import numpy as np\n",
|
| 59 |
+
"\n",
|
| 60 |
+
"import jax\n",
|
| 61 |
+
"import jax.numpy as jnp\n",
|
| 62 |
+
"from colabdesign.af.alphafold.common import residue_constants\n",
|
| 63 |
+
"\n",
|
| 64 |
+
"def get_pdb(pdb_code=\"\"):\n",
|
| 65 |
+
" if pdb_code is None or pdb_code == \"\":\n",
|
| 66 |
+
" upload_dict = files.upload()\n",
|
| 67 |
+
" pdb_string = upload_dict[list(upload_dict.keys())[0]]\n",
|
| 68 |
+
" with open(\"tmp.pdb\",\"wb\") as out: out.write(pdb_string)\n",
|
| 69 |
+
" return \"tmp.pdb\"\n",
|
| 70 |
+
" elif os.path.isfile(pdb_code):\n",
|
| 71 |
+
" return pdb_code\n",
|
| 72 |
+
" elif len(pdb_code) == 4:\n",
|
| 73 |
+
" os.system(f\"wget -qnc https://files.rcsb.org/view/{pdb_code}.pdb\")\n",
|
| 74 |
+
" return f\"{pdb_code}.pdb\"\n",
|
| 75 |
+
" else:\n",
|
| 76 |
+
" os.system(f\"wget -qnc https://alphafold.ebi.ac.uk/files/AF-{pdb_code}-F1-model_v3.pdb\")\n",
|
| 77 |
+
" return f\"AF-{pdb_code}-F1-model_v3.pdb\"\n",
|
| 78 |
+
"\n",
|
| 79 |
+
"def add_cyclic_offset(self, offset_type=2):\n",
|
| 80 |
+
" '''add cyclic offset to connect N and C term'''\n",
|
| 81 |
+
" def cyclic_offset(L):\n",
|
| 82 |
+
" i = np.arange(L)\n",
|
| 83 |
+
" ij = np.stack([i,i+L],-1)\n",
|
| 84 |
+
" offset = i[:,None] - i[None,:]\n",
|
| 85 |
+
" c_offset = np.abs(ij[:,None,:,None] - ij[None,:,None,:]).min((2,3))\n",
|
| 86 |
+
" if offset_type == 1:\n",
|
| 87 |
+
" c_offset = c_offset\n",
|
| 88 |
+
" elif offset_type >= 2:\n",
|
| 89 |
+
" a = c_offset < np.abs(offset)\n",
|
| 90 |
+
" c_offset[a] = -c_offset[a]\n",
|
| 91 |
+
" if offset_type == 3:\n",
|
| 92 |
+
" idx = np.abs(c_offset) > 2\n",
|
| 93 |
+
" c_offset[idx] = (32 * c_offset[idx] )/ abs(c_offset[idx])\n",
|
| 94 |
+
" return c_offset * np.sign(offset)\n",
|
| 95 |
+
" idx = self._inputs[\"residue_index\"]\n",
|
| 96 |
+
" offset = np.array(idx[:,None] - idx[None,:])\n",
|
| 97 |
+
"\n",
|
| 98 |
+
" if self.protocol == \"binder\":\n",
|
| 99 |
+
" c_offset = cyclic_offset(self._binder_len)\n",
|
| 100 |
+
" offset[self._target_len:,self._target_len:] = c_offset\n",
|
| 101 |
+
"\n",
|
| 102 |
+
" if self.protocol in [\"fixbb\",\"partial\",\"hallucination\"]:\n",
|
| 103 |
+
" Ln = 0\n",
|
| 104 |
+
" for L in self._lengths:\n",
|
| 105 |
+
" offset[Ln:Ln+L,Ln:Ln+L] = cyclic_offset(L)\n",
|
| 106 |
+
" Ln += L\n",
|
| 107 |
+
" self._inputs[\"offset\"] = offset\n",
|
| 108 |
+
"\n",
|
| 109 |
+
"def add_rg_loss(self, weight=0.1):\n",
|
| 110 |
+
" '''add radius of gyration loss'''\n",
|
| 111 |
+
" def loss_fn(inputs, outputs):\n",
|
| 112 |
+
" xyz = outputs[\"structure_module\"]\n",
|
| 113 |
+
" ca = xyz[\"final_atom_positions\"][:,residue_constants.atom_order[\"CA\"]]\n",
|
| 114 |
+
" rg = jnp.sqrt(jnp.square(ca - ca.mean(0)).sum(-1).mean() + 1e-8)\n",
|
| 115 |
+
" rg_th = 2.38 * ca.shape[0] ** 0.365\n",
|
| 116 |
+
" rg = jax.nn.elu(rg - rg_th)\n",
|
| 117 |
+
" return {\"rg\":rg}\n",
|
| 118 |
+
" self._callbacks[\"model\"][\"loss\"].append(loss_fn)\n",
|
| 119 |
+
" self.opt[\"weights\"][\"rg\"] = weight"
|
| 120 |
+
]
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"cell_type": "markdown",
|
| 124 |
+
"metadata": {
|
| 125 |
+
"id": "UUfKrOzT0gOS"
|
| 126 |
+
},
|
| 127 |
+
"source": [
|
| 128 |
+
"# fixed backbone design (fixbb) (~2 minutes)\n",
|
| 129 |
+
"For a given protein backbone, generate/design a new sequence that AlphaFold thinks folds into that conformation."
|
| 130 |
+
]
|
| 131 |
+
},
|
| 132 |
+
{
|
| 133 |
+
"cell_type": "code",
|
| 134 |
+
"execution_count": null,
|
| 135 |
+
"metadata": {
|
| 136 |
+
"id": "qLd1DsnKzxBJ"
|
| 137 |
+
},
|
| 138 |
+
"outputs": [],
|
| 139 |
+
"source": [
|
| 140 |
+
"clear_mem()\n",
|
| 141 |
+
"af_model = mk_afdesign_model(protocol=\"fixbb\")\n",
|
| 142 |
+
"af_model.prep_inputs(pdb_filename=get_pdb(\"7m28\"), chain=\"A\")\n",
|
| 143 |
+
"add_cyclic_offset(af_model, offset_type=2)\n",
|
| 144 |
+
"\n",
|
| 145 |
+
"print(\"length\", af_model._len)\n",
|
| 146 |
+
"print(\"weights\", af_model.opt[\"weights\"])"
|
| 147 |
+
]
|
| 148 |
+
},
|
| 149 |
+
{
|
| 150 |
+
"cell_type": "code",
|
| 151 |
+
"source": [
|
| 152 |
+
"import matplotlib.pyplot as plt\n",
|
| 153 |
+
"plt.imshow(af_model._inputs[\"offset\"],cmap=\"bwr\")"
|
| 154 |
+
],
|
| 155 |
+
"metadata": {
|
| 156 |
+
"id": "xr6mw-CXl_o3"
|
| 157 |
+
},
|
| 158 |
+
"execution_count": null,
|
| 159 |
+
"outputs": []
|
| 160 |
+
},
|
| 161 |
+
{
|
| 162 |
+
"cell_type": "code",
|
| 163 |
+
"source": [
|
| 164 |
+
"af_model.restart()\n",
|
| 165 |
+
"af_model.design_3stage()"
|
| 166 |
+
],
|
| 167 |
+
"metadata": {
|
| 168 |
+
"id": "u0AwskJ84NGx"
|
| 169 |
+
},
|
| 170 |
+
"execution_count": null,
|
| 171 |
+
"outputs": []
|
| 172 |
+
},
|
| 173 |
+
{
|
| 174 |
+
"cell_type": "code",
|
| 175 |
+
"source": [
|
| 176 |
+
"af_model.plot_traj()"
|
| 177 |
+
],
|
| 178 |
+
"metadata": {
|
| 179 |
+
"id": "8FB1v7dn1LL6"
|
| 180 |
+
},
|
| 181 |
+
"execution_count": null,
|
| 182 |
+
"outputs": []
|
| 183 |
+
},
|
| 184 |
+
{
|
| 185 |
+
"cell_type": "code",
|
| 186 |
+
"execution_count": null,
|
| 187 |
+
"metadata": {
|
| 188 |
+
"id": "YEApO8YzBoS0"
|
| 189 |
+
},
|
| 190 |
+
"outputs": [],
|
| 191 |
+
"source": [
|
| 192 |
+
"af_model.save_pdb(f\"{af_model.protocol}.pdb\")\n",
|
| 193 |
+
"af_model.plot_pdb(show_mainchains=True)"
|
| 194 |
+
]
|
| 195 |
+
},
|
| 196 |
+
{
|
| 197 |
+
"cell_type": "code",
|
| 198 |
+
"execution_count": null,
|
| 199 |
+
"metadata": {
|
| 200 |
+
"id": "cW1KQiHKJpfp"
|
| 201 |
+
},
|
| 202 |
+
"outputs": [],
|
| 203 |
+
"source": [
|
| 204 |
+
"HTML(af_model.animate())"
|
| 205 |
+
]
|
| 206 |
+
},
|
| 207 |
+
{
|
| 208 |
+
"cell_type": "code",
|
| 209 |
+
"source": [
|
| 210 |
+
"af_model.get_seqs()"
|
| 211 |
+
],
|
| 212 |
+
"metadata": {
|
| 213 |
+
"id": "YDrChASGVUUx"
|
| 214 |
+
},
|
| 215 |
+
"execution_count": null,
|
| 216 |
+
"outputs": []
|
| 217 |
+
},
|
| 218 |
+
{
|
| 219 |
+
"cell_type": "markdown",
|
| 220 |
+
"source": [
|
| 221 |
+
"# hallucination (~1 minute)\n",
|
| 222 |
+
"For a given length, generate/hallucinate a protein sequence that AlphaFold thinks folds into a well structured protein (high plddt, low pae, many contacts)."
|
| 223 |
+
],
|
| 224 |
+
"metadata": {
|
| 225 |
+
"id": "qLwS2s_xcjRI"
|
| 226 |
+
}
|
| 227 |
+
},
|
| 228 |
+
{
|
| 229 |
+
"cell_type": "code",
|
| 230 |
+
"execution_count": null,
|
| 231 |
+
"metadata": {
|
| 232 |
+
"id": "sZnYfCbfEvol"
|
| 233 |
+
},
|
| 234 |
+
"outputs": [],
|
| 235 |
+
"source": [
|
| 236 |
+
"clear_mem()\n",
|
| 237 |
+
"af_model = mk_afdesign_model(protocol=\"hallucination\")\n",
|
| 238 |
+
"af_model.prep_inputs(length=13, rm_aa=\"C\")\n",
|
| 239 |
+
"add_cyclic_offset(af_model)\n",
|
| 240 |
+
"# add_rg_loss(af_model)\n",
|
| 241 |
+
"\n",
|
| 242 |
+
"print(\"length\",af_model._len)\n",
|
| 243 |
+
"print(\"weights\",af_model.opt[\"weights\"])"
|
| 244 |
+
]
|
| 245 |
+
},
|
| 246 |
+
{
|
| 247 |
+
"cell_type": "code",
|
| 248 |
+
"source": [
|
| 249 |
+
"# pre-design with gumbel initialization and softmax activation\n",
|
| 250 |
+
"af_model.restart()\n",
|
| 251 |
+
"af_model.set_seq(mode=\"gumbel\")\n",
|
| 252 |
+
"af_model.set_opt(\"con\", binary=True, cutoff=21.6875, num=af_model._len, seqsep=0)\n",
|
| 253 |
+
"af_model.set_weights(pae=1, plddt=1, con=0.5)\n",
|
| 254 |
+
"af_model.design_soft(50)\n",
|
| 255 |
+
"\n",
|
| 256 |
+
"# three stage design\n",
|
| 257 |
+
"af_model.set_seq(seq=af_model.aux[\"seq\"][\"pseudo\"])\n",
|
| 258 |
+
"af_model.design_3stage(50,50,10)"
|
| 259 |
+
],
|
| 260 |
+
"metadata": {
|
| 261 |
+
"id": "f76xqCkw0vj9"
|
| 262 |
+
},
|
| 263 |
+
"execution_count": null,
|
| 264 |
+
"outputs": []
|
| 265 |
+
},
|
| 266 |
+
{
|
| 267 |
+
"cell_type": "code",
|
| 268 |
+
"execution_count": null,
|
| 269 |
+
"metadata": {
|
| 270 |
+
"id": "A1GxeLZdTTya"
|
| 271 |
+
},
|
| 272 |
+
"outputs": [],
|
| 273 |
+
"source": [
|
| 274 |
+
"af_model.save_pdb(f\"{af_model.protocol}.pdb\")\n",
|
| 275 |
+
"af_model.plot_pdb(show_mainchains=True)"
|
| 276 |
+
]
|
| 277 |
+
},
|
| 278 |
+
{
|
| 279 |
+
"cell_type": "code",
|
| 280 |
+
"execution_count": null,
|
| 281 |
+
"metadata": {
|
| 282 |
+
"id": "L2E9Tn2Acchj"
|
| 283 |
+
},
|
| 284 |
+
"outputs": [],
|
| 285 |
+
"source": [
|
| 286 |
+
"HTML(af_model.animate())"
|
| 287 |
+
]
|
| 288 |
+
},
|
| 289 |
+
{
|
| 290 |
+
"cell_type": "code",
|
| 291 |
+
"execution_count": null,
|
| 292 |
+
"metadata": {
|
| 293 |
+
"id": "YSKWYu0_GlUH"
|
| 294 |
+
},
|
| 295 |
+
"outputs": [],
|
| 296 |
+
"source": [
|
| 297 |
+
"af_model.get_seqs()"
|
| 298 |
+
]
|
| 299 |
+
}
|
| 300 |
+
],
|
| 301 |
+
"metadata": {
|
| 302 |
+
"accelerator": "GPU",
|
| 303 |
+
"colab": {
|
| 304 |
+
"collapsed_sections": [
|
| 305 |
+
"q4qiU9I0QHSz"
|
| 306 |
+
],
|
| 307 |
+
"provenance": [],
|
| 308 |
+
"include_colab_link": true
|
| 309 |
+
},
|
| 310 |
+
"kernelspec": {
|
| 311 |
+
"display_name": "Python 3",
|
| 312 |
+
"name": "python3"
|
| 313 |
+
},
|
| 314 |
+
"language_info": {
|
| 315 |
+
"name": "python"
|
| 316 |
+
}
|
| 317 |
+
},
|
| 318 |
+
"nbformat": 4,
|
| 319 |
+
"nbformat_minor": 0
|
| 320 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/af_pseudo_diffusion.ipynb
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/examples/af_pseudo_diffusion.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "markdown",
|
| 15 |
+
"metadata": {
|
| 16 |
+
"id": "VD9K5H2cnFxL"
|
| 17 |
+
},
|
| 18 |
+
"source": [
|
| 19 |
+
"#AF_pseudo_diffusion + proteinMPNN\n",
|
| 20 |
+
"Hacking AlphaFold to be a diffusion model (for backbone generation). At each step add logits from proteinMPNN.\n",
|
| 21 |
+
"\n",
|
| 22 |
+
"\n",
|
| 23 |
+
"**WARNING**: This notebook is experimental, designed as a control. Not intended for practical use at this stage.\n",
|
| 24 |
+
"\n",
|
| 25 |
+
"---\n",
|
| 26 |
+
"**NEW**\n",
|
| 27 |
+
"For latest version of notebook (reconfigured to work in distogram space) go here:\n",
|
| 28 |
+
"[af_pseudo_diffusion_dgram.ipynb](https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/examples/af_pseudo_diffusion_dgram.ipynb)"
|
| 29 |
+
]
|
| 30 |
+
},
|
| 31 |
+
{
|
| 32 |
+
"cell_type": "code",
|
| 33 |
+
"execution_count": null,
|
| 34 |
+
"metadata": {
|
| 35 |
+
"cellView": "form",
|
| 36 |
+
"id": "YCRzPGdTZfEe"
|
| 37 |
+
},
|
| 38 |
+
"outputs": [],
|
| 39 |
+
"source": [
|
| 40 |
+
"#@title setup\n",
|
| 41 |
+
"%%time\n",
|
| 42 |
+
"import os\n",
|
| 43 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 44 |
+
" # get code\n",
|
| 45 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git@v1.1.1\")\n",
|
| 46 |
+
" # for debugging\n",
|
| 47 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 48 |
+
" # download params\n",
|
| 49 |
+
" os.system(\"mkdir params\")\n",
|
| 50 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 51 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar\")\n",
|
| 52 |
+
" os.system(\"tar -xf alphafold_params_2022-12-06.tar -C params\")\n",
|
| 53 |
+
"\n",
|
| 54 |
+
"import warnings\n",
|
| 55 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 56 |
+
"\n",
|
| 57 |
+
"import os, re\n",
|
| 58 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 59 |
+
"from colabdesign.mpnn import mk_mpnn_model\n",
|
| 60 |
+
"from IPython.display import HTML\n",
|
| 61 |
+
"from google.colab import files\n",
|
| 62 |
+
"import numpy as np\n",
|
| 63 |
+
"\n",
|
| 64 |
+
"def get_pdb(pdb_code=\"\"):\n",
|
| 65 |
+
" if pdb_code is None or pdb_code == \"\":\n",
|
| 66 |
+
" upload_dict = files.upload()\n",
|
| 67 |
+
" pdb_string = upload_dict[list(upload_dict.keys())[0]]\n",
|
| 68 |
+
" with open(\"tmp.pdb\",\"wb\") as out: out.write(pdb_string)\n",
|
| 69 |
+
" return \"tmp.pdb\"\n",
|
| 70 |
+
" elif os.path.isfile(pdb_code):\n",
|
| 71 |
+
" return pdb_code\n",
|
| 72 |
+
" elif len(pdb_code) == 4:\n",
|
| 73 |
+
" os.system(f\"wget -qnc https://files.rcsb.org/view/{pdb_code}.pdb\")\n",
|
| 74 |
+
" return f\"{pdb_code}.pdb\"\n",
|
| 75 |
+
" else:\n",
|
| 76 |
+
" os.system(f\"wget -qnc https://alphafold.ebi.ac.uk/files/AF-{pdb_code}-F1-model_v3.pdb\")\n",
|
| 77 |
+
" return f\"AF-{pdb_code}-F1-model_v3.pdb\"\n",
|
| 78 |
+
"\n",
|
| 79 |
+
"def sample_gumbel(shape, eps=1e-20): \n",
|
| 80 |
+
" \"\"\"Sample from Gumbel(0, 1)\"\"\"\n",
|
| 81 |
+
" U = np.random.uniform(size=shape)\n",
|
| 82 |
+
" return -np.log(-np.log(U + eps) + eps)"
|
| 83 |
+
]
|
| 84 |
+
},
|
| 85 |
+
{
|
| 86 |
+
"cell_type": "code",
|
| 87 |
+
"execution_count": null,
|
| 88 |
+
"metadata": {
|
| 89 |
+
"id": "wxYMB4A9Zmrf",
|
| 90 |
+
"cellView": "form"
|
| 91 |
+
},
|
| 92 |
+
"outputs": [],
|
| 93 |
+
"source": [
|
| 94 |
+
"#@title initialize the model\n",
|
| 95 |
+
"length = 100 #@param {type:\"integer\"}\n",
|
| 96 |
+
"#@markdown Provide a starting point (optional)\n",
|
| 97 |
+
"starting_seq = \"\" #@param {type:\"string\"}\n",
|
| 98 |
+
"starting_seq = re.sub(\"[^A-Z]\", \"\", starting_seq.upper())\n",
|
| 99 |
+
"#@markdown - if `starting_seq` provided the `length` option will be overwritten by length of starting sequence.\n",
|
| 100 |
+
"use_starting_pdb = False #@param {type:\"boolean\"}\n",
|
| 101 |
+
"pdb = \"\" #@param {type:\"string\"}\n",
|
| 102 |
+
"#@markdown - specify PDB or Uniprot code or leave pdb blank for upload prompt\n",
|
| 103 |
+
"chains = \"A\" #@param {type:\"string\"}\n",
|
| 104 |
+
"#@markdown - (example `A` or `A,B` for complexes)\n",
|
| 105 |
+
"fix_pos = \"\" #@param {type:\"string\"}\n",
|
| 106 |
+
"#@markdown - specify which positions to keep fixed in the sequence (example: `1,2-10`)\n",
|
| 107 |
+
"#@markdown - you can also specify chain specific constraints (example: `A1-10,B1-20`)\n",
|
| 108 |
+
"#@markdown - you can also specify to fix entire chain(s) (example: `A`)\n",
|
| 109 |
+
"\n",
|
| 110 |
+
"if len(starting_seq) > 0:\n",
|
| 111 |
+
" length = len(starting_seq)\n",
|
| 112 |
+
"\n",
|
| 113 |
+
"clear_mem()\n",
|
| 114 |
+
"if use_starting_pdb:\n",
|
| 115 |
+
" af_model = mk_afdesign_model(protocol=\"fixbb\", use_templates=True)\n",
|
| 116 |
+
" af_model.prep_inputs(get_pdb(pdb), chains, fix_pos=fix_pos) \n",
|
| 117 |
+
"else:\n",
|
| 118 |
+
" af_model = mk_afdesign_model(protocol=\"hallucination\", use_templates=True)\n",
|
| 119 |
+
" af_model.prep_inputs(length=length)\n",
|
| 120 |
+
"mpnn_model = mk_mpnn_model()\n",
|
| 121 |
+
"print(\"lengths\",af_model._lengths)"
|
| 122 |
+
]
|
| 123 |
+
},
|
| 124 |
+
{
|
| 125 |
+
"cell_type": "code",
|
| 126 |
+
"execution_count": null,
|
| 127 |
+
"metadata": {
|
| 128 |
+
"id": "3Dt8i00UbxtW",
|
| 129 |
+
"cellView": "form"
|
| 130 |
+
},
|
| 131 |
+
"outputs": [],
|
| 132 |
+
"source": [
|
| 133 |
+
"#@title run protocol\n",
|
| 134 |
+
"#@markdown Optimization options\n",
|
| 135 |
+
"iterations = 100 #@param [\"50\", \"100\"] {type:\"raw\"}\n",
|
| 136 |
+
"use_xyz_noise = True #@param {type:\"boolean\"}\n",
|
| 137 |
+
"use_seq_noise = True #@param {type:\"boolean\"}\n",
|
| 138 |
+
"use_dropout = True #@param {type:\"boolean\"}\n",
|
| 139 |
+
"use_plddt = True #@param {type:\"boolean\"}\n",
|
| 140 |
+
"store_denoised = True #@param {type:\"boolean\"}\n",
|
| 141 |
+
"#@markdown - this does not change results, but toggle between storing noised vs denoised coordinates for animation.\n",
|
| 142 |
+
"\n",
|
| 143 |
+
"#@markdown AlphaFold options\n",
|
| 144 |
+
"sample_models = False #@param {type:\"boolean\"}\n",
|
| 145 |
+
"rm_template_seq = True #@param {type:\"boolean\"}\n",
|
| 146 |
+
"\n",
|
| 147 |
+
"#@markdown proteinMPNN options (disable to keep sequence the same)\n",
|
| 148 |
+
"use_mpnn = True #@param {type:\"boolean\"}\n",
|
| 149 |
+
"mpnn_mode = \"conditional\" #@param [\"conditional\", \"unconditional\"]\n",
|
| 150 |
+
"\n",
|
| 151 |
+
"af_model.restart(mode=\"gumbel\")\n",
|
| 152 |
+
"\n",
|
| 153 |
+
"if len(starting_seq) > 1:\n",
|
| 154 |
+
" af_model.set_seq(seq=starting_seq)\n",
|
| 155 |
+
"elif use_starting_pdb:\n",
|
| 156 |
+
" af_model.set_seq(mode=\"wildtype\")\n",
|
| 157 |
+
"\n",
|
| 158 |
+
"af_model._inputs[\"rm_template_seq\"] = rm_template_seq\n",
|
| 159 |
+
"L = sum(af_model._lengths)\n",
|
| 160 |
+
"\n",
|
| 161 |
+
"af_model._inputs[\"bias\"] = np.zeros((L,20))\n",
|
| 162 |
+
"\n",
|
| 163 |
+
"if not use_starting_pdb:\n",
|
| 164 |
+
" af_model._inputs[\"batch\"] = {\"aatype\":np.zeros(L).astype(int),\n",
|
| 165 |
+
" \"all_atom_mask\":np.zeros((L,37)),\n",
|
| 166 |
+
" \"all_atom_positions\":np.zeros((L,37,3))}\n",
|
| 167 |
+
"\n",
|
| 168 |
+
"for k in range(iterations):\n",
|
| 169 |
+
" # add noise\n",
|
| 170 |
+
" if use_seq_noise:\n",
|
| 171 |
+
" af_model._inputs[\"bias\"] = 0.1 * sample_gumbel((L,20))\n",
|
| 172 |
+
"\n",
|
| 173 |
+
" if use_xyz_noise:\n",
|
| 174 |
+
" n = np.random.normal(size=(L,37,3)) * (1-k/iterations)\n",
|
| 175 |
+
" af_model._inputs[\"batch\"][\"all_atom_positions\"] += n\n",
|
| 176 |
+
" if not store_denoised and k > 0:\n",
|
| 177 |
+
" af_model._tmp[\"traj\"][\"xyz\"][-1] += n[:,1]\n",
|
| 178 |
+
"\n",
|
| 179 |
+
" # denoise\n",
|
| 180 |
+
" aux = af_model.predict(return_aux=True, verbose=False,\n",
|
| 181 |
+
" sample_models=sample_models, dropout=use_dropout)\n",
|
| 182 |
+
" plddt = af_model.aux[\"plddt\"]\n",
|
| 183 |
+
" # update inputs\n",
|
| 184 |
+
" af_model._inputs[\"batch\"][\"aatype\"] = af_model.aux[\"seq\"][\"hard\"].argmax(-1)[0]\n",
|
| 185 |
+
" af_model._inputs[\"batch\"][\"all_atom_mask\"][:,:4] = 1\n",
|
| 186 |
+
" if use_plddt:\n",
|
| 187 |
+
" af_model._inputs[\"batch\"][\"all_atom_mask\"][:,(1,3)] = np.sqrt(plddt)[:,None]\n",
|
| 188 |
+
" af_model._inputs[\"batch\"][\"all_atom_positions\"] = af_model.aux[\"atom_positions\"].copy()\n",
|
| 189 |
+
"\n",
|
| 190 |
+
" # add logits from proteinmpnn at each stage\n",
|
| 191 |
+
" if use_mpnn:\n",
|
| 192 |
+
" mpnn_model.get_af_inputs(af_model)\n",
|
| 193 |
+
" opt = {} if mpnn_mode == \"conditional\" else {\"ar_mask\":np.zeros((L,L))}\n",
|
| 194 |
+
" mpnn_out = mpnn_model.score(**opt)\n",
|
| 195 |
+
" aux[\"log\"][\"mpnn\"] = mpnn_out[\"score\"]\n",
|
| 196 |
+
" mpnn_logits = mpnn_out[\"logits\"][:,:20]\n",
|
| 197 |
+
" m = (k/iterations)\n",
|
| 198 |
+
" af_model._params[\"seq\"] = (1-m) * af_model._params[\"seq\"] + m * mpnn_logits\n",
|
| 199 |
+
"\n",
|
| 200 |
+
" # save results\n",
|
| 201 |
+
" af_model._save_results(aux)\n",
|
| 202 |
+
" af_model._k += 1"
|
| 203 |
+
]
|
| 204 |
+
},
|
| 205 |
+
{
|
| 206 |
+
"cell_type": "code",
|
| 207 |
+
"execution_count": null,
|
| 208 |
+
"metadata": {
|
| 209 |
+
"id": "v3dPQeEQcAcT"
|
| 210 |
+
},
|
| 211 |
+
"outputs": [],
|
| 212 |
+
"source": [
|
| 213 |
+
"af_model.plot_pdb()"
|
| 214 |
+
]
|
| 215 |
+
},
|
| 216 |
+
{
|
| 217 |
+
"cell_type": "code",
|
| 218 |
+
"source": [
|
| 219 |
+
"af_model.save_pdb(\"tmp.pdb\")\n",
|
| 220 |
+
"af_model.get_seqs()"
|
| 221 |
+
],
|
| 222 |
+
"metadata": {
|
| 223 |
+
"id": "6Ck-ME5_99qE"
|
| 224 |
+
},
|
| 225 |
+
"execution_count": null,
|
| 226 |
+
"outputs": []
|
| 227 |
+
},
|
| 228 |
+
{
|
| 229 |
+
"cell_type": "code",
|
| 230 |
+
"execution_count": null,
|
| 231 |
+
"metadata": {
|
| 232 |
+
"id": "6cJhizcYcUxm"
|
| 233 |
+
},
|
| 234 |
+
"outputs": [],
|
| 235 |
+
"source": [
|
| 236 |
+
"HTML(af_model.animate(dpi=100))"
|
| 237 |
+
]
|
| 238 |
+
},
|
| 239 |
+
{
|
| 240 |
+
"cell_type": "code",
|
| 241 |
+
"source": [],
|
| 242 |
+
"metadata": {
|
| 243 |
+
"id": "aVS6VC7wKyhD"
|
| 244 |
+
},
|
| 245 |
+
"execution_count": null,
|
| 246 |
+
"outputs": []
|
| 247 |
+
}
|
| 248 |
+
],
|
| 249 |
+
"metadata": {
|
| 250 |
+
"accelerator": "GPU",
|
| 251 |
+
"colab": {
|
| 252 |
+
"provenance": [],
|
| 253 |
+
"include_colab_link": true
|
| 254 |
+
},
|
| 255 |
+
"gpuClass": "standard",
|
| 256 |
+
"kernelspec": {
|
| 257 |
+
"display_name": "Python 3",
|
| 258 |
+
"name": "python3"
|
| 259 |
+
},
|
| 260 |
+
"language_info": {
|
| 261 |
+
"name": "python"
|
| 262 |
+
}
|
| 263 |
+
},
|
| 264 |
+
"nbformat": 4,
|
| 265 |
+
"nbformat_minor": 0
|
| 266 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/af_pseudo_diffusion_dgram.ipynb
ADDED
|
@@ -0,0 +1,376 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/examples/af_pseudo_diffusion_dgram.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "markdown",
|
| 15 |
+
"metadata": {
|
| 16 |
+
"id": "VD9K5H2cnFxL"
|
| 17 |
+
},
|
| 18 |
+
"source": [
|
| 19 |
+
"#AF_pseudo_diffusion + proteinMPNN\n",
|
| 20 |
+
"Hacking AlphaFold to be a diffusion model (for backbone generation) via distogram. At each step add logits from proteinMPNN.\n",
|
| 21 |
+
"\n",
|
| 22 |
+
"\n",
|
| 23 |
+
"**WARNING**: This notebook is experimental, designed as a control. Not intended for practical use at this stage."
|
| 24 |
+
]
|
| 25 |
+
},
|
| 26 |
+
{
|
| 27 |
+
"cell_type": "code",
|
| 28 |
+
"execution_count": null,
|
| 29 |
+
"metadata": {
|
| 30 |
+
"cellView": "form",
|
| 31 |
+
"id": "YCRzPGdTZfEe"
|
| 32 |
+
},
|
| 33 |
+
"outputs": [],
|
| 34 |
+
"source": [
|
| 35 |
+
"#@title setup\n",
|
| 36 |
+
"%%time\n",
|
| 37 |
+
"import os\n",
|
| 38 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 39 |
+
" # get code\n",
|
| 40 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git@v1.1.1\")\n",
|
| 41 |
+
" # for debugging\n",
|
| 42 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 43 |
+
" # download params\n",
|
| 44 |
+
" os.system(\"mkdir params\")\n",
|
| 45 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 46 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar\")\n",
|
| 47 |
+
" os.system(\"tar -xf alphafold_params_2022-12-06.tar -C params\")\n",
|
| 48 |
+
"\n",
|
| 49 |
+
"import warnings\n",
|
| 50 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 51 |
+
"\n",
|
| 52 |
+
"import os, re\n",
|
| 53 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 54 |
+
"from colabdesign.mpnn import mk_mpnn_model\n",
|
| 55 |
+
"from colabdesign.af.alphafold.common import residue_constants\n",
|
| 56 |
+
"from colabdesign.shared.protein import _np_get_cb\n",
|
| 57 |
+
"\n",
|
| 58 |
+
"from IPython.display import HTML\n",
|
| 59 |
+
"from google.colab import files\n",
|
| 60 |
+
"import numpy as np\n",
|
| 61 |
+
"import jax.numpy as jnp\n",
|
| 62 |
+
"import jax\n",
|
| 63 |
+
"from scipy.special import softmax\n",
|
| 64 |
+
"\n",
|
| 65 |
+
"import tqdm.notebook\n",
|
| 66 |
+
"TQDM_BAR_FORMAT = '{l_bar}{bar}| {n_fmt}/{total_fmt} [elapsed: {elapsed} remaining: {remaining}]'\n",
|
| 67 |
+
"\n",
|
| 68 |
+
"def get_pdb(pdb_code=\"\"):\n",
|
| 69 |
+
" if pdb_code is None or pdb_code == \"\":\n",
|
| 70 |
+
" upload_dict = files.upload()\n",
|
| 71 |
+
" pdb_string = upload_dict[list(upload_dict.keys())[0]]\n",
|
| 72 |
+
" with open(\"tmp.pdb\",\"wb\") as out: out.write(pdb_string)\n",
|
| 73 |
+
" return \"tmp.pdb\"\n",
|
| 74 |
+
" elif os.path.isfile(pdb_code):\n",
|
| 75 |
+
" return pdb_code\n",
|
| 76 |
+
" elif len(pdb_code) == 4:\n",
|
| 77 |
+
" os.system(f\"wget -qnc https://files.rcsb.org/view/{pdb_code}.pdb\")\n",
|
| 78 |
+
" return f\"{pdb_code}.pdb\"\n",
|
| 79 |
+
" else:\n",
|
| 80 |
+
" os.system(f\"wget -qnc https://alphafold.ebi.ac.uk/files/AF-{pdb_code}-F1-model_v3.pdb\")\n",
|
| 81 |
+
" return f\"AF-{pdb_code}-F1-model_v3.pdb\"\n",
|
| 82 |
+
"\n",
|
| 83 |
+
"def sample_gumbel(shape, eps=1e-20): \n",
|
| 84 |
+
" \"\"\"Sample from Gumbel(0, 1)\"\"\"\n",
|
| 85 |
+
" U = np.random.uniform(size=shape)\n",
|
| 86 |
+
" return -np.log(-np.log(U + eps) + eps)"
|
| 87 |
+
]
|
| 88 |
+
},
|
| 89 |
+
{
|
| 90 |
+
"cell_type": "code",
|
| 91 |
+
"execution_count": null,
|
| 92 |
+
"metadata": {
|
| 93 |
+
"id": "wxYMB4A9Zmrf",
|
| 94 |
+
"cellView": "form"
|
| 95 |
+
},
|
| 96 |
+
"outputs": [],
|
| 97 |
+
"source": [
|
| 98 |
+
"#@title initialize the model\n",
|
| 99 |
+
"length = 100 #@param {type:\"integer\"}\n",
|
| 100 |
+
"#symmetry = \"C\" #@param [\"C\"]\n",
|
| 101 |
+
"#copies = 1 #@param {type:\"integer\"}\n",
|
| 102 |
+
"#@markdown Provide a starting point (optional)\n",
|
| 103 |
+
"starting_seq = \"\" #@param {type:\"string\"}\n",
|
| 104 |
+
"starting_seq = re.sub(\"[^A-Z]\", \"\", starting_seq.upper())\n",
|
| 105 |
+
"#@markdown - if `starting_seq` provided the `length` option will be overwritten by length of starting sequence.\n",
|
| 106 |
+
"\n",
|
| 107 |
+
"#@markdown Experimental options\n",
|
| 108 |
+
"use_multimer = False \n",
|
| 109 |
+
"mode = \"dgram_retrain\" #@param [\"dgram\",\"dgram_retrain\"]\n",
|
| 110 |
+
"##@markdown - `xyz` - use structure output as template input\n",
|
| 111 |
+
"#@markdown - `dgram` - use distogram output as template input\n",
|
| 112 |
+
"#@markdown - `dgram_retrain` - replace distogram head from AlphaFold with one retrained to map output bins to template bins.\n",
|
| 113 |
+
"\n",
|
| 114 |
+
"if len(starting_seq) > 0:\n",
|
| 115 |
+
" length = len(starting_seq)\n",
|
| 116 |
+
"\n",
|
| 117 |
+
"clear_mem()\n",
|
| 118 |
+
"af_model = mk_afdesign_model(protocol=\"hallucination\",\n",
|
| 119 |
+
" use_templates=True,\n",
|
| 120 |
+
" debug=True, \n",
|
| 121 |
+
" use_multimer=use_multimer)\n",
|
| 122 |
+
"af_model.prep_inputs(length=length)\n",
|
| 123 |
+
"mpnn_model = mk_mpnn_model()\n",
|
| 124 |
+
"print(\"lengths\",af_model._lengths)\n",
|
| 125 |
+
"\n",
|
| 126 |
+
"if \"dgram\" in mode:\n",
|
| 127 |
+
" if \"retrain\" in mode and not use_multimer:\n",
|
| 128 |
+
" # update distogram head to return all 39 bins\n",
|
| 129 |
+
" af_model._cfg.model.heads.distogram.first_break = 3.25\n",
|
| 130 |
+
" af_model._cfg.model.heads.distogram.last_break = 50.75\n",
|
| 131 |
+
" af_model._cfg.model.heads.distogram.num_bins = 39\n",
|
| 132 |
+
" af_model._model = af_model._get_model(af_model._cfg)\n",
|
| 133 |
+
" from colabdesign.af.weights import __file__ as af_path\n",
|
| 134 |
+
" template_dgram_head = np.load(os.path.join(os.path.dirname(af_path),'template_dgram_head.npy'))\n",
|
| 135 |
+
" for k in range(len(af_model._model_params)):\n",
|
| 136 |
+
" params = {\"weights\":jnp.array(template_dgram_head[k]),\"bias\":jnp.zeros(39)}\n",
|
| 137 |
+
" af_model._model_params[k][\"alphafold/alphafold_iteration/distogram_head/half_logits\"] = params\n",
|
| 138 |
+
" else:\n",
|
| 139 |
+
" dgram_map = np.eye(39)[np.repeat(np.append(0,np.arange(15)),4)]\n",
|
| 140 |
+
" dgram_map[-1,:] = 0 \n",
|
| 141 |
+
"\n",
|
| 142 |
+
"def get_dgram(positions, num_bins=39, min_bin=3.25, max_bin=50.75):\n",
|
| 143 |
+
" atom_idx = residue_constants.atom_order\n",
|
| 144 |
+
" atoms = {k:positions[...,atom_idx[k],:] for k in [\"N\",\"CA\",\"C\"]}\n",
|
| 145 |
+
" cb = _np_get_cb(**atoms, use_jax=False)\n",
|
| 146 |
+
" dist2 = np.square(cb[None,:] - cb[:,None]).sum(-1,keepdims=True)\n",
|
| 147 |
+
" lower_breaks = np.linspace(min_bin, max_bin, num_bins)\n",
|
| 148 |
+
" lower_breaks = np.square(lower_breaks)\n",
|
| 149 |
+
" upper_breaks = np.concatenate([lower_breaks[1:],np.array([1e8], dtype=jnp.float32)], axis=-1)\n",
|
| 150 |
+
" return ((dist2 > lower_breaks) * (dist2 < upper_breaks)).astype(float)"
|
| 151 |
+
]
|
| 152 |
+
},
|
| 153 |
+
{
|
| 154 |
+
"cell_type": "code",
|
| 155 |
+
"execution_count": null,
|
| 156 |
+
"metadata": {
|
| 157 |
+
"id": "3Dt8i00UbxtW",
|
| 158 |
+
"cellView": "form"
|
| 159 |
+
},
|
| 160 |
+
"outputs": [],
|
| 161 |
+
"source": [
|
| 162 |
+
"#@title run protocol\n",
|
| 163 |
+
"#@markdown Optimization options\n",
|
| 164 |
+
"iterations = 100 #@param [\"50\", \"100\"] {type:\"raw\"}\n",
|
| 165 |
+
"use_dgram_noise = True #@param {type:\"boolean\"}\n",
|
| 166 |
+
"use_seq_noise = True #@param {type:\"boolean\"}\n",
|
| 167 |
+
"use_dropout = True #@param {type:\"boolean\"}\n",
|
| 168 |
+
"seqsep_mask = 6 #@param {type:\"integer\"}\n",
|
| 169 |
+
"\n",
|
| 170 |
+
"#@markdown AlphaFold options\n",
|
| 171 |
+
"sample_models = True #@param {type:\"boolean\"}\n",
|
| 172 |
+
"num_recycles = 0 #@param [\"0\", \"1\", \"2\", \"3\"] {type:\"raw\"}\n",
|
| 173 |
+
"\n",
|
| 174 |
+
"#@markdown proteinMPNN options (set to `none` to disable)\n",
|
| 175 |
+
"mpnn_mode = \"conditional\" #@param [\"none\",\"sample\", \"conditional\", \"unconditional\"]\n",
|
| 176 |
+
"\n",
|
| 177 |
+
"L = sum(af_model._lengths)\n",
|
| 178 |
+
"af_model.restart(mode=\"gumbel\")\n",
|
| 179 |
+
"af_model._inputs[\"rm_template_seq\"] = True\n",
|
| 180 |
+
"\n",
|
| 181 |
+
"# gather info about inputs\n",
|
| 182 |
+
"if \"offset\" in af_model._inputs:\n",
|
| 183 |
+
" offset = af_model._inputs\n",
|
| 184 |
+
"else:\n",
|
| 185 |
+
" idx = af_model._inputs[\"residue_index\"]\n",
|
| 186 |
+
" offset = idx[:,None] - idx[None,:]\n",
|
| 187 |
+
"\n",
|
| 188 |
+
"# initialize sequence\n",
|
| 189 |
+
"if len(starting_seq) > 1:\n",
|
| 190 |
+
" af_model.set_seq(seq=starting_seq)\n",
|
| 191 |
+
"af_model._inputs[\"bias\"] = np.zeros((L,20))\n",
|
| 192 |
+
"\n",
|
| 193 |
+
"# initialize coordinates/dgram\n",
|
| 194 |
+
"af_model._inputs[\"batch\"] = {\"aatype\":np.zeros(L).astype(int),\n",
|
| 195 |
+
" \"all_atom_mask\":np.zeros((L,37)),\n",
|
| 196 |
+
" \"all_atom_positions\":np.zeros((L,37,3)),\n",
|
| 197 |
+
" \"dgram\":np.zeros((L,L,39))}\n",
|
| 198 |
+
"\n",
|
| 199 |
+
"for k in range(iterations):\n",
|
| 200 |
+
"\n",
|
| 201 |
+
" # disable stochastic part for the last 10 steps\n",
|
| 202 |
+
" if k > (iterations - 10):\n",
|
| 203 |
+
" use_dropout = False\n",
|
| 204 |
+
" sample_models = False\n",
|
| 205 |
+
" use_seq_noise = False\n",
|
| 206 |
+
" seqsep_mask = 0.0\n",
|
| 207 |
+
"\n",
|
| 208 |
+
" # noise\n",
|
| 209 |
+
" if k > 0:\n",
|
| 210 |
+
" dgram_xyz = get_dgram(xyz)\n",
|
| 211 |
+
" dgram_prob = softmax(dgram_logits,-1)\n",
|
| 212 |
+
"\n",
|
| 213 |
+
" if use_seq_noise:\n",
|
| 214 |
+
" af_model._inputs[\"bias\"] = 0.1 * sample_gumbel((L,20))\n",
|
| 215 |
+
"\n",
|
| 216 |
+
" if mode == \"xyz\":\n",
|
| 217 |
+
" dgram = dgram_xyz\n",
|
| 218 |
+
" if mode == \"dgram\":\n",
|
| 219 |
+
" dgram = dgram_prob @ dgram_map\n",
|
| 220 |
+
" dgram[...,14:] = dgram_xyz[...,14:] * dgram_prob[...,-1:]\n",
|
| 221 |
+
" if mode == \"dgram_retrain\":\n",
|
| 222 |
+
" dgram = dgram_prob\n",
|
| 223 |
+
" \n",
|
| 224 |
+
" if use_dgram_noise:\n",
|
| 225 |
+
" noise = sample_gumbel(dgram.shape) * (1 - k/iterations)\n",
|
| 226 |
+
" dgram = softmax(np.log(dgram + 1e-8) + noise, -1)\n",
|
| 227 |
+
"\n",
|
| 228 |
+
" # add mask to avoid local contacts being fixed (otherwise there is a bias toward helix)\n",
|
| 229 |
+
" mask = np.abs(offset) > seqsep_mask\n",
|
| 230 |
+
" af_model._inputs[\"batch\"][\"dgram\"] = dgram * mask[:,:,None]\n",
|
| 231 |
+
"\n",
|
| 232 |
+
" # denoise\n",
|
| 233 |
+
" aux = af_model.predict(return_aux=True, verbose=False,\n",
|
| 234 |
+
" sample_models=sample_models,\n",
|
| 235 |
+
" dropout=use_dropout, num_recycles=num_recycles)\n",
|
| 236 |
+
" plddt = aux[\"plddt\"]\n",
|
| 237 |
+
" seq = aux[\"seq\"][\"hard\"][0].argmax(-1)\n",
|
| 238 |
+
" xyz = aux[\"atom_positions\"].copy()\n",
|
| 239 |
+
" dgram_logits = aux[\"debug\"][\"outputs\"][\"distogram\"][\"logits\"] \n",
|
| 240 |
+
" \n",
|
| 241 |
+
" # update inputs \n",
|
| 242 |
+
" af_model._inputs[\"batch\"][\"aatype\"] = seq\n",
|
| 243 |
+
" af_model._inputs[\"batch\"][\"all_atom_mask\"][:,:4] = np.sqrt(plddt)[:,None]\n",
|
| 244 |
+
" af_model._inputs[\"batch\"][\"all_atom_positions\"] = xyz\n",
|
| 245 |
+
"\n",
|
| 246 |
+
" # add logits from proteinmpnn at each stage\n",
|
| 247 |
+
" if mpnn_mode != \"none\":\n",
|
| 248 |
+
" mpnn_model.get_af_inputs(af_model)\n",
|
| 249 |
+
" if mpnn_mode == \"sample\":\n",
|
| 250 |
+
" mpnn_out = mpnn_model.sample(temp = 1-k/iterations)\n",
|
| 251 |
+
" mpnn_logits = mpnn_out[\"logits\"][0,:,:20]\n",
|
| 252 |
+
" aux[\"log\"][\"mpnn\"] = mpnn_out[\"score\"][0]\n",
|
| 253 |
+
" else:\n",
|
| 254 |
+
" opt = {} if mpnn_mode == \"conditional\" else {\"ar_mask\":np.zeros((L,L))}\n",
|
| 255 |
+
" mpnn_out = mpnn_model.score(**opt)\n",
|
| 256 |
+
" mpnn_logits = mpnn_out[\"logits\"][:,:20]\n",
|
| 257 |
+
" aux[\"log\"][\"mpnn\"] = mpnn_out[\"score\"]\n",
|
| 258 |
+
" \n",
|
| 259 |
+
" beta = np.square(k/iterations) * plddt[:,None]\n",
|
| 260 |
+
" af_model._params[\"seq\"] = (1-beta) * af_model._params[\"seq\"] + beta * mpnn_logits\n",
|
| 261 |
+
"\n",
|
| 262 |
+
" # save results\n",
|
| 263 |
+
" af_model._save_results(aux)\n",
|
| 264 |
+
" af_model._k += 1"
|
| 265 |
+
]
|
| 266 |
+
},
|
| 267 |
+
{
|
| 268 |
+
"cell_type": "code",
|
| 269 |
+
"source": [
|
| 270 |
+
"af_model.save_pdb(\"0.pdb\")\n",
|
| 271 |
+
"af_model.plot_pdb()\n",
|
| 272 |
+
"af_model.get_seqs()"
|
| 273 |
+
],
|
| 274 |
+
"metadata": {
|
| 275 |
+
"id": "YeYD4KF8MUA_"
|
| 276 |
+
},
|
| 277 |
+
"execution_count": null,
|
| 278 |
+
"outputs": []
|
| 279 |
+
},
|
| 280 |
+
{
|
| 281 |
+
"cell_type": "code",
|
| 282 |
+
"execution_count": null,
|
| 283 |
+
"metadata": {
|
| 284 |
+
"id": "6cJhizcYcUxm"
|
| 285 |
+
},
|
| 286 |
+
"outputs": [],
|
| 287 |
+
"source": [
|
| 288 |
+
"HTML(af_model.animate(dpi=100))"
|
| 289 |
+
]
|
| 290 |
+
},
|
| 291 |
+
{
|
| 292 |
+
"cell_type": "code",
|
| 293 |
+
"source": [
|
| 294 |
+
"#@title sample new sequences using proteinMPNN and rescore with alphafold (w/o template)\n",
|
| 295 |
+
"#@markdown #### Design Options\n",
|
| 296 |
+
"num_seqs = 32 #@param [\"32\", \"64\", \"128\", \"256\", \"512\", \"1024\"] {type:\"raw\"}\n",
|
| 297 |
+
"sampling_temp = 0.1 \n",
|
| 298 |
+
"import pandas as pd\n",
|
| 299 |
+
"from google.colab import data_table\n",
|
| 300 |
+
"data_table.enable_dataframe_formatter()\n",
|
| 301 |
+
"\n",
|
| 302 |
+
"# zero out template inputs\n",
|
| 303 |
+
"out = mpnn_model.sample(num=num_seqs//32, batch=32,\n",
|
| 304 |
+
" temperature=sampling_temp)\n",
|
| 305 |
+
"af_terms = [\"plddt\",\"ptm\",\"pae\"]\n",
|
| 306 |
+
"for k in af_terms: out[k] = []\n",
|
| 307 |
+
"os.system(\"mkdir -p output/all_pdb\")\n",
|
| 308 |
+
"\n",
|
| 309 |
+
"af_model._inputs[\"batch\"][\"dgram\"] = np.zeros((L,L,39))\n",
|
| 310 |
+
"with tqdm.notebook.tqdm(total=out[\"S\"].shape[0], bar_format=TQDM_BAR_FORMAT) as pbar:\n",
|
| 311 |
+
" with open(\"design.fasta\",\"w\") as fasta:\n",
|
| 312 |
+
" for n in range(num_seqs):\n",
|
| 313 |
+
" seq = out[\"seq\"][n]\n",
|
| 314 |
+
" af_model.predict(seq=seq,\n",
|
| 315 |
+
" num_recycles=1,\n",
|
| 316 |
+
" num_models=1,\n",
|
| 317 |
+
" verbose=False)\n",
|
| 318 |
+
"\n",
|
| 319 |
+
" for t in af_terms:\n",
|
| 320 |
+
" out[t].append(af_model.aux[\"log\"][t])\n",
|
| 321 |
+
" out[\"pae\"][-1] = out[\"pae\"][-1] * 31\n",
|
| 322 |
+
" af_model._save_results(save_best=True, verbose=False)\n",
|
| 323 |
+
" af_model.save_current_pdb(f\"output/all_pdb/n{n}.pdb\")\n",
|
| 324 |
+
" af_model._k += 1\n",
|
| 325 |
+
"\n",
|
| 326 |
+
" line = f'>mpnn:{out[\"score\"][n]:.3f}_plddt:{out[\"plddt\"][n]:.3f}_ptm:{out[\"ptm\"][n]:.3f}_pae:{out[\"pae\"][n]:.3f}\\n{out[\"seq\"][n]}'\n",
|
| 327 |
+
" fasta.write(line+\"\\n\")\n",
|
| 328 |
+
" pbar.update(1)\n",
|
| 329 |
+
"\n",
|
| 330 |
+
"labels = [\"score\"] + af_terms + [\"seq\"]\n",
|
| 331 |
+
"data = [[out[k][n] for k in labels] for n in range(num_seqs)]\n",
|
| 332 |
+
"labels[0] = \"mpnn\"\n",
|
| 333 |
+
"\n",
|
| 334 |
+
"df = pd.DataFrame(data, columns=labels)\n",
|
| 335 |
+
"df.to_csv('output/mpnn_results.csv')\n",
|
| 336 |
+
"data_table.DataTable(df.round(3).sort_values(\"pae\"))"
|
| 337 |
+
],
|
| 338 |
+
"metadata": {
|
| 339 |
+
"cellView": "form",
|
| 340 |
+
"id": "3H_B0AoYIiWH"
|
| 341 |
+
},
|
| 342 |
+
"execution_count": null,
|
| 343 |
+
"outputs": []
|
| 344 |
+
},
|
| 345 |
+
{
|
| 346 |
+
"cell_type": "code",
|
| 347 |
+
"execution_count": null,
|
| 348 |
+
"metadata": {
|
| 349 |
+
"id": "v3dPQeEQcAcT"
|
| 350 |
+
},
|
| 351 |
+
"outputs": [],
|
| 352 |
+
"source": [
|
| 353 |
+
"af_model.save_pdb(\"1.pdb\")\n",
|
| 354 |
+
"af_model.plot_pdb()\n",
|
| 355 |
+
"af_model.get_seqs()"
|
| 356 |
+
]
|
| 357 |
+
}
|
| 358 |
+
],
|
| 359 |
+
"metadata": {
|
| 360 |
+
"accelerator": "GPU",
|
| 361 |
+
"colab": {
|
| 362 |
+
"provenance": [],
|
| 363 |
+
"include_colab_link": true
|
| 364 |
+
},
|
| 365 |
+
"gpuClass": "standard",
|
| 366 |
+
"kernelspec": {
|
| 367 |
+
"display_name": "Python 3",
|
| 368 |
+
"name": "python3"
|
| 369 |
+
},
|
| 370 |
+
"language_info": {
|
| 371 |
+
"name": "python"
|
| 372 |
+
}
|
| 373 |
+
},
|
| 374 |
+
"nbformat": 4,
|
| 375 |
+
"nbformat_minor": 0
|
| 376 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/af_pseudo_diffusion_recycle.ipynb
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/examples/af_pseudo_diffusion_recycle.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "markdown",
|
| 15 |
+
"metadata": {
|
| 16 |
+
"id": "VD9K5H2cnFxL"
|
| 17 |
+
},
|
| 18 |
+
"source": [
|
| 19 |
+
"#AF_pseudo_diffusion + proteinMPNN\n",
|
| 20 |
+
"Hacking AlphaFold to be a diffusion model (for backbone generation) via recycling mechanism. At each step add logits from proteinMPNN.\n",
|
| 21 |
+
"\n",
|
| 22 |
+
"\n",
|
| 23 |
+
"**WARNING**: This notebook is experimental, designed as a control. Not intended for practical use at this stage."
|
| 24 |
+
]
|
| 25 |
+
},
|
| 26 |
+
{
|
| 27 |
+
"cell_type": "code",
|
| 28 |
+
"execution_count": null,
|
| 29 |
+
"metadata": {
|
| 30 |
+
"cellView": "form",
|
| 31 |
+
"id": "YCRzPGdTZfEe"
|
| 32 |
+
},
|
| 33 |
+
"outputs": [],
|
| 34 |
+
"source": [
|
| 35 |
+
"#@title setup\n",
|
| 36 |
+
"%%time\n",
|
| 37 |
+
"import os\n",
|
| 38 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 39 |
+
" # get code\n",
|
| 40 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git@v1.1.1\")\n",
|
| 41 |
+
" # for debugging\n",
|
| 42 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 43 |
+
" # download params\n",
|
| 44 |
+
" os.system(\"mkdir params\")\n",
|
| 45 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 46 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar\")\n",
|
| 47 |
+
" os.system(\"tar -xf alphafold_params_2022-12-06.tar -C params\")\n",
|
| 48 |
+
"\n",
|
| 49 |
+
"import warnings\n",
|
| 50 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 51 |
+
"\n",
|
| 52 |
+
"import os, re\n",
|
| 53 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 54 |
+
"from colabdesign.mpnn import mk_mpnn_model\n",
|
| 55 |
+
"from colabdesign.af.alphafold.common import residue_constants\n",
|
| 56 |
+
"from colabdesign.shared.protein import _np_get_cb\n",
|
| 57 |
+
"\n",
|
| 58 |
+
"from IPython.display import HTML\n",
|
| 59 |
+
"from google.colab import files\n",
|
| 60 |
+
"import numpy as np\n",
|
| 61 |
+
"import jax.numpy as jnp\n",
|
| 62 |
+
"import jax\n",
|
| 63 |
+
"from scipy.special import softmax, log_softmax\n",
|
| 64 |
+
"\n",
|
| 65 |
+
"import tqdm.notebook\n",
|
| 66 |
+
"TQDM_BAR_FORMAT = '{l_bar}{bar}| {n_fmt}/{total_fmt} [elapsed: {elapsed} remaining: {remaining}]'\n",
|
| 67 |
+
"\n",
|
| 68 |
+
"def get_pdb(pdb_code=\"\"):\n",
|
| 69 |
+
" if pdb_code is None or pdb_code == \"\":\n",
|
| 70 |
+
" upload_dict = files.upload()\n",
|
| 71 |
+
" pdb_string = upload_dict[list(upload_dict.keys())[0]]\n",
|
| 72 |
+
" with open(\"tmp.pdb\",\"wb\") as out: out.write(pdb_string)\n",
|
| 73 |
+
" return \"tmp.pdb\"\n",
|
| 74 |
+
" elif os.path.isfile(pdb_code):\n",
|
| 75 |
+
" return pdb_code\n",
|
| 76 |
+
" elif len(pdb_code) == 4:\n",
|
| 77 |
+
" os.system(f\"wget -qnc https://files.rcsb.org/view/{pdb_code}.pdb\")\n",
|
| 78 |
+
" return f\"{pdb_code}.pdb\"\n",
|
| 79 |
+
" else:\n",
|
| 80 |
+
" os.system(f\"wget -qnc https://alphafold.ebi.ac.uk/files/AF-{pdb_code}-F1-model_v3.pdb\")\n",
|
| 81 |
+
" return f\"AF-{pdb_code}-F1-model_v3.pdb\"\n",
|
| 82 |
+
"\n",
|
| 83 |
+
"def sample_gumbel(shape, eps=1e-20): \n",
|
| 84 |
+
" \"\"\"Sample from Gumbel(0, 1)\"\"\"\n",
|
| 85 |
+
" U = np.random.uniform(size=shape)\n",
|
| 86 |
+
" return -np.log(-np.log(U + eps) + eps)"
|
| 87 |
+
]
|
| 88 |
+
},
|
| 89 |
+
{
|
| 90 |
+
"cell_type": "code",
|
| 91 |
+
"execution_count": null,
|
| 92 |
+
"metadata": {
|
| 93 |
+
"cellView": "form",
|
| 94 |
+
"id": "wxYMB4A9Zmrf"
|
| 95 |
+
},
|
| 96 |
+
"outputs": [],
|
| 97 |
+
"source": [
|
| 98 |
+
"#@title initialize the model\n",
|
| 99 |
+
"length = 100 #@param {type:\"integer\"}\n",
|
| 100 |
+
"#@markdown Provide a starting point (optional)\n",
|
| 101 |
+
"starting_seq = \"\" #@param {type:\"string\"}\n",
|
| 102 |
+
"starting_seq = re.sub(\"[^A-Z]\", \"\", starting_seq.upper())\n",
|
| 103 |
+
"#@markdown - if `starting_seq` provided the `length` option will be overwritten by length of starting sequence.\n",
|
| 104 |
+
"\n",
|
| 105 |
+
"if len(starting_seq) > 0:\n",
|
| 106 |
+
" length = len(starting_seq)\n",
|
| 107 |
+
"\n",
|
| 108 |
+
"clear_mem()\n",
|
| 109 |
+
"af_model = mk_afdesign_model(protocol=\"hallucination\")\n",
|
| 110 |
+
"af_model.prep_inputs(length=length)\n",
|
| 111 |
+
"mpnn_model = mk_mpnn_model()\n",
|
| 112 |
+
"\n",
|
| 113 |
+
"af_model_test = mk_afdesign_model(protocol=\"fixbb\", best_metric=\"rmsd\")\n",
|
| 114 |
+
"mpnn_model_test = mk_mpnn_model()\n",
|
| 115 |
+
"\n",
|
| 116 |
+
"print(\"lengths\",af_model._lengths)"
|
| 117 |
+
]
|
| 118 |
+
},
|
| 119 |
+
{
|
| 120 |
+
"cell_type": "code",
|
| 121 |
+
"execution_count": null,
|
| 122 |
+
"metadata": {
|
| 123 |
+
"id": "3Dt8i00UbxtW",
|
| 124 |
+
"cellView": "form"
|
| 125 |
+
},
|
| 126 |
+
"outputs": [],
|
| 127 |
+
"source": [
|
| 128 |
+
"#@title run protocol\n",
|
| 129 |
+
"#@markdown Optimization options\n",
|
| 130 |
+
"iterations = 100 #@param [\"50\", \"100\", \"200\"] {type:\"raw\"}\n",
|
| 131 |
+
"\n",
|
| 132 |
+
"#AlphaFold options\n",
|
| 133 |
+
"use_dropout = True\n",
|
| 134 |
+
"num_recycles = 0\n",
|
| 135 |
+
"\n",
|
| 136 |
+
"#@markdown proteinMPNN options (set to `none` to disable)\n",
|
| 137 |
+
"mpnn_mode = \"conditional\" #@param [\"none\",\"conditional\", \"unconditional\"]\n",
|
| 138 |
+
"\n",
|
| 139 |
+
"#@markdown proteinMPNN contact map masking options\n",
|
| 140 |
+
"cmap_seqsep = 6 #@param {type:\"raw\"}\n",
|
| 141 |
+
"cmap_num = 1 #@param {type:\"integer\"}\n",
|
| 142 |
+
"cmap_cutoff = 8 #@param {type:\"raw\"}\n",
|
| 143 |
+
"\n",
|
| 144 |
+
"L = sum(af_model._lengths)\n",
|
| 145 |
+
"af_model.restart(mode=\"gumbel\")\n",
|
| 146 |
+
"af_model._args[\"clear_prev\"] = False\n",
|
| 147 |
+
"af_model.set_opt(cmap_cutoff=cmap_cutoff)\n",
|
| 148 |
+
"af_model.set_weights(helix=1e-8)\n",
|
| 149 |
+
"\n",
|
| 150 |
+
"# gather info about inputs\n",
|
| 151 |
+
"if \"offset\" in af_model._inputs:\n",
|
| 152 |
+
" offset = af_model._inputs\n",
|
| 153 |
+
"else:\n",
|
| 154 |
+
" idx = af_model._inputs[\"residue_index\"]\n",
|
| 155 |
+
" offset = idx[:,None] - idx[None,:]\n",
|
| 156 |
+
"\n",
|
| 157 |
+
"# initialize sequence\n",
|
| 158 |
+
"if len(starting_seq) > 1:\n",
|
| 159 |
+
" af_model.set_seq(seq=starting_seq)\n",
|
| 160 |
+
"\n",
|
| 161 |
+
"# initialize coordinates\n",
|
| 162 |
+
"af_model._inputs.pop(\"prev\",None)\n",
|
| 163 |
+
"af_model._inputs[\"batch\"] = {\"aatype\":np.zeros(L).astype(int),\n",
|
| 164 |
+
" \"all_atom_mask\":np.zeros((L,37)),\n",
|
| 165 |
+
" \"all_atom_positions\":np.zeros((L,37,3))}\n",
|
| 166 |
+
"\n",
|
| 167 |
+
"save_best = False\n",
|
| 168 |
+
"for k in range(iterations):\n",
|
| 169 |
+
"\n",
|
| 170 |
+
" if k > (iterations - 10):\n",
|
| 171 |
+
" use_dropout = False\n",
|
| 172 |
+
" save_best = True\n",
|
| 173 |
+
"\n",
|
| 174 |
+
"\n",
|
| 175 |
+
" # denoise\n",
|
| 176 |
+
" aux = af_model.predict(return_aux=True, verbose=False,\n",
|
| 177 |
+
" dropout=use_dropout,\n",
|
| 178 |
+
" num_recycles=num_recycles)\n",
|
| 179 |
+
" af_model._inputs[\"prev\"] = aux[\"prev\"]\n",
|
| 180 |
+
" af_model._inputs[\"prev\"][\"prev_msa_first_row\"] *= 0\n",
|
| 181 |
+
" af_model._inputs[\"prev\"][\"prev_pos\"] *= 0\n",
|
| 182 |
+
"\n",
|
| 183 |
+
" # per position confidence\n",
|
| 184 |
+
" cmap = aux[\"cmap\"] * (np.abs(offset) > cmap_seqsep)\n",
|
| 185 |
+
" conf = np.sort(cmap)[:,-cmap_num:].mean(-1)\n",
|
| 186 |
+
"\n",
|
| 187 |
+
" # gather features\n",
|
| 188 |
+
" plddt = aux[\"plddt\"]\n",
|
| 189 |
+
" seq = aux[\"seq\"][\"hard\"][0].argmax(-1)\n",
|
| 190 |
+
" xyz = aux[\"atom_positions\"].copy()\n",
|
| 191 |
+
" \n",
|
| 192 |
+
" # update inputs \n",
|
| 193 |
+
" af_model._inputs[\"batch\"][\"aatype\"] = seq\n",
|
| 194 |
+
" af_model._inputs[\"batch\"][\"all_atom_positions\"] = xyz\n",
|
| 195 |
+
"\n",
|
| 196 |
+
" # add logits from proteinmpnn at each stage\n",
|
| 197 |
+
" if mpnn_mode != \"none\": \n",
|
| 198 |
+
" mpnn_model.get_af_inputs(af_model)\n",
|
| 199 |
+
" opt = {\"mask\":np.sqrt(conf)} \n",
|
| 200 |
+
" if mpnn_mode == \"unconditional\":\n",
|
| 201 |
+
" opt[\"ar_mask\"] = np.zeros((L,L))\n",
|
| 202 |
+
" mpnn_out = mpnn_model.score(**opt)\n",
|
| 203 |
+
" mpnn_logits = mpnn_out[\"logits\"][:,:20]\n",
|
| 204 |
+
" aux[\"log\"][\"mpnn\"] = mpnn_out[\"score\"]\n",
|
| 205 |
+
" \n",
|
| 206 |
+
" c = conf[:,None]\n",
|
| 207 |
+
" new_logits = (1 - c) * sample_gumbel(mpnn_logits.shape) + c * mpnn_logits\n",
|
| 208 |
+
" af_model._params[\"seq\"] = 0.9 * af_model._params[\"seq\"] + 0.1 * new_logits\n",
|
| 209 |
+
"\n",
|
| 210 |
+
" # save results\n",
|
| 211 |
+
" af_model._save_results(aux, save_best=save_best)\n",
|
| 212 |
+
" af_model._k += 1\n",
|
| 213 |
+
"\n",
|
| 214 |
+
"af_model.save_pdb(\"init.pdb\")"
|
| 215 |
+
]
|
| 216 |
+
},
|
| 217 |
+
{
|
| 218 |
+
"cell_type": "code",
|
| 219 |
+
"execution_count": null,
|
| 220 |
+
"metadata": {
|
| 221 |
+
"id": "YeYD4KF8MUA_"
|
| 222 |
+
},
|
| 223 |
+
"outputs": [],
|
| 224 |
+
"source": [
|
| 225 |
+
"af_model.plot_pdb()\n",
|
| 226 |
+
"af_model.get_seqs()"
|
| 227 |
+
]
|
| 228 |
+
},
|
| 229 |
+
{
|
| 230 |
+
"cell_type": "code",
|
| 231 |
+
"execution_count": null,
|
| 232 |
+
"metadata": {
|
| 233 |
+
"id": "6cJhizcYcUxm"
|
| 234 |
+
},
|
| 235 |
+
"outputs": [],
|
| 236 |
+
"source": [
|
| 237 |
+
"HTML(af_model.animate(dpi=100))"
|
| 238 |
+
]
|
| 239 |
+
},
|
| 240 |
+
{
|
| 241 |
+
"cell_type": "code",
|
| 242 |
+
"execution_count": null,
|
| 243 |
+
"metadata": {
|
| 244 |
+
"cellView": "form",
|
| 245 |
+
"id": "3H_B0AoYIiWH"
|
| 246 |
+
},
|
| 247 |
+
"outputs": [],
|
| 248 |
+
"source": [
|
| 249 |
+
"#@title sample new sequences using proteinMPNN and rescore with alphafold (w/o template)\n",
|
| 250 |
+
"#@markdown #### MPNN Options\n",
|
| 251 |
+
"num_seqs = 16 #@param [\"8\", \"16\", \"32\", \"64\", \"128\", \"256\", \"512\", \"1024\"] {type:\"raw\"}\n",
|
| 252 |
+
"sampling_temp = 0.1 \n",
|
| 253 |
+
"#@markdown #### AlphaFold Options\n",
|
| 254 |
+
"alphafold_model = \"model_4_ptm\" #@param [\"model_1_ptm\", \"model_2_ptm\", \"model_3_ptm\", \"model_4_ptm\", \"model_5_ptm\"]\n",
|
| 255 |
+
"num_recycles = 3 #@param [\"0\", \"1\", \"2\", \"3\"] {type:\"raw\"}\n",
|
| 256 |
+
"import pandas as pd\n",
|
| 257 |
+
"\n",
|
| 258 |
+
"# zero out template inputs\n",
|
| 259 |
+
"af_model_test.prep_inputs(\"init.pdb\")\n",
|
| 260 |
+
"mpnn_model_test.get_af_inputs(af_model_test)\n",
|
| 261 |
+
"out = mpnn_model_test.sample(num=num_seqs//8, batch=8,\n",
|
| 262 |
+
" temperature=sampling_temp)\n",
|
| 263 |
+
"af_terms = [\"plddt\",\"ptm\",\"pae\",\"rmsd\",\"dgram_cce\"]\n",
|
| 264 |
+
"for k in af_terms: out[k] = []\n",
|
| 265 |
+
"os.system(\"mkdir -p output/all_pdb\")\n",
|
| 266 |
+
"\n",
|
| 267 |
+
"with tqdm.notebook.tqdm(total=out[\"S\"].shape[0], bar_format=TQDM_BAR_FORMAT) as pbar:\n",
|
| 268 |
+
" with open(\"design.fasta\",\"w\") as fasta:\n",
|
| 269 |
+
" for n in range(num_seqs):\n",
|
| 270 |
+
" seq = out[\"seq\"][n]\n",
|
| 271 |
+
" af_model_test.predict(seq=seq,\n",
|
| 272 |
+
" num_recycles=num_recycles,\n",
|
| 273 |
+
" num_models=1,\n",
|
| 274 |
+
" verbose=False,\n",
|
| 275 |
+
" models=alphafold_model)\n",
|
| 276 |
+
"\n",
|
| 277 |
+
" for t in af_terms:\n",
|
| 278 |
+
" out[t].append(af_model_test.aux[\"log\"][t])\n",
|
| 279 |
+
" out[\"pae\"][-1] = out[\"pae\"][-1] * 31\n",
|
| 280 |
+
" af_model_test._save_results(save_best=True, verbose=False)\n",
|
| 281 |
+
" af_model_test.save_current_pdb(f\"output/all_pdb/n{n}.pdb\")\n",
|
| 282 |
+
" af_model_test._k += 1\n",
|
| 283 |
+
"\n",
|
| 284 |
+
" line = f'>mpnn:{out[\"score\"][n]:.3f}_plddt:{out[\"plddt\"][n]:.3f}_ptm:{out[\"ptm\"][n]:.3f}_pae:{out[\"pae\"][n]:.3f}\\n{out[\"seq\"][n]}'\n",
|
| 285 |
+
" fasta.write(line+\"\\n\")\n",
|
| 286 |
+
" pbar.update(1)\n",
|
| 287 |
+
"\n",
|
| 288 |
+
"af_model_test.save_pdb(\"final.pdb\")\n",
|
| 289 |
+
"\n",
|
| 290 |
+
"labels = [\"score\"] + af_terms + [\"seq\"]\n",
|
| 291 |
+
"data = [[out[k][n] for k in labels] for n in range(num_seqs)]\n",
|
| 292 |
+
"labels[0] = \"mpnn\"\n",
|
| 293 |
+
"\n",
|
| 294 |
+
"df = pd.DataFrame(data, columns=labels)\n",
|
| 295 |
+
"df.to_csv('output/mpnn_results.csv')\n",
|
| 296 |
+
"df.round(3).sort_values(\"rmsd\")"
|
| 297 |
+
]
|
| 298 |
+
},
|
| 299 |
+
{
|
| 300 |
+
"cell_type": "code",
|
| 301 |
+
"execution_count": null,
|
| 302 |
+
"metadata": {
|
| 303 |
+
"id": "v3dPQeEQcAcT"
|
| 304 |
+
},
|
| 305 |
+
"outputs": [],
|
| 306 |
+
"source": [
|
| 307 |
+
"af_model_test.plot_pdb()\n",
|
| 308 |
+
"af_model_test.get_seqs()"
|
| 309 |
+
]
|
| 310 |
+
}
|
| 311 |
+
],
|
| 312 |
+
"metadata": {
|
| 313 |
+
"accelerator": "GPU",
|
| 314 |
+
"colab": {
|
| 315 |
+
"provenance": [],
|
| 316 |
+
"include_colab_link": true
|
| 317 |
+
},
|
| 318 |
+
"gpuClass": "standard",
|
| 319 |
+
"kernelspec": {
|
| 320 |
+
"display_name": "Python 3",
|
| 321 |
+
"name": "python3"
|
| 322 |
+
},
|
| 323 |
+
"language_info": {
|
| 324 |
+
"name": "python"
|
| 325 |
+
}
|
| 326 |
+
},
|
| 327 |
+
"nbformat": 4,
|
| 328 |
+
"nbformat_minor": 0
|
| 329 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/af_relax_design.ipynb
ADDED
|
@@ -0,0 +1,400 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/main/af/examples/af_relax_design.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "markdown",
|
| 15 |
+
"metadata": {
|
| 16 |
+
"id": "OA2k3sAYuiXe"
|
| 17 |
+
},
|
| 18 |
+
"source": [
|
| 19 |
+
"#af_relax_design (WIP)\n",
|
| 20 |
+
"\n",
|
| 21 |
+
"\n",
|
| 22 |
+
"**Efficient and scalable de novo protein design using a relaxed sequence space**\n",
|
| 23 |
+
"\n",
|
| 24 |
+
"Christopher Josef Frank, Ali Khoshouei, Yosta de Stigter, Dominik Schiewitz, Shihao Feng, Sergey Ovchinnikov, Hendrik Dietz\n",
|
| 25 |
+
"\n",
|
| 26 |
+
"doi: https://doi.org/10.1101/2023.02.24.529906\n",
|
| 27 |
+
"\n",
|
| 28 |
+
"**<font color=\"red\">WARNING</font>** This notebook is in development, we are still working on adding all the options from the manuscript above."
|
| 29 |
+
]
|
| 30 |
+
},
|
| 31 |
+
{
|
| 32 |
+
"cell_type": "code",
|
| 33 |
+
"execution_count": null,
|
| 34 |
+
"metadata": {
|
| 35 |
+
"cellView": "form",
|
| 36 |
+
"id": "-AXy0s_4cKaK"
|
| 37 |
+
},
|
| 38 |
+
"outputs": [],
|
| 39 |
+
"source": [
|
| 40 |
+
"#@title setup\n",
|
| 41 |
+
"%%time\n",
|
| 42 |
+
"import os\n",
|
| 43 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 44 |
+
" # get code\n",
|
| 45 |
+
" os.system(\"pip -q install pyppeteer nest_asyncio\")\n",
|
| 46 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git\")\n",
|
| 47 |
+
" # for debugging\n",
|
| 48 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 49 |
+
" # download params\n",
|
| 50 |
+
" os.system(\"mkdir params\")\n",
|
| 51 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 52 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar\")\n",
|
| 53 |
+
" os.system(\"tar -xf alphafold_params_2022-12-06.tar -C params\")\n",
|
| 54 |
+
"\n",
|
| 55 |
+
"import warnings\n",
|
| 56 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 57 |
+
"\n",
|
| 58 |
+
"import os\n",
|
| 59 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 60 |
+
"from colabdesign.mpnn import mk_mpnn_model\n",
|
| 61 |
+
"\n",
|
| 62 |
+
"from IPython.display import HTML\n",
|
| 63 |
+
"from google.colab import files\n",
|
| 64 |
+
"import numpy as np\n",
|
| 65 |
+
"\n",
|
| 66 |
+
"import requests, time\n",
|
| 67 |
+
"if not os.path.isfile(\"TMscore\"):\n",
|
| 68 |
+
" os.system(\"wget -qnc https://zhanggroup.org/TM-score/TMscore.cpp\")\n",
|
| 69 |
+
" os.system(\"g++ -static -O3 -ffast-math -lm -o TMscore TMscore.cpp\")\n",
|
| 70 |
+
"def tmscore(x,y):\n",
|
| 71 |
+
" # pass to TMscore\n",
|
| 72 |
+
" output = os.popen(f'./TMscore {x} {y}')\n",
|
| 73 |
+
" # parse outputs\n",
|
| 74 |
+
" parse_float = lambda x: float(x.split(\"=\")[1].split()[0])\n",
|
| 75 |
+
" o = {}\n",
|
| 76 |
+
" for line in output:\n",
|
| 77 |
+
" line = line.rstrip()\n",
|
| 78 |
+
" if line.startswith(\"RMSD\"): o[\"rms\"] = parse_float(line)\n",
|
| 79 |
+
" if line.startswith(\"TM-score\"): o[\"tms\"] = parse_float(line)\n",
|
| 80 |
+
" if line.startswith(\"GDT-TS-score\"): o[\"gdt\"] = parse_float(line)\n",
|
| 81 |
+
" return o\n",
|
| 82 |
+
"\n",
|
| 83 |
+
"import asyncio\n",
|
| 84 |
+
"import nest_asyncio\n",
|
| 85 |
+
"from pyppeteer import launch\n",
|
| 86 |
+
"import base64\n",
|
| 87 |
+
"\n",
|
| 88 |
+
"# Apply nest_asyncio to enable nested event loops\n",
|
| 89 |
+
"nest_asyncio.apply()\n",
|
| 90 |
+
"\n",
|
| 91 |
+
"async def fetch_blob_content(page, blob_url):\n",
|
| 92 |
+
" blob_to_base64 = \"\"\"\n",
|
| 93 |
+
" async (blobUrl) => {\n",
|
| 94 |
+
" const blob = await fetch(blobUrl).then(r => r.blob());\n",
|
| 95 |
+
" return new Promise((resolve) => {\n",
|
| 96 |
+
" const reader = new FileReader();\n",
|
| 97 |
+
" reader.onloadend = () => resolve(reader.result);\n",
|
| 98 |
+
" reader.readAsDataURL(blob);\n",
|
| 99 |
+
" });\n",
|
| 100 |
+
" }\n",
|
| 101 |
+
" \"\"\"\n",
|
| 102 |
+
" base64_data = await page.evaluate(blob_to_base64, blob_url)\n",
|
| 103 |
+
" _, encoded = base64_data.split(',', 1)\n",
|
| 104 |
+
" return base64.b64decode(encoded)\n",
|
| 105 |
+
"\n",
|
| 106 |
+
"async def extract_pdb_file_download_link_and_content(url):\n",
|
| 107 |
+
" browser = await launch(headless=True, args=['--no-sandbox', '--disable-setuid-sandbox'])\n",
|
| 108 |
+
" page = await browser.newPage()\n",
|
| 109 |
+
" await page.goto(url, {'waitUntil': 'networkidle0'})\n",
|
| 110 |
+
" elements = await page.querySelectorAll('a.btn.bg-purple')\n",
|
| 111 |
+
" for element in elements:\n",
|
| 112 |
+
" href = await page.evaluate('(element) => element.getAttribute(\"href\")', element)\n",
|
| 113 |
+
" if 'blob:https://esmatlas.com/' in href:\n",
|
| 114 |
+
" content = await fetch_blob_content(page, href)\n",
|
| 115 |
+
" await browser.close()\n",
|
| 116 |
+
" return href, content\n",
|
| 117 |
+
" await browser.close()\n",
|
| 118 |
+
" return \"No PDB file link found.\", None\n",
|
| 119 |
+
"\n",
|
| 120 |
+
"def esmfold_api(sequence):\n",
|
| 121 |
+
" url = f'https://esmatlas.com/resources/fold/result?fasta_header=%3Eunnamed&sequence={sequence}'\n",
|
| 122 |
+
" result = asyncio.get_event_loop().run_until_complete(extract_pdb_file_download_link_and_content(url))\n",
|
| 123 |
+
" if result[1]:\n",
|
| 124 |
+
" pdb_str = result[1].decode('utf-8')\n",
|
| 125 |
+
" return pdb_str\n",
|
| 126 |
+
" else:\n",
|
| 127 |
+
" return \"Failed to retrieve PDB content.\"\n",
|
| 128 |
+
"\n",
|
| 129 |
+
"import jax\n",
|
| 130 |
+
"import jax.numpy as jnp\n",
|
| 131 |
+
"from colabdesign.af.alphafold.common import residue_constants"
|
| 132 |
+
]
|
| 133 |
+
},
|
| 134 |
+
{
|
| 135 |
+
"cell_type": "code",
|
| 136 |
+
"execution_count": null,
|
| 137 |
+
"metadata": {
|
| 138 |
+
"id": "sZnYfCbfEvol",
|
| 139 |
+
"cellView": "form"
|
| 140 |
+
},
|
| 141 |
+
"outputs": [],
|
| 142 |
+
"source": [
|
| 143 |
+
"#@title # hallucination\n",
|
| 144 |
+
"#@markdown For a given length, generate/hallucinate a protein sequence that AlphaFold thinks folds into a well structured protein (high plddt, low pae, many contacts).\n",
|
| 145 |
+
"LENGTH = 100 #@param {type:\"integer\"}\n",
|
| 146 |
+
"COPIES = 1 #@param [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"] {type:\"raw\"}\n",
|
| 147 |
+
"MODE = \"manuscript\" #@param [\"original\", \"manuscript\"]\n",
|
| 148 |
+
"use_rg_loss = True #@param {type:\"boolean\"}\n",
|
| 149 |
+
"\n",
|
| 150 |
+
"#@markdown ProteinMPNN Settings\n",
|
| 151 |
+
"use_mpnn_loss = False #@param {type:\"boolean\"}\n",
|
| 152 |
+
"use_solubleMPNN = False #@param {type:\"boolean\"}\n",
|
| 153 |
+
"#@markdown\n",
|
| 154 |
+
"\n",
|
| 155 |
+
"def add_rg_loss(self, weight=0.1):\n",
|
| 156 |
+
" '''add radius of gyration loss'''\n",
|
| 157 |
+
" def loss_fn(inputs, outputs):\n",
|
| 158 |
+
" xyz = outputs[\"structure_module\"]\n",
|
| 159 |
+
" ca = xyz[\"final_atom_positions\"][:,residue_constants.atom_order[\"CA\"]]\n",
|
| 160 |
+
" if self.protocol == \"binder\":\n",
|
| 161 |
+
" ca = ca[-self._binder_len:]\n",
|
| 162 |
+
" if MODE == \"manuscript\":\n",
|
| 163 |
+
" ca = ca[::5]\n",
|
| 164 |
+
" rg = jnp.sqrt(jnp.square(ca - ca.mean(0)).sum(-1).mean() + 1e-8)\n",
|
| 165 |
+
" if MODE == \"original\":\n",
|
| 166 |
+
" rg_th = 2.38 * ca.shape[0] ** 0.365\n",
|
| 167 |
+
" rg = jax.nn.elu(rg - rg_th)\n",
|
| 168 |
+
" return {\"rg\":rg}\n",
|
| 169 |
+
" self._callbacks[\"model\"][\"loss\"].append(loss_fn)\n",
|
| 170 |
+
" self.opt[\"weights\"][\"rg\"] = weight\n",
|
| 171 |
+
"\n",
|
| 172 |
+
"def add_mpnn_loss(self, mpnn=0.1, mpnn_seq=0.0):\n",
|
| 173 |
+
" '''\n",
|
| 174 |
+
" add mpnn loss\n",
|
| 175 |
+
" mpnn = maximize confidence of proteinmpnn\n",
|
| 176 |
+
" mpnn_seq = push designed sequence to match proteinmpnn logits\n",
|
| 177 |
+
" '''\n",
|
| 178 |
+
"\n",
|
| 179 |
+
" self._mpnn = mk_mpnn_model(weights = \"soluble\" if use_solubleMPNN else \"original\")\n",
|
| 180 |
+
" def loss_fn(inputs, outputs, aux, key):\n",
|
| 181 |
+
"\n",
|
| 182 |
+
" # get structure\n",
|
| 183 |
+
" atom_idx = tuple(residue_constants.atom_order[k] for k in [\"N\",\"CA\",\"C\",\"O\"])\n",
|
| 184 |
+
" I = {\"S\": inputs[\"aatype\"],\n",
|
| 185 |
+
" \"residue_idx\": inputs[\"residue_index\"],\n",
|
| 186 |
+
" \"chain_idx\": inputs[\"asym_id\"],\n",
|
| 187 |
+
" \"X\": outputs[\"structure_module\"][\"final_atom_positions\"][:,atom_idx],\n",
|
| 188 |
+
" \"mask\": outputs[\"structure_module\"][\"final_atom_mask\"][:,1],\n",
|
| 189 |
+
" \"lengths\": self._lengths,\n",
|
| 190 |
+
" \"key\": key}\n",
|
| 191 |
+
"\n",
|
| 192 |
+
" if \"offset\" in inputs:\n",
|
| 193 |
+
" I[\"offset\"] = inputs[\"offset\"]\n",
|
| 194 |
+
"\n",
|
| 195 |
+
" # set autoregressive mask\n",
|
| 196 |
+
" L = sum(self._lengths)\n",
|
| 197 |
+
" if self.protocol == \"binder\":\n",
|
| 198 |
+
" I[\"ar_mask\"] = 1 - np.eye(L)\n",
|
| 199 |
+
" I[\"ar_mask\"][-self._len:,-self._len:] = 0\n",
|
| 200 |
+
" else:\n",
|
| 201 |
+
" I[\"ar_mask\"] = np.zeros((L,L))\n",
|
| 202 |
+
"\n",
|
| 203 |
+
" # get logits\n",
|
| 204 |
+
" logits = self._mpnn._score(**I)[\"logits\"][:,:20]\n",
|
| 205 |
+
" if self.protocol == \"binder\":\n",
|
| 206 |
+
" logits = logits[-self._len:]\n",
|
| 207 |
+
" else:\n",
|
| 208 |
+
" logits = logits[:self._len]\n",
|
| 209 |
+
" aux[\"mpnn_logits\"] = logits\n",
|
| 210 |
+
"\n",
|
| 211 |
+
" # compute loss\n",
|
| 212 |
+
" log_q = jax.nn.log_softmax(logits)\n",
|
| 213 |
+
" p = inputs[\"seq\"][\"hard\"]\n",
|
| 214 |
+
" q = jax.nn.softmax(logits)\n",
|
| 215 |
+
" losses = {}\n",
|
| 216 |
+
" losses[\"mpnn\"] = -log_q.max(-1).mean()\n",
|
| 217 |
+
" losses[\"mpnn_seq\"] = -(p * jax.lax.stop_gradient(log_q)).sum(-1).mean()\n",
|
| 218 |
+
" return losses\n",
|
| 219 |
+
"\n",
|
| 220 |
+
" self._callbacks[\"model\"][\"loss\"].append(loss_fn)\n",
|
| 221 |
+
" self.opt[\"weights\"][\"mpnn\"] = mpnn\n",
|
| 222 |
+
" self.opt[\"weights\"][\"mpnn_seq\"] = mpnn_seq\n",
|
| 223 |
+
"\n",
|
| 224 |
+
"clear_mem()\n",
|
| 225 |
+
"af_model = mk_afdesign_model(protocol=\"hallucination\")\n",
|
| 226 |
+
"af_model.prep_inputs(length=LENGTH, copies=COPIES)\n",
|
| 227 |
+
"\n",
|
| 228 |
+
"# add extra losses\n",
|
| 229 |
+
"if use_rg_loss: add_rg_loss(af_model)\n",
|
| 230 |
+
"if use_mpnn_loss: add_mpnn_loss(af_model)\n",
|
| 231 |
+
"\n",
|
| 232 |
+
"print(\"length\",af_model._lengths)\n",
|
| 233 |
+
"print(\"weights\",af_model.opt[\"weights\"])"
|
| 234 |
+
]
|
| 235 |
+
},
|
| 236 |
+
{
|
| 237 |
+
"cell_type": "code",
|
| 238 |
+
"source": [
|
| 239 |
+
"af_model.restart()\n",
|
| 240 |
+
"if MODE == \"original\":\n",
|
| 241 |
+
" # pre-design with gumbel initialization and softmax activation\n",
|
| 242 |
+
" af_model.set_weights(plddt=0.0, pae=0.0)\n",
|
| 243 |
+
" af_model.set_seq(mode=[\"gumbel\"])\n",
|
| 244 |
+
" af_model.design_soft(50)\n",
|
| 245 |
+
" af_model.set_seq(af_model.aux[\"seq\"][\"pseudo\"])\n",
|
| 246 |
+
"\n",
|
| 247 |
+
"if MODE == \"manuscript\":\n",
|
| 248 |
+
" af_model.set_seq(mode=[\"gumbel\",\"soft\"])\n",
|
| 249 |
+
"\n",
|
| 250 |
+
"af_model.set_weights(plddt=1.0, pae=1.0)\n",
|
| 251 |
+
"af_model.design_logits(40)\n",
|
| 252 |
+
"af_model.design_logits(10, save_best=True)"
|
| 253 |
+
],
|
| 254 |
+
"metadata": {
|
| 255 |
+
"id": "f76xqCkw0vj9"
|
| 256 |
+
},
|
| 257 |
+
"execution_count": null,
|
| 258 |
+
"outputs": []
|
| 259 |
+
},
|
| 260 |
+
{
|
| 261 |
+
"cell_type": "code",
|
| 262 |
+
"execution_count": null,
|
| 263 |
+
"metadata": {
|
| 264 |
+
"id": "A1GxeLZdTTya"
|
| 265 |
+
},
|
| 266 |
+
"outputs": [],
|
| 267 |
+
"source": [
|
| 268 |
+
"af_model.save_pdb(f\"{af_model.protocol}.pdb\")\n",
|
| 269 |
+
"af_model.plot_pdb()"
|
| 270 |
+
]
|
| 271 |
+
},
|
| 272 |
+
{
|
| 273 |
+
"cell_type": "code",
|
| 274 |
+
"execution_count": null,
|
| 275 |
+
"metadata": {
|
| 276 |
+
"id": "L2E9Tn2Acchj"
|
| 277 |
+
},
|
| 278 |
+
"outputs": [],
|
| 279 |
+
"source": [
|
| 280 |
+
"HTML(af_model.animate())"
|
| 281 |
+
]
|
| 282 |
+
},
|
| 283 |
+
{
|
| 284 |
+
"cell_type": "code",
|
| 285 |
+
"execution_count": null,
|
| 286 |
+
"metadata": {
|
| 287 |
+
"id": "YSKWYu0_GlUH"
|
| 288 |
+
},
|
| 289 |
+
"outputs": [],
|
| 290 |
+
"source": [
|
| 291 |
+
"af_model.get_seqs()"
|
| 292 |
+
]
|
| 293 |
+
},
|
| 294 |
+
{
|
| 295 |
+
"cell_type": "code",
|
| 296 |
+
"source": [
|
| 297 |
+
"#@markdown #Redesign with ProteinMPNN\n",
|
| 298 |
+
"num_seqs = 8 #@param [\"8\", \"16\", \"32\", \"64\"] {type:\"raw\"}\n",
|
| 299 |
+
"mpnn_sampling_temp = 0.1 #@param [\"0.0001\", \"0.1\", \"0.15\", \"0.2\", \"0.25\", \"0.3\", \"0.5\", \"1.0\"] {type:\"raw\"}\n",
|
| 300 |
+
"rm_aa = \"C\" #@param {type:\"string\"}\n",
|
| 301 |
+
"use_solubleMPNN = False #@param {type:\"boolean\"}\n",
|
| 302 |
+
"#@markdown - `mpnn_sampling_temp` - control diversity of sampled sequences. (higher = more diverse).\n",
|
| 303 |
+
"#@markdown - `rm_aa='C'` - do not use [C]ysteines.\n",
|
| 304 |
+
"#@markdown - `use_solubleMPNN` - use weights trained only on soluble proteins. See [preprint](https://www.biorxiv.org/content/10.1101/2023.05.09.540044v2).\n",
|
| 305 |
+
"#@markdown"
|
| 306 |
+
],
|
| 307 |
+
"metadata": {
|
| 308 |
+
"cellView": "form",
|
| 309 |
+
"id": "m2qAYsDsCfqJ"
|
| 310 |
+
},
|
| 311 |
+
"execution_count": null,
|
| 312 |
+
"outputs": []
|
| 313 |
+
},
|
| 314 |
+
{
|
| 315 |
+
"cell_type": "code",
|
| 316 |
+
"source": [
|
| 317 |
+
"from colabdesign.shared.protein import alphabet_list as chain_list\n",
|
| 318 |
+
"mpnn_model = mk_mpnn_model()\n",
|
| 319 |
+
"mpnn_model.prep_inputs(pdb_filename=f\"{af_model.protocol}.pdb\",\n",
|
| 320 |
+
" chain=\",\".join(chain_list[:COPIES]),\n",
|
| 321 |
+
" homooligmer=COPIES>1,\n",
|
| 322 |
+
" rm_aa=rm_aa,\n",
|
| 323 |
+
" weights = \"soluble\" if use_solubleMPNN else\"original\")\n",
|
| 324 |
+
"out = mpnn_model.sample(num=num_seqs//8,\n",
|
| 325 |
+
" batch=8,\n",
|
| 326 |
+
" temperature=mpnn_sampling_temp)\n",
|
| 327 |
+
"for seq,score in zip(out[\"seq\"],out[\"score\"]):\n",
|
| 328 |
+
" print(score,seq.split(\"/\")[0])"
|
| 329 |
+
],
|
| 330 |
+
"metadata": {
|
| 331 |
+
"id": "uQa0FAp7bGQo"
|
| 332 |
+
},
|
| 333 |
+
"execution_count": null,
|
| 334 |
+
"outputs": []
|
| 335 |
+
},
|
| 336 |
+
{
|
| 337 |
+
"cell_type": "markdown",
|
| 338 |
+
"source": [
|
| 339 |
+
"#Run ESMfold"
|
| 340 |
+
],
|
| 341 |
+
"metadata": {
|
| 342 |
+
"id": "eDvyemgjNbX4"
|
| 343 |
+
}
|
| 344 |
+
},
|
| 345 |
+
{
|
| 346 |
+
"cell_type": "code",
|
| 347 |
+
"source": [
|
| 348 |
+
"print(\"# rmsd tmscore sequence\")\n",
|
| 349 |
+
"best = {}\n",
|
| 350 |
+
"best_rmsd = None\n",
|
| 351 |
+
"for n,seq in enumerate(out[\"seq\"]):\n",
|
| 352 |
+
" x = seq.split(\"/\")[0]\n",
|
| 353 |
+
" with open(f\"{af_model.protocol}.esmfold.{n}.pdb\",\"w\") as handle:\n",
|
| 354 |
+
" pdb_str = esmfold_api(x)\n",
|
| 355 |
+
" handle.write(pdb_str)\n",
|
| 356 |
+
" o = tmscore(f\"{af_model.protocol}.pdb\",\n",
|
| 357 |
+
" f\"{af_model.protocol}.esmfold.{n}.pdb\")\n",
|
| 358 |
+
" print(n,o[\"rms\"],o[\"tms\"],x)\n",
|
| 359 |
+
" if best_rmsd is None or o[\"rms\"] < best_rmsd:\n",
|
| 360 |
+
" best_rmsd = o[\"rms\"]\n",
|
| 361 |
+
" best = {**o,\"seq\":x}"
|
| 362 |
+
],
|
| 363 |
+
"metadata": {
|
| 364 |
+
"id": "Ey29NmNAFtK0"
|
| 365 |
+
},
|
| 366 |
+
"execution_count": null,
|
| 367 |
+
"outputs": []
|
| 368 |
+
},
|
| 369 |
+
{
|
| 370 |
+
"cell_type": "code",
|
| 371 |
+
"source": [
|
| 372 |
+
"best"
|
| 373 |
+
],
|
| 374 |
+
"metadata": {
|
| 375 |
+
"id": "ltH6cLw5NhuX"
|
| 376 |
+
},
|
| 377 |
+
"execution_count": null,
|
| 378 |
+
"outputs": []
|
| 379 |
+
}
|
| 380 |
+
],
|
| 381 |
+
"metadata": {
|
| 382 |
+
"accelerator": "GPU",
|
| 383 |
+
"colab": {
|
| 384 |
+
"collapsed_sections": [
|
| 385 |
+
"q4qiU9I0QHSz"
|
| 386 |
+
],
|
| 387 |
+
"provenance": [],
|
| 388 |
+
"include_colab_link": true
|
| 389 |
+
},
|
| 390 |
+
"kernelspec": {
|
| 391 |
+
"display_name": "Python 3",
|
| 392 |
+
"name": "python3"
|
| 393 |
+
},
|
| 394 |
+
"language_info": {
|
| 395 |
+
"name": "python"
|
| 396 |
+
}
|
| 397 |
+
},
|
| 398 |
+
"nbformat": 4,
|
| 399 |
+
"nbformat_minor": 0
|
| 400 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/af_single_sequential.ipynb
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/examples/af_single_sequential.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "code",
|
| 15 |
+
"execution_count": null,
|
| 16 |
+
"metadata": {
|
| 17 |
+
"cellView": "form",
|
| 18 |
+
"id": "-AXy0s_4cKaK"
|
| 19 |
+
},
|
| 20 |
+
"outputs": [],
|
| 21 |
+
"source": [
|
| 22 |
+
"#@title af_single_sequential\n",
|
| 23 |
+
"#@markdown implementing [@MartinPacesa](https://twitter.com/MartinPacesa/status/1640005299124707328)'s idea\n",
|
| 24 |
+
"import os\n",
|
| 25 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 26 |
+
" print(\"installing AlphaFold...\")\n",
|
| 27 |
+
" # get code\n",
|
| 28 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git@v1.1.1\")\n",
|
| 29 |
+
" # for debugging\n",
|
| 30 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 31 |
+
" print(\"downloading AlphaFold params...\")\n",
|
| 32 |
+
" # download params\n",
|
| 33 |
+
" os.system(\"mkdir params\")\n",
|
| 34 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 35 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-03-02.tar\")\n",
|
| 36 |
+
" os.system(\"tar -xf alphafold_params_2022-03-02.tar -C params\")\n",
|
| 37 |
+
"\n",
|
| 38 |
+
"import os\n",
|
| 39 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 40 |
+
"from IPython.display import HTML\n",
|
| 41 |
+
"from google.colab import files\n",
|
| 42 |
+
"import numpy as np\n",
|
| 43 |
+
"import tqdm.notebook\n",
|
| 44 |
+
"TQDM_BAR_FORMAT = '{l_bar}{bar}| {n_fmt}/{total_fmt} [elapsed: {elapsed} remaining: {remaining}]'\n",
|
| 45 |
+
"def get_pdb(pdb_code=\"\"):\n",
|
| 46 |
+
" if pdb_code is None or pdb_code == \"\":\n",
|
| 47 |
+
" upload_dict = files.upload()\n",
|
| 48 |
+
" pdb_string = upload_dict[list(upload_dict.keys())[0]]\n",
|
| 49 |
+
" with open(\"tmp.pdb\",\"wb\") as out: out.write(pdb_string)\n",
|
| 50 |
+
" return \"tmp.pdb\"\n",
|
| 51 |
+
" elif os.path.isfile(pdb_code):\n",
|
| 52 |
+
" return pdb_code\n",
|
| 53 |
+
" elif len(pdb_code) == 4:\n",
|
| 54 |
+
" os.system(f\"wget -qnc https://files.rcsb.org/view/{pdb_code}.pdb\")\n",
|
| 55 |
+
" return f\"{pdb_code}.pdb\"\n",
|
| 56 |
+
" else:\n",
|
| 57 |
+
" os.system(f\"wget -qnc https://alphafold.ebi.ac.uk/files/AF-{pdb_code}-F1-model_v3.pdb\")\n",
|
| 58 |
+
" return f\"AF-{pdb_code}-F1-model_v3.pdb\"\n",
|
| 59 |
+
"\n",
|
| 60 |
+
"#@markdown Specify either pdb/pdb_chain or sequence:\n",
|
| 61 |
+
"pdb = \"6D0T\" #@param {type:\"string\"}\n",
|
| 62 |
+
"pdb_chain = \"A\" #@param {type:\"string\"}\n",
|
| 63 |
+
"sequence = \"\" #@param {type:\"string\"}\n",
|
| 64 |
+
"num_recycles = 0 #@param [\"0\", \"1\", \"2\", \"4\", \"8\", \"16\"] {type:\"raw\"}\n",
|
| 65 |
+
"clear_mem()\n",
|
| 66 |
+
"if sequence == \"\":\n",
|
| 67 |
+
" pdb_filename = get_pdb(pdb)\n",
|
| 68 |
+
" af_model = mk_afdesign_model(protocol=\"fixbb\")\n",
|
| 69 |
+
" af_model.prep_inputs(pdb_filename=pdb_filename, chain=pdb_chain)\n",
|
| 70 |
+
" af_model.set_seq(mode=\"wildtype\")\n",
|
| 71 |
+
" mode = \"pdb\"\n",
|
| 72 |
+
"else:\n",
|
| 73 |
+
" af_model = mk_afdesign_model(protocol=\"hallucination\")\n",
|
| 74 |
+
" af_model.prep_inputs(length=len(sequence))\n",
|
| 75 |
+
" af_model.set_seq(sequence)\n",
|
| 76 |
+
" mode = \"free\"\n",
|
| 77 |
+
"\n",
|
| 78 |
+
"import random, string\n",
|
| 79 |
+
"path = ''.join(random.choices(string.ascii_lowercase + string.digits, k=5))\n",
|
| 80 |
+
"while os.path.isdir(path):\n",
|
| 81 |
+
" path = ''.join(random.choices(string.ascii_lowercase + string.digits, k=5))\n",
|
| 82 |
+
"\n",
|
| 83 |
+
"seq = af_model._params[\"seq\"].copy()\n",
|
| 84 |
+
"os.makedirs(path, exist_ok=True)\n",
|
| 85 |
+
"with tqdm.notebook.tqdm(total=af_model._len, bar_format=TQDM_BAR_FORMAT) as pbar:\n",
|
| 86 |
+
" for n in range(1,af_model._len+1):\n",
|
| 87 |
+
" \n",
|
| 88 |
+
" # replace sequence (this is just for visualization)\n",
|
| 89 |
+
" af_model._params[\"seq\"] = seq.copy()\n",
|
| 90 |
+
" af_model._params[\"seq\"][:,n:] = 0\n",
|
| 91 |
+
" \n",
|
| 92 |
+
" # mask part of the input features\n",
|
| 93 |
+
" af_model._inputs[\"seq_mask\"] = (np.arange(af_model._len) < n).astype(float)\n",
|
| 94 |
+
" af_model.predict(verbose=False, hard=False, num_recycles=num_recycles)\n",
|
| 95 |
+
" af_model._save_results(verbose=False)\n",
|
| 96 |
+
" af_model.save_current_pdb(f\"{path}/{n:04d}.pdb\")\n",
|
| 97 |
+
" pbar.update(1)"
|
| 98 |
+
]
|
| 99 |
+
},
|
| 100 |
+
{
|
| 101 |
+
"cell_type": "code",
|
| 102 |
+
"source": [
|
| 103 |
+
"HTML(af_model.animate(dpi=100))"
|
| 104 |
+
],
|
| 105 |
+
"metadata": {
|
| 106 |
+
"id": "lphWx8wkEpwP"
|
| 107 |
+
},
|
| 108 |
+
"execution_count": null,
|
| 109 |
+
"outputs": []
|
| 110 |
+
},
|
| 111 |
+
{
|
| 112 |
+
"cell_type": "code",
|
| 113 |
+
"source": [
|
| 114 |
+
"af_model.plot_pdb()"
|
| 115 |
+
],
|
| 116 |
+
"metadata": {
|
| 117 |
+
"id": "9h1uXK44TygM"
|
| 118 |
+
},
|
| 119 |
+
"execution_count": null,
|
| 120 |
+
"outputs": []
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"cell_type": "code",
|
| 124 |
+
"source": [
|
| 125 |
+
"#@title Package and download results\n",
|
| 126 |
+
"#@markdown If you are having issues downloading the result archive, \n",
|
| 127 |
+
"#@markdown try disabling your adblocker and run this cell again. \n",
|
| 128 |
+
"#@markdown If that fails click on the little folder icon to the \n",
|
| 129 |
+
"#@markdown left, navigate to file: `name.result.zip`, \n",
|
| 130 |
+
"#@markdown right-click and select \\\"Download\\\" \n",
|
| 131 |
+
"#@markdown (see [screenshot](https://pbs.twimg.com/media/E6wRW2lWUAEOuoe?format=jpg&name=small)).\n",
|
| 132 |
+
"from google.colab import files\n",
|
| 133 |
+
"!zip -r {path}.result.zip {path}/*\n",
|
| 134 |
+
"files.download(f\"{path}.result.zip\")"
|
| 135 |
+
],
|
| 136 |
+
"metadata": {
|
| 137 |
+
"id": "zGE1CJxuTzyQ",
|
| 138 |
+
"cellView": "form"
|
| 139 |
+
},
|
| 140 |
+
"execution_count": null,
|
| 141 |
+
"outputs": []
|
| 142 |
+
}
|
| 143 |
+
],
|
| 144 |
+
"metadata": {
|
| 145 |
+
"accelerator": "GPU",
|
| 146 |
+
"colab": {
|
| 147 |
+
"collapsed_sections": [
|
| 148 |
+
"q4qiU9I0QHSz"
|
| 149 |
+
],
|
| 150 |
+
"provenance": [],
|
| 151 |
+
"include_colab_link": true
|
| 152 |
+
},
|
| 153 |
+
"kernelspec": {
|
| 154 |
+
"display_name": "Python 3",
|
| 155 |
+
"name": "python3"
|
| 156 |
+
},
|
| 157 |
+
"language_info": {
|
| 158 |
+
"name": "python"
|
| 159 |
+
},
|
| 160 |
+
"gpuClass": "standard"
|
| 161 |
+
},
|
| 162 |
+
"nbformat": 4,
|
| 163 |
+
"nbformat_minor": 0
|
| 164 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/afdesign_hotspot_test.ipynb
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/examples/afdesign_hotspot_test.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "markdown",
|
| 15 |
+
"metadata": {
|
| 16 |
+
"id": "OA2k3sAYuiXe"
|
| 17 |
+
},
|
| 18 |
+
"source": [
|
| 19 |
+
"# AfDesign - binder + hotspot test"
|
| 20 |
+
]
|
| 21 |
+
},
|
| 22 |
+
{
|
| 23 |
+
"cell_type": "code",
|
| 24 |
+
"execution_count": null,
|
| 25 |
+
"metadata": {
|
| 26 |
+
"id": "-AXy0s_4cKaK",
|
| 27 |
+
"cellView": "form"
|
| 28 |
+
},
|
| 29 |
+
"outputs": [],
|
| 30 |
+
"source": [
|
| 31 |
+
"#@title setup\n",
|
| 32 |
+
"%%time\n",
|
| 33 |
+
"import os\n",
|
| 34 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 35 |
+
" # get code\n",
|
| 36 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git@v1.1.1\")\n",
|
| 37 |
+
" # for debugging\n",
|
| 38 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 39 |
+
" # download params\n",
|
| 40 |
+
" os.system(\"mkdir params\")\n",
|
| 41 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 42 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar\")\n",
|
| 43 |
+
" os.system(\"tar -xf alphafold_params_2022-12-06.tar -C params\")\n",
|
| 44 |
+
"\n",
|
| 45 |
+
"import warnings\n",
|
| 46 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 47 |
+
"\n",
|
| 48 |
+
"import os\n",
|
| 49 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 50 |
+
"from IPython.display import HTML\n",
|
| 51 |
+
"from google.colab import files\n",
|
| 52 |
+
"import numpy as np\n",
|
| 53 |
+
"\n",
|
| 54 |
+
"def get_pdb(pdb_code=\"\"):\n",
|
| 55 |
+
" if pdb_code is None or pdb_code == \"\":\n",
|
| 56 |
+
" upload_dict = files.upload()\n",
|
| 57 |
+
" pdb_string = upload_dict[list(upload_dict.keys())[0]]\n",
|
| 58 |
+
" with open(\"tmp.pdb\",\"wb\") as out: out.write(pdb_string)\n",
|
| 59 |
+
" return \"tmp.pdb\"\n",
|
| 60 |
+
" elif os.path.isfile(pdb_code):\n",
|
| 61 |
+
" return pdb_code\n",
|
| 62 |
+
" elif len(pdb_code) == 4:\n",
|
| 63 |
+
" os.system(f\"wget -qnc https://files.rcsb.org/view/{pdb_code}.pdb\")\n",
|
| 64 |
+
" return f\"{pdb_code}.pdb\"\n",
|
| 65 |
+
" else:\n",
|
| 66 |
+
" os.system(f\"wget -qnc https://alphafold.ebi.ac.uk/files/AF-{pdb_code}-F1-model_v3.pdb\")\n",
|
| 67 |
+
" return f\"AF-{pdb_code}-F1-model_v3.pdb\""
|
| 68 |
+
]
|
| 69 |
+
},
|
| 70 |
+
{
|
| 71 |
+
"cell_type": "code",
|
| 72 |
+
"source": [
|
| 73 |
+
"%%bash\n",
|
| 74 |
+
"wget -qnc https://raw.githubusercontent.com/casperg92/MaSIF_colab/main/example/monomerexample.pdb"
|
| 75 |
+
],
|
| 76 |
+
"metadata": {
|
| 77 |
+
"id": "TIGDV-NqGMAw"
|
| 78 |
+
},
|
| 79 |
+
"execution_count": null,
|
| 80 |
+
"outputs": []
|
| 81 |
+
},
|
| 82 |
+
{
|
| 83 |
+
"cell_type": "code",
|
| 84 |
+
"execution_count": null,
|
| 85 |
+
"metadata": {
|
| 86 |
+
"id": "3XLJPiRKx5Mw"
|
| 87 |
+
},
|
| 88 |
+
"outputs": [],
|
| 89 |
+
"source": [
|
| 90 |
+
"clear_mem()\n",
|
| 91 |
+
"model = mk_afdesign_model(protocol=\"binder\")\n",
|
| 92 |
+
"\n",
|
| 93 |
+
"# pos = define positions (hotspot) on target you want to target for binder\n",
|
| 94 |
+
"model.prep_inputs(pdb_filename=\"monomerexample.pdb\", chain=\"A\",\n",
|
| 95 |
+
" binder_len=20,\n",
|
| 96 |
+
" hotspot=\"33,17,6,34,30,19,37,15\") \n",
|
| 97 |
+
"\n",
|
| 98 |
+
"print(\"target_length\",model._target_len)\n",
|
| 99 |
+
"print(\"binder_length\",model._binder_len)\n",
|
| 100 |
+
"print(\"weights\",model.opt[\"weights\"])"
|
| 101 |
+
]
|
| 102 |
+
},
|
| 103 |
+
{
|
| 104 |
+
"cell_type": "code",
|
| 105 |
+
"execution_count": null,
|
| 106 |
+
"metadata": {
|
| 107 |
+
"id": "u6VxjuinyCZa"
|
| 108 |
+
},
|
| 109 |
+
"outputs": [],
|
| 110 |
+
"source": [
|
| 111 |
+
"model.restart(mode=\"soft_gumbel\")\n",
|
| 112 |
+
"model.design_3stage(100, 100, 10)"
|
| 113 |
+
]
|
| 114 |
+
},
|
| 115 |
+
{
|
| 116 |
+
"cell_type": "code",
|
| 117 |
+
"execution_count": null,
|
| 118 |
+
"metadata": {
|
| 119 |
+
"id": "9cARoviGyIKb"
|
| 120 |
+
},
|
| 121 |
+
"outputs": [],
|
| 122 |
+
"source": [
|
| 123 |
+
"HTML(model.animate())"
|
| 124 |
+
]
|
| 125 |
+
},
|
| 126 |
+
{
|
| 127 |
+
"cell_type": "code",
|
| 128 |
+
"source": [
|
| 129 |
+
"model.get_seqs()"
|
| 130 |
+
],
|
| 131 |
+
"metadata": {
|
| 132 |
+
"id": "RzE137NDZdZc"
|
| 133 |
+
},
|
| 134 |
+
"execution_count": null,
|
| 135 |
+
"outputs": []
|
| 136 |
+
},
|
| 137 |
+
{
|
| 138 |
+
"cell_type": "code",
|
| 139 |
+
"source": [
|
| 140 |
+
"model.plot_pdb()\n",
|
| 141 |
+
"model.save_pdb(f\"{model.protocol}.pdb\")"
|
| 142 |
+
],
|
| 143 |
+
"metadata": {
|
| 144 |
+
"id": "sTlS7_L8Zfwf"
|
| 145 |
+
},
|
| 146 |
+
"execution_count": null,
|
| 147 |
+
"outputs": []
|
| 148 |
+
},
|
| 149 |
+
{
|
| 150 |
+
"cell_type": "markdown",
|
| 151 |
+
"source": [
|
| 152 |
+
"as a control, let's try hallucinate a binder without defining a hotspot"
|
| 153 |
+
],
|
| 154 |
+
"metadata": {
|
| 155 |
+
"id": "aGW9s5t3Xlk4"
|
| 156 |
+
}
|
| 157 |
+
},
|
| 158 |
+
{
|
| 159 |
+
"cell_type": "code",
|
| 160 |
+
"source": [
|
| 161 |
+
"clear_mem()\n",
|
| 162 |
+
"model = mk_afdesign_model(protocol=\"binder\")\n",
|
| 163 |
+
"model.prep_inputs(pdb_filename=\"monomerexample.pdb\", chain=\"A\", binder_len=20)"
|
| 164 |
+
],
|
| 165 |
+
"metadata": {
|
| 166 |
+
"id": "KzkNzuS6Xpqj"
|
| 167 |
+
},
|
| 168 |
+
"execution_count": null,
|
| 169 |
+
"outputs": []
|
| 170 |
+
},
|
| 171 |
+
{
|
| 172 |
+
"cell_type": "code",
|
| 173 |
+
"source": [
|
| 174 |
+
"model.restart(mode=\"soft_gumbel\")\n",
|
| 175 |
+
"model.design_3stage(100, 100, 10)"
|
| 176 |
+
],
|
| 177 |
+
"metadata": {
|
| 178 |
+
"id": "wjFi2uhwXtPz"
|
| 179 |
+
},
|
| 180 |
+
"execution_count": null,
|
| 181 |
+
"outputs": []
|
| 182 |
+
},
|
| 183 |
+
{
|
| 184 |
+
"cell_type": "code",
|
| 185 |
+
"source": [
|
| 186 |
+
"HTML(model.animate())"
|
| 187 |
+
],
|
| 188 |
+
"metadata": {
|
| 189 |
+
"id": "pBRNpspoX6pR"
|
| 190 |
+
},
|
| 191 |
+
"execution_count": null,
|
| 192 |
+
"outputs": []
|
| 193 |
+
},
|
| 194 |
+
{
|
| 195 |
+
"cell_type": "code",
|
| 196 |
+
"source": [
|
| 197 |
+
"model.get_seqs()"
|
| 198 |
+
],
|
| 199 |
+
"metadata": {
|
| 200 |
+
"id": "J43oqomrYA8v"
|
| 201 |
+
},
|
| 202 |
+
"execution_count": null,
|
| 203 |
+
"outputs": []
|
| 204 |
+
},
|
| 205 |
+
{
|
| 206 |
+
"cell_type": "code",
|
| 207 |
+
"source": [
|
| 208 |
+
"model.plot_pdb()\n",
|
| 209 |
+
"model.save_pdb(f\"{model.protocol}.control.pdb\")"
|
| 210 |
+
],
|
| 211 |
+
"metadata": {
|
| 212 |
+
"id": "r2d86kMVX_SL"
|
| 213 |
+
},
|
| 214 |
+
"execution_count": null,
|
| 215 |
+
"outputs": []
|
| 216 |
+
},
|
| 217 |
+
{
|
| 218 |
+
"cell_type": "code",
|
| 219 |
+
"source": [],
|
| 220 |
+
"metadata": {
|
| 221 |
+
"id": "xw_5hblQmRqn"
|
| 222 |
+
},
|
| 223 |
+
"execution_count": null,
|
| 224 |
+
"outputs": []
|
| 225 |
+
}
|
| 226 |
+
],
|
| 227 |
+
"metadata": {
|
| 228 |
+
"accelerator": "GPU",
|
| 229 |
+
"colab": {
|
| 230 |
+
"collapsed_sections": [
|
| 231 |
+
"q4qiU9I0QHSz"
|
| 232 |
+
],
|
| 233 |
+
"name": "afdesign_hotspot_test.ipynb",
|
| 234 |
+
"provenance": [],
|
| 235 |
+
"include_colab_link": true
|
| 236 |
+
},
|
| 237 |
+
"kernelspec": {
|
| 238 |
+
"display_name": "Python 3",
|
| 239 |
+
"name": "python3"
|
| 240 |
+
},
|
| 241 |
+
"language_info": {
|
| 242 |
+
"name": "python"
|
| 243 |
+
}
|
| 244 |
+
},
|
| 245 |
+
"nbformat": 4,
|
| 246 |
+
"nbformat_minor": 0
|
| 247 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/binder_hallucination.ipynb
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/examples/peptide_binder_design.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "markdown",
|
| 15 |
+
"metadata": {
|
| 16 |
+
"id": "OA2k3sAYuiXe"
|
| 17 |
+
},
|
| 18 |
+
"source": [
|
| 19 |
+
"this notebook moved to: [peptide_binder_design.ipynb](https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/examples/peptide_binder_design.ipynb)"
|
| 20 |
+
]
|
| 21 |
+
}
|
| 22 |
+
],
|
| 23 |
+
"metadata": {
|
| 24 |
+
"accelerator": "GPU",
|
| 25 |
+
"colab": {
|
| 26 |
+
"collapsed_sections": [
|
| 27 |
+
"q4qiU9I0QHSz"
|
| 28 |
+
],
|
| 29 |
+
"provenance": [],
|
| 30 |
+
"include_colab_link": true
|
| 31 |
+
},
|
| 32 |
+
"kernelspec": {
|
| 33 |
+
"display_name": "Python 3",
|
| 34 |
+
"name": "python3"
|
| 35 |
+
},
|
| 36 |
+
"language_info": {
|
| 37 |
+
"name": "python"
|
| 38 |
+
}
|
| 39 |
+
},
|
| 40 |
+
"nbformat": 4,
|
| 41 |
+
"nbformat_minor": 0
|
| 42 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/disulfide_design.ipynb
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/examples/disulfide_design.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "markdown",
|
| 15 |
+
"metadata": {
|
| 16 |
+
"id": "YRk_XS2NILil"
|
| 17 |
+
},
|
| 18 |
+
"source": [
|
| 19 |
+
"# disulfide-hallucination\n",
|
| 20 |
+
"For a given length, generate/hallucinate a disulfide-rich sequence that AlphaFold thinks folds into a well structured protein"
|
| 21 |
+
]
|
| 22 |
+
},
|
| 23 |
+
{
|
| 24 |
+
"cell_type": "code",
|
| 25 |
+
"execution_count": null,
|
| 26 |
+
"metadata": {
|
| 27 |
+
"cellView": "form",
|
| 28 |
+
"id": "-AXy0s_4cKaK"
|
| 29 |
+
},
|
| 30 |
+
"outputs": [],
|
| 31 |
+
"source": [
|
| 32 |
+
"#@title setup\n",
|
| 33 |
+
"%%time\n",
|
| 34 |
+
"import os\n",
|
| 35 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 36 |
+
" # get code\n",
|
| 37 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git@v1.1.1\")\n",
|
| 38 |
+
" # for debugging\n",
|
| 39 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 40 |
+
" # download params\n",
|
| 41 |
+
" os.system(\"mkdir params\")\n",
|
| 42 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 43 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar\")\n",
|
| 44 |
+
" os.system(\"tar -xf alphafold_params_2022-12-06.tar -C params\")\n",
|
| 45 |
+
"\n",
|
| 46 |
+
"import warnings\n",
|
| 47 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 48 |
+
"\n",
|
| 49 |
+
"import os\n",
|
| 50 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 51 |
+
"from IPython.display import HTML\n",
|
| 52 |
+
"from google.colab import files\n",
|
| 53 |
+
"import numpy as np\n",
|
| 54 |
+
"\n",
|
| 55 |
+
"def get_pdb(pdb_code=\"\"):\n",
|
| 56 |
+
" if pdb_code is None or pdb_code == \"\":\n",
|
| 57 |
+
" upload_dict = files.upload()\n",
|
| 58 |
+
" pdb_string = upload_dict[list(upload_dict.keys())[0]]\n",
|
| 59 |
+
" with open(\"tmp.pdb\",\"wb\") as out: out.write(pdb_string)\n",
|
| 60 |
+
" return \"tmp.pdb\"\n",
|
| 61 |
+
" elif os.path.isfile(pdb_code):\n",
|
| 62 |
+
" return pdb_code\n",
|
| 63 |
+
" elif len(pdb_code) == 4:\n",
|
| 64 |
+
" os.system(f\"wget -qnc https://files.rcsb.org/view/{pdb_code}.pdb\")\n",
|
| 65 |
+
" return f\"{pdb_code}.pdb\"\n",
|
| 66 |
+
" else:\n",
|
| 67 |
+
" os.system(f\"wget -qnc https://alphafold.ebi.ac.uk/files/AF-{pdb_code}-F1-model_v3.pdb\")\n",
|
| 68 |
+
" return f\"AF-{pdb_code}-F1-model_v3.pdb\""
|
| 69 |
+
]
|
| 70 |
+
},
|
| 71 |
+
{
|
| 72 |
+
"cell_type": "code",
|
| 73 |
+
"execution_count": null,
|
| 74 |
+
"metadata": {
|
| 75 |
+
"id": "7JbLyVu4ILil"
|
| 76 |
+
},
|
| 77 |
+
"outputs": [],
|
| 78 |
+
"source": [
|
| 79 |
+
"import random\n",
|
| 80 |
+
"from jax.lax import dynamic_slice\n",
|
| 81 |
+
"import jax.numpy as jnp\n",
|
| 82 |
+
"\n",
|
| 83 |
+
"from colabdesign.af.loss import _get_con_loss\n",
|
| 84 |
+
"def get_con_loss(dgram, dgram_bins, cutoff=None, binary=True,\n",
|
| 85 |
+
" num=1, seqsep=0, offset=None):\n",
|
| 86 |
+
" '''convert distogram into contact loss''' \n",
|
| 87 |
+
" x = _get_con_loss(dgram, dgram_bins, cutoff, binary) \n",
|
| 88 |
+
" a,b = x.shape\n",
|
| 89 |
+
" if offset is None:\n",
|
| 90 |
+
" mask = jnp.abs(jnp.arange(a)[:,None] - jnp.arange(b)[None,:]) >= seqsep\n",
|
| 91 |
+
" else:\n",
|
| 92 |
+
" mask = jnp.abs(offset) >= seqsep\n",
|
| 93 |
+
" x = jnp.sort(jnp.where(mask,x,jnp.nan))\n",
|
| 94 |
+
" k_mask = (jnp.arange(b) < num) * (jnp.isnan(x) == False) \n",
|
| 95 |
+
" return jnp.where(k_mask,x,0.0).sum(-1) / (k_mask.sum(-1) + 1e-8)\n",
|
| 96 |
+
"\n",
|
| 97 |
+
"def generate_disulfide_pattern(L, disulfide_num, min_sep=5):\n",
|
| 98 |
+
" disulfide_pattern = []\n",
|
| 99 |
+
" positions = list(range(L))\n",
|
| 100 |
+
" for n in range(disulfide_num):\n",
|
| 101 |
+
" for _ in range(100): # try 100 time per postion.\n",
|
| 102 |
+
" i,j = random.sample(positions, k=2)\n",
|
| 103 |
+
" if abs(i-j)<=min_sep: continue # set min loop len.\n",
|
| 104 |
+
" positions.remove(i)\n",
|
| 105 |
+
" positions.remove(j)\n",
|
| 106 |
+
" disulfide_pattern.append((i,j))\n",
|
| 107 |
+
" # check\n",
|
| 108 |
+
" if _ > 99:\n",
|
| 109 |
+
" print('Not find good disulfide_pos! exit....')\n",
|
| 110 |
+
" return 0 # not good pose!\n",
|
| 111 |
+
" else:\n",
|
| 112 |
+
" break\n",
|
| 113 |
+
" sequence_pattern = list('X'*L)\n",
|
| 114 |
+
" for pair in disulfide_pattern:\n",
|
| 115 |
+
" for i in pair: sequence_pattern[i] = 'C'\n",
|
| 116 |
+
"\n",
|
| 117 |
+
" return disulfide_pattern, ''.join(sequence_pattern), L\n",
|
| 118 |
+
"\n",
|
| 119 |
+
"def disulfide_loss(inputs, outputs):\n",
|
| 120 |
+
" def get_disulfide_loss(dgram, dgram_bins, disulfide_pattern):\n",
|
| 121 |
+
" '''\n",
|
| 122 |
+
" Func: simple disulfide loss, make the contacts < 7.0/7.5A.\n",
|
| 123 |
+
" # see: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7316719/\n",
|
| 124 |
+
" params: disulfide_pattern: List[(pos1, pos2), (pos3, pos4)...]\n",
|
| 125 |
+
" '''\n",
|
| 126 |
+
" disulfide_loss = 0.0\n",
|
| 127 |
+
" for pair in disulfide_pattern:\n",
|
| 128 |
+
" i,j = pair\n",
|
| 129 |
+
" pair_dgram = dynamic_slice(dgram, (i,j,0), (1,1,len(dgram_bins))) + dynamic_slice(dgram, (j,i,0), (1,1,len(dgram_bins)))\n",
|
| 130 |
+
" disulfide_loss += get_con_loss(pair_dgram, dgram_bins, cutoff=7.0, binary=False, num=1)\n",
|
| 131 |
+
" return disulfide_loss.mean()\n",
|
| 132 |
+
"\n",
|
| 133 |
+
" # add disulfide loss here:\n",
|
| 134 |
+
" dgram_logits = outputs['distogram']['logits']\n",
|
| 135 |
+
" dgram_bins = jnp.append(0, outputs[\"distogram\"][\"bin_edges\"])\n",
|
| 136 |
+
" return {\"disulfide\":get_disulfide_loss(dgram_logits, dgram_bins, inputs['opt']['disulfide_pattern'])}"
|
| 137 |
+
]
|
| 138 |
+
},
|
| 139 |
+
{
|
| 140 |
+
"cell_type": "markdown",
|
| 141 |
+
"metadata": {
|
| 142 |
+
"id": "aU4e-ZkfILim"
|
| 143 |
+
},
|
| 144 |
+
"source": [
|
| 145 |
+
"0. generate_cys_pattern"
|
| 146 |
+
]
|
| 147 |
+
},
|
| 148 |
+
{
|
| 149 |
+
"cell_type": "code",
|
| 150 |
+
"execution_count": null,
|
| 151 |
+
"metadata": {
|
| 152 |
+
"id": "vrSatV2sILim"
|
| 153 |
+
},
|
| 154 |
+
"outputs": [],
|
| 155 |
+
"source": [
|
| 156 |
+
"disulfide_pattern, sequence_pattern, L = generate_disulfide_pattern(35, 3)\n",
|
| 157 |
+
"print(disulfide_pattern)\n",
|
| 158 |
+
"print(sequence_pattern)\n",
|
| 159 |
+
"print(L)"
|
| 160 |
+
]
|
| 161 |
+
},
|
| 162 |
+
{
|
| 163 |
+
"cell_type": "markdown",
|
| 164 |
+
"metadata": {
|
| 165 |
+
"id": "jGNGjHeyILim"
|
| 166 |
+
},
|
| 167 |
+
"source": [
|
| 168 |
+
"1. hallucination with disulfide-pattern"
|
| 169 |
+
]
|
| 170 |
+
},
|
| 171 |
+
{
|
| 172 |
+
"cell_type": "code",
|
| 173 |
+
"execution_count": null,
|
| 174 |
+
"metadata": {
|
| 175 |
+
"id": "HmsBDNhmILin"
|
| 176 |
+
},
|
| 177 |
+
"outputs": [],
|
| 178 |
+
"source": [
|
| 179 |
+
"# using some disulfide sequence as input:\n",
|
| 180 |
+
"clear_mem()\n",
|
| 181 |
+
"af_model = mk_afdesign_model(protocol=\"hallucination\", loss_callback=disulfide_loss)\n",
|
| 182 |
+
"af_model.opt[\"weights\"][\"disulfide\"] = 1.0\n",
|
| 183 |
+
"af_model.prep_inputs(length=L)\n",
|
| 184 |
+
"\n",
|
| 185 |
+
"print(\"length\",af_model._len)\n",
|
| 186 |
+
"print(\"weights\",af_model.opt[\"weights\"])"
|
| 187 |
+
]
|
| 188 |
+
},
|
| 189 |
+
{
|
| 190 |
+
"cell_type": "code",
|
| 191 |
+
"execution_count": null,
|
| 192 |
+
"metadata": {
|
| 193 |
+
"id": "MmBtBMnBILin"
|
| 194 |
+
},
|
| 195 |
+
"outputs": [],
|
| 196 |
+
"source": [
|
| 197 |
+
"# set disulfide_pattern sequence.\n",
|
| 198 |
+
"af_model.restart(seq=sequence_pattern, add_seq=True, rm_aa='C')\n",
|
| 199 |
+
"# set disulfide_pattern:\n",
|
| 200 |
+
"af_model.opt['disulfide_pattern'] = disulfide_pattern\n",
|
| 201 |
+
"# reweight con:\n",
|
| 202 |
+
"af_model.opt[\"weights\"]['con'] = 0.5"
|
| 203 |
+
]
|
| 204 |
+
},
|
| 205 |
+
{
|
| 206 |
+
"cell_type": "code",
|
| 207 |
+
"source": [
|
| 208 |
+
"af_model.design_3stage(50,50,10)"
|
| 209 |
+
],
|
| 210 |
+
"metadata": {
|
| 211 |
+
"id": "wstI0n4zMydi"
|
| 212 |
+
},
|
| 213 |
+
"execution_count": null,
|
| 214 |
+
"outputs": []
|
| 215 |
+
},
|
| 216 |
+
{
|
| 217 |
+
"cell_type": "code",
|
| 218 |
+
"execution_count": null,
|
| 219 |
+
"metadata": {
|
| 220 |
+
"id": "ewlj8671ILio"
|
| 221 |
+
},
|
| 222 |
+
"outputs": [],
|
| 223 |
+
"source": [
|
| 224 |
+
"af_model.save_pdb(f\"{af_model.protocol}.pdb\")\n",
|
| 225 |
+
"af_model.plot_pdb(show_sidechains=True)"
|
| 226 |
+
]
|
| 227 |
+
},
|
| 228 |
+
{
|
| 229 |
+
"cell_type": "markdown",
|
| 230 |
+
"metadata": {
|
| 231 |
+
"id": "iVEqJKaKILio"
|
| 232 |
+
},
|
| 233 |
+
"source": [
|
| 234 |
+
"2. fix-sidechain with pyRosetta"
|
| 235 |
+
]
|
| 236 |
+
},
|
| 237 |
+
{
|
| 238 |
+
"cell_type": "code",
|
| 239 |
+
"execution_count": null,
|
| 240 |
+
"metadata": {
|
| 241 |
+
"id": "VGwyvaodILio"
|
| 242 |
+
},
|
| 243 |
+
"outputs": [],
|
| 244 |
+
"source": [
|
| 245 |
+
"from pyrosetta import init, pose_from_pdb, Pose, create_score_function\n",
|
| 246 |
+
"from pyrosetta.rosetta.protocols.relax import FastRelax\n",
|
| 247 |
+
"from pyrosetta.rosetta.core.pack.task import TaskFactory\n",
|
| 248 |
+
"from pyrosetta.rosetta.core.kinematics import MoveMap\n",
|
| 249 |
+
"from pyrosetta.rosetta.core.pack.task.operation import InitializeFromCommandline\n",
|
| 250 |
+
"from pyrosetta.rosetta.protocols.denovo_design import DisulfidizeMover\n",
|
| 251 |
+
"from pyrosetta.rosetta.core.pack.task.operation import RestrictToRepacking\n",
|
| 252 |
+
"from pyrosetta.rosetta.core.select.residue_selector import ChainSelector\n",
|
| 253 |
+
"\n",
|
| 254 |
+
"def fastrelax(pose):\n",
|
| 255 |
+
" full_score = create_score_function('ref2015')\n",
|
| 256 |
+
" tf = TaskFactory()\n",
|
| 257 |
+
" # tf.push_back(InitializeFromCommandline())\n",
|
| 258 |
+
" tf.push_back(RestrictToRepacking())\n",
|
| 259 |
+
" mmap = MoveMap()\n",
|
| 260 |
+
" mmap.set_bb(True)\n",
|
| 261 |
+
" mmap.set_chi(True)\n",
|
| 262 |
+
"\n",
|
| 263 |
+
" # FastRelax:\n",
|
| 264 |
+
" fast_design = FastRelax(full_score, 4) # repeat:6\n",
|
| 265 |
+
" fast_design.set_task_factory(tf)\n",
|
| 266 |
+
" fast_design.set_movemap(mmap)\n",
|
| 267 |
+
" fast_design.apply(pose)\n",
|
| 268 |
+
" \n",
|
| 269 |
+
"def build_stapled_pose(pose, cys_pattern):\n",
|
| 270 |
+
" # rebuild \n",
|
| 271 |
+
" disulfidizer = DisulfidizeMover()\n",
|
| 272 |
+
" disulfidizer.set_match_rt_limit(999.0)\n",
|
| 273 |
+
" disulfidizer.set_max_disulf_score(999.0)\n",
|
| 274 |
+
" for pair in cys_pattern:\n",
|
| 275 |
+
" full_score = create_score_function('ref2015')\n",
|
| 276 |
+
" stapled_pose = Pose().assign(pose) # pose for disulfides stapled\n",
|
| 277 |
+
" residue1, residue2 = pair\n",
|
| 278 |
+
" disulfidizer.make_disulfide(stapled_pose, residue1+1, residue2+1, False, full_score)\n",
|
| 279 |
+
" # fastdesign mover\n",
|
| 280 |
+
" pdbnum1 = stapled_pose.pdb_info().pose2pdb(residue1)\n",
|
| 281 |
+
" pdbnum2 = stapled_pose.pdb_info().pose2pdb(residue2)\n",
|
| 282 |
+
" print('# OPTIMIZE: Around These Residues: %s %s' % (pdbnum1, pdbnum2))\n",
|
| 283 |
+
"\n",
|
| 284 |
+
" # save pdb:\n",
|
| 285 |
+
" fastrelax(stapled_pose)\n",
|
| 286 |
+
" \n",
|
| 287 |
+
" # filter: all stapled?\n",
|
| 288 |
+
" v = ChainSelector(1).apply(stapled_pose)\n",
|
| 289 |
+
" l = disulfidizer.find_current_disulfides(stapled_pose, v, v)\n",
|
| 290 |
+
" print(len([i for i in l]), len(cys_pattern))\n",
|
| 291 |
+
" if len([i for i in l]) == len(cys_pattern):\n",
|
| 292 |
+
" return stapled_pose\n",
|
| 293 |
+
" else:\n",
|
| 294 |
+
" return 0\n",
|
| 295 |
+
" "
|
| 296 |
+
]
|
| 297 |
+
},
|
| 298 |
+
{
|
| 299 |
+
"cell_type": "code",
|
| 300 |
+
"execution_count": null,
|
| 301 |
+
"metadata": {
|
| 302 |
+
"id": "zhMey-4lILip"
|
| 303 |
+
},
|
| 304 |
+
"outputs": [],
|
| 305 |
+
"source": [
|
| 306 |
+
"# optimze the side-chain\n",
|
| 307 |
+
"init('-mute all')\n",
|
| 308 |
+
"pose = pose_from_pdb(f\"{af_model.protocol}.pdb\")\n",
|
| 309 |
+
"stapled_pose = build_stapled_pose(pose, disulfide_pattern)"
|
| 310 |
+
]
|
| 311 |
+
}
|
| 312 |
+
],
|
| 313 |
+
"metadata": {
|
| 314 |
+
"accelerator": "GPU",
|
| 315 |
+
"colab": {
|
| 316 |
+
"collapsed_sections": [
|
| 317 |
+
"q4qiU9I0QHSz"
|
| 318 |
+
],
|
| 319 |
+
"name": "disulfide_design.ipynb",
|
| 320 |
+
"provenance": [],
|
| 321 |
+
"include_colab_link": true
|
| 322 |
+
},
|
| 323 |
+
"kernelspec": {
|
| 324 |
+
"display_name": "Python 3.8.10 64-bit",
|
| 325 |
+
"language": "python",
|
| 326 |
+
"name": "python3"
|
| 327 |
+
},
|
| 328 |
+
"language_info": {
|
| 329 |
+
"codemirror_mode": {
|
| 330 |
+
"name": "ipython",
|
| 331 |
+
"version": 3
|
| 332 |
+
},
|
| 333 |
+
"file_extension": ".py",
|
| 334 |
+
"mimetype": "text/x-python",
|
| 335 |
+
"name": "python",
|
| 336 |
+
"nbconvert_exporter": "python",
|
| 337 |
+
"pygments_lexer": "ipython3",
|
| 338 |
+
"version": "3.8.10"
|
| 339 |
+
},
|
| 340 |
+
"vscode": {
|
| 341 |
+
"interpreter": {
|
| 342 |
+
"hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
|
| 343 |
+
}
|
| 344 |
+
}
|
| 345 |
+
},
|
| 346 |
+
"nbformat": 4,
|
| 347 |
+
"nbformat_minor": 0
|
| 348 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/hallucination.ipynb
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/examples/hallucination.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "markdown",
|
| 15 |
+
"metadata": {
|
| 16 |
+
"id": "OA2k3sAYuiXe"
|
| 17 |
+
},
|
| 18 |
+
"source": [
|
| 19 |
+
"# AfDesign - hallucination\n",
|
| 20 |
+
"For a given length, generate/hallucinate a protein sequence that AlphaFold thinks folds into a well structured protein (high plddt, low pae, many contacts).\n",
|
| 21 |
+
"\n",
|
| 22 |
+
"**WARNING**\n",
|
| 23 |
+
"1. This notebook is in active development and was designed for demonstration purposes only.\n",
|
| 24 |
+
"2. Using AfDesign as the only \"loss\" function for design might be a bad idea, you may find adversarial sequences (aka. sequences that trick AlphaFold)."
|
| 25 |
+
]
|
| 26 |
+
},
|
| 27 |
+
{
|
| 28 |
+
"cell_type": "code",
|
| 29 |
+
"execution_count": null,
|
| 30 |
+
"metadata": {
|
| 31 |
+
"cellView": "form",
|
| 32 |
+
"id": "-AXy0s_4cKaK"
|
| 33 |
+
},
|
| 34 |
+
"outputs": [],
|
| 35 |
+
"source": [
|
| 36 |
+
"#@title setup\n",
|
| 37 |
+
"%%time\n",
|
| 38 |
+
"import os\n",
|
| 39 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 40 |
+
" # get code\n",
|
| 41 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git@v1.1.1\")\n",
|
| 42 |
+
" # for debugging\n",
|
| 43 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 44 |
+
" # download params\n",
|
| 45 |
+
" os.system(\"mkdir params\")\n",
|
| 46 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 47 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar\")\n",
|
| 48 |
+
" os.system(\"tar -xf alphafold_params_2022-12-06.tar -C params\")\n",
|
| 49 |
+
"\n",
|
| 50 |
+
"import warnings\n",
|
| 51 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 52 |
+
"\n",
|
| 53 |
+
"import os\n",
|
| 54 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 55 |
+
"from IPython.display import HTML\n",
|
| 56 |
+
"from google.colab import files\n",
|
| 57 |
+
"import numpy as np\n",
|
| 58 |
+
"\n",
|
| 59 |
+
"def get_pdb(pdb_code=\"\"):\n",
|
| 60 |
+
" if pdb_code is None or pdb_code == \"\":\n",
|
| 61 |
+
" upload_dict = files.upload()\n",
|
| 62 |
+
" pdb_string = upload_dict[list(upload_dict.keys())[0]]\n",
|
| 63 |
+
" with open(\"tmp.pdb\",\"wb\") as out: out.write(pdb_string)\n",
|
| 64 |
+
" return \"tmp.pdb\"\n",
|
| 65 |
+
" elif os.path.isfile(pdb_code):\n",
|
| 66 |
+
" return pdb_code\n",
|
| 67 |
+
" elif len(pdb_code) == 4:\n",
|
| 68 |
+
" os.system(f\"wget -qnc https://files.rcsb.org/view/{pdb_code}.pdb\")\n",
|
| 69 |
+
" return f\"{pdb_code}.pdb\"\n",
|
| 70 |
+
" else:\n",
|
| 71 |
+
" os.system(f\"wget -qnc https://alphafold.ebi.ac.uk/files/AF-{pdb_code}-F1-model_v3.pdb\")\n",
|
| 72 |
+
" return f\"AF-{pdb_code}-F1-model_v3.pdb\""
|
| 73 |
+
]
|
| 74 |
+
},
|
| 75 |
+
{
|
| 76 |
+
"cell_type": "code",
|
| 77 |
+
"source": [
|
| 78 |
+
"#@title Hallucination Options\n",
|
| 79 |
+
"length = 100#@param {type:\"integer\"}\n",
|
| 80 |
+
"copies = 1#@param {type:\"integer\"}\n",
|
| 81 |
+
"#@markdown ####Weights\n",
|
| 82 |
+
"#@markdown - Minimizing `pae` or maximizing `plddt` often results in a single helix.\n",
|
| 83 |
+
"#@markdown To avoid this, we start with a random sequence and instead try to optimize \n",
|
| 84 |
+
"#@markdown defined `num`ber of `con`tacts per position. \n",
|
| 85 |
+
"pae = 0.1 #@param [\"0.01\", \"0.1\", \"0.5\", \"1.0\"] {type:\"raw\"}\n",
|
| 86 |
+
"plddt = 0.1 #@param [\"0.01\", \"0.1\", \"0.5\", \"1.0\"] {type:\"raw\"}\n",
|
| 87 |
+
"con = 1.0 #@param [\"0.01\", \"0.1\", \"0.5\", \"1.0\"] {type:\"raw\"}\n",
|
| 88 |
+
"#@markdown ####Contact Definition\n",
|
| 89 |
+
"#@markdown - The contact definition is based on Cb-Cb diststance `cutoff`. To avoid \n",
|
| 90 |
+
"#@markdown biasing towards helical contact, only contacts with sequence seperation > \n",
|
| 91 |
+
"#@markdown `seqsep` are considered.\n",
|
| 92 |
+
"\n",
|
| 93 |
+
"\n",
|
| 94 |
+
"seqsep = 9 #@param [\"0\",\"5\",\"9\"] {type:\"raw\"}\n",
|
| 95 |
+
"cutoff = \"14\" #@param [\"8\", \"14\", \"max\"]\n",
|
| 96 |
+
"num = \"2\" #@param [\"1\", \"2\", \"4\", \"8\", \"max\"]\n",
|
| 97 |
+
"binary = False #@param {type:\"boolean\"}\n",
|
| 98 |
+
"if cutoff == \"max\": cutoff = 21.6875\n",
|
| 99 |
+
"if num == \"max\": num = length\n",
|
| 100 |
+
"\n",
|
| 101 |
+
"opt = {\"con\":{\"seqsep\":int(seqsep),\"cutoff\":float(cutoff),\"num\":int(num),\n",
|
| 102 |
+
" \"binary\":binary}}\n",
|
| 103 |
+
"weights = {\"con\":float(con), \"pae\":float(pae),\"plddt\":float(plddt)}\n",
|
| 104 |
+
"\n",
|
| 105 |
+
"if \"model\" not in dir() or model._len != length or model._args[\"copies\"] != copies:\n",
|
| 106 |
+
" clear_mem()\n",
|
| 107 |
+
" model = mk_afdesign_model(protocol=\"hallucination\")\n",
|
| 108 |
+
" model.prep_inputs(length=length, copies=copies)\n",
|
| 109 |
+
"\n",
|
| 110 |
+
"#@markdown ####Optimizer settings\n",
|
| 111 |
+
"pre_iters = 100 #@param {type:\"integer\"}\n",
|
| 112 |
+
"soft_iters = 50 #@param {type:\"integer\"}\n",
|
| 113 |
+
"temp_iters = 50 #@param {type:\"integer\"}\n",
|
| 114 |
+
"hard_iters = 10 #@param {type:\"integer\"}\n",
|
| 115 |
+
"\n",
|
| 116 |
+
"# pre-design with gumbel initialization and softmax activation\n",
|
| 117 |
+
"model.restart(mode=\"gumbel\",opt=opt,weights=weights)\n",
|
| 118 |
+
"model.design_soft(pre_iters)\n",
|
| 119 |
+
"\n",
|
| 120 |
+
"# three stage design \n",
|
| 121 |
+
"model.set_seq(model.aux[\"seq\"][\"pseudo\"])\n",
|
| 122 |
+
"model.design_3stage(soft_iters,temp_iters,hard_iters)"
|
| 123 |
+
],
|
| 124 |
+
"metadata": {
|
| 125 |
+
"cellView": "form",
|
| 126 |
+
"id": "eCGc3J663NGz"
|
| 127 |
+
},
|
| 128 |
+
"execution_count": null,
|
| 129 |
+
"outputs": []
|
| 130 |
+
},
|
| 131 |
+
{
|
| 132 |
+
"cell_type": "code",
|
| 133 |
+
"execution_count": null,
|
| 134 |
+
"metadata": {
|
| 135 |
+
"id": "A1GxeLZdTTya",
|
| 136 |
+
"cellView": "form"
|
| 137 |
+
},
|
| 138 |
+
"outputs": [],
|
| 139 |
+
"source": [
|
| 140 |
+
"#@markdown ## display hallucinated protein {run: \"auto\"}\n",
|
| 141 |
+
"color = \"pLDDT\" #@param [\"chain\", \"pLDDT\", \"rainbow\"]\n",
|
| 142 |
+
"show_sidechains = False #@param {type:\"boolean\"}\n",
|
| 143 |
+
"show_mainchains = False #@param {type:\"boolean\"}\n",
|
| 144 |
+
"model.save_pdb(f\"{model.protocol}.pdb\")\n",
|
| 145 |
+
"model.plot_pdb(show_sidechains=show_sidechains,\n",
|
| 146 |
+
" show_mainchains=show_mainchains,\n",
|
| 147 |
+
" color=color)"
|
| 148 |
+
]
|
| 149 |
+
},
|
| 150 |
+
{
|
| 151 |
+
"cell_type": "code",
|
| 152 |
+
"execution_count": null,
|
| 153 |
+
"metadata": {
|
| 154 |
+
"id": "L2E9Tn2Acchj"
|
| 155 |
+
},
|
| 156 |
+
"outputs": [],
|
| 157 |
+
"source": [
|
| 158 |
+
"HTML(model.animate())"
|
| 159 |
+
]
|
| 160 |
+
},
|
| 161 |
+
{
|
| 162 |
+
"cell_type": "code",
|
| 163 |
+
"execution_count": null,
|
| 164 |
+
"metadata": {
|
| 165 |
+
"id": "YSKWYu0_GlUH"
|
| 166 |
+
},
|
| 167 |
+
"outputs": [],
|
| 168 |
+
"source": [
|
| 169 |
+
"model.get_seqs()"
|
| 170 |
+
]
|
| 171 |
+
}
|
| 172 |
+
],
|
| 173 |
+
"metadata": {
|
| 174 |
+
"accelerator": "GPU",
|
| 175 |
+
"colab": {
|
| 176 |
+
"collapsed_sections": [
|
| 177 |
+
"q4qiU9I0QHSz"
|
| 178 |
+
],
|
| 179 |
+
"name": "hallucination.ipynb",
|
| 180 |
+
"provenance": [],
|
| 181 |
+
"include_colab_link": true
|
| 182 |
+
},
|
| 183 |
+
"kernelspec": {
|
| 184 |
+
"display_name": "Python 3",
|
| 185 |
+
"name": "python3"
|
| 186 |
+
},
|
| 187 |
+
"language_info": {
|
| 188 |
+
"name": "python"
|
| 189 |
+
}
|
| 190 |
+
},
|
| 191 |
+
"nbformat": 4,
|
| 192 |
+
"nbformat_minor": 0
|
| 193 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/hallucination_custom_loss.ipynb
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/examples/hallucination_custom_loss.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "markdown",
|
| 15 |
+
"metadata": {
|
| 16 |
+
"id": "OA2k3sAYuiXe"
|
| 17 |
+
},
|
| 18 |
+
"source": [
|
| 19 |
+
"# AfDesign - hallucination custom loss example\n",
|
| 20 |
+
"Backprop through AlphaFold for protein design."
|
| 21 |
+
]
|
| 22 |
+
},
|
| 23 |
+
{
|
| 24 |
+
"cell_type": "code",
|
| 25 |
+
"execution_count": null,
|
| 26 |
+
"metadata": {
|
| 27 |
+
"cellView": "form",
|
| 28 |
+
"id": "-AXy0s_4cKaK"
|
| 29 |
+
},
|
| 30 |
+
"outputs": [],
|
| 31 |
+
"source": [
|
| 32 |
+
"#@title setup\n",
|
| 33 |
+
"%%time\n",
|
| 34 |
+
"import os\n",
|
| 35 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 36 |
+
" # get code\n",
|
| 37 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git@v1.1.1\")\n",
|
| 38 |
+
" # for debugging\n",
|
| 39 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 40 |
+
" # download params\n",
|
| 41 |
+
" os.system(\"mkdir params\")\n",
|
| 42 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 43 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar\")\n",
|
| 44 |
+
" os.system(\"tar -xf alphafold_params_2022-12-06.tar -C params\")\n",
|
| 45 |
+
"\n",
|
| 46 |
+
"import warnings\n",
|
| 47 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 48 |
+
"\n",
|
| 49 |
+
"import os\n",
|
| 50 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 51 |
+
"from IPython.display import HTML\n",
|
| 52 |
+
"from google.colab import files\n",
|
| 53 |
+
"import numpy as np\n",
|
| 54 |
+
"\n",
|
| 55 |
+
"def get_pdb(pdb_code=\"\"):\n",
|
| 56 |
+
" if pdb_code is None or pdb_code == \"\":\n",
|
| 57 |
+
" upload_dict = files.upload()\n",
|
| 58 |
+
" pdb_string = upload_dict[list(upload_dict.keys())[0]]\n",
|
| 59 |
+
" with open(\"tmp.pdb\",\"wb\") as out: out.write(pdb_string)\n",
|
| 60 |
+
" return \"tmp.pdb\"\n",
|
| 61 |
+
" elif os.path.isfile(pdb_code):\n",
|
| 62 |
+
" return pdb_code\n",
|
| 63 |
+
" elif len(pdb_code) == 4:\n",
|
| 64 |
+
" os.system(f\"wget -qnc https://files.rcsb.org/view/{pdb_code}.pdb\")\n",
|
| 65 |
+
" return f\"{pdb_code}.pdb\"\n",
|
| 66 |
+
" else:\n",
|
| 67 |
+
" os.system(f\"wget -qnc https://alphafold.ebi.ac.uk/files/AF-{pdb_code}-F1-model_v3.pdb\")\n",
|
| 68 |
+
" return f\"AF-{pdb_code}-F1-model_v3.pdb\""
|
| 69 |
+
]
|
| 70 |
+
},
|
| 71 |
+
{
|
| 72 |
+
"cell_type": "markdown",
|
| 73 |
+
"metadata": {
|
| 74 |
+
"id": "UUfKrOzT0gOS"
|
| 75 |
+
},
|
| 76 |
+
"source": [
|
| 77 |
+
"# Custom loss"
|
| 78 |
+
]
|
| 79 |
+
},
|
| 80 |
+
{
|
| 81 |
+
"cell_type": "code",
|
| 82 |
+
"execution_count": null,
|
| 83 |
+
"metadata": {
|
| 84 |
+
"id": "qLd1DsnKzxBJ"
|
| 85 |
+
},
|
| 86 |
+
"outputs": [],
|
| 87 |
+
"source": [
|
| 88 |
+
"clear_mem()\n",
|
| 89 |
+
"af_model = mk_afdesign_model(protocol=\"hallucination\", debug=True)\n",
|
| 90 |
+
"af_model.prep_inputs(length=100)\n",
|
| 91 |
+
"\n",
|
| 92 |
+
"print(\"length\", af_model._len)\n",
|
| 93 |
+
"print(\"weights\", af_model.opt[\"weights\"])"
|
| 94 |
+
]
|
| 95 |
+
},
|
| 96 |
+
{
|
| 97 |
+
"cell_type": "code",
|
| 98 |
+
"source": [
|
| 99 |
+
"af_model.restart(mode=\"gumbel\",seed=0)\n",
|
| 100 |
+
"af_model.set_opt(soft=True)\n",
|
| 101 |
+
"af_model.run(backprop=False)"
|
| 102 |
+
],
|
| 103 |
+
"metadata": {
|
| 104 |
+
"id": "u0AwskJ84NGx"
|
| 105 |
+
},
|
| 106 |
+
"execution_count": null,
|
| 107 |
+
"outputs": []
|
| 108 |
+
},
|
| 109 |
+
{
|
| 110 |
+
"cell_type": "code",
|
| 111 |
+
"source": [
|
| 112 |
+
"from colabdesign.af.alphafold.common import residue_constants\n",
|
| 113 |
+
"import jax\n",
|
| 114 |
+
"import jax.numpy as jnp\n",
|
| 115 |
+
"\n",
|
| 116 |
+
"# first off, let's implement a custom Radius of Gyration loss function\n",
|
| 117 |
+
"def rg_loss(inputs, outputs):\n",
|
| 118 |
+
" positions = outputs[\"structure_module\"][\"final_atom_positions\"]\n",
|
| 119 |
+
" ca = positions[:,residue_constants.atom_order[\"CA\"]]\n",
|
| 120 |
+
" center = ca.mean(0)\n",
|
| 121 |
+
" rg = jnp.sqrt(jnp.square(ca - center).sum(-1).mean() + 1e-8)\n",
|
| 122 |
+
" rg_th = 2.38 * ca.shape[0] ** 0.365\n",
|
| 123 |
+
" rg = jax.nn.elu(rg - rg_th)\n",
|
| 124 |
+
" return {\"rg\":rg}"
|
| 125 |
+
],
|
| 126 |
+
"metadata": {
|
| 127 |
+
"id": "SGxkLR_4VsQI"
|
| 128 |
+
},
|
| 129 |
+
"execution_count": null,
|
| 130 |
+
"outputs": []
|
| 131 |
+
},
|
| 132 |
+
{
|
| 133 |
+
"cell_type": "code",
|
| 134 |
+
"source": [
|
| 135 |
+
"af_model.aux[\"debug\"].keys()"
|
| 136 |
+
],
|
| 137 |
+
"metadata": {
|
| 138 |
+
"id": "LAgsoVLhcJdr"
|
| 139 |
+
},
|
| 140 |
+
"execution_count": null,
|
| 141 |
+
"outputs": []
|
| 142 |
+
},
|
| 143 |
+
{
|
| 144 |
+
"cell_type": "code",
|
| 145 |
+
"source": [
|
| 146 |
+
"rg_loss(**af_model.aux[\"debug\"])"
|
| 147 |
+
],
|
| 148 |
+
"metadata": {
|
| 149 |
+
"id": "enMbbgFnWLwF"
|
| 150 |
+
},
|
| 151 |
+
"execution_count": null,
|
| 152 |
+
"outputs": []
|
| 153 |
+
},
|
| 154 |
+
{
|
| 155 |
+
"cell_type": "markdown",
|
| 156 |
+
"source": [
|
| 157 |
+
"#Let's add it to the model!"
|
| 158 |
+
],
|
| 159 |
+
"metadata": {
|
| 160 |
+
"id": "jmHGCynter0p"
|
| 161 |
+
}
|
| 162 |
+
},
|
| 163 |
+
{
|
| 164 |
+
"cell_type": "code",
|
| 165 |
+
"source": [
|
| 166 |
+
"clear_mem()\n",
|
| 167 |
+
"af_model = mk_afdesign_model(protocol=\"hallucination\",\n",
|
| 168 |
+
" debug=False,\n",
|
| 169 |
+
" loss_callback=rg_loss) # add our custom loss\n",
|
| 170 |
+
"af_model.opt[\"weights\"][\"rg\"] = 0.1 # add our loss to weights (so we can later control it)\n",
|
| 171 |
+
"af_model.prep_inputs(length=100)\n",
|
| 172 |
+
"print(\"weights\", af_model.opt[\"weights\"])"
|
| 173 |
+
],
|
| 174 |
+
"metadata": {
|
| 175 |
+
"id": "0D7Z0U6aVD1V"
|
| 176 |
+
},
|
| 177 |
+
"execution_count": null,
|
| 178 |
+
"outputs": []
|
| 179 |
+
},
|
| 180 |
+
{
|
| 181 |
+
"cell_type": "code",
|
| 182 |
+
"source": [
|
| 183 |
+
"af_model.restart(mode=\"gumbel\", seed=0)\n",
|
| 184 |
+
"af_model.design_soft(50)\n",
|
| 185 |
+
"\n",
|
| 186 |
+
"# three stage design \n",
|
| 187 |
+
"af_model.set_seq(af_model.aux[\"seq\"][\"pseudo\"])\n",
|
| 188 |
+
"af_model.design_3stage(50,50,10)"
|
| 189 |
+
],
|
| 190 |
+
"metadata": {
|
| 191 |
+
"id": "Wsc9IWsqXreX"
|
| 192 |
+
},
|
| 193 |
+
"execution_count": null,
|
| 194 |
+
"outputs": []
|
| 195 |
+
},
|
| 196 |
+
{
|
| 197 |
+
"cell_type": "code",
|
| 198 |
+
"execution_count": null,
|
| 199 |
+
"metadata": {
|
| 200 |
+
"id": "YEApO8YzBoS0"
|
| 201 |
+
},
|
| 202 |
+
"outputs": [],
|
| 203 |
+
"source": [
|
| 204 |
+
"af_model.save_pdb(f\"{af_model.protocol}.pdb\")\n",
|
| 205 |
+
"af_model.plot_pdb()"
|
| 206 |
+
]
|
| 207 |
+
},
|
| 208 |
+
{
|
| 209 |
+
"cell_type": "code",
|
| 210 |
+
"execution_count": null,
|
| 211 |
+
"metadata": {
|
| 212 |
+
"id": "cW1KQiHKJpfp"
|
| 213 |
+
},
|
| 214 |
+
"outputs": [],
|
| 215 |
+
"source": [
|
| 216 |
+
"HTML(af_model.animate())"
|
| 217 |
+
]
|
| 218 |
+
},
|
| 219 |
+
{
|
| 220 |
+
"cell_type": "code",
|
| 221 |
+
"source": [
|
| 222 |
+
"af_model.get_seqs()"
|
| 223 |
+
],
|
| 224 |
+
"metadata": {
|
| 225 |
+
"id": "YDrChASGVUUx"
|
| 226 |
+
},
|
| 227 |
+
"execution_count": null,
|
| 228 |
+
"outputs": []
|
| 229 |
+
},
|
| 230 |
+
{
|
| 231 |
+
"cell_type": "code",
|
| 232 |
+
"source": [],
|
| 233 |
+
"metadata": {
|
| 234 |
+
"id": "-js6TX9ZytR9"
|
| 235 |
+
},
|
| 236 |
+
"execution_count": null,
|
| 237 |
+
"outputs": []
|
| 238 |
+
}
|
| 239 |
+
],
|
| 240 |
+
"metadata": {
|
| 241 |
+
"accelerator": "GPU",
|
| 242 |
+
"colab": {
|
| 243 |
+
"collapsed_sections": [
|
| 244 |
+
"q4qiU9I0QHSz"
|
| 245 |
+
],
|
| 246 |
+
"name": "hallucination_custom_loss.ipynb",
|
| 247 |
+
"provenance": [],
|
| 248 |
+
"include_colab_link": true
|
| 249 |
+
},
|
| 250 |
+
"kernelspec": {
|
| 251 |
+
"display_name": "Python 3",
|
| 252 |
+
"name": "python3"
|
| 253 |
+
},
|
| 254 |
+
"language_info": {
|
| 255 |
+
"name": "python"
|
| 256 |
+
}
|
| 257 |
+
},
|
| 258 |
+
"nbformat": 4,
|
| 259 |
+
"nbformat_minor": 0
|
| 260 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/partial_hallucination_rewire.ipynb
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/examples/partial_hallucination_rewire.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "markdown",
|
| 15 |
+
"metadata": {
|
| 16 |
+
"id": "OA2k3sAYuiXe"
|
| 17 |
+
},
|
| 18 |
+
"source": [
|
| 19 |
+
"# AfDesign - rewire (partial hallucination)"
|
| 20 |
+
]
|
| 21 |
+
},
|
| 22 |
+
{
|
| 23 |
+
"cell_type": "code",
|
| 24 |
+
"execution_count": null,
|
| 25 |
+
"metadata": {
|
| 26 |
+
"cellView": "form",
|
| 27 |
+
"id": "-AXy0s_4cKaK"
|
| 28 |
+
},
|
| 29 |
+
"outputs": [],
|
| 30 |
+
"source": [
|
| 31 |
+
"#@title setup\n",
|
| 32 |
+
"%%time\n",
|
| 33 |
+
"import os\n",
|
| 34 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 35 |
+
" # get code\n",
|
| 36 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git@v1.1.1\")\n",
|
| 37 |
+
" # for debugging\n",
|
| 38 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 39 |
+
" # download params\n",
|
| 40 |
+
" os.system(\"mkdir params\")\n",
|
| 41 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 42 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar\")\n",
|
| 43 |
+
" os.system(\"tar -xf alphafold_params_2022-12-06.tar -C params\")\n",
|
| 44 |
+
"\n",
|
| 45 |
+
"import warnings\n",
|
| 46 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 47 |
+
"\n",
|
| 48 |
+
"import os\n",
|
| 49 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 50 |
+
"from IPython.display import HTML\n",
|
| 51 |
+
"from google.colab import files\n",
|
| 52 |
+
"import numpy as np\n",
|
| 53 |
+
"\n",
|
| 54 |
+
"def get_pdb(pdb_code=\"\"):\n",
|
| 55 |
+
" if pdb_code is None or pdb_code == \"\":\n",
|
| 56 |
+
" upload_dict = files.upload()\n",
|
| 57 |
+
" pdb_string = upload_dict[list(upload_dict.keys())[0]]\n",
|
| 58 |
+
" with open(\"tmp.pdb\",\"wb\") as out: out.write(pdb_string)\n",
|
| 59 |
+
" return \"tmp.pdb\"\n",
|
| 60 |
+
" elif os.path.isfile(pdb_code):\n",
|
| 61 |
+
" return pdb_code\n",
|
| 62 |
+
" elif len(pdb_code) == 4:\n",
|
| 63 |
+
" os.system(f\"wget -qnc https://files.rcsb.org/view/{pdb_code}.pdb\")\n",
|
| 64 |
+
" return f\"{pdb_code}.pdb\"\n",
|
| 65 |
+
" else:\n",
|
| 66 |
+
" os.system(f\"wget -qnc https://alphafold.ebi.ac.uk/files/AF-{pdb_code}-F1-model_v3.pdb\")\n",
|
| 67 |
+
" return f\"AF-{pdb_code}-F1-model_v3.pdb\""
|
| 68 |
+
]
|
| 69 |
+
},
|
| 70 |
+
{
|
| 71 |
+
"cell_type": "code",
|
| 72 |
+
"source": [
|
| 73 |
+
"# setup the model\n",
|
| 74 |
+
"clear_mem()\n",
|
| 75 |
+
"model = mk_afdesign_model(protocol=\"partial\",\n",
|
| 76 |
+
" use_templates=False) # set True to constrain positions using template input\n",
|
| 77 |
+
" \n",
|
| 78 |
+
"# define positions we want to constrain (input PDB numbering)\n",
|
| 79 |
+
"old_pos = \"4-9,13-26,30-33,37-50,54-59,63-76,80-84,112-125\"\n",
|
| 80 |
+
"\n",
|
| 81 |
+
"model.prep_inputs(get_pdb(\"2MR5\"), chain=\"A\",\n",
|
| 82 |
+
" pos=old_pos, # define positions to contrain\n",
|
| 83 |
+
" length=100, # define if the desired length is different from input PDB\n",
|
| 84 |
+
" fix_seq=False) # set True to constrain the sequence\n",
|
| 85 |
+
"\n",
|
| 86 |
+
"# set positions (if different from PDB)\n",
|
| 87 |
+
"# reorder the segments, \n",
|
| 88 |
+
"model.rewire(order = [1,2,3,0,7,4,5,6], # set order of segments\n",
|
| 89 |
+
" loops = [3,3,3,4,3,3,4], # change loop length inbetween segments\n",
|
| 90 |
+
" offset=0) # essentially loop length at the N term\n",
|
| 91 |
+
"\n",
|
| 92 |
+
"print(model.opt[\"pos\"])"
|
| 93 |
+
],
|
| 94 |
+
"metadata": {
|
| 95 |
+
"id": "_m7ZaaP4NkII"
|
| 96 |
+
},
|
| 97 |
+
"execution_count": null,
|
| 98 |
+
"outputs": []
|
| 99 |
+
},
|
| 100 |
+
{
|
| 101 |
+
"cell_type": "code",
|
| 102 |
+
"source": [
|
| 103 |
+
"# restart optimization\n",
|
| 104 |
+
"model.restart()\n",
|
| 105 |
+
"# model.set_seq(mode=\"wildtype\") # initialize with wildtype sequence\n",
|
| 106 |
+
"\n",
|
| 107 |
+
"# balance weights [dgram_cce = restraint weight], [con = hallucination weight]\n",
|
| 108 |
+
"model.set_weights(dgram_cce=1, con=0)\n",
|
| 109 |
+
"model.design_3stage(300,100,10)"
|
| 110 |
+
],
|
| 111 |
+
"metadata": {
|
| 112 |
+
"id": "bDA8cPqMT_eY"
|
| 113 |
+
},
|
| 114 |
+
"execution_count": null,
|
| 115 |
+
"outputs": []
|
| 116 |
+
},
|
| 117 |
+
{
|
| 118 |
+
"cell_type": "code",
|
| 119 |
+
"source": [
|
| 120 |
+
"model.save_pdb(f\"{model.protocol}.pdb\")\n",
|
| 121 |
+
"model.plot_pdb()"
|
| 122 |
+
],
|
| 123 |
+
"metadata": {
|
| 124 |
+
"id": "qFegtgcnHdqr"
|
| 125 |
+
},
|
| 126 |
+
"execution_count": null,
|
| 127 |
+
"outputs": []
|
| 128 |
+
},
|
| 129 |
+
{
|
| 130 |
+
"cell_type": "code",
|
| 131 |
+
"source": [
|
| 132 |
+
"HTML(model.animate())"
|
| 133 |
+
],
|
| 134 |
+
"metadata": {
|
| 135 |
+
"id": "9sjG7kvoHaVi"
|
| 136 |
+
},
|
| 137 |
+
"execution_count": null,
|
| 138 |
+
"outputs": []
|
| 139 |
+
}
|
| 140 |
+
],
|
| 141 |
+
"metadata": {
|
| 142 |
+
"accelerator": "GPU",
|
| 143 |
+
"colab": {
|
| 144 |
+
"collapsed_sections": [
|
| 145 |
+
"q4qiU9I0QHSz"
|
| 146 |
+
],
|
| 147 |
+
"name": "partial_hallucination_rewire.ipynb",
|
| 148 |
+
"provenance": [],
|
| 149 |
+
"include_colab_link": true
|
| 150 |
+
},
|
| 151 |
+
"kernelspec": {
|
| 152 |
+
"display_name": "Python 3",
|
| 153 |
+
"name": "python3"
|
| 154 |
+
},
|
| 155 |
+
"language_info": {
|
| 156 |
+
"name": "python"
|
| 157 |
+
}
|
| 158 |
+
},
|
| 159 |
+
"nbformat": 4,
|
| 160 |
+
"nbformat_minor": 0
|
| 161 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/peptide_binder_design.ipynb
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/examples/peptide_binder_design.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "markdown",
|
| 15 |
+
"metadata": {
|
| 16 |
+
"id": "OA2k3sAYuiXe"
|
| 17 |
+
},
|
| 18 |
+
"source": [
|
| 19 |
+
"# AfDesign - peptide binder design\n",
|
| 20 |
+
"For a given protein target and protein binder length, generate/hallucinate a protein binder sequence AlphaFold thinks will bind to the target structure. To do this, we maximize number of contacts at the interface and maximize pLDDT of the binder.\n",
|
| 21 |
+
"\n",
|
| 22 |
+
"**WARNING**\n",
|
| 23 |
+
"1. This notebook is in active development and was designed for demonstration purposes only.\n",
|
| 24 |
+
"2. Using AfDesign as the only \"loss\" function for design might be a bad idea, you may find adversarial sequences (aka. sequences that trick AlphaFold)."
|
| 25 |
+
]
|
| 26 |
+
},
|
| 27 |
+
{
|
| 28 |
+
"cell_type": "code",
|
| 29 |
+
"execution_count": null,
|
| 30 |
+
"metadata": {
|
| 31 |
+
"cellView": "form",
|
| 32 |
+
"id": "-AXy0s_4cKaK"
|
| 33 |
+
},
|
| 34 |
+
"outputs": [],
|
| 35 |
+
"source": [
|
| 36 |
+
"#@title **setup**\n",
|
| 37 |
+
"import os\n",
|
| 38 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 39 |
+
" # get code\n",
|
| 40 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git@v1.1.1\")\n",
|
| 41 |
+
" # for debugging\n",
|
| 42 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 43 |
+
" # download params\n",
|
| 44 |
+
" os.system(\"mkdir params\")\n",
|
| 45 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 46 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar\")\n",
|
| 47 |
+
" os.system(\"tar -xf alphafold_params_2022-12-06.tar -C params\")\n",
|
| 48 |
+
"\n",
|
| 49 |
+
"import warnings\n",
|
| 50 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 51 |
+
"\n",
|
| 52 |
+
"import os\n",
|
| 53 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 54 |
+
"from colabdesign.shared.utils import copy_dict\n",
|
| 55 |
+
"from colabdesign.af.alphafold.common import residue_constants\n",
|
| 56 |
+
"\n",
|
| 57 |
+
"from IPython.display import HTML\n",
|
| 58 |
+
"from google.colab import files\n",
|
| 59 |
+
"import numpy as np\n",
|
| 60 |
+
"\n",
|
| 61 |
+
"#########################\n",
|
| 62 |
+
"def get_pdb(pdb_code=\"\"):\n",
|
| 63 |
+
" if pdb_code is None or pdb_code == \"\":\n",
|
| 64 |
+
" upload_dict = files.upload()\n",
|
| 65 |
+
" pdb_string = upload_dict[list(upload_dict.keys())[0]]\n",
|
| 66 |
+
" with open(\"tmp.pdb\",\"wb\") as out: out.write(pdb_string)\n",
|
| 67 |
+
" return \"tmp.pdb\"\n",
|
| 68 |
+
" elif os.path.isfile(pdb_code):\n",
|
| 69 |
+
" return pdb_code\n",
|
| 70 |
+
" elif len(pdb_code) == 4:\n",
|
| 71 |
+
" os.system(f\"wget -qnc https://files.rcsb.org/view/{pdb_code}.pdb\")\n",
|
| 72 |
+
" return f\"{pdb_code}.pdb\"\n",
|
| 73 |
+
" else:\n",
|
| 74 |
+
" os.system(f\"wget -qnc https://alphafold.ebi.ac.uk/files/AF-{pdb_code}-F1-model_v3.pdb\")\n",
|
| 75 |
+
" return f\"AF-{pdb_code}-F1-model_v3.pdb\""
|
| 76 |
+
]
|
| 77 |
+
},
|
| 78 |
+
{
|
| 79 |
+
"cell_type": "code",
|
| 80 |
+
"source": [
|
| 81 |
+
"#@title **prep inputs**\n",
|
| 82 |
+
"import re\n",
|
| 83 |
+
"#@markdown ---\n",
|
| 84 |
+
"#@markdown **target info**\n",
|
| 85 |
+
"pdb = \"4N5T\" #@param {type:\"string\"}\n",
|
| 86 |
+
"#@markdown - enter PDB code or UniProt code (to fetch AlphaFoldDB model) or leave blink to upload your own\n",
|
| 87 |
+
"target_chain = \"A\" #@param {type:\"string\"}\n",
|
| 88 |
+
"target_hotspot = \"\" #@param {type:\"string\"}\n",
|
| 89 |
+
"if target_hotspot == \"\": target_hotspot = None\n",
|
| 90 |
+
"#@markdown - restrict loss to predefined positions on target (eg. \"1-10,12,15\")\n",
|
| 91 |
+
"target_flexible = False #@param {type:\"boolean\"}\n",
|
| 92 |
+
"#@markdown - allow backbone of target structure to be flexible\n",
|
| 93 |
+
"\n",
|
| 94 |
+
"#@markdown ---\n",
|
| 95 |
+
"#@markdown **binder info**\n",
|
| 96 |
+
"binder_len = 14 #@param {type:\"integer\"}\n",
|
| 97 |
+
"#@markdown - length of binder to hallucination\n",
|
| 98 |
+
"binder_seq = \"\" #@param {type:\"string\"}\n",
|
| 99 |
+
"binder_seq = re.sub(\"[^A-Z]\", \"\", binder_seq.upper())\n",
|
| 100 |
+
"if len(binder_seq) > 0:\n",
|
| 101 |
+
" binder_len = len(binder_seq)\n",
|
| 102 |
+
"else:\n",
|
| 103 |
+
" binder_seq = None\n",
|
| 104 |
+
"#@markdown - if defined, will initialize design with this sequence\n",
|
| 105 |
+
"\n",
|
| 106 |
+
"binder_chain = \"\" #@param {type:\"string\"}\n",
|
| 107 |
+
"if binder_chain == \"\": binder_chain = None\n",
|
| 108 |
+
"#@markdown - if defined, supervised loss is used (binder_len is ignored)\n",
|
| 109 |
+
"\n",
|
| 110 |
+
"#@markdown ---\n",
|
| 111 |
+
"#@markdown **model config**\n",
|
| 112 |
+
"use_multimer = False #@param {type:\"boolean\"}\n",
|
| 113 |
+
"#@markdown - use alphafold-multimer for design\n",
|
| 114 |
+
"num_recycles = 0 #@param [\"0\", \"1\", \"3\", \"6\"] {type:\"raw\"}\n",
|
| 115 |
+
"num_models = \"2\" #@param [\"1\", \"2\", \"3\", \"4\", \"5\", \"all\"]\n",
|
| 116 |
+
"num_models = 5 if num_models == \"all\" else int(num_models)\n",
|
| 117 |
+
"#@markdown - number of trained models to use during optimization\n",
|
| 118 |
+
"\n",
|
| 119 |
+
"\n",
|
| 120 |
+
"x = {\"pdb_filename\":pdb,\n",
|
| 121 |
+
" \"chain\":target_chain,\n",
|
| 122 |
+
" \"binder_len\":binder_len,\n",
|
| 123 |
+
" \"binder_chain\":binder_chain,\n",
|
| 124 |
+
" \"hotspot\":target_hotspot,\n",
|
| 125 |
+
" \"use_multimer\":use_multimer,\n",
|
| 126 |
+
" \"rm_target_seq\":target_flexible}\n",
|
| 127 |
+
" \n",
|
| 128 |
+
"x[\"pdb_filename\"] = get_pdb(x[\"pdb_filename\"]) \n",
|
| 129 |
+
"\n",
|
| 130 |
+
"if \"x_prev\" not in dir() or x != x_prev:\n",
|
| 131 |
+
" clear_mem()\n",
|
| 132 |
+
" model = mk_afdesign_model(protocol=\"binder\",\n",
|
| 133 |
+
" use_multimer=x[\"use_multimer\"],\n",
|
| 134 |
+
" num_recycles=num_recycles,\n",
|
| 135 |
+
" recycle_mode=\"sample\")\n",
|
| 136 |
+
" model.prep_inputs(**x,\n",
|
| 137 |
+
" ignore_missing=False)\n",
|
| 138 |
+
" x_prev = copy_dict(x)\n",
|
| 139 |
+
" print(\"target length:\", model._target_len)\n",
|
| 140 |
+
" print(\"binder length:\", model._binder_len)\n",
|
| 141 |
+
" binder_len = model._binder_len"
|
| 142 |
+
],
|
| 143 |
+
"metadata": {
|
| 144 |
+
"id": "HSgE99WALOE-",
|
| 145 |
+
"cellView": "form"
|
| 146 |
+
},
|
| 147 |
+
"execution_count": null,
|
| 148 |
+
"outputs": []
|
| 149 |
+
},
|
| 150 |
+
{
|
| 151 |
+
"cell_type": "code",
|
| 152 |
+
"source": [
|
| 153 |
+
"#@title **run AfDesign**\n",
|
| 154 |
+
"from scipy.special import softmax\n",
|
| 155 |
+
"\n",
|
| 156 |
+
"optimizer = \"pssm_semigreedy\" #@param [\"pssm_semigreedy\", \"3stage\", \"semigreedy\", \"pssm\", \"logits\", \"soft\", \"hard\"]\n",
|
| 157 |
+
"#@markdown - `pssm_semigreedy` - uses the designed PSSM to bias semigreedy opt. (Recommended)\n",
|
| 158 |
+
"#@markdown - `3stage` - gradient based optimization (GD) (logits → soft → hard)\n",
|
| 159 |
+
"#@markdown - `pssm` - GD optimize (logits → soft) to get a sequence profile (PSSM).\n",
|
| 160 |
+
"#@markdown - `semigreedy` - tries X random mutations, accepts those that decrease loss\n",
|
| 161 |
+
"#@markdown - `logits` - GD optimize logits inputs (continious)\n",
|
| 162 |
+
"#@markdown - `soft` - GD optimize softmax(logits) inputs (probabilities)\n",
|
| 163 |
+
"#@markdown - `hard` - GD optimize one_hot(logits) inputs (discrete)\n",
|
| 164 |
+
"\n",
|
| 165 |
+
"#@markdown WARNING: The output sequence from `pssm`,`logits`,`soft` is not one_hot. To get a valid sequence use the other optimizers, or redesign the output backbone with another protocol like ProteinMPNN.\n",
|
| 166 |
+
"\n",
|
| 167 |
+
"#@markdown ----\n",
|
| 168 |
+
"#@markdown #### advanced GD settings\n",
|
| 169 |
+
"GD_method = \"sgd\" #@param [\"adabelief\", \"adafactor\", \"adagrad\", \"adam\", \"adamw\", \"fromage\", \"lamb\", \"lars\", \"noisy_sgd\", \"dpsgd\", \"radam\", \"rmsprop\", \"sgd\", \"sm3\", \"yogi\"]\n",
|
| 170 |
+
"learning_rate = 0.1 #@param {type:\"raw\"}\n",
|
| 171 |
+
"norm_seq_grad = True #@param {type:\"boolean\"}\n",
|
| 172 |
+
"dropout = True #@param {type:\"boolean\"}\n",
|
| 173 |
+
"\n",
|
| 174 |
+
"model.restart(seq=binder_seq)\n",
|
| 175 |
+
"model.set_optimizer(optimizer=GD_method,\n",
|
| 176 |
+
" learning_rate=learning_rate,\n",
|
| 177 |
+
" norm_seq_grad=norm_seq_grad)\n",
|
| 178 |
+
"models = model._model_names[:num_models]\n",
|
| 179 |
+
"\n",
|
| 180 |
+
"flags = {\"num_recycles\":num_recycles,\n",
|
| 181 |
+
" \"models\":models,\n",
|
| 182 |
+
" \"dropout\":dropout}\n",
|
| 183 |
+
"\n",
|
| 184 |
+
"if optimizer == \"3stage\":\n",
|
| 185 |
+
" model.design_3stage(120, 60, 10, **flags)\n",
|
| 186 |
+
" pssm = softmax(model._tmp[\"seq_logits\"],-1)\n",
|
| 187 |
+
"\n",
|
| 188 |
+
"if optimizer == \"pssm_semigreedy\":\n",
|
| 189 |
+
" model.design_pssm_semigreedy(120, 32, **flags)\n",
|
| 190 |
+
" pssm = softmax(model._tmp[\"seq_logits\"],1)\n",
|
| 191 |
+
"\n",
|
| 192 |
+
"if optimizer == \"semigreedy\":\n",
|
| 193 |
+
" model.design_pssm_semigreedy(0, 32, **flags)\n",
|
| 194 |
+
" pssm = None\n",
|
| 195 |
+
"\n",
|
| 196 |
+
"if optimizer == \"pssm\":\n",
|
| 197 |
+
" model.design_logits(120, e_soft=1.0, num_models=1, ramp_recycles=True, **flags)\n",
|
| 198 |
+
" model.design_soft(32, num_models=1, **flags)\n",
|
| 199 |
+
" flags.update({\"dropout\":False,\"save_best\":True})\n",
|
| 200 |
+
" model.design_soft(10, num_models=num_models, **flags)\n",
|
| 201 |
+
" pssm = softmax(model.aux[\"seq\"][\"logits\"],-1)\n",
|
| 202 |
+
"\n",
|
| 203 |
+
"O = {\"logits\":model.design_logits,\n",
|
| 204 |
+
" \"soft\":model.design_soft,\n",
|
| 205 |
+
" \"hard\":model.design_hard}\n",
|
| 206 |
+
"\n",
|
| 207 |
+
"if optimizer in O:\n",
|
| 208 |
+
" O[optimizer](120, num_models=1, ramp_recycles=True, **flags)\n",
|
| 209 |
+
" flags.update({\"dropout\":False,\"save_best\":True})\n",
|
| 210 |
+
" O[optimizer](10, num_models=num_models, **flags)\n",
|
| 211 |
+
" pssm = softmax(model.aux[\"seq\"][\"logits\"],-1)\n",
|
| 212 |
+
"\n",
|
| 213 |
+
"model.save_pdb(f\"{model.protocol}.pdb\")"
|
| 214 |
+
],
|
| 215 |
+
"metadata": {
|
| 216 |
+
"cellView": "form",
|
| 217 |
+
"id": "60qmxpzno0yV"
|
| 218 |
+
},
|
| 219 |
+
"execution_count": null,
|
| 220 |
+
"outputs": []
|
| 221 |
+
},
|
| 222 |
+
{
|
| 223 |
+
"cell_type": "code",
|
| 224 |
+
"execution_count": null,
|
| 225 |
+
"metadata": {
|
| 226 |
+
"id": "A1GxeLZdTTya",
|
| 227 |
+
"cellView": "form"
|
| 228 |
+
},
|
| 229 |
+
"outputs": [],
|
| 230 |
+
"source": [
|
| 231 |
+
"#@title display hallucinated protein {run: \"auto\"}\n",
|
| 232 |
+
"color = \"pLDDT\" #@param [\"chain\", \"pLDDT\", \"rainbow\"]\n",
|
| 233 |
+
"show_sidechains = False #@param {type:\"boolean\"}\n",
|
| 234 |
+
"show_mainchains = False #@param {type:\"boolean\"}\n",
|
| 235 |
+
"color_HP = False #@param {type:\"boolean\"}\n",
|
| 236 |
+
"animate = True #@param {type:\"boolean\"}\n",
|
| 237 |
+
"model.plot_pdb(show_sidechains=show_sidechains,\n",
|
| 238 |
+
" show_mainchains=show_mainchains,\n",
|
| 239 |
+
" color=color, color_HP=color_HP, animate=animate)"
|
| 240 |
+
]
|
| 241 |
+
},
|
| 242 |
+
{
|
| 243 |
+
"cell_type": "code",
|
| 244 |
+
"execution_count": null,
|
| 245 |
+
"metadata": {
|
| 246 |
+
"id": "L2E9Tn2Acchj"
|
| 247 |
+
},
|
| 248 |
+
"outputs": [],
|
| 249 |
+
"source": [
|
| 250 |
+
"HTML(model.animate(dpi=100))"
|
| 251 |
+
]
|
| 252 |
+
},
|
| 253 |
+
{
|
| 254 |
+
"cell_type": "code",
|
| 255 |
+
"execution_count": null,
|
| 256 |
+
"metadata": {
|
| 257 |
+
"id": "YSKWYu0_GlUH"
|
| 258 |
+
},
|
| 259 |
+
"outputs": [],
|
| 260 |
+
"source": [
|
| 261 |
+
"model.save_pdb(f\"{model.protocol}.pdb\")\n",
|
| 262 |
+
"model.get_seqs()"
|
| 263 |
+
]
|
| 264 |
+
},
|
| 265 |
+
{
|
| 266 |
+
"cell_type": "code",
|
| 267 |
+
"source": [
|
| 268 |
+
"#@markdown ### Amino acid probabilties\n",
|
| 269 |
+
"import plotly.express as px\n",
|
| 270 |
+
"alphabet = \"ACDEFGHIKLMNPQRSTVWY\"\n",
|
| 271 |
+
"if \"pssm\" in dir() and pssm is not None:\n",
|
| 272 |
+
" fig = px.imshow(pssm.mean(0).T,\n",
|
| 273 |
+
" labels=dict(x=\"positions\", y=\"amino acids\", color=\"probability\"),\n",
|
| 274 |
+
" y=residue_constants.restypes,\n",
|
| 275 |
+
" zmin=0,\n",
|
| 276 |
+
" zmax=1,\n",
|
| 277 |
+
" template=\"simple_white\",\n",
|
| 278 |
+
" )\n",
|
| 279 |
+
" fig.update_xaxes(side=\"top\")\n",
|
| 280 |
+
" fig.show()"
|
| 281 |
+
],
|
| 282 |
+
"metadata": {
|
| 283 |
+
"cellView": "form",
|
| 284 |
+
"id": "3pvptBM55GHU"
|
| 285 |
+
},
|
| 286 |
+
"execution_count": null,
|
| 287 |
+
"outputs": []
|
| 288 |
+
},
|
| 289 |
+
{
|
| 290 |
+
"cell_type": "code",
|
| 291 |
+
"source": [
|
| 292 |
+
"# log\n",
|
| 293 |
+
"model._tmp[\"best\"][\"aux\"][\"log\"]"
|
| 294 |
+
],
|
| 295 |
+
"metadata": {
|
| 296 |
+
"id": "1SGmdJKLNKvb"
|
| 297 |
+
},
|
| 298 |
+
"execution_count": null,
|
| 299 |
+
"outputs": []
|
| 300 |
+
}
|
| 301 |
+
],
|
| 302 |
+
"metadata": {
|
| 303 |
+
"accelerator": "GPU",
|
| 304 |
+
"colab": {
|
| 305 |
+
"collapsed_sections": [],
|
| 306 |
+
"provenance": [],
|
| 307 |
+
"include_colab_link": true
|
| 308 |
+
},
|
| 309 |
+
"kernelspec": {
|
| 310 |
+
"display_name": "Python 3",
|
| 311 |
+
"name": "python3"
|
| 312 |
+
},
|
| 313 |
+
"language_info": {
|
| 314 |
+
"name": "python"
|
| 315 |
+
}
|
| 316 |
+
},
|
| 317 |
+
"nbformat": 4,
|
| 318 |
+
"nbformat_minor": 0
|
| 319 |
+
}
|
model/PXDesignBench/ColabDesign/af/examples/use_esm_1b_bias.ipynb
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {
|
| 6 |
+
"id": "view-in-github",
|
| 7 |
+
"colab_type": "text"
|
| 8 |
+
},
|
| 9 |
+
"source": [
|
| 10 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/v1.1.1/af/examples/use_esm_1b_bias.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 11 |
+
]
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"cell_type": "markdown",
|
| 15 |
+
"source": [
|
| 16 |
+
"# Gather inputs"
|
| 17 |
+
],
|
| 18 |
+
"metadata": {
|
| 19 |
+
"id": "M9xamJDvx1pd"
|
| 20 |
+
}
|
| 21 |
+
},
|
| 22 |
+
{
|
| 23 |
+
"cell_type": "code",
|
| 24 |
+
"source": [
|
| 25 |
+
"import requests, re\n",
|
| 26 |
+
"from google.colab import files\n",
|
| 27 |
+
"\n",
|
| 28 |
+
"def get_uniprot_seq(uid):\n",
|
| 29 |
+
" url = f'https://rest.uniprot.org/uniprotkb/stream?compressed=false&format=fasta&query={uid}'\n",
|
| 30 |
+
" sequence = \"\".join(re.split(r'\\n(?=>)', requests.get(url).text)[0].split(\"\\n\")[1:])\n",
|
| 31 |
+
" return sequence\n",
|
| 32 |
+
"\n",
|
| 33 |
+
"def get_pdb(pdb_code=\"\",alphafold_model=False):\n",
|
| 34 |
+
" if pdb_code is None or pdb_code == \"\":\n",
|
| 35 |
+
" upload_dict = files.upload()\n",
|
| 36 |
+
" pdb_string = upload_dict[list(upload_dict.keys())[0]]\n",
|
| 37 |
+
" with open(\"tmp.pdb\",\"wb\") as out: out.write(pdb_string)\n",
|
| 38 |
+
" return \"tmp.pdb\"\n",
|
| 39 |
+
" else:\n",
|
| 40 |
+
" if alphafold_model:\n",
|
| 41 |
+
" os.system(f\"wget -qnc https://alphafold.ebi.ac.uk/files/AF-{pdb_code}-F1-model_v3.pdb\")\n",
|
| 42 |
+
" return f\"AF-{pdb_code}-F1-model_v3.pdb\" \n",
|
| 43 |
+
" else:\n",
|
| 44 |
+
" os.system(f\"wget -qnc https://files.rcsb.org/view/{pdb_code}.pdb\")\n",
|
| 45 |
+
" return f\"{pdb_code}.pdb\""
|
| 46 |
+
],
|
| 47 |
+
"metadata": {
|
| 48 |
+
"id": "lev6Nc_-vx2D"
|
| 49 |
+
},
|
| 50 |
+
"execution_count": null,
|
| 51 |
+
"outputs": []
|
| 52 |
+
},
|
| 53 |
+
{
|
| 54 |
+
"cell_type": "code",
|
| 55 |
+
"source": [
|
| 56 |
+
"UNIPROT = \"P0A6A8\"\n",
|
| 57 |
+
"SEQUENCE = get_uniprot_seq(UNIPROT)\n",
|
| 58 |
+
"PDB_FILENAME = get_pdb(UNIPROT, alphafold_model=True)"
|
| 59 |
+
],
|
| 60 |
+
"metadata": {
|
| 61 |
+
"id": "VkPdQj-Fv1LQ"
|
| 62 |
+
},
|
| 63 |
+
"execution_count": null,
|
| 64 |
+
"outputs": []
|
| 65 |
+
},
|
| 66 |
+
{
|
| 67 |
+
"cell_type": "markdown",
|
| 68 |
+
"metadata": {
|
| 69 |
+
"id": "H5LVw2BwijkB"
|
| 70 |
+
},
|
| 71 |
+
"source": [
|
| 72 |
+
"#ESM_1b\n",
|
| 73 |
+
"use logits from ESM_1b as prior to AfDesign"
|
| 74 |
+
]
|
| 75 |
+
},
|
| 76 |
+
{
|
| 77 |
+
"cell_type": "code",
|
| 78 |
+
"execution_count": null,
|
| 79 |
+
"metadata": {
|
| 80 |
+
"id": "8j12AU-SikvN"
|
| 81 |
+
},
|
| 82 |
+
"outputs": [],
|
| 83 |
+
"source": [
|
| 84 |
+
"!pip -q install fair-esm\n",
|
| 85 |
+
"import esm\n",
|
| 86 |
+
"import gc\n",
|
| 87 |
+
"import torch\n",
|
| 88 |
+
"import numpy as np"
|
| 89 |
+
]
|
| 90 |
+
},
|
| 91 |
+
{
|
| 92 |
+
"cell_type": "code",
|
| 93 |
+
"execution_count": null,
|
| 94 |
+
"metadata": {
|
| 95 |
+
"id": "63LNj3dHilRW"
|
| 96 |
+
},
|
| 97 |
+
"outputs": [],
|
| 98 |
+
"source": [
|
| 99 |
+
"model, alphabet = esm.pretrained.esm1b_t33_650M_UR50S()\n",
|
| 100 |
+
"\n",
|
| 101 |
+
"# run model on GPU if available\n",
|
| 102 |
+
"device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')\n",
|
| 103 |
+
"model = model.to(device)\n",
|
| 104 |
+
"model = model.eval()\n",
|
| 105 |
+
"model.args.token_dropout = False"
|
| 106 |
+
]
|
| 107 |
+
},
|
| 108 |
+
{
|
| 109 |
+
"cell_type": "code",
|
| 110 |
+
"execution_count": null,
|
| 111 |
+
"metadata": {
|
| 112 |
+
"id": "ql8K460bjQtv"
|
| 113 |
+
},
|
| 114 |
+
"outputs": [],
|
| 115 |
+
"source": [
|
| 116 |
+
"def get_bias_from_esm(seq, p=None):\n",
|
| 117 |
+
" '''p=None; number of calculation done in parallel (increase if you have more gpu-memory)'''\n",
|
| 118 |
+
"\n",
|
| 119 |
+
" # map esm-alphabet to standard-alphabet\n",
|
| 120 |
+
" tmp_a2n = {a:n for n,a in enumerate(alphabet.all_toks[4:24])}\n",
|
| 121 |
+
" tmp_aa_map = np.array([tmp_a2n[a] for a in \"ARNDCQEGHILKMFPSTWYV\"])\n",
|
| 122 |
+
"\n",
|
| 123 |
+
" x,ln = alphabet.get_batch_converter()([(None,seq)])[-1],len(seq)\n",
|
| 124 |
+
" if p is None: p = ln\n",
|
| 125 |
+
" with torch.no_grad():\n",
|
| 126 |
+
" f = lambda x: model(x)[\"logits\"][:,1:(ln+1),4:24]\n",
|
| 127 |
+
" logits = np.zeros((ln,20))\n",
|
| 128 |
+
" for n in range(0,ln,p):\n",
|
| 129 |
+
" m = min(n+p,ln)\n",
|
| 130 |
+
" x_h = torch.tile(torch.clone(x),[m-n,1])\n",
|
| 131 |
+
" for i in range(m-n):\n",
|
| 132 |
+
" x_h[i,n+i+1] = alphabet.mask_idx\n",
|
| 133 |
+
" fx_h = f(x_h.to(device))\n",
|
| 134 |
+
" for i in range(m-n):\n",
|
| 135 |
+
" logits[n+i] = fx_h[i,n+i].cpu().numpy()\n",
|
| 136 |
+
" \n",
|
| 137 |
+
" return logits[:,tmp_aa_map]"
|
| 138 |
+
]
|
| 139 |
+
},
|
| 140 |
+
{
|
| 141 |
+
"cell_type": "code",
|
| 142 |
+
"execution_count": null,
|
| 143 |
+
"metadata": {
|
| 144 |
+
"id": "mrD1PRRMkZt3"
|
| 145 |
+
},
|
| 146 |
+
"outputs": [],
|
| 147 |
+
"source": [
|
| 148 |
+
"# get bias\n",
|
| 149 |
+
"seq = SEQUENCE\n",
|
| 150 |
+
"bias = get_bias_from_esm(seq)\n",
|
| 151 |
+
"np.savetxt(\"bias.txt\",bias)"
|
| 152 |
+
]
|
| 153 |
+
},
|
| 154 |
+
{
|
| 155 |
+
"cell_type": "code",
|
| 156 |
+
"execution_count": null,
|
| 157 |
+
"metadata": {
|
| 158 |
+
"id": "K_8S9rXOkwZ8"
|
| 159 |
+
},
|
| 160 |
+
"outputs": [],
|
| 161 |
+
"source": [
|
| 162 |
+
"import matplotlib.pyplot as plt\n",
|
| 163 |
+
"plt.imshow(bias.T,cmap=\"bwr_r\",vmin=-10,vmax=10)"
|
| 164 |
+
]
|
| 165 |
+
},
|
| 166 |
+
{
|
| 167 |
+
"cell_type": "code",
|
| 168 |
+
"source": [
|
| 169 |
+
"# clear GPU memory\n",
|
| 170 |
+
"del model\n",
|
| 171 |
+
"gc.collect()\n",
|
| 172 |
+
"torch.cuda.empty_cache()"
|
| 173 |
+
],
|
| 174 |
+
"metadata": {
|
| 175 |
+
"id": "10_kZfNQJpsz"
|
| 176 |
+
},
|
| 177 |
+
"execution_count": null,
|
| 178 |
+
"outputs": []
|
| 179 |
+
},
|
| 180 |
+
{
|
| 181 |
+
"cell_type": "markdown",
|
| 182 |
+
"metadata": {
|
| 183 |
+
"id": "OA2k3sAYuiXe"
|
| 184 |
+
},
|
| 185 |
+
"source": [
|
| 186 |
+
"#AfDesign \n"
|
| 187 |
+
]
|
| 188 |
+
},
|
| 189 |
+
{
|
| 190 |
+
"cell_type": "code",
|
| 191 |
+
"execution_count": null,
|
| 192 |
+
"metadata": {
|
| 193 |
+
"cellView": "form",
|
| 194 |
+
"id": "-AXy0s_4cKaK"
|
| 195 |
+
},
|
| 196 |
+
"outputs": [],
|
| 197 |
+
"source": [
|
| 198 |
+
"#@title setup afdesign\n",
|
| 199 |
+
"%%time\n",
|
| 200 |
+
"import os\n",
|
| 201 |
+
"if not os.path.isdir(\"params\"):\n",
|
| 202 |
+
" # get code\n",
|
| 203 |
+
" os.system(\"pip -q install git+https://github.com/sokrypton/ColabDesign.git@v1.1.1\")\n",
|
| 204 |
+
" # for debugging\n",
|
| 205 |
+
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabdesign colabdesign\")\n",
|
| 206 |
+
" # download params\n",
|
| 207 |
+
" os.system(\"mkdir params\")\n",
|
| 208 |
+
" os.system(\"apt-get install aria2 -qq\")\n",
|
| 209 |
+
" os.system(\"aria2c -q -x 16 https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar\")\n",
|
| 210 |
+
" os.system(\"tar -xf alphafold_params_2022-12-06.tar -C params\")\n",
|
| 211 |
+
"\n",
|
| 212 |
+
"import warnings\n",
|
| 213 |
+
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
|
| 214 |
+
"\n",
|
| 215 |
+
"import os\n",
|
| 216 |
+
"from colabdesign import mk_afdesign_model, clear_mem\n",
|
| 217 |
+
"from colabdesign.af.alphafold.common import residue_constants\n",
|
| 218 |
+
"from IPython.display import HTML\n",
|
| 219 |
+
"import numpy as np\n",
|
| 220 |
+
"\n"
|
| 221 |
+
]
|
| 222 |
+
|
| 223 |
+
},
|
| 224 |
+
{
|
| 225 |
+
"cell_type": "code",
|
| 226 |
+
"execution_count": null,
|
| 227 |
+
"metadata": {
|
| 228 |
+
"id": "qLd1DsnKzxBJ"
|
| 229 |
+
},
|
| 230 |
+
"outputs": [],
|
| 231 |
+
"source": [
|
| 232 |
+
"clear_mem()\n",
|
| 233 |
+
"model = mk_afdesign_model(protocol=\"fixbb\",\n",
|
| 234 |
+
" use_templates=False) # set True to constrain structure\n",
|
| 235 |
+
"model.prep_inputs(PDB_FILENAME, chain=\"A\")\n",
|
| 236 |
+
"print(\"length\", model._len)"
|
| 237 |
+
]
|
| 238 |
+
},
|
| 239 |
+
{
|
| 240 |
+
"cell_type": "code",
|
| 241 |
+
"execution_count": null,
|
| 242 |
+
"metadata": {
|
| 243 |
+
"id": "WZGyGfMTmdXE"
|
| 244 |
+
},
|
| 245 |
+
"outputs": [],
|
| 246 |
+
"source": [
|
| 247 |
+
"import matplotlib.pyplot as plt\n",
|
| 248 |
+
"bias = np.loadtxt(\"bias.txt\")\n",
|
| 249 |
+
"plt.imshow(bias.T,cmap=\"bwr_r\",vmin=-10,vmax=10)"
|
| 250 |
+
]
|
| 251 |
+
},
|
| 252 |
+
{
|
| 253 |
+
"cell_type": "code",
|
| 254 |
+
"execution_count": null,
|
| 255 |
+
"metadata": {
|
| 256 |
+
"id": "xeVuwTYWmQmp"
|
| 257 |
+
},
|
| 258 |
+
"outputs": [],
|
| 259 |
+
"source": [
|
| 260 |
+
"model.restart()\n",
|
| 261 |
+
"model.set_seq(bias=bias)\n",
|
| 262 |
+
"model.design_3stage(50,50,10)"
|
| 263 |
+
]
|
| 264 |
+
},
|
| 265 |
+
{
|
| 266 |
+
"cell_type": "code",
|
| 267 |
+
"execution_count": null,
|
| 268 |
+
"metadata": {
|
| 269 |
+
"id": "cW1KQiHKJpfp"
|
| 270 |
+
},
|
| 271 |
+
"outputs": [],
|
| 272 |
+
"source": [
|
| 273 |
+
"HTML(model.animate())"
|
| 274 |
+
]
|
| 275 |
+
},
|
| 276 |
+
{
|
| 277 |
+
"cell_type": "code",
|
| 278 |
+
"execution_count": null,
|
| 279 |
+
"metadata": {
|
| 280 |
+
"id": "YDrChASGVUUx"
|
| 281 |
+
},
|
| 282 |
+
"outputs": [],
|
| 283 |
+
"source": [
|
| 284 |
+
"model.get_seqs()"
|
| 285 |
+
]
|
| 286 |
+
},
|
| 287 |
+
{
|
| 288 |
+
"cell_type": "code",
|
| 289 |
+
"execution_count": null,
|
| 290 |
+
"metadata": {
|
| 291 |
+
"id": "YEApO8YzBoS0"
|
| 292 |
+
},
|
| 293 |
+
"outputs": [],
|
| 294 |
+
"source": [
|
| 295 |
+
"model.save_pdb(f\"{model.protocol}.pdb\")\n",
|
| 296 |
+
"model.plot_pdb()"
|
| 297 |
+
]
|
| 298 |
+
},
|
| 299 |
+
{
|
| 300 |
+
"cell_type": "code",
|
| 301 |
+
"source": [],
|
| 302 |
+
"metadata": {
|
| 303 |
+
"id": "0Xd7zQ-PqTly"
|
| 304 |
+
},
|
| 305 |
+
"execution_count": null,
|
| 306 |
+
"outputs": []
|
| 307 |
+
}
|
| 308 |
+
],
|
| 309 |
+
"metadata": {
|
| 310 |
+
"accelerator": "GPU",
|
| 311 |
+
"colab": {
|
| 312 |
+
"collapsed_sections": [
|
| 313 |
+
"q4qiU9I0QHSz"
|
| 314 |
+
],
|
| 315 |
+
"name": "use_esm_1b_bias.ipynb",
|
| 316 |
+
"provenance": [],
|
| 317 |
+
"include_colab_link": true
|
| 318 |
+
},
|
| 319 |
+
"kernelspec": {
|
| 320 |
+
"display_name": "Python 3",
|
| 321 |
+
"name": "python3"
|
| 322 |
+
},
|
| 323 |
+
"language_info": {
|
| 324 |
+
"name": "python"
|
| 325 |
+
}
|
| 326 |
+
},
|
| 327 |
+
"nbformat": 4,
|
| 328 |
+
"nbformat_minor": 0
|
| 329 |
+
}
|
model/PXDesignBench/ColabDesign/af_design_tutorial.ipynb
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"nbformat": 4,
|
| 3 |
+
"nbformat_minor": 0,
|
| 4 |
+
"metadata": {
|
| 5 |
+
"colab": {
|
| 6 |
+
"provenance": [],
|
| 7 |
+
"authorship_tag": "ABX9TyM3Mazv53Et9F6cqnRak08f",
|
| 8 |
+
"include_colab_link": true
|
| 9 |
+
},
|
| 10 |
+
"kernelspec": {
|
| 11 |
+
"name": "python3",
|
| 12 |
+
"display_name": "Python 3"
|
| 13 |
+
},
|
| 14 |
+
"language_info": {
|
| 15 |
+
"name": "python"
|
| 16 |
+
}
|
| 17 |
+
},
|
| 18 |
+
"cells": [
|
| 19 |
+
{
|
| 20 |
+
"cell_type": "markdown",
|
| 21 |
+
"metadata": {
|
| 22 |
+
"id": "view-in-github",
|
| 23 |
+
"colab_type": "text"
|
| 24 |
+
},
|
| 25 |
+
"source": [
|
| 26 |
+
"<a href=\"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/main/af/design.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
| 27 |
+
]
|
| 28 |
+
},
|
| 29 |
+
{
|
| 30 |
+
"cell_type": "markdown",
|
| 31 |
+
"source": [
|
| 32 |
+
"The general tutorial has moved to:\n",
|
| 33 |
+
"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/main/af/design.ipynb\n",
|
| 34 |
+
"\n",
|
| 35 |
+
"For peptide design tutorial see:\n",
|
| 36 |
+
"https://colab.research.google.com/github/sokrypton/ColabDesign/blob/main/af/examples/peptide_binder_design.ipynb"
|
| 37 |
+
],
|
| 38 |
+
"metadata": {
|
| 39 |
+
"id": "IabCAgHR6Xa3"
|
| 40 |
+
}
|
| 41 |
+
}
|
| 42 |
+
]
|
| 43 |
+
}
|
model/PXDesignBench/ColabDesign/colabdesign/__init__.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os,jax
|
| 2 |
+
# disable triton_gemm for jax versions > 0.3
|
| 3 |
+
if int(jax.__version__.split(".")[1]) > 3:
|
| 4 |
+
os.environ["XLA_FLAGS"] = "--xla_gpu_enable_triton_gemm=false"
|
| 5 |
+
|
| 6 |
+
import warnings
|
| 7 |
+
warnings.simplefilter(action='ignore', category=FutureWarning)
|
| 8 |
+
|
| 9 |
+
from colabdesign.shared.utils import clear_mem
|
| 10 |
+
from colabdesign.af.model import mk_af_model
|
| 11 |
+
from colabdesign.tr.model import mk_tr_model
|
| 12 |
+
from colabdesign.mpnn.model import mk_mpnn_model
|
| 13 |
+
|
| 14 |
+
# backward compatability
|
| 15 |
+
mk_design_model = mk_afdesign_model = mk_af_model
|
| 16 |
+
mk_trdesign_model = mk_tr_model
|
model/PXDesignBench/ColabDesign/colabdesign/af/README.md
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
- model.py - configure the model
|
| 2 |
+
- inputs.py - configure the inputs
|
| 3 |
+
- loss.py - configure the loss
|
| 4 |
+
- prep.py - prep features
|
| 5 |
+
- design.py - gradient update loop
|
| 6 |
+
- utils.py - various tools for saving/plotting
|
model/PXDesignBench/ColabDesign/colabdesign/af/__init__.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os,jax
|
| 2 |
+
# disable triton_gemm for jax versions > 0.3
|
| 3 |
+
if int(jax.__version__.split(".")[1]) > 3:
|
| 4 |
+
os.environ["XLA_FLAGS"] = "--xla_gpu_enable_triton_gemm=false"
|
| 5 |
+
|
| 6 |
+
import warnings
|
| 7 |
+
warnings.simplefilter(action='ignore', category=FutureWarning)
|
| 8 |
+
|
| 9 |
+
from colabdesign.shared.utils import clear_mem
|
| 10 |
+
from colabdesign.af.model import mk_af_model
|
| 11 |
+
|
| 12 |
+
# backward compatability
|
| 13 |
+
mk_design_model = mk_afdesign_model = mk_af_model
|
model/PXDesignBench/ColabDesign/colabdesign/af/alphafold/__init__.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2021 DeepMind Technologies Limited
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""An implementation of the inference pipeline of AlphaFold v2.0."""
|
model/PXDesignBench/ColabDesign/colabdesign/af/alphafold/common/__init__.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2021 DeepMind Technologies Limited
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""Common data types and constants used within Alphafold."""
|
model/PXDesignBench/ColabDesign/colabdesign/af/alphafold/common/confidence.py
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2021 DeepMind Technologies Limited
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
"""Functions for processing confidence metrics."""
|
| 16 |
+
|
| 17 |
+
import jax.numpy as jnp
|
| 18 |
+
import jax
|
| 19 |
+
import numpy as np
|
| 20 |
+
from colabdesign.af.alphafold.common import residue_constants
|
| 21 |
+
import scipy.special
|
| 22 |
+
|
| 23 |
+
def compute_tol(prev_pos, current_pos, mask, use_jnp=False):
|
| 24 |
+
# Early stopping criteria based on criteria used in
|
| 25 |
+
# AF2Complex: https://www.nature.com/articles/s41467-022-29394-2
|
| 26 |
+
_np = jnp if use_jnp else np
|
| 27 |
+
dist = lambda x:_np.sqrt(((x[:,None] - x[None,:])**2).sum(-1))
|
| 28 |
+
ca_idx = residue_constants.atom_order['CA']
|
| 29 |
+
sq_diff = _np.square(dist(prev_pos[:,ca_idx])-dist(current_pos[:,ca_idx]))
|
| 30 |
+
mask_2d = mask[:,None] * mask[None,:]
|
| 31 |
+
return _np.sqrt((sq_diff * mask_2d).sum()/mask_2d.sum() + 1e-8)
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def compute_plddt(logits, use_jnp=False):
|
| 35 |
+
"""Computes per-residue pLDDT from logits.
|
| 36 |
+
Args:
|
| 37 |
+
logits: [num_res, num_bins] output from the PredictedLDDTHead.
|
| 38 |
+
Returns:
|
| 39 |
+
plddt: [num_res] per-residue pLDDT.
|
| 40 |
+
"""
|
| 41 |
+
if use_jnp:
|
| 42 |
+
_np, _softmax = jnp, jax.nn.softmax
|
| 43 |
+
else:
|
| 44 |
+
_np, _softmax = np, scipy.special.softmax
|
| 45 |
+
|
| 46 |
+
num_bins = logits.shape[-1]
|
| 47 |
+
bin_width = 1.0 / num_bins
|
| 48 |
+
bin_centers = _np.arange(start=0.5 * bin_width, stop=1.0, step=bin_width)
|
| 49 |
+
probs = _softmax(logits, axis=-1)
|
| 50 |
+
predicted_lddt_ca = (probs * bin_centers[None, :]).sum(-1)
|
| 51 |
+
return predicted_lddt_ca * 100
|
| 52 |
+
|
| 53 |
+
def _calculate_bin_centers(breaks, use_jnp=False):
|
| 54 |
+
"""Gets the bin centers from the bin edges.
|
| 55 |
+
Args:
|
| 56 |
+
breaks: [num_bins - 1] the error bin edges.
|
| 57 |
+
Returns:
|
| 58 |
+
bin_centers: [num_bins] the error bin centers.
|
| 59 |
+
"""
|
| 60 |
+
_np = jnp if use_jnp else np
|
| 61 |
+
step = breaks[1] - breaks[0]
|
| 62 |
+
|
| 63 |
+
# Add half-step to get the center
|
| 64 |
+
bin_centers = breaks + step / 2
|
| 65 |
+
|
| 66 |
+
# Add a catch-all bin at the end.
|
| 67 |
+
return _np.append(bin_centers, bin_centers[-1] + step)
|
| 68 |
+
|
| 69 |
+
def _calculate_expected_aligned_error(
|
| 70 |
+
alignment_confidence_breaks,
|
| 71 |
+
aligned_distance_error_probs,
|
| 72 |
+
use_jnp=False):
|
| 73 |
+
"""Calculates expected aligned distance errors for every pair of residues.
|
| 74 |
+
Args:
|
| 75 |
+
alignment_confidence_breaks: [num_bins - 1] the error bin edges.
|
| 76 |
+
aligned_distance_error_probs: [num_res, num_res, num_bins] the predicted
|
| 77 |
+
probs for each error bin, for each pair of residues.
|
| 78 |
+
Returns:
|
| 79 |
+
predicted_aligned_error: [num_res, num_res] the expected aligned distance
|
| 80 |
+
error for each pair of residues.
|
| 81 |
+
max_predicted_aligned_error: The maximum predicted error possible.
|
| 82 |
+
"""
|
| 83 |
+
bin_centers = _calculate_bin_centers(alignment_confidence_breaks, use_jnp=use_jnp)
|
| 84 |
+
# Tuple of expected aligned distance error and max possible error.
|
| 85 |
+
pae = (aligned_distance_error_probs * bin_centers).sum(-1)
|
| 86 |
+
return (pae, bin_centers[-1])
|
| 87 |
+
|
| 88 |
+
def compute_predicted_aligned_error(logits, breaks, use_jnp=False):
|
| 89 |
+
"""Computes aligned confidence metrics from logits.
|
| 90 |
+
Args:
|
| 91 |
+
logits: [num_res, num_res, num_bins] the logits output from
|
| 92 |
+
PredictedAlignedErrorHead.
|
| 93 |
+
breaks: [num_bins - 1] the error bin edges.
|
| 94 |
+
|
| 95 |
+
Returns:
|
| 96 |
+
aligned_confidence_probs: [num_res, num_res, num_bins] the predicted
|
| 97 |
+
aligned error probabilities over bins for each residue pair.
|
| 98 |
+
predicted_aligned_error: [num_res, num_res] the expected aligned distance
|
| 99 |
+
error for each pair of residues.
|
| 100 |
+
max_predicted_aligned_error: The maximum predicted error possible.
|
| 101 |
+
"""
|
| 102 |
+
_softmax = jax.nn.softmax if use_jnp else scipy.special.softmax
|
| 103 |
+
aligned_confidence_probs = _softmax(logits,axis=-1)
|
| 104 |
+
predicted_aligned_error, max_predicted_aligned_error = \
|
| 105 |
+
_calculate_expected_aligned_error(breaks, aligned_confidence_probs, use_jnp=use_jnp)
|
| 106 |
+
|
| 107 |
+
return {
|
| 108 |
+
'aligned_confidence_probs': aligned_confidence_probs,
|
| 109 |
+
'predicted_aligned_error': predicted_aligned_error,
|
| 110 |
+
'max_predicted_aligned_error': max_predicted_aligned_error,
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
def predicted_tm_score(logits, breaks, residue_weights = None,
|
| 114 |
+
asym_id = None, use_jnp=False):
|
| 115 |
+
"""Computes predicted TM alignment or predicted interface TM alignment score.
|
| 116 |
+
|
| 117 |
+
Args:
|
| 118 |
+
logits: [num_res, num_res, num_bins] the logits output from
|
| 119 |
+
PredictedAlignedErrorHead.
|
| 120 |
+
breaks: [num_bins] the error bins.
|
| 121 |
+
residue_weights: [num_res] the per residue weights to use for the
|
| 122 |
+
expectation.
|
| 123 |
+
asym_id: [num_res] the asymmetric unit ID - the chain ID. Only needed for
|
| 124 |
+
ipTM calculation.
|
| 125 |
+
|
| 126 |
+
Returns:
|
| 127 |
+
ptm_score: The predicted TM alignment or the predicted iTM score.
|
| 128 |
+
"""
|
| 129 |
+
if use_jnp:
|
| 130 |
+
_np, _softmax = jnp, jax.nn.softmax
|
| 131 |
+
else:
|
| 132 |
+
_np, _softmax = np, scipy.special.softmax
|
| 133 |
+
|
| 134 |
+
# residue_weights has to be in [0, 1], but can be floating-point, i.e. the
|
| 135 |
+
# exp. resolved head's probability.
|
| 136 |
+
if residue_weights is None:
|
| 137 |
+
residue_weights = _np.ones(logits.shape[0])
|
| 138 |
+
|
| 139 |
+
bin_centers = _calculate_bin_centers(breaks, use_jnp=use_jnp)
|
| 140 |
+
num_res = residue_weights.shape[0]
|
| 141 |
+
|
| 142 |
+
# Clip num_res to avoid negative/undefined d0.
|
| 143 |
+
clipped_num_res = _np.maximum(residue_weights.sum(), 19)
|
| 144 |
+
|
| 145 |
+
# Compute d_0(num_res) as defined by TM-score, eqn. (5) in Yang & Skolnick
|
| 146 |
+
# "Scoring function for automated assessment of protein structure template
|
| 147 |
+
# quality", 2004: http://zhanglab.ccmb.med.umich.edu/papers/2004_3.pdf
|
| 148 |
+
d0 = 1.24 * (clipped_num_res - 15) ** (1./3) - 1.8
|
| 149 |
+
|
| 150 |
+
# Convert logits to probs.
|
| 151 |
+
probs = _softmax(logits, axis=-1)
|
| 152 |
+
|
| 153 |
+
# TM-Score term for every bin.
|
| 154 |
+
tm_per_bin = 1. / (1 + _np.square(bin_centers) / _np.square(d0))
|
| 155 |
+
# E_distances tm(distance).
|
| 156 |
+
predicted_tm_term = (probs * tm_per_bin).sum(-1)
|
| 157 |
+
|
| 158 |
+
if asym_id is None:
|
| 159 |
+
pair_mask = _np.full((num_res,num_res),True)
|
| 160 |
+
else:
|
| 161 |
+
pair_mask = asym_id[:, None] != asym_id[None, :]
|
| 162 |
+
|
| 163 |
+
predicted_tm_term *= pair_mask
|
| 164 |
+
|
| 165 |
+
pair_residue_weights = pair_mask * (residue_weights[None, :] * residue_weights[:, None])
|
| 166 |
+
normed_residue_mask = pair_residue_weights / (1e-8 + pair_residue_weights.sum(-1, keepdims=True))
|
| 167 |
+
per_alignment = (predicted_tm_term * normed_residue_mask).sum(-1)
|
| 168 |
+
|
| 169 |
+
return (per_alignment * residue_weights).max()
|
model/PXDesignBench/ColabDesign/colabdesign/af/alphafold/common/protein.py
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2021 DeepMind Technologies Limited
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
"""Protein data type."""
|
| 16 |
+
import dataclasses
|
| 17 |
+
import io
|
| 18 |
+
from typing import Any, Mapping, Optional
|
| 19 |
+
from colabdesign.af.alphafold.common import residue_constants
|
| 20 |
+
from Bio.PDB import PDBParser
|
| 21 |
+
import numpy as np
|
| 22 |
+
|
| 23 |
+
FeatureDict = Mapping[str, np.ndarray]
|
| 24 |
+
ModelOutput = Mapping[str, Any] # Is a nested dict.
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
@dataclasses.dataclass(frozen=True)
|
| 28 |
+
class Protein:
|
| 29 |
+
"""Protein structure representation."""
|
| 30 |
+
|
| 31 |
+
# Cartesian coordinates of atoms in angstroms. The atom types correspond to
|
| 32 |
+
# residue_constants.atom_types, i.e. the first three are N, CA, CB.
|
| 33 |
+
atom_positions: np.ndarray # [num_res, num_atom_type, 3]
|
| 34 |
+
|
| 35 |
+
# Amino-acid type for each residue represented as an integer between 0 and
|
| 36 |
+
# 20, where 20 is 'X'.
|
| 37 |
+
aatype: np.ndarray # [num_res]
|
| 38 |
+
|
| 39 |
+
# Binary float mask to indicate presence of a particular atom. 1.0 if an atom
|
| 40 |
+
# is present and 0.0 if not. This should be used for loss masking.
|
| 41 |
+
atom_mask: np.ndarray # [num_res, num_atom_type]
|
| 42 |
+
|
| 43 |
+
# Residue index as used in PDB. It is not necessarily continuous or 0-indexed.
|
| 44 |
+
residue_index: np.ndarray # [num_res]
|
| 45 |
+
|
| 46 |
+
# B-factors, or temperature factors, of each residue (in sq. angstroms units),
|
| 47 |
+
# representing the displacement of the residue from its ground truth mean
|
| 48 |
+
# value.
|
| 49 |
+
b_factors: np.ndarray # [num_res, num_atom_type]
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
def from_pdb_string(pdb_str: str, chain_id: Optional[str] = None) -> Protein:
|
| 53 |
+
"""Takes a PDB string and constructs a Protein object.
|
| 54 |
+
|
| 55 |
+
WARNING: All non-standard residue types will be converted into UNK. All
|
| 56 |
+
non-standard atoms will be ignored.
|
| 57 |
+
|
| 58 |
+
Args:
|
| 59 |
+
pdb_str: The contents of the pdb file
|
| 60 |
+
chain_id: If None, then the pdb file must contain a single chain (which
|
| 61 |
+
will be parsed). If chain_id is specified (e.g. A), then only that chain
|
| 62 |
+
is parsed.
|
| 63 |
+
|
| 64 |
+
Returns:
|
| 65 |
+
A new `Protein` parsed from the pdb contents.
|
| 66 |
+
"""
|
| 67 |
+
pdb_fh = io.StringIO(pdb_str)
|
| 68 |
+
parser = PDBParser(QUIET=True)
|
| 69 |
+
structure = parser.get_structure('none', pdb_fh)
|
| 70 |
+
models = list(structure.get_models())
|
| 71 |
+
if len(models) != 1:
|
| 72 |
+
raise ValueError(
|
| 73 |
+
f'Only single model PDBs are supported. Found {len(models)} models.')
|
| 74 |
+
model = models[0]
|
| 75 |
+
|
| 76 |
+
if chain_id is not None:
|
| 77 |
+
chain = model[chain_id]
|
| 78 |
+
else:
|
| 79 |
+
chains = list(model.get_chains())
|
| 80 |
+
if len(chains) != 1:
|
| 81 |
+
raise ValueError(
|
| 82 |
+
'Only single chain PDBs are supported when chain_id not specified. '
|
| 83 |
+
f'Found {len(chains)} chains.')
|
| 84 |
+
else:
|
| 85 |
+
chain = chains[0]
|
| 86 |
+
|
| 87 |
+
atom_positions = []
|
| 88 |
+
aatype = []
|
| 89 |
+
atom_mask = []
|
| 90 |
+
residue_index = []
|
| 91 |
+
b_factors = []
|
| 92 |
+
|
| 93 |
+
for res in chain:
|
| 94 |
+
if res.id[2] != ' ':
|
| 95 |
+
raise ValueError(
|
| 96 |
+
f'PDB contains an insertion code at chain {chain.id} and residue '
|
| 97 |
+
f'index {res.id[1]}. These are not supported.')
|
| 98 |
+
res_shortname = residue_constants.restype_3to1.get(res.resname, 'X')
|
| 99 |
+
restype_idx = residue_constants.restype_order.get(
|
| 100 |
+
res_shortname, residue_constants.restype_num)
|
| 101 |
+
pos = np.zeros((residue_constants.atom_type_num, 3))
|
| 102 |
+
mask = np.zeros((residue_constants.atom_type_num,))
|
| 103 |
+
res_b_factors = np.zeros((residue_constants.atom_type_num,))
|
| 104 |
+
for atom in res:
|
| 105 |
+
if atom.name not in residue_constants.atom_types:
|
| 106 |
+
continue
|
| 107 |
+
pos[residue_constants.atom_order[atom.name]] = atom.coord
|
| 108 |
+
mask[residue_constants.atom_order[atom.name]] = 1.
|
| 109 |
+
res_b_factors[residue_constants.atom_order[atom.name]] = atom.bfactor
|
| 110 |
+
if np.sum(mask) < 0.5:
|
| 111 |
+
# If no known atom positions are reported for the residue then skip it.
|
| 112 |
+
continue
|
| 113 |
+
aatype.append(restype_idx)
|
| 114 |
+
atom_positions.append(pos)
|
| 115 |
+
atom_mask.append(mask)
|
| 116 |
+
residue_index.append(res.id[1])
|
| 117 |
+
b_factors.append(res_b_factors)
|
| 118 |
+
|
| 119 |
+
return Protein(
|
| 120 |
+
atom_positions=np.array(atom_positions),
|
| 121 |
+
atom_mask=np.array(atom_mask),
|
| 122 |
+
aatype=np.array(aatype),
|
| 123 |
+
residue_index=np.array(residue_index),
|
| 124 |
+
b_factors=np.array(b_factors))
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
def to_pdb(prot: Protein) -> str:
|
| 128 |
+
"""Converts a `Protein` instance to a PDB string.
|
| 129 |
+
|
| 130 |
+
Args:
|
| 131 |
+
prot: The protein to convert to PDB.
|
| 132 |
+
|
| 133 |
+
Returns:
|
| 134 |
+
PDB string.
|
| 135 |
+
"""
|
| 136 |
+
restypes = residue_constants.restypes + ['X']
|
| 137 |
+
res_1to3 = lambda r: residue_constants.restype_1to3.get(restypes[r], 'UNK')
|
| 138 |
+
atom_types = residue_constants.atom_types
|
| 139 |
+
|
| 140 |
+
pdb_lines = []
|
| 141 |
+
|
| 142 |
+
atom_mask = prot.atom_mask
|
| 143 |
+
aatype = prot.aatype
|
| 144 |
+
atom_positions = prot.atom_positions
|
| 145 |
+
residue_index = prot.residue_index.astype(np.int32)
|
| 146 |
+
b_factors = prot.b_factors
|
| 147 |
+
|
| 148 |
+
if np.any(aatype > residue_constants.restype_num):
|
| 149 |
+
raise ValueError('Invalid aatypes.')
|
| 150 |
+
|
| 151 |
+
pdb_lines.append('MODEL 1')
|
| 152 |
+
atom_index = 1
|
| 153 |
+
chain_id = 'A'
|
| 154 |
+
# Add all atom sites.
|
| 155 |
+
for i in range(aatype.shape[0]):
|
| 156 |
+
res_name_3 = res_1to3(aatype[i])
|
| 157 |
+
for atom_name, pos, mask, b_factor in zip(
|
| 158 |
+
atom_types, atom_positions[i], atom_mask[i], b_factors[i]):
|
| 159 |
+
if mask < 0.5:
|
| 160 |
+
continue
|
| 161 |
+
|
| 162 |
+
record_type = 'ATOM'
|
| 163 |
+
name = atom_name if len(atom_name) == 4 else f' {atom_name}'
|
| 164 |
+
alt_loc = ''
|
| 165 |
+
insertion_code = ''
|
| 166 |
+
occupancy = 1.00
|
| 167 |
+
element = atom_name[0] # Protein supports only C, N, O, S, this works.
|
| 168 |
+
charge = ''
|
| 169 |
+
# PDB is a columnar format, every space matters here!
|
| 170 |
+
atom_line = (f'{record_type:<6}{atom_index:>5} {name:<4}{alt_loc:>1}'
|
| 171 |
+
f'{res_name_3:>3} {chain_id:>1}'
|
| 172 |
+
f'{residue_index[i]:>4}{insertion_code:>1} '
|
| 173 |
+
f'{pos[0]:>8.3f}{pos[1]:>8.3f}{pos[2]:>8.3f}'
|
| 174 |
+
f'{occupancy:>6.2f}{b_factor:>6.2f} '
|
| 175 |
+
f'{element:>2}{charge:>2}')
|
| 176 |
+
pdb_lines.append(atom_line)
|
| 177 |
+
atom_index += 1
|
| 178 |
+
|
| 179 |
+
# Close the chain.
|
| 180 |
+
chain_end = 'TER'
|
| 181 |
+
chain_termination_line = (
|
| 182 |
+
f'{chain_end:<6}{atom_index:>5} {res_1to3(aatype[-1]):>3} '
|
| 183 |
+
f'{chain_id:>1}{residue_index[-1]:>4}')
|
| 184 |
+
pdb_lines.append(chain_termination_line)
|
| 185 |
+
pdb_lines.append('ENDMDL')
|
| 186 |
+
|
| 187 |
+
pdb_lines.append('END')
|
| 188 |
+
pdb_lines.append('')
|
| 189 |
+
return '\n'.join(pdb_lines)
|
| 190 |
+
|
| 191 |
+
|
| 192 |
+
def ideal_atom_mask(prot: Protein) -> np.ndarray:
|
| 193 |
+
"""Computes an ideal atom mask.
|
| 194 |
+
|
| 195 |
+
`Protein.atom_mask` typically is defined according to the atoms that are
|
| 196 |
+
reported in the PDB. This function computes a mask according to heavy atoms
|
| 197 |
+
that should be present in the given sequence of amino acids.
|
| 198 |
+
|
| 199 |
+
Args:
|
| 200 |
+
prot: `Protein` whose fields are `numpy.ndarray` objects.
|
| 201 |
+
|
| 202 |
+
Returns:
|
| 203 |
+
An ideal atom mask.
|
| 204 |
+
"""
|
| 205 |
+
return residue_constants.STANDARD_ATOM_MASK[prot.aatype]
|
| 206 |
+
|
| 207 |
+
|
| 208 |
+
def from_prediction(features: FeatureDict, result: ModelOutput,
|
| 209 |
+
b_factors: Optional[np.ndarray] = None) -> Protein:
|
| 210 |
+
"""Assembles a protein from a prediction.
|
| 211 |
+
|
| 212 |
+
Args:
|
| 213 |
+
features: Dictionary holding model inputs.
|
| 214 |
+
result: Dictionary holding model outputs.
|
| 215 |
+
b_factors: (Optional) B-factors to use for the protein.
|
| 216 |
+
|
| 217 |
+
Returns:
|
| 218 |
+
A protein instance.
|
| 219 |
+
"""
|
| 220 |
+
fold_output = result['structure_module']
|
| 221 |
+
if b_factors is None:
|
| 222 |
+
b_factors = np.zeros_like(fold_output['final_atom_mask'])
|
| 223 |
+
|
| 224 |
+
return Protein(
|
| 225 |
+
aatype=features['aatype'][0],
|
| 226 |
+
atom_positions=fold_output['final_atom_positions'],
|
| 227 |
+
atom_mask=fold_output['final_atom_mask'],
|
| 228 |
+
residue_index=features['residue_index'][0] + 1,
|
| 229 |
+
b_factors=b_factors)
|
model/PXDesignBench/ColabDesign/colabdesign/af/alphafold/common/residue_constants.py
ADDED
|
@@ -0,0 +1,911 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2021 DeepMind Technologies Limited
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
"""Constants used in AlphaFold."""
|
| 16 |
+
|
| 17 |
+
import collections
|
| 18 |
+
import functools
|
| 19 |
+
from typing import List, Mapping, Tuple
|
| 20 |
+
|
| 21 |
+
import numpy as np
|
| 22 |
+
import tree
|
| 23 |
+
|
| 24 |
+
# Internal import (35fd).
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
# Distance from one CA to next CA [trans configuration: omega = 180].
|
| 28 |
+
ca_ca = 3.80209737096
|
| 29 |
+
|
| 30 |
+
# Format: The list for each AA type contains chi1, chi2, chi3, chi4 in
|
| 31 |
+
# this order (or a relevant subset from chi1 onwards). ALA and GLY don't have
|
| 32 |
+
# chi angles so their chi angle lists are empty.
|
| 33 |
+
chi_angles_atoms = {
|
| 34 |
+
'ALA': [],
|
| 35 |
+
# Chi5 in arginine is always 0 +- 5 degrees, so ignore it.
|
| 36 |
+
'ARG': [['N', 'CA', 'CB', 'CG'], ['CA', 'CB', 'CG', 'CD'],
|
| 37 |
+
['CB', 'CG', 'CD', 'NE'], ['CG', 'CD', 'NE', 'CZ']],
|
| 38 |
+
'ASN': [['N', 'CA', 'CB', 'CG'], ['CA', 'CB', 'CG', 'OD1']],
|
| 39 |
+
'ASP': [['N', 'CA', 'CB', 'CG'], ['CA', 'CB', 'CG', 'OD1']],
|
| 40 |
+
'CYS': [['N', 'CA', 'CB', 'SG']],
|
| 41 |
+
'GLN': [['N', 'CA', 'CB', 'CG'], ['CA', 'CB', 'CG', 'CD'],
|
| 42 |
+
['CB', 'CG', 'CD', 'OE1']],
|
| 43 |
+
'GLU': [['N', 'CA', 'CB', 'CG'], ['CA', 'CB', 'CG', 'CD'],
|
| 44 |
+
['CB', 'CG', 'CD', 'OE1']],
|
| 45 |
+
'GLY': [],
|
| 46 |
+
'HIS': [['N', 'CA', 'CB', 'CG'], ['CA', 'CB', 'CG', 'ND1']],
|
| 47 |
+
'ILE': [['N', 'CA', 'CB', 'CG1'], ['CA', 'CB', 'CG1', 'CD1']],
|
| 48 |
+
'LEU': [['N', 'CA', 'CB', 'CG'], ['CA', 'CB', 'CG', 'CD1']],
|
| 49 |
+
'LYS': [['N', 'CA', 'CB', 'CG'], ['CA', 'CB', 'CG', 'CD'],
|
| 50 |
+
['CB', 'CG', 'CD', 'CE'], ['CG', 'CD', 'CE', 'NZ']],
|
| 51 |
+
'MET': [['N', 'CA', 'CB', 'CG'], ['CA', 'CB', 'CG', 'SD'],
|
| 52 |
+
['CB', 'CG', 'SD', 'CE']],
|
| 53 |
+
'PHE': [['N', 'CA', 'CB', 'CG'], ['CA', 'CB', 'CG', 'CD1']],
|
| 54 |
+
'PRO': [['N', 'CA', 'CB', 'CG'], ['CA', 'CB', 'CG', 'CD']],
|
| 55 |
+
'SER': [['N', 'CA', 'CB', 'OG']],
|
| 56 |
+
'THR': [['N', 'CA', 'CB', 'OG1']],
|
| 57 |
+
'TRP': [['N', 'CA', 'CB', 'CG'], ['CA', 'CB', 'CG', 'CD1']],
|
| 58 |
+
'TYR': [['N', 'CA', 'CB', 'CG'], ['CA', 'CB', 'CG', 'CD1']],
|
| 59 |
+
'VAL': [['N', 'CA', 'CB', 'CG1']],
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
# If chi angles given in fixed-length array, this matrix determines how to mask
|
| 63 |
+
# them for each AA type. The order is as per restype_order (see below).
|
| 64 |
+
chi_angles_mask = [
|
| 65 |
+
[0.0, 0.0, 0.0, 0.0], # ALA
|
| 66 |
+
[1.0, 1.0, 1.0, 1.0], # ARG
|
| 67 |
+
[1.0, 1.0, 0.0, 0.0], # ASN
|
| 68 |
+
[1.0, 1.0, 0.0, 0.0], # ASP
|
| 69 |
+
[1.0, 0.0, 0.0, 0.0], # CYS
|
| 70 |
+
[1.0, 1.0, 1.0, 0.0], # GLN
|
| 71 |
+
[1.0, 1.0, 1.0, 0.0], # GLU
|
| 72 |
+
[0.0, 0.0, 0.0, 0.0], # GLY
|
| 73 |
+
[1.0, 1.0, 0.0, 0.0], # HIS
|
| 74 |
+
[1.0, 1.0, 0.0, 0.0], # ILE
|
| 75 |
+
[1.0, 1.0, 0.0, 0.0], # LEU
|
| 76 |
+
[1.0, 1.0, 1.0, 1.0], # LYS
|
| 77 |
+
[1.0, 1.0, 1.0, 0.0], # MET
|
| 78 |
+
[1.0, 1.0, 0.0, 0.0], # PHE
|
| 79 |
+
[1.0, 1.0, 0.0, 0.0], # PRO
|
| 80 |
+
[1.0, 0.0, 0.0, 0.0], # SER
|
| 81 |
+
[1.0, 0.0, 0.0, 0.0], # THR
|
| 82 |
+
[1.0, 1.0, 0.0, 0.0], # TRP
|
| 83 |
+
[1.0, 1.0, 0.0, 0.0], # TYR
|
| 84 |
+
[1.0, 0.0, 0.0, 0.0], # VAL
|
| 85 |
+
]
|
| 86 |
+
|
| 87 |
+
# The following chi angles are pi periodic: they can be rotated by a multiple
|
| 88 |
+
# of pi without affecting the structure.
|
| 89 |
+
chi_pi_periodic = [
|
| 90 |
+
[0.0, 0.0, 0.0, 0.0], # ALA
|
| 91 |
+
[0.0, 0.0, 0.0, 0.0], # ARG
|
| 92 |
+
[0.0, 0.0, 0.0, 0.0], # ASN
|
| 93 |
+
[0.0, 1.0, 0.0, 0.0], # ASP
|
| 94 |
+
[0.0, 0.0, 0.0, 0.0], # CYS
|
| 95 |
+
[0.0, 0.0, 0.0, 0.0], # GLN
|
| 96 |
+
[0.0, 0.0, 1.0, 0.0], # GLU
|
| 97 |
+
[0.0, 0.0, 0.0, 0.0], # GLY
|
| 98 |
+
[0.0, 0.0, 0.0, 0.0], # HIS
|
| 99 |
+
[0.0, 0.0, 0.0, 0.0], # ILE
|
| 100 |
+
[0.0, 0.0, 0.0, 0.0], # LEU
|
| 101 |
+
[0.0, 0.0, 0.0, 0.0], # LYS
|
| 102 |
+
[0.0, 0.0, 0.0, 0.0], # MET
|
| 103 |
+
[0.0, 1.0, 0.0, 0.0], # PHE
|
| 104 |
+
[0.0, 0.0, 0.0, 0.0], # PRO
|
| 105 |
+
[0.0, 0.0, 0.0, 0.0], # SER
|
| 106 |
+
[0.0, 0.0, 0.0, 0.0], # THR
|
| 107 |
+
[0.0, 0.0, 0.0, 0.0], # TRP
|
| 108 |
+
[0.0, 1.0, 0.0, 0.0], # TYR
|
| 109 |
+
[0.0, 0.0, 0.0, 0.0], # VAL
|
| 110 |
+
[0.0, 0.0, 0.0, 0.0], # UNK
|
| 111 |
+
]
|
| 112 |
+
|
| 113 |
+
# Atoms positions relative to the 8 rigid groups, defined by the pre-omega, phi,
|
| 114 |
+
# psi and chi angles:
|
| 115 |
+
# 0: 'backbone group',
|
| 116 |
+
# 1: 'pre-omega-group', (empty)
|
| 117 |
+
# 2: 'phi-group', (currently empty, because it defines only hydrogens)
|
| 118 |
+
# 3: 'psi-group',
|
| 119 |
+
# 4,5,6,7: 'chi1,2,3,4-group'
|
| 120 |
+
# The atom positions are relative to the axis-end-atom of the corresponding
|
| 121 |
+
# rotation axis. The x-axis is in direction of the rotation axis, and the y-axis
|
| 122 |
+
# is defined such that the dihedral-angle-definiting atom (the last entry in
|
| 123 |
+
# chi_angles_atoms above) is in the xy-plane (with a positive y-coordinate).
|
| 124 |
+
# format: [atomname, group_idx, rel_position]
|
| 125 |
+
rigid_group_atom_positions = {
|
| 126 |
+
'ALA': [
|
| 127 |
+
['N', 0, (-0.525, 1.363, 0.000)],
|
| 128 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 129 |
+
['C', 0, (1.526, -0.000, -0.000)],
|
| 130 |
+
['CB', 0, (-0.529, -0.774, -1.205)],
|
| 131 |
+
['O', 3, (0.627, 1.062, 0.000)],
|
| 132 |
+
],
|
| 133 |
+
'ARG': [
|
| 134 |
+
['N', 0, (-0.524, 1.362, -0.000)],
|
| 135 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 136 |
+
['C', 0, (1.525, -0.000, -0.000)],
|
| 137 |
+
['CB', 0, (-0.524, -0.778, -1.209)],
|
| 138 |
+
['O', 3, (0.626, 1.062, 0.000)],
|
| 139 |
+
['CG', 4, (0.616, 1.390, -0.000)],
|
| 140 |
+
['CD', 5, (0.564, 1.414, 0.000)],
|
| 141 |
+
['NE', 6, (0.539, 1.357, -0.000)],
|
| 142 |
+
['NH1', 7, (0.206, 2.301, 0.000)],
|
| 143 |
+
['NH2', 7, (2.078, 0.978, -0.000)],
|
| 144 |
+
['CZ', 7, (0.758, 1.093, -0.000)],
|
| 145 |
+
],
|
| 146 |
+
'ASN': [
|
| 147 |
+
['N', 0, (-0.536, 1.357, 0.000)],
|
| 148 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 149 |
+
['C', 0, (1.526, -0.000, -0.000)],
|
| 150 |
+
['CB', 0, (-0.531, -0.787, -1.200)],
|
| 151 |
+
['O', 3, (0.625, 1.062, 0.000)],
|
| 152 |
+
['CG', 4, (0.584, 1.399, 0.000)],
|
| 153 |
+
['ND2', 5, (0.593, -1.188, 0.001)],
|
| 154 |
+
['OD1', 5, (0.633, 1.059, 0.000)],
|
| 155 |
+
],
|
| 156 |
+
'ASP': [
|
| 157 |
+
['N', 0, (-0.525, 1.362, -0.000)],
|
| 158 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 159 |
+
['C', 0, (1.527, 0.000, -0.000)],
|
| 160 |
+
['CB', 0, (-0.526, -0.778, -1.208)],
|
| 161 |
+
['O', 3, (0.626, 1.062, -0.000)],
|
| 162 |
+
['CG', 4, (0.593, 1.398, -0.000)],
|
| 163 |
+
['OD1', 5, (0.610, 1.091, 0.000)],
|
| 164 |
+
['OD2', 5, (0.592, -1.101, -0.003)],
|
| 165 |
+
],
|
| 166 |
+
'CYS': [
|
| 167 |
+
['N', 0, (-0.522, 1.362, -0.000)],
|
| 168 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 169 |
+
['C', 0, (1.524, 0.000, 0.000)],
|
| 170 |
+
['CB', 0, (-0.519, -0.773, -1.212)],
|
| 171 |
+
['O', 3, (0.625, 1.062, -0.000)],
|
| 172 |
+
['SG', 4, (0.728, 1.653, 0.000)],
|
| 173 |
+
],
|
| 174 |
+
'GLN': [
|
| 175 |
+
['N', 0, (-0.526, 1.361, -0.000)],
|
| 176 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 177 |
+
['C', 0, (1.526, 0.000, 0.000)],
|
| 178 |
+
['CB', 0, (-0.525, -0.779, -1.207)],
|
| 179 |
+
['O', 3, (0.626, 1.062, -0.000)],
|
| 180 |
+
['CG', 4, (0.615, 1.393, 0.000)],
|
| 181 |
+
['CD', 5, (0.587, 1.399, -0.000)],
|
| 182 |
+
['NE2', 6, (0.593, -1.189, -0.001)],
|
| 183 |
+
['OE1', 6, (0.634, 1.060, 0.000)],
|
| 184 |
+
],
|
| 185 |
+
'GLU': [
|
| 186 |
+
['N', 0, (-0.528, 1.361, 0.000)],
|
| 187 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 188 |
+
['C', 0, (1.526, -0.000, -0.000)],
|
| 189 |
+
['CB', 0, (-0.526, -0.781, -1.207)],
|
| 190 |
+
['O', 3, (0.626, 1.062, 0.000)],
|
| 191 |
+
['CG', 4, (0.615, 1.392, 0.000)],
|
| 192 |
+
['CD', 5, (0.600, 1.397, 0.000)],
|
| 193 |
+
['OE1', 6, (0.607, 1.095, -0.000)],
|
| 194 |
+
['OE2', 6, (0.589, -1.104, -0.001)],
|
| 195 |
+
],
|
| 196 |
+
'GLY': [
|
| 197 |
+
['N', 0, (-0.572, 1.337, 0.000)],
|
| 198 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 199 |
+
['C', 0, (1.517, -0.000, -0.000)],
|
| 200 |
+
['O', 3, (0.626, 1.062, -0.000)],
|
| 201 |
+
],
|
| 202 |
+
'HIS': [
|
| 203 |
+
['N', 0, (-0.527, 1.360, 0.000)],
|
| 204 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 205 |
+
['C', 0, (1.525, 0.000, 0.000)],
|
| 206 |
+
['CB', 0, (-0.525, -0.778, -1.208)],
|
| 207 |
+
['O', 3, (0.625, 1.063, 0.000)],
|
| 208 |
+
['CG', 4, (0.600, 1.370, -0.000)],
|
| 209 |
+
['CD2', 5, (0.889, -1.021, 0.003)],
|
| 210 |
+
['ND1', 5, (0.744, 1.160, -0.000)],
|
| 211 |
+
['CE1', 5, (2.030, 0.851, 0.002)],
|
| 212 |
+
['NE2', 5, (2.145, -0.466, 0.004)],
|
| 213 |
+
],
|
| 214 |
+
'ILE': [
|
| 215 |
+
['N', 0, (-0.493, 1.373, -0.000)],
|
| 216 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 217 |
+
['C', 0, (1.527, -0.000, -0.000)],
|
| 218 |
+
['CB', 0, (-0.536, -0.793, -1.213)],
|
| 219 |
+
['O', 3, (0.627, 1.062, -0.000)],
|
| 220 |
+
['CG1', 4, (0.534, 1.437, -0.000)],
|
| 221 |
+
['CG2', 4, (0.540, -0.785, -1.199)],
|
| 222 |
+
['CD1', 5, (0.619, 1.391, 0.000)],
|
| 223 |
+
],
|
| 224 |
+
'LEU': [
|
| 225 |
+
['N', 0, (-0.520, 1.363, 0.000)],
|
| 226 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 227 |
+
['C', 0, (1.525, -0.000, -0.000)],
|
| 228 |
+
['CB', 0, (-0.522, -0.773, -1.214)],
|
| 229 |
+
['O', 3, (0.625, 1.063, -0.000)],
|
| 230 |
+
['CG', 4, (0.678, 1.371, 0.000)],
|
| 231 |
+
['CD1', 5, (0.530, 1.430, -0.000)],
|
| 232 |
+
['CD2', 5, (0.535, -0.774, 1.200)],
|
| 233 |
+
],
|
| 234 |
+
'LYS': [
|
| 235 |
+
['N', 0, (-0.526, 1.362, -0.000)],
|
| 236 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 237 |
+
['C', 0, (1.526, 0.000, 0.000)],
|
| 238 |
+
['CB', 0, (-0.524, -0.778, -1.208)],
|
| 239 |
+
['O', 3, (0.626, 1.062, -0.000)],
|
| 240 |
+
['CG', 4, (0.619, 1.390, 0.000)],
|
| 241 |
+
['CD', 5, (0.559, 1.417, 0.000)],
|
| 242 |
+
['CE', 6, (0.560, 1.416, 0.000)],
|
| 243 |
+
['NZ', 7, (0.554, 1.387, 0.000)],
|
| 244 |
+
],
|
| 245 |
+
'MET': [
|
| 246 |
+
['N', 0, (-0.521, 1.364, -0.000)],
|
| 247 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 248 |
+
['C', 0, (1.525, 0.000, 0.000)],
|
| 249 |
+
['CB', 0, (-0.523, -0.776, -1.210)],
|
| 250 |
+
['O', 3, (0.625, 1.062, -0.000)],
|
| 251 |
+
['CG', 4, (0.613, 1.391, -0.000)],
|
| 252 |
+
['SD', 5, (0.703, 1.695, 0.000)],
|
| 253 |
+
['CE', 6, (0.320, 1.786, -0.000)],
|
| 254 |
+
],
|
| 255 |
+
'PHE': [
|
| 256 |
+
['N', 0, (-0.518, 1.363, 0.000)],
|
| 257 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 258 |
+
['C', 0, (1.524, 0.000, -0.000)],
|
| 259 |
+
['CB', 0, (-0.525, -0.776, -1.212)],
|
| 260 |
+
['O', 3, (0.626, 1.062, -0.000)],
|
| 261 |
+
['CG', 4, (0.607, 1.377, 0.000)],
|
| 262 |
+
['CD1', 5, (0.709, 1.195, -0.000)],
|
| 263 |
+
['CD2', 5, (0.706, -1.196, 0.000)],
|
| 264 |
+
['CE1', 5, (2.102, 1.198, -0.000)],
|
| 265 |
+
['CE2', 5, (2.098, -1.201, -0.000)],
|
| 266 |
+
['CZ', 5, (2.794, -0.003, -0.001)],
|
| 267 |
+
],
|
| 268 |
+
'PRO': [
|
| 269 |
+
['N', 0, (-0.566, 1.351, -0.000)],
|
| 270 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 271 |
+
['C', 0, (1.527, -0.000, 0.000)],
|
| 272 |
+
['CB', 0, (-0.546, -0.611, -1.293)],
|
| 273 |
+
['O', 3, (0.621, 1.066, 0.000)],
|
| 274 |
+
['CG', 4, (0.382, 1.445, 0.0)],
|
| 275 |
+
# ['CD', 5, (0.427, 1.440, 0.0)],
|
| 276 |
+
['CD', 5, (0.477, 1.424, 0.0)], # manually made angle 2 degrees larger
|
| 277 |
+
],
|
| 278 |
+
'SER': [
|
| 279 |
+
['N', 0, (-0.529, 1.360, -0.000)],
|
| 280 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 281 |
+
['C', 0, (1.525, -0.000, -0.000)],
|
| 282 |
+
['CB', 0, (-0.518, -0.777, -1.211)],
|
| 283 |
+
['O', 3, (0.626, 1.062, -0.000)],
|
| 284 |
+
['OG', 4, (0.503, 1.325, 0.000)],
|
| 285 |
+
],
|
| 286 |
+
'THR': [
|
| 287 |
+
['N', 0, (-0.517, 1.364, 0.000)],
|
| 288 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 289 |
+
['C', 0, (1.526, 0.000, -0.000)],
|
| 290 |
+
['CB', 0, (-0.516, -0.793, -1.215)],
|
| 291 |
+
['O', 3, (0.626, 1.062, 0.000)],
|
| 292 |
+
['CG2', 4, (0.550, -0.718, -1.228)],
|
| 293 |
+
['OG1', 4, (0.472, 1.353, 0.000)],
|
| 294 |
+
],
|
| 295 |
+
'TRP': [
|
| 296 |
+
['N', 0, (-0.521, 1.363, 0.000)],
|
| 297 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 298 |
+
['C', 0, (1.525, -0.000, 0.000)],
|
| 299 |
+
['CB', 0, (-0.523, -0.776, -1.212)],
|
| 300 |
+
['O', 3, (0.627, 1.062, 0.000)],
|
| 301 |
+
['CG', 4, (0.609, 1.370, -0.000)],
|
| 302 |
+
['CD1', 5, (0.824, 1.091, 0.000)],
|
| 303 |
+
['CD2', 5, (0.854, -1.148, -0.005)],
|
| 304 |
+
['CE2', 5, (2.186, -0.678, -0.007)],
|
| 305 |
+
['CE3', 5, (0.622, -2.530, -0.007)],
|
| 306 |
+
['NE1', 5, (2.140, 0.690, -0.004)],
|
| 307 |
+
['CH2', 5, (3.028, -2.890, -0.013)],
|
| 308 |
+
['CZ2', 5, (3.283, -1.543, -0.011)],
|
| 309 |
+
['CZ3', 5, (1.715, -3.389, -0.011)],
|
| 310 |
+
],
|
| 311 |
+
'TYR': [
|
| 312 |
+
['N', 0, (-0.522, 1.362, 0.000)],
|
| 313 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 314 |
+
['C', 0, (1.524, -0.000, -0.000)],
|
| 315 |
+
['CB', 0, (-0.522, -0.776, -1.213)],
|
| 316 |
+
['O', 3, (0.627, 1.062, -0.000)],
|
| 317 |
+
['CG', 4, (0.607, 1.382, -0.000)],
|
| 318 |
+
['CD1', 5, (0.716, 1.195, -0.000)],
|
| 319 |
+
['CD2', 5, (0.713, -1.194, -0.001)],
|
| 320 |
+
['CE1', 5, (2.107, 1.200, -0.002)],
|
| 321 |
+
['CE2', 5, (2.104, -1.201, -0.003)],
|
| 322 |
+
['OH', 5, (4.168, -0.002, -0.005)],
|
| 323 |
+
['CZ', 5, (2.791, -0.001, -0.003)],
|
| 324 |
+
],
|
| 325 |
+
'VAL': [
|
| 326 |
+
['N', 0, (-0.494, 1.373, -0.000)],
|
| 327 |
+
['CA', 0, (0.000, 0.000, 0.000)],
|
| 328 |
+
['C', 0, (1.527, -0.000, -0.000)],
|
| 329 |
+
['CB', 0, (-0.533, -0.795, -1.213)],
|
| 330 |
+
['O', 3, (0.627, 1.062, -0.000)],
|
| 331 |
+
['CG1', 4, (0.540, 1.429, -0.000)],
|
| 332 |
+
['CG2', 4, (0.533, -0.776, 1.203)],
|
| 333 |
+
],
|
| 334 |
+
}
|
| 335 |
+
|
| 336 |
+
# A list of atoms (excluding hydrogen) for each AA type. PDB naming convention.
|
| 337 |
+
residue_atoms = {
|
| 338 |
+
'ALA': ['C', 'CA', 'CB', 'N', 'O'],
|
| 339 |
+
'ARG': ['C', 'CA', 'CB', 'CG', 'CD', 'CZ', 'N', 'NE', 'O', 'NH1', 'NH2'],
|
| 340 |
+
'ASP': ['C', 'CA', 'CB', 'CG', 'N', 'O', 'OD1', 'OD2'],
|
| 341 |
+
'ASN': ['C', 'CA', 'CB', 'CG', 'N', 'ND2', 'O', 'OD1'],
|
| 342 |
+
'CYS': ['C', 'CA', 'CB', 'N', 'O', 'SG'],
|
| 343 |
+
'GLU': ['C', 'CA', 'CB', 'CG', 'CD', 'N', 'O', 'OE1', 'OE2'],
|
| 344 |
+
'GLN': ['C', 'CA', 'CB', 'CG', 'CD', 'N', 'NE2', 'O', 'OE1'],
|
| 345 |
+
'GLY': ['C', 'CA', 'N', 'O'],
|
| 346 |
+
'HIS': ['C', 'CA', 'CB', 'CG', 'CD2', 'CE1', 'N', 'ND1', 'NE2', 'O'],
|
| 347 |
+
'ILE': ['C', 'CA', 'CB', 'CG1', 'CG2', 'CD1', 'N', 'O'],
|
| 348 |
+
'LEU': ['C', 'CA', 'CB', 'CG', 'CD1', 'CD2', 'N', 'O'],
|
| 349 |
+
'LYS': ['C', 'CA', 'CB', 'CG', 'CD', 'CE', 'N', 'NZ', 'O'],
|
| 350 |
+
'MET': ['C', 'CA', 'CB', 'CG', 'CE', 'N', 'O', 'SD'],
|
| 351 |
+
'PHE': ['C', 'CA', 'CB', 'CG', 'CD1', 'CD2', 'CE1', 'CE2', 'CZ', 'N', 'O'],
|
| 352 |
+
'PRO': ['C', 'CA', 'CB', 'CG', 'CD', 'N', 'O'],
|
| 353 |
+
'SER': ['C', 'CA', 'CB', 'N', 'O', 'OG'],
|
| 354 |
+
'THR': ['C', 'CA', 'CB', 'CG2', 'N', 'O', 'OG1'],
|
| 355 |
+
'TRP': ['C', 'CA', 'CB', 'CG', 'CD1', 'CD2', 'CE2', 'CE3', 'CZ2', 'CZ3',
|
| 356 |
+
'CH2', 'N', 'NE1', 'O'],
|
| 357 |
+
'TYR': ['C', 'CA', 'CB', 'CG', 'CD1', 'CD2', 'CE1', 'CE2', 'CZ', 'N', 'O',
|
| 358 |
+
'OH'],
|
| 359 |
+
'VAL': ['C', 'CA', 'CB', 'CG1', 'CG2', 'N', 'O']
|
| 360 |
+
}
|
| 361 |
+
|
| 362 |
+
# Naming swaps for ambiguous atom names.
|
| 363 |
+
# Due to symmetries in the amino acids the naming of atoms is ambiguous in
|
| 364 |
+
# 4 of the 20 amino acids.
|
| 365 |
+
# (The LDDT paper lists 7 amino acids as ambiguous, but the naming ambiguities
|
| 366 |
+
# in LEU, VAL and ARG can be resolved by using the 3d constellations of
|
| 367 |
+
# the 'ambiguous' atoms and their neighbours)
|
| 368 |
+
residue_atom_renaming_swaps = {
|
| 369 |
+
'ASP': {'OD1': 'OD2'},
|
| 370 |
+
'GLU': {'OE1': 'OE2'},
|
| 371 |
+
'PHE': {'CD1': 'CD2', 'CE1': 'CE2'},
|
| 372 |
+
'TYR': {'CD1': 'CD2', 'CE1': 'CE2'},
|
| 373 |
+
}
|
| 374 |
+
|
| 375 |
+
# Van der Waals radii [Angstroem] of the atoms (from Wikipedia)
|
| 376 |
+
van_der_waals_radius = {
|
| 377 |
+
'C': 1.7,
|
| 378 |
+
'N': 1.55,
|
| 379 |
+
'O': 1.52,
|
| 380 |
+
'S': 1.8,
|
| 381 |
+
}
|
| 382 |
+
|
| 383 |
+
Bond = collections.namedtuple(
|
| 384 |
+
'Bond', ['atom1_name', 'atom2_name', 'length', 'stddev'])
|
| 385 |
+
BondAngle = collections.namedtuple(
|
| 386 |
+
'BondAngle',
|
| 387 |
+
['atom1_name', 'atom2_name', 'atom3name', 'angle_rad', 'stddev'])
|
| 388 |
+
|
| 389 |
+
|
| 390 |
+
@functools.lru_cache(maxsize=None)
|
| 391 |
+
def load_stereo_chemical_props() -> Tuple[Mapping[str, List[Bond]],
|
| 392 |
+
Mapping[str, List[Bond]],
|
| 393 |
+
Mapping[str, List[BondAngle]]]:
|
| 394 |
+
"""Load stereo_chemical_props.txt into a nice structure.
|
| 395 |
+
|
| 396 |
+
Load literature values for bond lengths and bond angles and translate
|
| 397 |
+
bond angles into the length of the opposite edge of the triangle
|
| 398 |
+
("residue_virtual_bonds").
|
| 399 |
+
|
| 400 |
+
Returns:
|
| 401 |
+
residue_bonds: dict that maps resname --> list of Bond tuples
|
| 402 |
+
residue_virtual_bonds: dict that maps resname --> list of Bond tuples
|
| 403 |
+
residue_bond_angles: dict that maps resname --> list of BondAngle tuples
|
| 404 |
+
"""
|
| 405 |
+
stereo_chemical_props_path = (
|
| 406 |
+
'alphafold/common/stereo_chemical_props.txt')
|
| 407 |
+
with open(stereo_chemical_props_path, 'rt') as f:
|
| 408 |
+
stereo_chemical_props = f.read()
|
| 409 |
+
lines_iter = iter(stereo_chemical_props.splitlines())
|
| 410 |
+
# Load bond lengths.
|
| 411 |
+
residue_bonds = {}
|
| 412 |
+
next(lines_iter) # Skip header line.
|
| 413 |
+
for line in lines_iter:
|
| 414 |
+
if line.strip() == '-':
|
| 415 |
+
break
|
| 416 |
+
bond, resname, length, stddev = line.split()
|
| 417 |
+
atom1, atom2 = bond.split('-')
|
| 418 |
+
if resname not in residue_bonds:
|
| 419 |
+
residue_bonds[resname] = []
|
| 420 |
+
residue_bonds[resname].append(
|
| 421 |
+
Bond(atom1, atom2, float(length), float(stddev)))
|
| 422 |
+
residue_bonds['UNK'] = []
|
| 423 |
+
|
| 424 |
+
# Load bond angles.
|
| 425 |
+
residue_bond_angles = {}
|
| 426 |
+
next(lines_iter) # Skip empty line.
|
| 427 |
+
next(lines_iter) # Skip header line.
|
| 428 |
+
for line in lines_iter:
|
| 429 |
+
if line.strip() == '-':
|
| 430 |
+
break
|
| 431 |
+
bond, resname, angle_degree, stddev_degree = line.split()
|
| 432 |
+
atom1, atom2, atom3 = bond.split('-')
|
| 433 |
+
if resname not in residue_bond_angles:
|
| 434 |
+
residue_bond_angles[resname] = []
|
| 435 |
+
residue_bond_angles[resname].append(
|
| 436 |
+
BondAngle(atom1, atom2, atom3,
|
| 437 |
+
float(angle_degree) / 180. * np.pi,
|
| 438 |
+
float(stddev_degree) / 180. * np.pi))
|
| 439 |
+
residue_bond_angles['UNK'] = []
|
| 440 |
+
|
| 441 |
+
def make_bond_key(atom1_name, atom2_name):
|
| 442 |
+
"""Unique key to lookup bonds."""
|
| 443 |
+
return '-'.join(sorted([atom1_name, atom2_name]))
|
| 444 |
+
|
| 445 |
+
# Translate bond angles into distances ("virtual bonds").
|
| 446 |
+
residue_virtual_bonds = {}
|
| 447 |
+
for resname, bond_angles in residue_bond_angles.items():
|
| 448 |
+
# Create a fast lookup dict for bond lengths.
|
| 449 |
+
bond_cache = {}
|
| 450 |
+
for b in residue_bonds[resname]:
|
| 451 |
+
bond_cache[make_bond_key(b.atom1_name, b.atom2_name)] = b
|
| 452 |
+
residue_virtual_bonds[resname] = []
|
| 453 |
+
for ba in bond_angles:
|
| 454 |
+
bond1 = bond_cache[make_bond_key(ba.atom1_name, ba.atom2_name)]
|
| 455 |
+
bond2 = bond_cache[make_bond_key(ba.atom2_name, ba.atom3name)]
|
| 456 |
+
|
| 457 |
+
# Compute distance between atom1 and atom3 using the law of cosines
|
| 458 |
+
# c^2 = a^2 + b^2 - 2ab*cos(gamma).
|
| 459 |
+
gamma = ba.angle_rad
|
| 460 |
+
length = np.sqrt(bond1.length**2 + bond2.length**2
|
| 461 |
+
- 2 * bond1.length * bond2.length * np.cos(gamma))
|
| 462 |
+
|
| 463 |
+
# Propagation of uncertainty assuming uncorrelated errors.
|
| 464 |
+
dl_outer = 0.5 / length
|
| 465 |
+
dl_dgamma = (2 * bond1.length * bond2.length * np.sin(gamma)) * dl_outer
|
| 466 |
+
dl_db1 = (2 * bond1.length - 2 * bond2.length * np.cos(gamma)) * dl_outer
|
| 467 |
+
dl_db2 = (2 * bond2.length - 2 * bond1.length * np.cos(gamma)) * dl_outer
|
| 468 |
+
stddev = np.sqrt((dl_dgamma * ba.stddev)**2 +
|
| 469 |
+
(dl_db1 * bond1.stddev)**2 +
|
| 470 |
+
(dl_db2 * bond2.stddev)**2)
|
| 471 |
+
residue_virtual_bonds[resname].append(
|
| 472 |
+
Bond(ba.atom1_name, ba.atom3name, length, stddev))
|
| 473 |
+
|
| 474 |
+
return (residue_bonds,
|
| 475 |
+
residue_virtual_bonds,
|
| 476 |
+
residue_bond_angles)
|
| 477 |
+
|
| 478 |
+
|
| 479 |
+
# Between-residue bond lengths for general bonds (first element) and for Proline
|
| 480 |
+
# (second element).
|
| 481 |
+
between_res_bond_length_c_n = [1.329, 1.341]
|
| 482 |
+
between_res_bond_length_stddev_c_n = [0.014, 0.016]
|
| 483 |
+
|
| 484 |
+
# Between-residue cos_angles.
|
| 485 |
+
between_res_cos_angles_c_n_ca = [-0.5203, 0.0353] # degrees: 121.352 +- 2.315
|
| 486 |
+
between_res_cos_angles_ca_c_n = [-0.4473, 0.0311] # degrees: 116.568 +- 1.995
|
| 487 |
+
|
| 488 |
+
# This mapping is used when we need to store atom data in a format that requires
|
| 489 |
+
# fixed atom data size for every residue (e.g. a numpy array).
|
| 490 |
+
atom_types = [
|
| 491 |
+
'N', 'CA', 'C', 'CB', 'O', 'CG', 'CG1', 'CG2', 'OG', 'OG1', 'SG', 'CD',
|
| 492 |
+
'CD1', 'CD2', 'ND1', 'ND2', 'OD1', 'OD2', 'SD', 'CE', 'CE1', 'CE2', 'CE3',
|
| 493 |
+
'NE', 'NE1', 'NE2', 'OE1', 'OE2', 'CH2', 'NH1', 'NH2', 'OH', 'CZ', 'CZ2',
|
| 494 |
+
'CZ3', 'NZ', 'OXT'
|
| 495 |
+
]
|
| 496 |
+
atom_order = {atom_type: i for i, atom_type in enumerate(atom_types)}
|
| 497 |
+
atom_type_num = len(atom_types) # := 37.
|
| 498 |
+
|
| 499 |
+
# A compact atom encoding with 14 columns
|
| 500 |
+
# pylint: disable=line-too-long
|
| 501 |
+
# pylint: disable=bad-whitespace
|
| 502 |
+
restype_name_to_atom14_names = {
|
| 503 |
+
'ALA': ['N', 'CA', 'C', 'O', 'CB', '', '', '', '', '', '', '', '', ''],
|
| 504 |
+
'ARG': ['N', 'CA', 'C', 'O', 'CB', 'CG', 'CD', 'NE', 'CZ', 'NH1', 'NH2', '', '', ''],
|
| 505 |
+
'ASN': ['N', 'CA', 'C', 'O', 'CB', 'CG', 'OD1', 'ND2', '', '', '', '', '', ''],
|
| 506 |
+
'ASP': ['N', 'CA', 'C', 'O', 'CB', 'CG', 'OD1', 'OD2', '', '', '', '', '', ''],
|
| 507 |
+
'CYS': ['N', 'CA', 'C', 'O', 'CB', 'SG', '', '', '', '', '', '', '', ''],
|
| 508 |
+
'GLN': ['N', 'CA', 'C', 'O', 'CB', 'CG', 'CD', 'OE1', 'NE2', '', '', '', '', ''],
|
| 509 |
+
'GLU': ['N', 'CA', 'C', 'O', 'CB', 'CG', 'CD', 'OE1', 'OE2', '', '', '', '', ''],
|
| 510 |
+
'GLY': ['N', 'CA', 'C', 'O', '', '', '', '', '', '', '', '', '', ''],
|
| 511 |
+
'HIS': ['N', 'CA', 'C', 'O', 'CB', 'CG', 'ND1', 'CD2', 'CE1', 'NE2', '', '', '', ''],
|
| 512 |
+
'ILE': ['N', 'CA', 'C', 'O', 'CB', 'CG1', 'CG2', 'CD1', '', '', '', '', '', ''],
|
| 513 |
+
'LEU': ['N', 'CA', 'C', 'O', 'CB', 'CG', 'CD1', 'CD2', '', '', '', '', '', ''],
|
| 514 |
+
'LYS': ['N', 'CA', 'C', 'O', 'CB', 'CG', 'CD', 'CE', 'NZ', '', '', '', '', ''],
|
| 515 |
+
'MET': ['N', 'CA', 'C', 'O', 'CB', 'CG', 'SD', 'CE', '', '', '', '', '', ''],
|
| 516 |
+
'PHE': ['N', 'CA', 'C', 'O', 'CB', 'CG', 'CD1', 'CD2', 'CE1', 'CE2', 'CZ', '', '', ''],
|
| 517 |
+
'PRO': ['N', 'CA', 'C', 'O', 'CB', 'CG', 'CD', '', '', '', '', '', '', ''],
|
| 518 |
+
'SER': ['N', 'CA', 'C', 'O', 'CB', 'OG', '', '', '', '', '', '', '', ''],
|
| 519 |
+
'THR': ['N', 'CA', 'C', 'O', 'CB', 'OG1', 'CG2', '', '', '', '', '', '', ''],
|
| 520 |
+
'TRP': ['N', 'CA', 'C', 'O', 'CB', 'CG', 'CD1', 'CD2', 'NE1', 'CE2', 'CE3', 'CZ2', 'CZ3', 'CH2'],
|
| 521 |
+
'TYR': ['N', 'CA', 'C', 'O', 'CB', 'CG', 'CD1', 'CD2', 'CE1', 'CE2', 'CZ', 'OH', '', ''],
|
| 522 |
+
'VAL': ['N', 'CA', 'C', 'O', 'CB', 'CG1', 'CG2', '', '', '', '', '', '', ''],
|
| 523 |
+
'UNK': ['', '', '', '', '', '', '', '', '', '', '', '', '', ''],
|
| 524 |
+
|
| 525 |
+
}
|
| 526 |
+
# pylint: enable=line-too-long
|
| 527 |
+
# pylint: enable=bad-whitespace
|
| 528 |
+
|
| 529 |
+
|
| 530 |
+
# This is the standard residue order when coding AA type as a number.
|
| 531 |
+
# Reproduce it by taking 3-letter AA codes and sorting them alphabetically.
|
| 532 |
+
restypes = [
|
| 533 |
+
'A', 'R', 'N', 'D', 'C', 'Q', 'E', 'G', 'H', 'I', 'L', 'K', 'M', 'F', 'P',
|
| 534 |
+
'S', 'T', 'W', 'Y', 'V'
|
| 535 |
+
]
|
| 536 |
+
restype_order = {restype: i for i, restype in enumerate(restypes)}
|
| 537 |
+
restype_num = len(restypes) # := 20.
|
| 538 |
+
unk_restype_index = restype_num # Catch-all index for unknown restypes.
|
| 539 |
+
|
| 540 |
+
restypes_with_x = restypes + ['X']
|
| 541 |
+
restype_order_with_x = {restype: i for i, restype in enumerate(restypes_with_x)}
|
| 542 |
+
|
| 543 |
+
|
| 544 |
+
def sequence_to_onehot(
|
| 545 |
+
sequence: str,
|
| 546 |
+
mapping: Mapping[str, int],
|
| 547 |
+
map_unknown_to_x: bool = False) -> np.ndarray:
|
| 548 |
+
"""Maps the given sequence into a one-hot encoded matrix.
|
| 549 |
+
|
| 550 |
+
Args:
|
| 551 |
+
sequence: An amino acid sequence.
|
| 552 |
+
mapping: A dictionary mapping amino acids to integers.
|
| 553 |
+
map_unknown_to_x: If True, any amino acid that is not in the mapping will be
|
| 554 |
+
mapped to the unknown amino acid 'X'. If the mapping doesn't contain
|
| 555 |
+
amino acid 'X', an error will be thrown. If False, any amino acid not in
|
| 556 |
+
the mapping will throw an error.
|
| 557 |
+
|
| 558 |
+
Returns:
|
| 559 |
+
A numpy array of shape (seq_len, num_unique_aas) with one-hot encoding of
|
| 560 |
+
the sequence.
|
| 561 |
+
|
| 562 |
+
Raises:
|
| 563 |
+
ValueError: If the mapping doesn't contain values from 0 to
|
| 564 |
+
num_unique_aas - 1 without any gaps.
|
| 565 |
+
"""
|
| 566 |
+
num_entries = max(mapping.values()) + 1
|
| 567 |
+
|
| 568 |
+
if sorted(set(mapping.values())) != list(range(num_entries)):
|
| 569 |
+
raise ValueError('The mapping must have values from 0 to num_unique_aas-1 '
|
| 570 |
+
'without any gaps. Got: %s' % sorted(mapping.values()))
|
| 571 |
+
|
| 572 |
+
one_hot_arr = np.zeros((len(sequence), num_entries), dtype=np.int32)
|
| 573 |
+
|
| 574 |
+
for aa_index, aa_type in enumerate(sequence):
|
| 575 |
+
if map_unknown_to_x:
|
| 576 |
+
if aa_type.isalpha() and aa_type.isupper():
|
| 577 |
+
aa_id = mapping.get(aa_type, mapping['X'])
|
| 578 |
+
else:
|
| 579 |
+
raise ValueError(f'Invalid character in the sequence: {aa_type}')
|
| 580 |
+
else:
|
| 581 |
+
aa_id = mapping[aa_type]
|
| 582 |
+
one_hot_arr[aa_index, aa_id] = 1
|
| 583 |
+
|
| 584 |
+
return one_hot_arr
|
| 585 |
+
|
| 586 |
+
|
| 587 |
+
restype_1to3 = {
|
| 588 |
+
'A': 'ALA',
|
| 589 |
+
'R': 'ARG',
|
| 590 |
+
'N': 'ASN',
|
| 591 |
+
'D': 'ASP',
|
| 592 |
+
'C': 'CYS',
|
| 593 |
+
'Q': 'GLN',
|
| 594 |
+
'E': 'GLU',
|
| 595 |
+
'G': 'GLY',
|
| 596 |
+
'H': 'HIS',
|
| 597 |
+
'I': 'ILE',
|
| 598 |
+
'L': 'LEU',
|
| 599 |
+
'K': 'LYS',
|
| 600 |
+
'M': 'MET',
|
| 601 |
+
'F': 'PHE',
|
| 602 |
+
'P': 'PRO',
|
| 603 |
+
'S': 'SER',
|
| 604 |
+
'T': 'THR',
|
| 605 |
+
'W': 'TRP',
|
| 606 |
+
'Y': 'TYR',
|
| 607 |
+
'V': 'VAL',
|
| 608 |
+
}
|
| 609 |
+
|
| 610 |
+
|
| 611 |
+
# NB: restype_3to1 differs from Bio.PDB.protein_letters_3to1 by being a simple
|
| 612 |
+
# 1-to-1 mapping of 3 letter names to one letter names. The latter contains
|
| 613 |
+
# many more, and less common, three letter names as keys and maps many of these
|
| 614 |
+
# to the same one letter name (including 'X' and 'U' which we don't use here).
|
| 615 |
+
restype_3to1 = {v: k for k, v in restype_1to3.items()}
|
| 616 |
+
|
| 617 |
+
# Define a restype name for all unknown residues.
|
| 618 |
+
unk_restype = 'UNK'
|
| 619 |
+
|
| 620 |
+
resnames = [restype_1to3[r] for r in restypes] + [unk_restype]
|
| 621 |
+
resname_to_idx = {resname: i for i, resname in enumerate(resnames)}
|
| 622 |
+
|
| 623 |
+
|
| 624 |
+
# The mapping here uses hhblits convention, so that B is mapped to D, J and O
|
| 625 |
+
# are mapped to X, U is mapped to C, and Z is mapped to E. Other than that the
|
| 626 |
+
# remaining 20 amino acids are kept in alphabetical order.
|
| 627 |
+
# There are 2 non-amino acid codes, X (representing any amino acid) and
|
| 628 |
+
# "-" representing a missing amino acid in an alignment. The id for these
|
| 629 |
+
# codes is put at the end (20 and 21) so that they can easily be ignored if
|
| 630 |
+
# desired.
|
| 631 |
+
HHBLITS_AA_TO_ID = {
|
| 632 |
+
'A': 0,
|
| 633 |
+
'B': 2,
|
| 634 |
+
'C': 1,
|
| 635 |
+
'D': 2,
|
| 636 |
+
'E': 3,
|
| 637 |
+
'F': 4,
|
| 638 |
+
'G': 5,
|
| 639 |
+
'H': 6,
|
| 640 |
+
'I': 7,
|
| 641 |
+
'J': 20,
|
| 642 |
+
'K': 8,
|
| 643 |
+
'L': 9,
|
| 644 |
+
'M': 10,
|
| 645 |
+
'N': 11,
|
| 646 |
+
'O': 20,
|
| 647 |
+
'P': 12,
|
| 648 |
+
'Q': 13,
|
| 649 |
+
'R': 14,
|
| 650 |
+
'S': 15,
|
| 651 |
+
'T': 16,
|
| 652 |
+
'U': 1,
|
| 653 |
+
'V': 17,
|
| 654 |
+
'W': 18,
|
| 655 |
+
'X': 20,
|
| 656 |
+
'Y': 19,
|
| 657 |
+
'Z': 3,
|
| 658 |
+
'-': 21,
|
| 659 |
+
}
|
| 660 |
+
|
| 661 |
+
# Partial inversion of HHBLITS_AA_TO_ID.
|
| 662 |
+
ID_TO_HHBLITS_AA = {
|
| 663 |
+
0: 'A',
|
| 664 |
+
1: 'C', # Also U.
|
| 665 |
+
2: 'D', # Also B.
|
| 666 |
+
3: 'E', # Also Z.
|
| 667 |
+
4: 'F',
|
| 668 |
+
5: 'G',
|
| 669 |
+
6: 'H',
|
| 670 |
+
7: 'I',
|
| 671 |
+
8: 'K',
|
| 672 |
+
9: 'L',
|
| 673 |
+
10: 'M',
|
| 674 |
+
11: 'N',
|
| 675 |
+
12: 'P',
|
| 676 |
+
13: 'Q',
|
| 677 |
+
14: 'R',
|
| 678 |
+
15: 'S',
|
| 679 |
+
16: 'T',
|
| 680 |
+
17: 'V',
|
| 681 |
+
18: 'W',
|
| 682 |
+
19: 'Y',
|
| 683 |
+
20: 'X', # Includes J and O.
|
| 684 |
+
21: '-',
|
| 685 |
+
}
|
| 686 |
+
|
| 687 |
+
restypes_with_x_and_gap = restypes + ['X', '-']
|
| 688 |
+
MAP_HHBLITS_AATYPE_TO_OUR_AATYPE = tuple(
|
| 689 |
+
restypes_with_x_and_gap.index(ID_TO_HHBLITS_AA[i])
|
| 690 |
+
for i in range(len(restypes_with_x_and_gap)))
|
| 691 |
+
|
| 692 |
+
|
| 693 |
+
def _make_standard_atom_mask() -> np.ndarray:
|
| 694 |
+
"""Returns [num_res_types, num_atom_types] mask array."""
|
| 695 |
+
# +1 to account for unknown (all 0s).
|
| 696 |
+
mask = np.zeros([restype_num + 1, atom_type_num], dtype=np.int32)
|
| 697 |
+
for restype, restype_letter in enumerate(restypes):
|
| 698 |
+
restype_name = restype_1to3[restype_letter]
|
| 699 |
+
atom_names = residue_atoms[restype_name]
|
| 700 |
+
for atom_name in atom_names:
|
| 701 |
+
atom_type = atom_order[atom_name]
|
| 702 |
+
mask[restype, atom_type] = 1
|
| 703 |
+
return mask
|
| 704 |
+
|
| 705 |
+
|
| 706 |
+
STANDARD_ATOM_MASK = _make_standard_atom_mask()
|
| 707 |
+
|
| 708 |
+
|
| 709 |
+
# A one hot representation for the first and second atoms defining the axis
|
| 710 |
+
# of rotation for each chi-angle in each residue.
|
| 711 |
+
def chi_angle_atom(atom_index: int) -> np.ndarray:
|
| 712 |
+
"""Define chi-angle rigid groups via one-hot representations."""
|
| 713 |
+
chi_angles_index = {}
|
| 714 |
+
one_hots = []
|
| 715 |
+
|
| 716 |
+
for k, v in chi_angles_atoms.items():
|
| 717 |
+
indices = [atom_types.index(s[atom_index]) for s in v]
|
| 718 |
+
indices.extend([-1]*(4-len(indices)))
|
| 719 |
+
chi_angles_index[k] = indices
|
| 720 |
+
|
| 721 |
+
for r in restypes:
|
| 722 |
+
res3 = restype_1to3[r]
|
| 723 |
+
one_hot = np.eye(atom_type_num)[chi_angles_index[res3]]
|
| 724 |
+
one_hots.append(one_hot)
|
| 725 |
+
|
| 726 |
+
one_hots.append(np.zeros([4, atom_type_num])) # Add zeros for residue `X`.
|
| 727 |
+
one_hot = np.stack(one_hots, axis=0)
|
| 728 |
+
one_hot = np.transpose(one_hot, [0, 2, 1])
|
| 729 |
+
|
| 730 |
+
return one_hot
|
| 731 |
+
|
| 732 |
+
chi_atom_1_one_hot = chi_angle_atom(1)
|
| 733 |
+
chi_atom_2_one_hot = chi_angle_atom(2)
|
| 734 |
+
|
| 735 |
+
# An array like chi_angles_atoms but using indices rather than names.
|
| 736 |
+
chi_angles_atom_indices = [chi_angles_atoms[restype_1to3[r]] for r in restypes]
|
| 737 |
+
chi_angles_atom_indices = tree.map_structure(
|
| 738 |
+
lambda atom_name: atom_order[atom_name], chi_angles_atom_indices)
|
| 739 |
+
chi_angles_atom_indices = np.array([
|
| 740 |
+
chi_atoms + ([[0, 0, 0, 0]] * (4 - len(chi_atoms)))
|
| 741 |
+
for chi_atoms in chi_angles_atom_indices])
|
| 742 |
+
|
| 743 |
+
# Mapping from (res_name, atom_name) pairs to the atom's chi group index
|
| 744 |
+
# and atom index within that group.
|
| 745 |
+
chi_groups_for_atom = collections.defaultdict(list)
|
| 746 |
+
for res_name, chi_angle_atoms_for_res in chi_angles_atoms.items():
|
| 747 |
+
for chi_group_i, chi_group in enumerate(chi_angle_atoms_for_res):
|
| 748 |
+
for atom_i, atom in enumerate(chi_group):
|
| 749 |
+
chi_groups_for_atom[(res_name, atom)].append((chi_group_i, atom_i))
|
| 750 |
+
chi_groups_for_atom = dict(chi_groups_for_atom)
|
| 751 |
+
|
| 752 |
+
|
| 753 |
+
def _make_rigid_transformation_4x4(ex, ey, translation):
|
| 754 |
+
"""Create a rigid 4x4 transformation matrix from two axes and transl."""
|
| 755 |
+
# Normalize ex.
|
| 756 |
+
ex_normalized = ex / np.linalg.norm(ex)
|
| 757 |
+
|
| 758 |
+
# make ey perpendicular to ex
|
| 759 |
+
ey_normalized = ey - np.dot(ey, ex_normalized) * ex_normalized
|
| 760 |
+
ey_normalized /= np.linalg.norm(ey_normalized)
|
| 761 |
+
|
| 762 |
+
# compute ez as cross product
|
| 763 |
+
eznorm = np.cross(ex_normalized, ey_normalized)
|
| 764 |
+
m = np.stack([ex_normalized, ey_normalized, eznorm, translation]).transpose()
|
| 765 |
+
m = np.concatenate([m, [[0., 0., 0., 1.]]], axis=0)
|
| 766 |
+
return m
|
| 767 |
+
|
| 768 |
+
|
| 769 |
+
# create an array with (restype, atomtype) --> rigid_group_idx
|
| 770 |
+
# and an array with (restype, atomtype, coord) for the atom positions
|
| 771 |
+
# and compute affine transformation matrices (4,4) from one rigid group to the
|
| 772 |
+
# previous group
|
| 773 |
+
restype_atom37_to_rigid_group = np.zeros([21, 37], dtype=np.int32)
|
| 774 |
+
restype_atom37_mask = np.zeros([21, 37], dtype=np.float32)
|
| 775 |
+
restype_atom37_rigid_group_positions = np.zeros([21, 37, 3], dtype=np.float32)
|
| 776 |
+
restype_atom14_to_rigid_group = np.zeros([21, 14], dtype=np.int32)
|
| 777 |
+
restype_atom14_mask = np.zeros([21, 14], dtype=np.float32)
|
| 778 |
+
restype_atom14_rigid_group_positions = np.zeros([21, 14, 3], dtype=np.float32)
|
| 779 |
+
restype_rigid_group_default_frame = np.zeros([21, 8, 4, 4], dtype=np.float32)
|
| 780 |
+
|
| 781 |
+
###############################################
|
| 782 |
+
restype_atom14_to_atom37 = []
|
| 783 |
+
restype_atom37_to_atom14 = []
|
| 784 |
+
for rt in restypes:
|
| 785 |
+
atom_names = restype_name_to_atom14_names[restype_1to3[rt]]
|
| 786 |
+
restype_atom14_to_atom37.append([(atom_order[name] if name else 0) for name in atom_names])
|
| 787 |
+
atom_name_to_idx14 = {name: i for i, name in enumerate(atom_names)}
|
| 788 |
+
restype_atom37_to_atom14.append([(atom_name_to_idx14[name] if name in atom_name_to_idx14 else 0) for name in atom_types])
|
| 789 |
+
restype_atom14_to_atom37.append([0] * 14)
|
| 790 |
+
restype_atom37_to_atom14.append([0] * 37)
|
| 791 |
+
restype_atom14_to_atom37 = np.array(restype_atom14_to_atom37, dtype=np.int32)
|
| 792 |
+
restype_atom37_to_atom14 = np.array(restype_atom37_to_atom14, dtype=np.int32)
|
| 793 |
+
################################################
|
| 794 |
+
|
| 795 |
+
def _make_rigid_group_constants():
|
| 796 |
+
"""Fill the arrays above."""
|
| 797 |
+
|
| 798 |
+
|
| 799 |
+
for restype, restype_letter in enumerate(restypes):
|
| 800 |
+
resname = restype_1to3[restype_letter]
|
| 801 |
+
for atomname, group_idx, atom_position in rigid_group_atom_positions[resname]:
|
| 802 |
+
atomtype = atom_order[atomname]
|
| 803 |
+
restype_atom37_to_rigid_group[restype, atomtype] = group_idx
|
| 804 |
+
restype_atom37_mask[restype, atomtype] = 1
|
| 805 |
+
restype_atom37_rigid_group_positions[restype, atomtype, :] = atom_position
|
| 806 |
+
|
| 807 |
+
atom14idx = restype_name_to_atom14_names[resname].index(atomname)
|
| 808 |
+
restype_atom14_to_rigid_group[restype, atom14idx] = group_idx
|
| 809 |
+
restype_atom14_mask[restype, atom14idx] = 1
|
| 810 |
+
restype_atom14_rigid_group_positions[restype, atom14idx, :] = atom_position
|
| 811 |
+
|
| 812 |
+
atom_names = residue_atoms[resname]
|
| 813 |
+
atom_name_to_idx14 = {name: i for i, name in enumerate(atom_names)}
|
| 814 |
+
|
| 815 |
+
for restype, restype_letter in enumerate(restypes):
|
| 816 |
+
resname = restype_1to3[restype_letter]
|
| 817 |
+
atom_positions = {name: np.array(pos) for name, _, pos
|
| 818 |
+
in rigid_group_atom_positions[resname]}
|
| 819 |
+
|
| 820 |
+
# backbone to backbone is the identity transform
|
| 821 |
+
restype_rigid_group_default_frame[restype, 0, :, :] = np.eye(4)
|
| 822 |
+
|
| 823 |
+
# pre-omega-frame to backbone (currently dummy identity matrix)
|
| 824 |
+
restype_rigid_group_default_frame[restype, 1, :, :] = np.eye(4)
|
| 825 |
+
|
| 826 |
+
# phi-frame to backbone
|
| 827 |
+
mat = _make_rigid_transformation_4x4(
|
| 828 |
+
ex=atom_positions['N'] - atom_positions['CA'],
|
| 829 |
+
ey=np.array([1., 0., 0.]),
|
| 830 |
+
translation=atom_positions['N'])
|
| 831 |
+
restype_rigid_group_default_frame[restype, 2, :, :] = mat
|
| 832 |
+
|
| 833 |
+
# psi-frame to backbone
|
| 834 |
+
mat = _make_rigid_transformation_4x4(
|
| 835 |
+
ex=atom_positions['C'] - atom_positions['CA'],
|
| 836 |
+
ey=atom_positions['CA'] - atom_positions['N'],
|
| 837 |
+
translation=atom_positions['C'])
|
| 838 |
+
restype_rigid_group_default_frame[restype, 3, :, :] = mat
|
| 839 |
+
|
| 840 |
+
# chi1-frame to backbone
|
| 841 |
+
if chi_angles_mask[restype][0]:
|
| 842 |
+
base_atom_names = chi_angles_atoms[resname][0]
|
| 843 |
+
base_atom_positions = [atom_positions[name] for name in base_atom_names]
|
| 844 |
+
mat = _make_rigid_transformation_4x4(
|
| 845 |
+
ex=base_atom_positions[2] - base_atom_positions[1],
|
| 846 |
+
ey=base_atom_positions[0] - base_atom_positions[1],
|
| 847 |
+
translation=base_atom_positions[2])
|
| 848 |
+
restype_rigid_group_default_frame[restype, 4, :, :] = mat
|
| 849 |
+
|
| 850 |
+
# chi2-frame to chi1-frame
|
| 851 |
+
# chi3-frame to chi2-frame
|
| 852 |
+
# chi4-frame to chi3-frame
|
| 853 |
+
# luckily all rotation axes for the next frame start at (0,0,0) of the
|
| 854 |
+
# previous frame
|
| 855 |
+
for chi_idx in range(1, 4):
|
| 856 |
+
if chi_angles_mask[restype][chi_idx]:
|
| 857 |
+
axis_end_atom_name = chi_angles_atoms[resname][chi_idx][2]
|
| 858 |
+
axis_end_atom_position = atom_positions[axis_end_atom_name]
|
| 859 |
+
mat = _make_rigid_transformation_4x4(
|
| 860 |
+
ex=axis_end_atom_position,
|
| 861 |
+
ey=np.array([-1., 0., 0.]),
|
| 862 |
+
translation=axis_end_atom_position)
|
| 863 |
+
restype_rigid_group_default_frame[restype, 4 + chi_idx, :, :] = mat
|
| 864 |
+
|
| 865 |
+
|
| 866 |
+
_make_rigid_group_constants()
|
| 867 |
+
|
| 868 |
+
|
| 869 |
+
def make_atom14_dists_bounds(overlap_tolerance=1.5,
|
| 870 |
+
bond_length_tolerance_factor=15):
|
| 871 |
+
"""compute upper and lower bounds for bonds to assess violations."""
|
| 872 |
+
restype_atom14_bond_lower_bound = np.zeros([21, 14, 14], np.float32)
|
| 873 |
+
restype_atom14_bond_upper_bound = np.zeros([21, 14, 14], np.float32)
|
| 874 |
+
restype_atom14_bond_stddev = np.zeros([21, 14, 14], np.float32)
|
| 875 |
+
residue_bonds, residue_virtual_bonds, _ = load_stereo_chemical_props()
|
| 876 |
+
for restype, restype_letter in enumerate(restypes):
|
| 877 |
+
resname = restype_1to3[restype_letter]
|
| 878 |
+
atom_list = restype_name_to_atom14_names[resname]
|
| 879 |
+
|
| 880 |
+
# create lower and upper bounds for clashes
|
| 881 |
+
for atom1_idx, atom1_name in enumerate(atom_list):
|
| 882 |
+
if not atom1_name:
|
| 883 |
+
continue
|
| 884 |
+
atom1_radius = van_der_waals_radius[atom1_name[0]]
|
| 885 |
+
for atom2_idx, atom2_name in enumerate(atom_list):
|
| 886 |
+
if (not atom2_name) or atom1_idx == atom2_idx:
|
| 887 |
+
continue
|
| 888 |
+
atom2_radius = van_der_waals_radius[atom2_name[0]]
|
| 889 |
+
lower = atom1_radius + atom2_radius - overlap_tolerance
|
| 890 |
+
upper = 1e10
|
| 891 |
+
restype_atom14_bond_lower_bound[restype, atom1_idx, atom2_idx] = lower
|
| 892 |
+
restype_atom14_bond_lower_bound[restype, atom2_idx, atom1_idx] = lower
|
| 893 |
+
restype_atom14_bond_upper_bound[restype, atom1_idx, atom2_idx] = upper
|
| 894 |
+
restype_atom14_bond_upper_bound[restype, atom2_idx, atom1_idx] = upper
|
| 895 |
+
|
| 896 |
+
# overwrite lower and upper bounds for bonds and angles
|
| 897 |
+
for b in residue_bonds[resname] + residue_virtual_bonds[resname]:
|
| 898 |
+
atom1_idx = atom_list.index(b.atom1_name)
|
| 899 |
+
atom2_idx = atom_list.index(b.atom2_name)
|
| 900 |
+
lower = b.length - bond_length_tolerance_factor * b.stddev
|
| 901 |
+
upper = b.length + bond_length_tolerance_factor * b.stddev
|
| 902 |
+
restype_atom14_bond_lower_bound[restype, atom1_idx, atom2_idx] = lower
|
| 903 |
+
restype_atom14_bond_lower_bound[restype, atom2_idx, atom1_idx] = lower
|
| 904 |
+
restype_atom14_bond_upper_bound[restype, atom1_idx, atom2_idx] = upper
|
| 905 |
+
restype_atom14_bond_upper_bound[restype, atom2_idx, atom1_idx] = upper
|
| 906 |
+
restype_atom14_bond_stddev[restype, atom1_idx, atom2_idx] = b.stddev
|
| 907 |
+
restype_atom14_bond_stddev[restype, atom2_idx, atom1_idx] = b.stddev
|
| 908 |
+
return {'lower_bound': restype_atom14_bond_lower_bound, # shape (21,14,14)
|
| 909 |
+
'upper_bound': restype_atom14_bond_upper_bound, # shape (21,14,14)
|
| 910 |
+
'stddev': restype_atom14_bond_stddev, # shape (21,14,14)
|
| 911 |
+
}
|