La pdbm (pdb matrix) correspond à une structure de données qui regroupe des lignes ATOM ou HETATM (coordonnées moléculaires) tout en conservant la trace des autres lignes (entête par exemple) du fichier PDB. Les fonctions de base pour la gestion de cette structure de données sont regroupées dans le module pdbm. Une pdbm, c’est une liste (de listes) Python dont le nombre de colonnes va varier en fonction du type de ligne PDB. Dans le cas de lignes (row) correspondant à des coordonnées moléculaires, il y aura 17 colonnes (indices 0 à 16).
Publication initiale sur buidez.net (2014) – Article mis à jour en Avril 2025.
Navigation dans le guide
Guide [ Composants : buildez.pdb ]
1. Premiers pas
Une fois de plus nous allons utiliser la structure 1HXD [Weaver_2001]. Cette structure correspond à BirA (Biotin Ligase), une enzyme qui ligande de la biotine et qui propose une dynamique structurale. Voyons simplement comment générer une pdbm à partir de cette structure :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
print("loading [1HXD] from local test directory") s = pdb_file2str(file_cleanpath(site_package + "/test/1hxd.pdb") print("*** Compute a pdbm matrix") m0 = pdb_str2pdbm(s) print("found %d atoms" % (len(m0))) print() print("*** Output the first 10 lines of pdbm") for i in range (0,10,1): print(m0[i]) print("the pdbm keeps all lines of PDB file even if it is not coordinate files") print() print("***Get from line 460 to 470 in PDB file") for i in range (459,470,1): print(m0[i]) print("notice that the lines keep file numbering (last record)") |
La fonction pdb_str2pdbm lit une chaine de caractères (contenant le fichier PDB) et la transforme en pdbm, le résultat de cette opération:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
loading [1HXD] from local test directory *** Compute a pdbm matrix found 5302 atoms -> output the first 10 lines of pdbm ['-', 1] ['-', 2] ['-', 3] ['-', 4] ['-', 5] ['-', 6] ['-', 7] ['-', 8] ['-', 9] ['-', 10] -> output the last 10 lines of pdbm ['-', 5293] ['-', 5294] ['-', 5295] ['-', 5296] ['-', 5297] ['-', 5298] ['-', 5299] ['-', 5300] ['-', 5301] ['-', 5302] the pdbm keeps all lines of PDB file even if it is not coordinate files ***Get from lines 450 to 470 in PDB file ['-', 450] ['-', 451] ['-', 452] ['-', 453] ['-', 454] ['-', 455] ['-', 456] ['-', 457] ['-', 458] ['-', 459] ['-', 460] ['-', 461] ['-', 462] ['ATOM', 1, 'N', '', 'ASN', 'A', 4, '', 66.039, 30.785, 50.117, 1.0, 88.31, '', 'N', '', 463] ['ATOM', 2, 'CA', '', 'ASN', 'A', 4, '', 66.049, 29.799, 51.2, 1.0, 85.31, '', 'C', '', 464] ['ATOM', 3, 'C', '', 'ASN', 'A', 4, '', 67.44, 29.525, 51.712, 1.0, 73.8, '', 'C', '', 465] ['ATOM', 4, 'O', '', 'ASN', 'A', 4, '', 67.713, 28.613, 52.474, 1.0, 78.35, '', 'O', '', 466] ['ATOM', 5, 'CB', '', 'ASN', 'A', 4, '', 65.401, 28.459, 50.827, 1.0, 85.69, '', 'C', '', 467] ['ATOM', 6, 'CG', '', 'ASN', 'A', 4, '', 64.012, 28.337, 51.41, 1.0, 100.0, '', 'C', '', 468] ['ATOM', 7, 'OD1', '', 'ASN', 'A', 4, '', 63.343, 27.285, 51.281, 1.0, 100.0, '', 'O', '', 469] ['ATOM', 8, 'ND2', '', 'ASN', 'A', 4, '', 63.571, 29.431, 52.045, 1.0, 100.0, '', 'N', '', 470] notice that the lines keep file numbering (last record) |
La dernière colonne de chaque ligne correspond à l’index (1 à n) de la ligne correspondant dans le fichier PDB, nous commençons logiquement à 1, l’exemple s’arrête à la ligne 470.
Nous constatons que pour les lignes correspondant à des coordonnées atomiques (dernier bloc) nous retrouvons tous les champs d’un fichier PDB, sauf que les données correspondantes sont typées: string, float, int en fonction du type de données, puis l’index (typé int) dans le fichier PDB original.
Les premières lignes de la matrice ne sont pas des coordonnées, dans ce cas il n’y a de deux colonnes, une première matérialisée par un caractère nul ou spécifique, ici -. Ces lignes de la matrice pdbm correspondent à l’entête du fichier PDB, s’il y en a un dans le fichier. Elles sont automatiquement renvoyées par un appel à la fonction pdb_str2pdbm mais elles peuvent être facilement nettoyées si on veut exclusivement travailler sur les coordonnées moléculaires.
Une structure de données qui embarque des éléments décoratifs (cf. dernière colonne) à priori accessoires, peut apporter des simplifications dans les opérations ultérieures.
La colonne d’index (indice 16 dans une ligne pdbm) est très utile. Elle peut nous permettre de générer un nouveau fichier PDB avec les lignes du fichier original, par exemple les entêtes. Cette colonne va nous permettre aussi de nous affranchir de l’ordre d’arrivée des lignes dans la matrice pour définir des indices pour les atomes ATOM / HETATM et donc de combiner en désordre différents blocs de coordonnées moléculaires qui pourront être réordonnés après.
2. Pourquoi une pdbm ?
Pourquoi donc adopter ce type de structures plutôt qu’un arbre qui tiendrait compte de la hiérarchie chaines, résidus, atomes ?
En premier lieu, nous avons souvent besoin d’une structure de plus bas niveau, facile à utiliser et sur laquelle il est assez évident de réaliser des requêtes puisqu’il s’agit in fine d’une table. Une structure tabulaire est également plus facile à interfacer avec d’autres outils, comme des objets CSVM, tables Pandas …. Dans ces cas il est possible de combiner le meilleur des deux mondes soit pour réaliser des pipes applicatifs, soit pour profiter de fonctions de recherches génériques.
La colonne d’indice 16 garde donc une trace ‘fossile’ du fichiers PDB initial qui peut être très utile pour des reconstructions de fichiers. Elle peut également servir, si on la remplit non pas par des entiers mais des chaines de caractères à marquer chaque atome du fichier par un tag unique. Si on combine différents blocs de structures moléculaires (par exemple des chaines avec des ligands issus de fichiers différents mais alignés dans le même référentiel cartésien) on est souvent amené à renuméroter les atomes de manière contigüe, sinon certains logiciels applicatifs (modélisation et docking moléculaires) peuvent dysfonctionner. Dans ce cas la renumérotation (et la reconstruction du bloc de connectivité pour les ligands) sont dramatiquement facilités par les tags que l’on aura pu placer dans la dernière colonne d’une pdbm.
En bref, ce type de structure est l’émanation d’une programmation simple, sans à priori, mais efficace. L’utilisation d’une pdbm associée à celle d’une resmap (carte des résidus consécutifs dans une chaine) permet de faire énormément de choses avancées sur une structure moléculaire et avec un gain net de programmation, tout en restant proche des données de base (intelligibles par les humains et les machines).
3. Régénération de chaines PDB
Cette fonctionnalité est détaillée dans [ buildez.pdb : matrices pdbm et regénération de structures ].
4. Intersection de matrices pdbm
Une propriété intéressante des pdbm est de pouvoir créer un code pour leur intersection. Dans un fichier PDB il n’y a pas recouvrement des atomes, par principe. Mais si nous confrontons deux blocs (deux matrices pdbm) avec un opérateur de distance atomique, nous pouvons l’assimiler à une intersection. Si les deux blocs sont globalement trop loin, nous aurons une structure de données vide. Si des atomes sont ‘suffisamment’ près, nous aurons un nouveau bloc (une nouvelle matrice) pdbm. Nous avons donc un outil conceptuel qui nous permet de concevoir des filtres, requêtes 3D, calculs de structures … qui est simple et intéressant. Les fonctions impliquées et des principes d’opération font l’objet d’un article à part [ à venir ].
5. Autres fonctions
Le module pdbm.py implémente quelques fonctions supplémentaires. Par exemple, la fonction pdb_str2pdbl renvoie une ligne d’une pdbm à partir d’une chaine de caractères, avec un filtre sur les lignes ATOM, HETATM et not (ATOM or HETATM). La fonction pdb_strvec2pdbm génère une pdbm à partir d’une liste Python standard. Les 3 fonctions (en incluant pdb_str2pdbm) utilisent de manière intensive la fonction pdb_coordlinetyped_get du module pdb.str qui permet de générer une ligne de coordonnées moléculaires (ou non) à partir d’un flot de données arbitraires.
La fonction pdb_pdbm_eq permet de tester l’égalité partielle (sur une colonne) ou totale (mode strict) entre 2 matrices pdbm et est très utile par exemple pour vérifier si les résidus ou leur numérotation est équivalente en l’absence de resmap.
Primitives d’extraction
Il existe aussi deux primitives d’extraction très basiques. La première pdb_pdbm_getatom_bytype permet de sortir une ligne de la matrice pdbm en fonction d’un type d’atome PDB (‘C’, ‘CA’, ‘CB’ …) et d’un indice de ligne. La seconde fonction pdb_pdbm_getchain_name tente d’extraire la lettre correspondant à une chaîne polypeptidique de la structure moléculaire et permet de vérifier très rapidement si la structure est conforme de ce point de vue. Par exemple le code suivant :
|
1 2 3 4 5 6 7 8 9 10 11 12 |
print("\n*** Try to find unique chain name") print("found [%s]" % (pdb_pdbm_getchain_name(m0))) print("if 'None' found, some PDB lines exist with another chain_id or no chain_id") print("apply a filter: get chain 'A' lines") s1 = pdb_str_coordsblock_get(s, "ATOM HETATM", pdb_field_coords_id("CHAINID"), "A", "=", 0) m1 = pdb_str2pdbm(s1) print("found %d atoms" % (len(m1))) print("now, unique chain exists ?") print("found [%s]" % (pdb_pdbm_getchain_name(m1))) print("\n*** Get the 10th CA atom of chain 'A'") print(pdb_pdbm_getatom_bytype(m1, "CA", 10)) print("*** Test pdb.pdbm done.") |
Donnera le résultat:
*** Try to find unique chain namefound [None]if 'None' found, some PDB lines exist with another chain_id or no chain_idapply a filter: get chain 'A' linesfound 2356 atomsnow, unique chain exists ?found [A]*** Get the 10th CA atom of chain 'A'['ATOM', 77, 'CA', '', 'LEU', 'A', 14, '', 74.096, 25.748, 64.49, 1.0, 27.24, '', 'C', '', 77] |
6. Référentiel
Fonctions du module pdbm.py en mode abrégé (avril 2025).
| Fonction | Utilisation |
pdb_str2pdbl |
Lit une ligne (string) au format PDB et la transforme en ligne (row) d’une matrice pdbm. |
pdb_str2pdbm |
Lit un fichier PDB (string) et retourne une matrice pdbm. |
pdb_strvec2pdbm |
Identique à pdb_str2pdbm mais utilise une liste de lignes du fichier PDB (string list) en entrée. |
pdb_pdbm_row2str |
Transforme directement une ligne (row) d’une pdbm en chaine de caractères au format PDB. |
pdb_pdbm_rows2str |
Convertit directement une matrice pdbm en une chaine de caractères au format PDB. |
pdb_pdbm2str |
Identique à pdb_pdbm_rows2str mais utilise les pointeurs vers le fichier PDB original pour produire la chaine de caractères. |
pdb_pdbm2str_extended |
Identique à pdb_pdbm2str mais utilise une liste de mots clés PDB pour sélectionner les lignes qui vont être dans la sortie. |
pdb_pdbm_eq |
Teste deux matrices pdbm de longueur indéfinie pour égalité , en mode strict (basé sur les atomes) ou non (basé sur les résidus). |
pdb_pdbm_getatom_bytype |
Extrait une ligne (row) d’une pdbm en utilisant un type atomique donné (ex: CA) et un ordre d’apparition dans le bloc pdbm. |
pdb_pdbm_getchain_name |
Si tous les atomes de la pdbm ont le même identificateur de chaine, cette lettre est retournée. |
pdb_pdbm_sortm |
Tri associé (ascendant, descendant) d’une pdbm, en place, en utilisant une colonne donnée. |
pdb_pdbm2serials |
Lit une pdbm et retourne une liste des numéros de série en fonction de types d’atomes (N, CA, C …) et de types (ATOM, HETATM) de lignes PDB. |
7. Conclusion
Nous disposons ainsi de quelques primitives qui permettent d’interagir avec la matrice pdbm dont l’essentiel de l’utilité sera exposée dans d’autres modules. Il s’agit vraiment d’une structure de données pensée comme une brique de base pour le reste du paquetage.
Liens et lectures
- Structure 1HXD [ https://www.rcsb.org/structure/1HXD ].
- C. Inard, E. Fourcade, E. Baron, D. Tovar, L. Chaisemartin, C. Blonski, J.C. Faye (2006) Syntheses of functionalized biotin N-1′ derivatives: new tools for the control of gene expression with small molecules. Bioconjug. Chem. 17, 1030-5 [Inard_2006].
- Vitamine B8 (biotine) [ https://fr.wikipedia.org/wiki/Vitamine_B8 ].
- Biotinylation [ https://en.wikipedia.org/wiki/Biotinylation ].