buildez.pdb : utilisation d’une liste de résidus

Dans le module pdb.residue nous trouvons également des fonctions qui produisent ou utilisent une reslist, généralement associée à une resmap et à une matrice pdbm. Il s’agit encore d’une simplification de la matrice pdbm adaptée à des calculs dont le codage serait trop lourd si on opérait directement à partir d’une –pdbm. Nous allons voir ici comment utiliser ces reslist pour réaliser quelques requêtes avancées dans une structure PDB.

D’après un article publié en 2012 sur buildez.net – Revu en Avril 2025.

Navigation dans le guide

Guide [ Composants : buildez.pdb ]




1. Structures utilisées

Les structures protéiques que nous allons utiliser correspondent à la chaîne A de 1FDJ [Blom_2001] et à 1GHE [He_2003] qui contient deux chaines A et B. Les deux structures contiennent des ligands et des molécules d’eau et présentent quelques subtilités au niveau de la syntaxe du fichier PDB.

La structure 1FDJ complexe (ligande) des ions sulfate (SO4), du 1,6-fructose diphosphate (2FP), de la 1,3-dihydroxyacetonephosphate (13P) et du glycerol-3-phosphate (G3P). Mais il n’y a pas de lettre indicatrice de la chaine (par exemple A ou B) dans les lignes HETATM. Ce qui veut dire qu’une requête basique (par exemple un GREP) oubliera les ligands. Par ailleurs toutes les molécules d’eau sont regroupées dans une autre chaîne W indépendante des chaines polypeptidiques. Pour finir la chaîne A que nous allons utiliser ne ligande que du 2FP. Ce phénomène est simple à expliquer dans le principe. Il s’agit d’une réaction enzymatique qui a été capturée dans le cristal, dans certaines chaines on voit un intermédiaire réactionnel (il y a réaction) dans d’autres chaînes ce n’est pas le cas et on ne voit que le substrat (2FP).

Cette enzyme est une aldolase de lapin, qui dégrade le D-fructose mono(1) ou di(1,6) phosphate en D-glycéraldéhyde + dihydroxyacétone phosphate ou D-glycéraldéhyde-3-phosphate + dihydroxyacétone phosphate. Elle intervient notamment dans dans la glycolyse et était une cible thérapeutique possible pour des anti-cancéreux.

La structure 1GHE suit le même principe, les indicateurs de chaînes polypeptidiques sont présents pour la partie ATOM (protéine) mais absents cette fois pour l’ensemble des hétéro-atomes, soit 2 ligands (ACO de l’acetyl coenzyme A) à raison d’un par chaîne et des molécules d’eau. En plus cette protéine contient un acide aminé non standard dérivé de la méthionine : la sélénométhionine (code MSE).

Il s’agit d’une protéine (TTR) de résistance à une toxine (Tabtoxin, un ß-lactame monocyclique). La TTR fournit aux bactéries pathogènes qui produisent la toxine (ex: Pseudomonas syringae) un moyen d’y être tolérantes. Cette protéine possède des points communs avec des protéines d’acétylation, telles les histones acetyl transférases (HATs) au niveau d’un motif du site actif et utilisent le même cofacteur.

2. Intégration avec une matrice pdbm

Le code suivant va donner rapidement une idée de la génération d’une reslist res à partir d’une matrice pdbm m0 et de sa resmap correspondante r0 en utilisant la fonction pdb_pdbm2reslist :

Ce qui va donner comme résultat:

Nous constatons que la reslist correspond à la liste des indices des lignes d’une resmap et nous sommes très contents car aucun résidu de la resmap n’a été oublié dans la reslist. Dans ce cas on peut bien se demander à quoi cette structure pourrait servir. Un élément de réponse va nous être donné par le code suivant:

Donc le premier intérêt est de faire ressortir instantanément le bloc de coordonnées d’un résidu donné, sans se préoccuper de l’analyser ou de connaitre les atomes de début ou de fin, on utilise la fonction pdb_reslist2pdbm :

C’est très utile dans beaucoup de calculs intermédiaires. Mais la structure reslist peut également servir à la réciproque, dans le code précédent on réutilise la matrice pdbm que l’on vient de générer pour connaitre l’index (+1) ou l’indice (0 .. n-1) du bloc de coordonnées dans la resmap avec la fonction pdb_pdbm2reslist :

=> output of the residue indice of this residue from corresponding pdbm
residue indice = 1
residue index = 2

Et cela c’est déjà moins trivial, car on s’est intéressé au résidu HIS1002, c’est en fait le second résidu de la chaîne A de 1FDJ (index=2), mais il est numéroté 1002 (RESSEQ=1002). Il pourrait également être numéroté avec autre numéro de résidu, rien n’oblige à utiliser des numéros de résidus contigus et correspondant à la réalité de la séquence primaire dans un fichier PDB.

