Ce référentiel contient les codes de notre article End-to-End Full-Atom Antibody Design.
Il y a 3 conditions préalables nécessaires et 1 facultative : configuration de l'environnement conda (nécessaire), obtention des marqueurs (nécessaire), préparation des données pdb des anticorps (nécessaire) et téléchargement des lignes de base (facultatif).
1. Environnement
Nous avons fourni le env.yml
pour créer l'environnement d'exécution conda simplement en exécutant :
conda env create -f env.yml
2. Buteurs
Veuillez d'abord préparer les scores pour TMscore et DockQ comme suit :
Le code source pour évaluer TMscore se trouve sur evaluation/TMscore.cpp
. Veuillez le compiler par :
g++ -static -O3 -ffast-math -lm -o evaluation/TMscore evaluation/TMscore.cpp
Pour préparer le marqueur DockQ, veuillez cloner son github officiel et compiler les prérequis selon ses instructions. Après cela, veuillez réviser la variable DOCKQ_DIR
dans configs.py
pour pointer vers le répertoire contenant le projet DockQ (par exemple ./DockQ).
Le marqueur lDDT est dans l'environnement conda, et le
3. Données PDB
Veuillez télécharger toutes les données structurelles des anticorps depuis la page de téléchargement de SAbDab. Veuillez entrer dans l'onglet Téléchargements à gauche de la page Web et télécharger le fichier zip archivé pour les structures, puis décompresser :
wget https://opig.stats.ox.ac.uk/webapps/newsabdab/sabdab/archive/all/ -O all_structures.zip
unzip all_structures.zip
Vous devriez obtenir un dossier nommé all_structures avec la hiérarchie suivante :
├── all_structures
│ ├── chothia
│ ├── imgt
│ ├── raw
Chaque sous-dossier contient les fichiers pdb renumérotés avec le schéma correspondant. Nous utilisons IMGT dans le journal, donc le sous-dossier imgt est ce qui nous intéresse.
Étant donné que les fichiers PDB sont lourds à traiter, les utilisateurs génèrent généralement un fichier récapitulatif pour la base de données structurelle qui enregistre les informations de base sur chaque structure pour un accès rapide. Nous avons fourni le résumé de l'ensemble de données récupéré le 12 novembre 2022 ( summaries/sabdab_summary.tsv
). Étant donné que l'ensemble de données est mis à jour chaque semaine, si vous souhaitez utiliser la dernière version, veuillez la télécharger depuis le site officiel.
(Facultatif) 4. Lignes de base
Si vous êtes intéressé par les références du pipeline, incluant les projets suivants et intégrez leurs dépendances en fonction de vos besoins :
Après avoir ajouté ces projets, n'oubliez pas également de réviser les chemins correspondants dans ./configs.py
. Nous avons également fourni les scripts pour mettre en cascade les modules dans ./scripts/pipeline_inference.sh
.
Les points de contrôle formés pour chaque tâche sont fournis sur la page de version de github. Pour les utiliser, veuillez télécharger ceux qui vous intéressent et enregistrez-les dans le dossier ./checkpoints
. Nous fournissons les noms, les configurations de formation (sous ./scripts/train/configs
) et les descriptions des points de contrôle comme suit :
point(s) de contrôle | configurer | description |
---|---|---|
cdrh3_design.ckpt | single_cdr_design.json | Conception CDR-H3 se liant aux épitopes |
struct_prediction.ckpt | struct_prediction.json | Prédiction de structures complexes |
affinity_opt.ckpt & ddg_predictor.ckp | single_cdr_opt.json | Optimisation d'affinité sur CDR-H3 |
multi_cdr_design.ckpt | multi_cdr_design.json | Concevoir les 6 CDR simultanément |
multi_cdr_opt.ckpt & multi_cdr_ddg_predictor | multi_cdr_opt.json | Optimiser l'affinité sur les 6 CDR simultanément |
full_design.ckpt | full_design.json | Concevoir l'intégralité du domaine variable, y compris la région framework |
Données
Pour prétraiter les données brutes, nous devons d'abord générer des résumés pour chaque benchmark au format json, puis diviser les ensembles de données en ensembles d'entraînement/validation/test, et enfin transformer les données pdb en objets python. Nous avons fourni le script de toutes ces procédures dans scripts/data_preprocess.sh
. Supposons que les données pdb renumérotées IMGT se trouvent dans all_structures/imgt/
et que vous souhaitiez stocker les données traitées (~ 5G) dans all_data
, vous pouvez simplement exécuter :
bash scripts/data_preprocess.sh all_structures/imgt all_data
ce qui prend environ 1 heure pour traiter SAbDab, RAbD, l'ensemble de tests Igfold et SKEMPI V2.0. Il est normal de voir des erreurs signalées dans ce processus, car certaines structures d'anticorps sont mal annotées ou ont un mauvais format, qui seront abandonnées lors de la phase de nettoyage des données.
(Facultatif) Modèle conservé
Nous avons fourni le modèle conservé de SAbDab dans ./data/template.json
. Si vous êtes intéressé par le processus d'extraction, il est également possible d'extraire un modèle conservé d'un ensemble de données spécifié (par exemple l'ensemble d'entraînement pour la tâche de conception CDR-H3) en exécutant la commande suivante :
python -m data.framework_templates
--dataset ./all_data/RAbD/train.json
--out ./data/new_template.json
Nous utilisons SAbDab pour la formation et RAbD pour les tests. Veuillez d'abord réviser les paramètres dans scripts/train/configs/cdr_design.json
(chemin d'accès aux ensembles de données et autres hyperparamètres), puis exécutez la commande ci-dessous pour l'entraînement :
GPU=0,1 bash scripts/train/train.sh scripts/train/configs/single_cdr_design.json
Normalement, la procédure de formation dure environ 7 heures sur 2 GPU GeForce RTX 2080 Ti. Nous avons également fourni le point de contrôle formé à checkpoints/cdrh3_design.ckpt
. Veuillez ensuite réviser le chemin d'accès à l'ensemble de tests dans scripts/test/test.sh
et exécutez la commande suivante pour tester :
GPU=0 bash scripts/test/test.sh ./checkpoints/cdrh3_design.ckpt ./all_data/RAbD/test.json ./results
qui enregistrera les résultats générés dans ./results
.
Nous utilisons SAbDab pour la formation et IgFold pour les tests. La procédure de formation et de test est similaire à celle de la conception CDR-H3. Après avoir révisé les paramètres dans scripts/train/configs/cdr_design.json
et scripts/test/test.sh
comme mentionné précédemment, veuillez exécuter la commande suivante pour la formation :
GPU=0,1 bash scripts/train/train.sh scripts/train/configs/struct_prediction.json
Normalement, la procédure de formation dure environ 8 heures sur 2 GPU GeForce RTX 2080 Ti. Nous avons également fourni le point de contrôle formé à checkpoints/struct_prediction.ckpt
. Ensuite, veuillez exécuter la commande suivante pour tester :
GPU=0 bash scripts/test/test.sh ./checkpoints/struct_prediction.ckpt ./all_data/IgFold/test.json ./results
Nous utilisons SAbDab pour la formation et les anticorps de SKEMPI V2.0 pour les tests. De même, veuillez d'abord réviser les paramètres dans scripts/train/configs/affinity_opt.json
, scripts/test/optimize_test.sh
, ainsi que scripts/train/train_predictor.sh
. Alors merci de réaliser une formation de dyMEANOpt (~ 5h) :
GPU=0,1 bash scripts/train/train.sh scripts/train/configs/single_cdr_opt.json
Ensuite il faut entraîner un prédicteur de ddg sur les représentations du complexe généré (~ 40min) :
GPU=0 bash scripts/train/train_predictor.sh checkpoints/cdrh3_opt.ckpt
Nous avons fourni les points de contrôle formés sur checkpoints/cdrh3_opt.ckpt
et checkpoints/cdrh3_ddg_predictor.ckpt
. Le test d’optimisation peut être réalisé à travers :
GPU=0 bash scripts/test/optimize_test.sh checkpoints/cdrh3_opt.ckpt checkpoints/cdrh3_ddg_predictor.ckpt ./all_data/SKEMPI/test.json 0 50
qui effectuera 50 étapes de recherche de gradient sans restrictions sur le nombre maximum de résidus modifiés (changez 0 par n'importe quel nombre pour restreindre la limite supérieure de
Nous fournissons également une API d'inférence et des démonstrations in silico pour les applications courantes dans les problèmes du monde réel, qui se trouvent dans les fichiers ./api
et ./demos
.
Nous fournissons l'API de conception et l'API d'optimisation dans ./api
, qui peuvent être facilement intégrées dans les codes Python.
L'API de conception ( ./api/design.py
) peut être utilisée pour générer des CDR étant donné les séquences de la région charpente, le fichier PDB de l'antigène ainsi que les définitions d'épitopes. Nous utiliserons un scénario intéressant pour illustrer l'utilisation de l'API de conception .
Nous souhaitons concevoir un anticorps se combinant à l’état ouvert du membre 1 de la sous-famille V du canal cationique potentiel du récepteur transitoire (TRPV1), qui joue un rôle essentiel dans la douleur aiguë et persistante. Au lieu de fabriquer manuellement l'épitope sur TRPV1, nous essayons d'imiter un liant existant qui est une toxine à double nœud (DkTx). Par conséquent, nous devons d’abord extraire la définition de l’épitope en analysant le modèle de liaison de la toxine, puis concevoir un anticorps avec des séquences données des régions charpentes.
1. Extraire la définition de l'épitope
Nous fournissons le fichier PDB du complexe du membre 1 de la sous-famille V du canal cationique potentiel du récepteur transitoire (TRPV1, chaîne ABCD) et de la toxine à double nœud (DkTx, chaîne EF) dans ./demos/data/7l2m.pdb
. Le PDB original comporte 4 unités symétriques, nous divisons donc manuellement les deux toxines (chaîne EF) au milieu pour former 4 chaînes symétriques e, f, E, F. Chaque anticorps ne doit se concentrer que sur une seule unité. Ici, nous choisissons la chaîne E comme exemple.
Nous générons la définition de l'épitope en analysant l'interface de liaison de la chaîne E au TRPV1 :
python -m api.binding_interface
--pdb ./demos/data/7l2m.pdb
--receptor A B C D
--ligand E
--out ./demos/data/E_epitope.json
Désormais, la définition de l'épitope (c'est-à-dire les résidus de TRPV1 sur l'interface de liaison) est enregistrée dans ./demos/data/E_epitope.json
. En changeant la valeur de l'argument « ligand » en e, f et F, nous pouvons obtenir les définitions d'épitopes pour d'autres unités (n'oubliez pas de réviser également le chemin de sortie).
2. Obtenir les séquences des régions-cadres
En fonction des objectifs finaux de conception de l'anticorps, des régions de charpente ayant des propriétés physicochimiques différentes peuvent être souhaitées. Puisque nous ne fournissons ici qu’un cas de preuve de concept, nous en sélectionnons un au hasard dans l’ensemble de données existant :
heavy chain (H): ' QVQLKESGPGLLQPSQTLSLTCTVSGISLSDYGVHWVRQAPGKGLEWMGIIGHAGGTDYNSNLKSRVSISRDTSKSQVFLKLNSLQQEDTAMYFC----------WGQGIQVTVSSA '
light chain (L): ' YTLTQPPLVSVALGQKATITCSGDKLSDVYVHWYQQKAGQAPVLVIYEDNRRPSGIPDHFSGSNSGNMATLTISKAQAGDEADYYCQSWDGTNSAWVFGSGTKVTVLGQ '
Le CDR-H3 original est masqué par "-". La conception de plusieurs CDR est également prise en charge, ce qui sera illustré plus tard.
3. Concevoir les CDR
La dernière étape consiste à concevoir les CDR avec l'API de conception :
from api . design import design
ckpt = './checkpoints/cdrh3_design.ckpt'
root_dir = './demos/data'
pdbs = [ os . path . join ( root_dir , '7l2m.pdb' ) for _ in range ( 4 )]
toxin_chains = [ 'E' , 'e' , 'F' , 'f' ]
remove_chains = [ toxin_chains for _ in range ( 4 )]
epitope_defs = [ os . path . join ( root_dir , c + '_epitope.json' ) for c in toxin_chains ]
identifiers = [ f' { c } _antibody' for c in toxin_chains ]
# use '-' for masking amino acids
frameworks = [
(
( 'H' , 'QVQLKESGPGLLQPSQTLSLTCTVSGISLSDYGVHWVRQAPGKGLEWMGIIGHAGGTDYNSNLKSRVSISRDTSKSQVFLKLNSLQQEDTAMYFC----------WGQGIQVTVSSA' ),
( 'L' , 'YTLTQPPLVSVALGQKATITCSGDKLSDVYVHWYQQKAGQAPVLVIYEDNRRPSGIPDHFSGSNSGNMATLTISKAQAGDEADYYCQSWDGTNSAWVFGSGTKVTVLGQ' )
)
for _ in pdbs
] # the first item of each tuple is heavy chain, the second is light chain
design ( ckpt = ckpt , # path to the checkpoint of the trained model
gpu = 0 , # the ID of the GPU to use
pdbs = pdbs , # paths to the PDB file of each antigen (here antigen is all TRPV1)
epitope_defs = epitope_defs , # paths to the epitope definitions
frameworks = frameworks , # the given sequences of the framework regions
out_dir = root_dir , # output directory
identifiers = identifiers , # name of each output antibody
remove_chains = remove_chains , # remove the original ligand
enable_openmm_relax = True , # use openmm to relax the generated structure
auto_detect_cdrs = False ) # manually use '-' to represent CDR residues
Ces codes sont également ajoutés à titre d'exemple dans ./api/design.py
, vous pouvez donc l'exécuter directement par :
python -m api.design
Ici, nous utilisons "-" pour marquer le CDR-H3 manuellement, mais vous pouvez également définir auto_detect_cdrs=True
pour laisser le CDR être automatiquement décidé par le système de numérotation IMGT. Les types de CDR à concevoir seront automatiquement dérivés du point de contrôle donné. Actuellement, l'API prend en charge la reconception d'un ou de plusieurs CDR, ainsi que la conception de l'anticorps complet (en passant "-" * length
comme entrée).
L'activation d'Openmm relax ralentira considérablement le processus de génération, mais rectifiera les longueurs et les angles des liaisons pour se conformer aux contraintes physiques.
L'API d'optimisation ( ./api/optimize.py
) est simple. Nous optimisons ./demos/data/1nca.pdb
à titre d'exemple :
from api . optimize import optimize , ComplexSummary
ckpt = './checkpoints/cdrh3_opt.ckpt'
predictor_ckpt = './checkpoints/cdrh3_ddg_predictor.ckpt'
root_dir = './demos/data/1nca_opt'
summary = ComplexSummary (
pdb = './demos/data/1nca.pdb' ,
heavy_chain = 'H' ,
light_chain = 'L' ,
antigen_chains = [ 'N' ]
)
optimize (
ckpt = ckpt , # path to the checkpoint of the trained model
predictor_ckpt = predictor_ckpt , # path to the checkpoint of the trained ddG predictor
gpu = 0 , # the ID of the GPU to use
cplx_summary = summary , # summary of the complex as well as its PDB file
num_residue_changes = [ 1 , 2 , 3 , 4 , 5 ], # generate 5 samples, changing at most 1, 2, 3, 4, and 5 residues, respectively
out_dir = root_dir , # output directory
batch_size = 16 , # batch size
num_workers = 4 , # number of workers to use
optimize_steps = 50 # number of steps for gradient desend
)
Les codes de cet exemple sont également ajoutés à ./api/optimize.py
, vous pouvez donc les exécuter directement par :
python -m api.optimize
Vous obtiendrez alors les résultats suivants :
├── demos/data/1nca_opt
│ ├── 1nca_0_1.pdb
│ ├── 1nca_1_2.pdb
│ ├── 1nca_2_3.pdb
│ ├── 1nca_3_4.pdb
│ ├── 1nca_4_5.pdb
│ ├── 1nca_original.pdb
où 1nca_original.pdb
est le complexe d'origine et 1nca_a_b.pdb
signifie le
L'API de prédiction de structure complexe ( ./api/structure_prediction.py
) prédit la structure complexe en fonction de l'antigène, des séquences de la chaîne lourde et de la chaîne légère et de la définition de l'épitope. L'amarrage mondial reste très difficile, c'est pourquoi nous réduisons la portée à l'épitope d'intérêt. Nous prévoyons ./demos/data/1nca.pdb
à titre d'exemple :
from api . structure_prediction import structure_prediction
ckpt = './checkpoints/struct_prediction.ckpt'
root_dir = './demos/data'
n_sample = 10 # sample 10 conformations
pdbs = [ os . path . join ( root_dir , '1nca_antigen.pdb' ) for _ in range ( n_sample )]
epitope_defs = [ os . path . join ( root_dir , '1nca_epitope.json' ) for _ in range ( n_sample )]
identifiers = [ f'1nca_model_ { i } ' for i in range ( n_sample )]
seqs = [
(
( 'H' , 'QIQLVQSGPELKKPGETVKISCKASGYTFTNYGMNWVKQAPGKGLKWMGWINTNTGEPTYGEEFKGRFAFSLETSASTANLQINNLKNEDTATFFCARGEDNFGSLSDYWGQGTTVTVSS' ),
( 'L' , 'DIVMTQSPKFMSTSVGDRVTITCKASQDVSTAVVWYQQKPGQSPKLLIYWASTRHIGVPDRFAGSGSGTDYTLTISSVQAEDLALYYCQQHYSPPWTFGGGTKLEIK' )
)
for _ in pdbs
] # the first item of each tuple is heavy chain, the second is light chain
structure_prediction (
ckpt = ckpt , # path to the checkpoint of the trained model
gpu = 0 , # the ID of the GPU to use
pdbs = pdbs , # paths to the PDB file of each antigen (here antigen is all TRPV1)
epitope_defs = epitope_defs , # paths to the epitope definitions
seqs = seqs , # the given sequences of the framework regions
out_dir = root_dir , # output directory
identifiers = identifiers , # name of each output antibody
enable_openmm_relax = True ) # use openmm to relax the generated structure
Les codes de cet exemple sont également ajoutés à ./api/structure_prediction.py
, vous pouvez donc les exécuter directement par :
python -m api.structure_prediction
Vous obtiendrez alors les résultats suivants :
├── demos/data
│ ├── 1nca_model_0.pdb
│ ├── 1nca_model_1.pdb
│ ├── 1nca_model_2.pdb
│ ├── ...
où il devrait y avoir un total de 10 conformations échantillonnées. Notez que les premiers ou derniers résidus peuvent être ignorés dans les résultats s'ils se trouvent en dehors du domaine variable selon le système de numérotation IMGT.
L'affichage in vitro est couramment utilisé pour sélectionner des mutants de liaison dans des bibliothèques d'anticorps. Ici, nous implémentons une version in silico avec l'API de conception en générant et en filtrant les candidats à partir d'un ensemble de données existant par rapport à l'antigène avec une définition d'épitope. De plus, nous avons besoin d’une mesure pour évaluer dans quelle mesure l’anticorps généré se lie à la cible. Ici, nous utilisons FoldX comme prédicteur d'affinité, donc pour exécuter cette démo, vous devrez peut-être d'abord la télécharger depuis le site officiel et réviser le chemin dans ./configs.py
en conséquence. Nous utilisons toujours l'exemple TRPV1 dans la section précédente et utilisons le benchmark RAbD comme bibliothèque d'anticorps fournissant les régions charpentes :
python -m demos.display
--ckpt checkpoints/multi_cdr_design.ckpt
--pdb demos/data/7l2m.pdb
--epitope_def demos/data/E_epitope.json
--library ./all_data/rabd_all.json
--n_sample 30
--save_dir demos/display
--gpu 0
ce qui donnera 30 candidats avec leur affinité prédite par FoldX.
Merci de votre intérêt pour notre travail !
N'hésitez pas à nous poser des questions sur les algorithmes, les codes, ainsi que sur les problèmes rencontrés lors de leur exécution afin que nous puissions le rendre plus clair et meilleur. Vous pouvez soit créer un problème dans le dépôt github, soit nous contacter à [email protected].
Les fichiers ci-dessous sont empruntés à des référentiels existants :
evaluation/TMscore.cpp
: https://zhanggroup.org/TM-score/evaluation/ddg
: https://github.com/HeliXonProtein/binding-ddg-predictor