L’utilisation conjointe d’une resmap et d’ure reslist permet alors de gagner en robustesse dans les codes car on peut s’affranchir des numéros de résidus. C’est quelque chose qui a de l’importance lorsque on va analyser une structure pour en faire sortir une chaine, sans informations sur la lettre de la chaine (dans les blocs ATOM ou HETATM). C’est la base d’une programmation qui sera moins naïve que l’analyse purement textuelle du fichier PDB.

3. Intégration avec une resmap

L’équivalent de la fonction pdb_pdbm2reslist existe pour une resmap avec la fonction pdb_resmap2reslist. Dans ce cas, il suffit de fournir comme arguments une resmap et un numéro (index) de résidu pour le début et pour la fin, par exemple:

Ce qui donnera comme résultat:

*** Test residue functions for polypeptidic chains
loading string for [1ghe.pdb] structure
filtering: get only coordinates string for chain A
computing pdbm matrix m0 and resmap r0
get resmap indices for residues 38,39,40
[34, 35, 36] gives => ['MSE', 38, 265, 272, -1, ''] ['ALA', 39, 273, 277, -1, ''] ['ASP', 40, 278, 285, -1, '']

La fonction pdb_resmap2res est équivalente mais plus complète :

Ce qui va se traduire par la création de la même mini-resmap (3 lignes) que dans le cas précédent.

or get directly corresponding residues
[['MSE', 38, 265, 272, -1, ''], ['ALA', 39, 273, 277, -1, ''], ['ASP', 40, 278, 285, -1, '']]

la différence entre pdb_resmap2reslist et pdb_resmap2res c’est que cette dernière fonction peut utiliser des index (dernier argument, mode=1) ou des indices (dernier argument, mode=0) alors que la première fonctionne en mode=1. En utilisant la reslist, et une des deux mini-resmap que l’on vient de générer, et la matrice pdbm initiale, il est alors possible de régénérer les blocs de coordonnées moléculaires correspondants à ces résidus, en utilisant la fonction pdb_reslist2pdbm que l’on a déjà vue en action dans la section précédente:

Ce qui donne comme résultat:

Et là surprise, on constate que la séléno-méthionine qui est constitutive de la chaîne polypeptidique (comme la méthionine) correspond à des lignes HETATM et non à des lignes ATOM comme les autres acides aminés de la protéine. Cela veut dire que une recherche avec un GREP ou une stratégie de ce type (par exemple filtre basé sur le mot clef ATOM pour extraire la partie protéique de la structure) aurait échoué sans aménagements supplémentaires.

4. Reconnaissance de résidus

Plusieurs fonctions dans le module permettent de réaliser ce type d’action, la reconnaissance se fait soit par identification du résidu grâce à son nom et un dictionnaire, soit en analysant son contenu en atomes par rapport à ce que l’on s’attend à trouver dans le cas d’un acide aminé.
Les fonctions pdb_reslist2restypes, pdb_resmap2restypes et pdb_pdbm2restypes utilisent un dictionnaire (par exemple chargé avec pdb_csvm2resdico du module pdb.resname) pour identifier les résidus. la première nécessite une reslist et une resmap, la seconde seulement une resmap, la troisième une matrice pdbm et une resmap.
La fonction pdb_pdbmlist2reshit utilise ces primitives pour calculer un score global à partir d’une reslist et d’une resmap. Par exemple, le code suivant utilise une liste de matrices pdbm [p1, p2] ou p1 a déjà été calculée dans le cas de l’exemple précédent (et correspond à la MSE38) et la resmap r0:

Ce qui donne comme résultat:

extract the second residue (ALA) of the list
count the amino acids in the list compose dof the two first residues
=> found value = 2
note than MSE is counted as a true amino acid (chain calculations)

Le nombre d’acides aminés dans la liste de blocs (matrices) pdbm correspond bien à 2 résidus, la MSE a été reconnue.

Fonctions de bas niveau

Ces fonctions sont d’un usage simplifié par rapport aux précédentes, mais elles sont également basées soit sur l’utilisation d’un dictionnaire (fonction pdb_dict_restype), soit la détermination d’une liaison (fonction pdb_bond_restype).

Par exemple le code suivant:

Donnera comme résultat:

*** using pdb_dict_restype subroutine
check residue 38 for type, using default method
=> 'MSE' type = ukn
check residue 38 for type, using extended method
=> 'MSE' type = alt
lucky ! 'MSE' is included in default dictionary but not labeled as 'aa'

Nous nous rendons compte que la reconnaissance de la MSE va dépendre de la qualité du dictionnaire, si aucun n’est fourni (argument None) le dictionnaire standard du module resname est utilisé. Le mode par défaut (mode=0) fait un check très rapide avec la fonction pdb_isaatype (du module resname) qui ne prends en compte que des résidus standards et de l’eau. Pour éviter ce type de problème il est possible d’utiliser l’autre fonction, par exemple:

Qui donnera comme résultat:

*** using pdb_bond_restype subroutine
check residue 38 for type, using default method
=> 'MSE' type = ukn
check residue 38 for type, using extended method
=> 'MSE' type = aa

Si le mode strict=0 est utilisé, de la même manière seuls les résidus standards sont testés. Si le mode étendu (strict=1) est utilisé la fonction vérifie la présence des 3 atomes CA, C, et N dans le résidu. S’ils sont présents, c’est un acide aminé et ce test est déjà suffisant pour la MSE. Si strict=2, un test de distance (1.6 Angstrom) est effectué entre C et CA d’une part et CA et N d’autre part. Cette méthode permet d’aller très vite pour des résidus standard ou non et s’affranchit d’un nom de résidu qui ne serait pas dans un dictionnaire.

5. Reconnaissance d’une liaison peptidique

L’approche précédente peut être mise en défaut si on a un ligand peptidique dans la structure, mais dans ce cas il s’agira d’une chaîne supplémentaire (un autre polypeptide) que l’on pourra détecter par une analyse plus poussée.
La fonction pdb_pdbm_reslinked permet de faire ce type d’opération, elle accepte en entrée 2 blocs pdbm correspondant chacun à un résidu et détermine si ces deux résidus sont liés. On comprends alors l’intérêt de la resmap/reslist, la reslist permet de parcourir rapidement la chaine polypeptidique, la resmap permet de régénérer une matrice pdbm correspondant à un résidu entier, et la fonction pdb_pdbm_reslinked permet de savoir s’il s’agit de deux résidus liés.

De cette manière on peut envisager de reconstruire rapidement la chaîne polypeptidique sans trop d’efforts de présentation des données car les structures de données que l’on utilise s’emboitent parfaitement et limitent la profondeur algorithmique à utiliser.

Le code suivant montre l’utilisation de cette fonction:

Et le résultat que l’on peut en attendre :

*** Link test
extract residue ALA39 from same protein
are MSE38 and ALA39 linked ? result = 1
extract residue ASP from same protein
are MSE38 and ASP40 linked ? result = 0

Et nous constatons que deux résidus contigus sont effectivement bien liés (result > 0).

6. Référentiel

Fonctions du module residue.py en relation avec la structure reslist, en mode abrégé (avril 2025).
Consulter l’article [ buildez.pdb: la matrice resmap ] pour les autres fonctions du module.

Fonction Utilisation
pdb_resmap2reslist Similaire à pdb_resmap2res mais 1) bloqué sur le mode RESSEQ (numéros de résidus dans le fichier PDB) et 2) renvoie une liste d’indices de la resmap (une reslist).
pdb_reslist2pdbm A partir d’une pdbm (source), d’une resmap et d’une reslist (filtres), produit une nouvelle pdbm.
pdb_pdbm2reslist A partir d’une pdbm et d’une resmap, produit une reslist, en mode positif ou négatif (la reslist contient les indices ne correspondant pas à la requête).
pdb_reslist2restypes Convertit une liste de résidus en liste de types dans le même ordre, utilise une resmap, un dictionnaire.
pdb_resmap2restypes Lit la colonne correspondant aux noms de résidus d’une resmap et renvoie une liste de types de résidus, utilise un dictionnaire.
pdb_pdbm2restypes Produit une liste de types de résidus, à partir d’une matrice pdbm (éventuellement une resmap sinon elle est recalculée)  et d’un dictionnaire.
pdb_pdbmlist2reshit A partir d’une resmap et d’une liste (Python) de blocs pdbm correspondant à des résidus, revoie le nombre de résidus de type aa ou alt.

7. Conclusion

Le module pdb.residue contient donc deux structures de données resmap et reslist qui sont utilisables pour aller assez loin dans l’analyse d’un fichier PDB et surtout de manière robuste. Ces concepts sont extensivement utilisés dans le module pdb.chain qui effectue une reconnaissance des chaines sans analyse textuelle du fichier PDB.

Le module inclue également un système de requête/extraction de blocs par masque qui qui fera l’objet d’un autre article avec l’utilisation d’une autre structure de données la matrice uniq.

L’ensemble permet de s’affranchir d’une programmation naïve et peu robuste eu égard de toutes les exceptions que l’on peut trouver dans des fichiers PDB, il permet également de s’affranchir de parseurs dont on ignore comment ils fonctionnent et s’ils sont effectivement validés pour des structures qui comportent ces exceptions. Dans les cas ou on traite un fichier à l’unité ce n’est pas grave, mais si on traite un ensemble de structures (par exemple la totalité de la PDB) on peut imaginer perdre des touches (hits) à cause de structures qui auraient générées une exception dans le parseur et donc n’auraient pas été prises en compte.

Liens et lectures
Retour en haut