Visualització de proteïnes en 3D
El RCSB Protein Data Bank (RCSB PDB) permet avenços en ciència i educació proporcionant accés i eines per a l'exploració, visualització i anàlisi de:
-
Estructures 3D determinades experimentalment a partir de l'arxiu del Protein Data Bank (PDB).
-
Computed Structure Models (CSM) d'AlphaFold DB i ModelArchiv
-
Fins i tot, programes d’anàlisis de proteïnes i predicció d’estructura com FireProt 2.0 i Modeller
Aquesta base de dades, amb més de cinquanta mil registres, és el repositori de referència de dades estructurals de proteïnes. Un fitxer PDB emmagatzema les posicions espacials dels àtoms obtingudes per cristal·lografia de raigs X, espectroscòpia RMN i altres tècniques experimentals.
Pots accedir als registres d'aquesta base de dades a través de la pàgina web de RCSB a https://www.rcsb.org/
Per exemple, visualitzem el registre de l’Hemoglobina humana en 3D, que té el codi 4N7N
:
iCn3D Structure Viewer
I see in 3D" (iCn3D) Structure Viewer is not only a web-based 3D viewer, but also a structure analysis tool interactively or in the batch mode using NodeJS scripts based on the npm package icn3d. iCn3D synchronizes the display of 3D structure, 2D interaction, and 1D sequences and annotation.
TODO té tutorials, etc.
NCBI
L’NCBI proporciona una eina molt potent per a visualitzar i treballar amb proteïnes i altres estructures en format PDB i molts altres: ICN3D.
Obrim la pàgina, i ens dóna diverses opcions per visualizar en 3D les proteïnes.
O bé indicant una llista d’indentificadors (de PDB o altres) i pitjant INTRO.
Per exemple 1HHO,4N7N
;
Apart d’obtenir la animació en 3d de 2 proteïnes alhora, teniu una barra d’eines molt potent.
L’altra manera de carregar el/s fitxers PDB (o altres formats) és obrint un o més fitxers descarregats.
Provem de carregar la proteïna 6YYT del SARS-CoV-2 al portal web de l’icn3d. És la polimerasa (encarregada de replicar el virus) Primer cal descarregar-la:
$ wget https://files.rcsb.org/download/6YYT.pdb
Obrim el menú principal de la pàgina, opció File i seleccionem el format.
Així és la proteïna 6YYT SARS-CoV-2:
-
Dos suports helicoïdals amb diferents tons de color blau són la cadena de plantilla d'ARN i la seva cadena de producte.
-
La major part de les cintes de color rosa és la polimerasa, que és un enzim (proteïna funcional) que fa còpies de la cadena d'ARN. Aquesta polimerasa és un objectiu atractiu per a la vacuna antiviral COVID-19.
Si voltem la molècula, podem veure les cintes grogues, verdes i taronges, que són les proteïnes víriques que ajuden a la polimerasa a mantenir-se en el camí i copiar porcions llargues de la cadena d'ARN.
Hi ha diverses formes d’exposar la proteïna animada o una imatge estàtica (PNG) a la nostra pàgina web. S’exposa com funciona cada una a la web oficial:
Tal i com veieu les captures, tenim maneres molt interessants: crear scripts de Python juntament amb Biopython i bolcar els resultats al front-end.
Mètode 1. Embedir el giny (widget) amb un IFrame d’HTML (tal i com faríem amb Google Maps i altres serveis)
La web proposa aquest Iframe:
<iframe allowFullScreen='true' src='https://www.ncbi.nlm.nih.gov/Structure/icn3d/?mmdbid=1tup&width=300&height=300&closepopup=1&showcommand=0&shownote=0&mobilemenu=1&showtitle=0' width='320' height='320' style='border:none'></iframe>
Per a què quedi una mica millor cal decidit adaptar-lo d’aquesta manera, així es mostrarà el títol:
<main className="container mt-5">
<h2 className="text-center mt-5 fs-2">BioActivitat 6 - Estructures de proteïnes.</h2>
<iframe src='https://www.ncbi.nlm.nih.gov/Structure/icn3d/?mmdbid=1tup&closepopup=1&showcommand=0&shownote=0&mobilemenu=1&showtitle=1'
class="w-full aspect-video">
</iframe>
</main>
I així ja el pots en una pàgina qualsevol.
El paràmetre de l’iframe que defineix la proteïna és mmdbid
, pots provar de canviar-la per veure si et visualitza una altra proteïna
TODO mmdbid=4N78
Activitats
1.- Prova d’embedir l’ <iframe>
en una de les teves pàgines web, assegura’t que es vegi bé i surti el títol de la proteïna.
2.- A fegeix una utilitat al plugin per tal que l’usuari pugui posar un id de proteïna en un camp d’un formulari i al pitjar el botó se li carregui la proteïna en 3d que ha seleccionat.
En ambdós casos hauràs de personalitzar de manera estàtica (2.1) o dinàmica (2.2) la URL del iframe.
El resultat hauria de ser semblant a aquest:
Possible solució activitat (pròximament):
TODO canviar solucío a pàgina estàtica
https://gitlab.com/xtec/bio-uniprot/-/blob/main/app/page.tsx
Biopython
Referència: Going 3D: The PDB module
Biopython té un el mòdul PDB que ens permet obtenir tota la informació de les proteïnes, i manipular-la.
Aquí en veiem un exemple, que descarrega una cadena d’aminoàcids del Sars-Cov-2.
from Bio.PDB import PDBParser
import urllib.parse
import os
# Original sources.
# https://biopython.org/DIST/docs/tutorial/Tutorial.html#sec240
pdb_file : str = 'data/6YYT.pdb'
if not os.path.exists(pdb_file):
urllib.request.urlretrieve('http://files.rcsb.org/download/6YYT.pdb', pdb_file)
parser = PDBParser()
structure = parser.get_structure('6YYT', pdb_file)
print(structure)
# To identify how many chains this 6YYT SARS-CoV-2 viral protein has, we use chain.id function which gives us the list of the chains that are present.
for chain in structure[0]:
print(f'chain ID: {chain.id}')
# Other useful data.
# Long JSON.
# print(structure.header)
print('Keywords ',structure.header["keywords"])
Fitxers PDB
Working with PDB files in Python
La manipulació i visualització dels fitxers del Protein Data Bank (PDB) és un recurs essencial per a aplicacions com el disseny de fàrmacs i l'enginyeria de proteïnes.
El punt principal d'aquesta activitat és mostrar com podem manipular les dades de PDB amb la pila habitual de PyData, especialment els dataframes de Pandas (de manera que no cal que aprenguis una API completament nova) i com podem visualitzar de manerar simle les proteïnes.
Què és un fitxer PDB?
Un fitxer PDB (Protein Data Bank) és un format de fitxer estandarditzat basat en text que emmagatzema les dades estructurals tridimensionals (3D) de macromolècules biològiques, principalment proteïnes i àcids nucleics, així com els seus complexos. Aquests fitxers contenen les coordenades atòmiques, informació d'enllaç i altres detalls rellevants de les biomolècules derivades de mètodes experimentals...
Les claus PDB comunes són:
Key | Descripció |
---|---|
HEADER |
Proporciona una descripció general del contingut del fitxer PDB, inclòs el nom de la macromolècula, la classificació, la data de deposició i l'ID PDB. |
TITLE |
Ofereix una descripció més detallada de l'estructura, incloent sovint la funció de la proteïna, els lligands o cofactors i les condicions experimentals rellevants. |
COMPND |
Descriu els components macromoleculars de l'estructura, com ara els noms de les cadenes proteiques individuals, els àcids nucleics o els lligands. |
SOURCE |
Especifica la font natural o sintètica de cada component macromolecular, inclòs l'organisme, el teixit o la línia cel·lular de la qual es va derivar l'estructura. |
KEYWDS |
Enumera les paraules clau que descriuen l'estructura, com ara la classificació d'enzims, la família de proteïnes o el procés biològic. |
EXPDTA |
Proporciona informació sobre el mètode experimental utilitzat per determinar l'estructura, com ara cristal·lografia de raigs X, espectroscòpia RMN o microscòpia crioelectrònica. |
AUTHOR |
Enumera els noms dels investigadors que han contribuït a la determinació de l'estructura i han enviat el fitxer PDB. |
REVDAT |
Registra l'historial de revisions del fitxer PDB, incloses les dates de les modificacions i una breu descripció dels canvis realitzats. |
JRNL |
Conté informació de citació de les publicacions associades a la determinació de l'estructura, com ara el títol, els autors, el nom de la revista, el volum, les pàgines i l'any de publicació. |
REMARK |
Conté diverses observacions o comentaris relacionats amb l'estructura, com ara detalls experimentals, processament de dades, qualitat del model i altres notes rellevants. |
SEQRES |
Descriu la seqüència primària de cada proteïna o cadena d'àcids nucleics de l'estructura, enumerant els residus d'aminoàcids o nucleòtids en codis d'una lletra. |
CRYST |
Paràmetres de la cel·la unitat, grup d'espai i valor Z. Si l'estructura no s'ha determinat per mitjans cristal·logràfics, simplement es defineix una unitat de cub |
ORIGXn |
(n=1, 2, 3) Defineix la transformació de les coordenades ortogonals contingudes a l'entrada de la base de dades a les coordenades enviades |
SCALEn |
(n=1,2, 3) Defineix la transformació de les coordenades ortogonals contingudes a l'entrada a coordenades cristal·logràfiques fraccionades. |
ATOM |
Conté les coordenades atòmiques de cada àtom que no sigui d'hidrogen de la macromolècula, inclosa informació com ara el nom de l'àtom, el nom del residu, l'identificador de cadena, el número de residus i l'ocupació. |
HETATM |
Similar al registre ATOM, però per a residus no estàndard, com ara lligands, cofactors o aminoàcids modificats. |
HELIX i SHEET |
Proporcioneu informació sobre els elements de l'estructura secundària, com ara les hèlixs alfa i les fulles beta, especificant els residus implicats i els seus identificadors de cadena. |
TER |
Indica el final d'una cadena proteica o d'àcid nucleic en els registres de coordenades, permetent la separació de diferents cadenes en l'estructura. |
CONECT |
Llista la informació de connectivitat dels enllaços covalents i no covalents de l'estructura, inclosos els ponts disulfur, els llocs de coordinació metàl·lica i els enllaços entre residus estàndard i no estàndard. |
MASTER |
Proporciona un resum del nombre de línies per a diversos tipus de registre al fitxer PDB, que sovint es troba just abans del registre END . |
Un exemple d'una part del fitxer de proteïnes 3NIR (s'eliminen els àtoms del 26 al 1026):
HEADER PLANT PROTEIN 16-JUHEADER PLANT PROTEIN 16-JUN-10 3NIR
TITLE CRYSTAL STRUCTURE OF SMALL PROTEIN CRAMBIN AT 0.48 A RESOLUTION
COMPND MOL_ID: 1;
COMPND 2 MOLECULE: CRAMBIN;
COMPND 3 CHAIN: A
SOURCE MOL_ID: 1;
SOURCE 2 ORGANISM_SCIENTIFIC: CRAMBE HISPANICA;
SOURCE 3 ORGANISM_COMMON: ABYSSINIAN CRAMBE, ABYSSINIAN KALE;
SOURCE 4 ORGANISM_TAXID: 3721;
SOURCE 5 STRAIN: SUBSP. ABYSSINICA
KEYWDS PLANT PROTEIN
EXPDTA X-RAY DIFFRACTION
AUTHOR A.SCHMIDT,M.TEETER,E.WECKERT,V.S.LAMZIN
REVDAT 5 04-APR-18 3NIR 1 REMARK
REVDAT 4 24-JAN-18 3NIR 1 JRNL
REVDAT 3 08-NOV-17 3NIR 1 REMARK
REVDAT 2 02-MAR-16 3NIR 1 SEQADV SEQRES VERSN
REVDAT 1 18-MAY-11 3NIR 0
JRNL AUTH A.SCHMIDT,M.TEETER,E.WECKERT,V.S.LAMZIN
JRNL TITL CRYSTAL STRUCTURE OF SMALL PROTEIN CRAMBIN AT 0.48 A
JRNL TITL 2 RESOLUTION
JRNL REF ACTA CRYSTALLOGR.,SECT.F V. 67 424 2011
JRNL REFN ESSN 1744-3091
JRNL PMID 21505232
JRNL DOI 10.1107/S1744309110052607
REMARK 1
REMARK 1 REFERENCE 1
REMARK 1 AUTH C.JELSCH,M.M.TEETER,V.S.LAMZIN,V.PICHON-PESME,R.H.BLESSING,
REMARK 1 AUTH 2 C.LECOMTE
REMARK 1 TITL ACCURATE PROTEIN CRYSTALLOGRAPHY AT ULTRA-HIGH RESOLUTION:
REMARK 1 TITL 2 VALENCE ELECTRON DISTRIBUTION IN CRAMBIN.
REMARK 1 REF PROC.NATL.ACAD.SCI.USA V. 97 3171 2000
REMARK 1 REFN ISSN 0027-8424
REMARK 1 PMID 10737790
REMARK 2
REMARK 2 RESOLUTION. 0.48 ANGSTROMS.
REMARK 3
REMARK 3 REFINEMENT.
REMARK 3 PROGRAM : MOPRO
REMARK 3 AUTHORS : GUILLOT,VIRY,GUILLOT,LECOMTE,JELSCH
DBREF 3NIR A 1 46 UNP P01542 CRAM_CRAAB 1 46
SEQADV 3NIR SER A 22 UNP P01542 PRO 22 MICROHETEROGENEITY
SEQADV 3NIR ILE A 25 UNP P01542 LEU 25 MICROHETEROGENEITY
SEQRES 1 A 46 THR THR CYS CYS PRO SER ILE VAL ALA ARG SER ASN PHE
SEQRES 2 A 46 ASN VAL CYS ARG LEU PRO GLY THR PRO GLU ALA LEU CYS
SEQRES 3 A 46 ALA THR TYR THR GLY CYS ILE ILE ILE PRO GLY ALA THR
SEQRES 4 A 46 CYS PRO GLY ASP TYR ALA ASN
HET EOH A2001 3
HET EOH A2002 6
HET EOH A2003 6
HET EOH A2004 3
HETNAM EOH ETHANOL
FORMUL 2 EOH 4(C2 H6 O)
FORMUL 6 HOH *98(H2 O)
HELIX 1 1 SER A 6 LEU A 18 1 13
SHEET 1 A 2 THR A 2 CYS A 3 0
SHEET 2 A 2 ILE A 33 ILE A 34 -1 O ILE A 33 N CYS A 3
SSBOND 1 CYS A 3 CYS A 40 1555 1555 2.03
SSBOND 2 CYS A 4 CYS A 32 1555 1555 2.05
SSBOND 3 CYS A 16 CYS A 26 1555 1555 2.04
SITE 1 AC1 8 ALA A 45 ASN A 46 EOH A2004 HOH A3006
SITE 2 AC1 8 HOH A3027 HOH A3038 HOH A3087 HOH A3091
SITE 1 AC2 10 ILE A 7 VAL A 8 SER A 11 ALA A 27
SITE 2 AC2 10 GLY A 31 CYS A 32 ILE A 33 HOH A3002
SITE 3 AC2 10 HOH A3068 HOH A3102
SITE 1 AC3 3 ILE A 7 ASN A 46 HOH A3063
SITE 1 AC4 7 ASN A 14 LEU A 18 EOH A2001 HOH A3011
SITE 2 AC4 7 HOH A3020 HOH A3023 HOH A3085
CRYST1 22.329 18.471 40.769 90.00 90.55 90.00 P 1 21 1 2
ORIGX1 1.000000 0.000000 0.000000 0.00000
ORIGX2 0.000000 1.000000 0.000000 0.00000
ORIGX3 0.000000 0.000000 1.000000 0.00000
SCALE1 0.044785 0.000000 0.000430 0.00000
SCALE2 0.000000 0.054139 0.000000 0.00000
SCALE3 0.000000 0.000000 0.024530 0.00000
ATOM 1 N ATHR A 1 3.265 -14.107 16.877 0.87 4.71 N
ATOM 2 N BTHR A 1 4.046 -14.111 17.614 0.25 9.35 N
ATOM 3 CA ATHR A 1 4.047 -12.839 16.901 0.76 3.80 C
ATOM 4 CA BTHR A 1 4.261 -12.797 17.017 0.20 4.94 C
ATOM 5 C ATHR A 1 4.817 -12.834 15.587 0.80 3.68 C
ATOM 6 C BTHR A 1 4.935 -12.642 15.657 0.22 3.77 C
ATOM 7 O ATHR A 1 5.379 -13.834 15.145 0.85 5.76 O
ATOM 8 O BTHR A 1 5.025 -13.745 15.106 0.16 5.61 O
ATOM 9 CB ATHR A 1 5.042 -12.868 18.075 0.65 4.22 C
ATOM 10 CB BTHR A 1 4.850 -11.840 18.069 0.25 9.70 C
ATOM 11 OG1ATHR A 1 4.228 -13.043 19.244 0.78 6.21 O
ATOM 12 OG1BTHR A 1 4.711 -10.458 17.718 0.25 10.60 O
ATOM 13 CG2ATHR A 1 5.890 -11.610 18.173 0.63 5.67 C
ATOM 14 CG2BTHR A 1 6.341 -12.129 18.134 0.25 9.55 C
ATOM 15 H1 ATHR A 1 3.035 -14.005 16.173 0.75 6.58 H
ATOM 16 H1 BTHR A 1 2.914 -14.713 18.488 0.25 11.77 H
ATOM 17 H2 ATHR A 1 2.830 -14.148 17.523 0.75 6.58 H
ATOM 18 H2 BTHR A 1 4.980 -14.983 15.512 0.25 11.77 H
ATOM 19 H3 ATHR A 1 3.680 -15.162 17.238 0.75 6.58 H
ATOM 20 H3 BTHR A 1 9.013 -8.192 18.474 0.25 11.77 H
ATOM 21 HA ATHR A 1 3.181 -11.806 16.823 0.75 4.19 H
ATOM 22 HA BTHR A 1 3.605 -12.290 17.060 0.25 5.98 H
ATOM 23 HB ATHR A 1 5.699 -13.731 17.989 0.75 4.53 H
ATOM 24 HB BTHR A 1 4.523 -12.115 19.103 0.25 9.37 H
ATOM 25 HG1ATHR A 1 3.314 -12.887 19.057 0.75 8.30 H
HETATM 1027 O HOH A3123 21.546 -12.379 16.777 1.00 61.40 O
CONECT 66 795
CONECT 76 633
CONECT 324 515
CONECT 515 324
CONECT 633 76
CONECT 795 66
CONECT 894 895 896
CONECT 895 894
CONECT 896 894
CONECT 897 899 901
CONECT 898 900 902
CONECT 899 897
CONECT 900 898
CONECT 901 897
CONECT 902 898
CONECT 903 905 907
CONECT 904 906 908
CONECT 905 903
CONECT 906 904
CONECT 907 903
CONECT 908 904
CONECT 909 910 911
CONECT 910 909
CONECT 911 909
MASTER 322 0 4 1 2 0 8 6 451 1 24
END
Càrrega en fitxers PDB
Per a aquesta part, farem servir BioPandas i ProDy, podeu instal·lar-los al vostre entorn Python mitjançant pip
:
pip install biopandas prody
A continuació tens una funció que llegeix un fitxer PDB des d'una ruta d'arxiu o un ID PDB/Uniprot a un DataFrame de pandas, que s'ha adaptat del paquet Graphein:
import pandas as pd
from biopandas.pdb import PandasPdb
from prody import parsePDBHeader
from typing import Optional
def read_pdb_to_dataframe(
pdb_path: Optional[str] = None,
model_index: int = 1,
parse_header: bool = True,
) -> pd.DataFrame:
"""
Read a PDB file, and return a Pandas DataFrame containing the atomic coordinates and metadata.
Args:
pdb_path (str, optional): Path to a local PDB file to read. Defaults to None.
model_index (int, optional): Index of the model to extract from the PDB file, in case
it contains multiple models. Defaults to 1.
parse_header (bool, optional): Whether to parse the PDB header and extract metadata.
Defaults to True.
Returns:
pd.DataFrame: A DataFrame containing the atomic coordinates and metadata, with one row
per atom
"""
atomic_df = PandasPdb().read_pdb(pdb_path)
if parse_header:
header = parsePDBHeader(pdb_path)
else:
header = None
atomic_df = atomic_df.get_model(model_index)
if len(atomic_df.df["ATOM"]) == 0:
raise ValueError(f"No model found for index: {model_index}")
return pd.concat([atomic_df.df["ATOM"], atomic_df.df["HETATM"]]), header
Aquesta funció integra la capacitat d'analitzar la capçalera PDB en forma de diccionari de tal manera que ens permet emmagatzemar tota la informació útil que cal utilitzar en les tasques posteriors.
Descarregua el fitxer 3NIR
:
$ wget https://files.rcsb.org/download/3NIR.pdb
Llegim el fitxer
df, df_header = read_pdb_to_dataframe('3nir.pdb')
df.head(10)
TODO resultat
>>> print(df.shape)
(1026, 22)
>>> print(df_header.keys())
dict_keys(['helix', 'helix_range', 'sheet', 'sheet_range', 'chemicals', 'polymers', 'reference', 'resolution', 'biomoltrans', 'version', 'deposition_date', 'classification', 'identifier', 'title', 'experiment', 'authors', 'space_group', 'related_entries', 'EOH', 'A'])
La variable df
és un dataframe Pandas que permet manipular i analitzar dades de manera molt fàcil.
Aquí tens un exemple d'obtenir les coordenades x, y, z dels carbonis alfa:
df.loc[df['atom_name']=='CA', ['x_coord', 'y_coord', 'z_coord']]
Visualitzacions en 3D senzilles: traçar àtoms
La visualització de proteïnes és crucial perquè proporciona una manera tangible d'entendre les seves complexes estructures 3D, que és fonamental per entendre les seves funcions, interaccions i el paper que tenen en els processos biològics.
Per a això, utilitzem el paquet Plotly de Python per a la visualització en 3D.
Si encara no està instal·lat al vostre entorn Python, podeu instal·lar-lo fàcilment:
$ pip install plotly
Utilitzant la funció scatter_3d, podem representar el núvol de punts àtoms acolorit pel seu element:
import plotly.express as px
fig = px.scatter_3d(df, x='x_coord', y='y_coord', z='z_coord', color='element_symbol')
fig.update_traces(marker_size = 4)
fig.show()
TODO mostrar gràfic
Manipulació de marcs de dades PDB — Construcció de gràfics de proteïnes
Utilitzarem el paquet Graphein a Python com a eix vertebrador de les nostres manipulacions i visualitzacions de dades més complexes. Per instal·lar-lo executeu:
pip install graphein
Admet la creació de representacions de gràfics a partir de dades estructurals de proteïnes, permetent una anàlisi i una visualització més detallada i interactiva de les estructures de proteïnes més enllà del simple gràfic de núvols de punts. Tracem gràfics de residus per entendre les complexes relacions espacials i interaccions entre diferents residus en una estructura de proteïnes. Graphein proposa una API d'alt nivell, però, es carrega directament a la proteïna des del fitxer PDB, forçant la manipulació de dades a través de la seva API opaca, que pot ser feixuga. Per evitar-ho, aquí teniu passos ràpids i senzills per construir el gràfic a partir d'un marc de dades de Pandas (que hem carregat anteriorment al pas 1):
Primer processem el marc de dades mitjançant mètodes pandas estàndard. És important etiquetar cada node (àtom/residu) amb un identificador únic. Per a això fem servir label_node_id , que concatena chain_id:residue_name:residue_number:alt_loc (si la granularitat s'estableix a 'atom', substitueix residue amb atom ).
from graphein.protein.graphs import label_node_id
def process_dataframe(df: pd.DataFrame, granularity='CA') -> pd.DataFrame:
"""
Process a DataFrame of protein structure data to reduce ambiguity and simplify analysis.
This function performs the following steps:
1. Handles alternate locations for an atom, defaulting to keep the first one if multiple exist.
2. Assigns a unique node_id to each residue in the DataFrame, using a helper function label_node_id.
3. Filters the DataFrame based on specified granularity (defaults to 'CA' for alpha carbon).
Parameters
----------
df : pd.DataFrame
The DataFrame containing protein structure data to process. It is expected to contain columns 'alt_loc' and 'atom_name'.
granularity : str, optional
The level of detail or perspective at which the DataFrame should be analyzed. Defaults to 'CA' (alpha carbon).
"""
# handle the case of alternative locations,
# if so default to the 1st one = A
if 'alt_loc' in df.columns:
df['alt_loc'] = df['alt_loc'].replace('', 'A')
df = df.loc[(df['alt_loc']=='A')]
df = label_node_id(df, granularity)
df = df.loc[(df['atom_name']==granularity)]
return df
>>> process_df = process_dataframe(df)
>>> print(process_df.shape)
(46, 24)
- A continuació, inicialitzem un gràfic (és a networkx object) amb totes les metadades útils.
from graphein.protein.graphs import initialise_graph_with_metadata
>>> g = initialise_graph_with_metadata(protein_df=process_df, # from above cell
raw_pdb_df=df, # Store this for traceability
pdb_code = '3nir', #and again
granularity = 'CA' # Store this so we know what kind of graph we have
)
- Ara afegim tots els nodes al nostre gràfic.
from graphein.protein.graphs import add_nodes_to_graph
>>> g = add_nodes_to_graph(g)
>>> print(g.nodes)
NodeView(('A:THR:1:A', 'A:THR:2:A', 'A:CYS:3:A', 'A:CYS:4:A', 'A:PRO:5:A', 'A:SER:6:A', 'A:ILE:7:A', 'A:VAL:8:A', 'A:ALA:9:A',
'A:ARG:10:A', 'A:SER:11:A', 'A:ASN:12:A', 'A:PHE:13:A', 'A:ASN:14:A', 'A:VAL:15:A', 'A:CYS:16:A', 'A:ARG:17:A', 'A:LEU:18:A',
'A:PRO:19:A', 'A:GLY:20:A', 'A:THR:21:A', 'A:PRO:22:A', 'A:GLU:23:A', 'A:ALA:24:A', 'A:LEU:25:A', 'A:CYS:26:A', 'A:ALA:27:A',
'A:THR:28:A', 'A:TYR:29:A', 'A:THR:30:A', 'A:GLY:31:A', 'A:CYS:32:A', 'A:ILE:33:A', 'A:ILE:34:A', 'A:ILE:35:A', 'A:PRO:36:A',
'A:GLY:37:A', 'A:ALA:38:A', 'A:THR:39:A', 'A:CYS:40:A', 'A:PRO:41:A', 'A:GLY:42:A', 'A:ASP:43:A', 'A:TYR:44:A', 'A:ALA:45:A',
'A:ASN:46:A'))
- Les interaccions que volem capturar a la nostra proteïna defineixen quin tipus d'arestes construirem en el nostre gràfic. Per a aquest exemple, simplement connectarem els residus seguint la columna vertebral, això il·lustra com podem escriure funcions de vora personalitzades. La majoria dels bons ja estan implementats graphein.protein.edges. Aquesta és una versió simplificada de add_peptide_bond
import networkx as nx
def add_backbone_edges(G: nx.Graph) -> nx.Graph:
# Iterate over every chain
for chain_id in G.graph["chain_ids"]:
# Find chain residues
chain_residues = [
(n, v) for n, v in G.nodes(data=True) if v["chain_id"] == chain_id
]
# Iterate over every residue in chain
for i, residue in enumerate(chain_residues):
try:
# Checks not at chain terminus
if i == len(chain_residues) - 1:
continue
# Asserts residues are on the same chain
cond_1 = ( residue[1]["chain_id"] == chain_residues[i + 1][1]["chain_id"])
# Asserts residue numbers are adjacent
cond_2 = (abs(residue[1]["residue_number"] - chain_residues[i + 1][1]["residue_number"])== 1)
# If this checks out, we add a peptide bond
if (cond_1) and (cond_2):
# Adds "peptide bond" between current residue and the next
if G.has_edge(i, i + 1):
G.edges[i, i + 1]["kind"].add('backbone_bond')
else:
G.add_edge(residue[0],chain_residues[i + 1][0],kind={'backbone_bond'},)
except IndexError as e:
print(e)
return G
>>> g = add_backbone_edges(g)
>>> print(len(g.edges()))
45
Nota: el paquet Graphein és molt rígid en la manera com està dissenyat per utilitzar-lo. Requereix que ho inicialitzeu tot mitjançant les classes Graphein, qualsevol pas fora de l'ecosistema sol trobar-se amb errors. Això no funciona bé en un context de recerca. Tanmateix, trobo que el paquet és útil per a les plantilles de codi que puc modificar per adaptar-se als meus casos d'ús específics.
El paquet Graphein a Python (creat amb Plotly) també es pot utilitzar per visualitzar proteïnes.
Cada residu aquí està representat i connectat pel seu carboni alfa.
from graphein.protein.visualisation import plotly_protein_structure_graph
p = plotly_protein_structure_graph(
g,
colour_edges_by="kind",
colour_nodes_by="seq_position",
label_node_ids=False,
plot_title="3NIR Backbone Protein Graph",
node_size_multiplier=1,
)
p.show()
Treballar amb fitxers PDB multicadena
No ens limitem a cadenes proteiques úniques. Les proteïnes sovint formen complexos perquè molts processos biològics requereixen l'acció coordinada de múltiples proteïnes. Una proteïna multicadena és un complex proteic format per més d'una cadena polipeptídica, cadascuna codificada per un gen separat, que interaccionen junts per realitzar una funció o conjunt de funcions específics.
Per a això, prenem el complex https://www.rcsb.org/structure/6KDE6KDE (heterodímer). Mirant la capçalera del fitxer PDB ( descarregueu aquí ) observem que tenim informació sobre cada cadena:
HEADER OXIDOREDUCTASE 02-JUL-19 6KDE
TITLE CRYSTAL STRUCTURE OF THE ALPHA BETA HETERODIMER OF HUMAN IDH3 IN
TITLE 2 COMPLEX WITH CA(2+)
COMPND MOL_ID: 1;
COMPND 2 MOLECULE: ISOCITRATE DEHYDROGENASE [NAD] SUBUNIT ALPHA,
COMPND 3 MITOCHONDRIAL;
COMPND 4 CHAIN: A, C;
COMPND 5 SYNONYM: ISOCITRIC DEHYDROGENASE SUBUNIT ALPHA,NAD(+)-SPECIFIC ICDH
COMPND 6 SUBUNIT ALPHA;
COMPND 7 EC: 1.1.1.41;
COMPND 8 ENGINEERED: YES;
COMPND 9 MOL_ID: 2;
COMPND 10 MOLECULE: ISOCITRATE DEHYDROGENASE [NAD] SUBUNIT BETA, MITOCHONDRIAL;
COMPND 11 CHAIN: B, D;
COMPND 12 SYNONYM: ISOCITRIC DEHYDROGENASE SUBUNIT BETA,NAD(+)-SPECIFIC ICDH
COMPND 13 SUBUNIT BETA;
COMPND 14 ENGINEERED: YES
El complex està format per cadenes A i C (subunitat alfa) que s'uneixen amb cadenes B i D (subunitat beta). El dibuix del núvol de punts atòmics acolorit per la cadena d'identificació dóna:
df, df_header = read_pdb_to_dataframe('6kde.pdb')
fig = px.scatter_3d(df, x='x_coord', y='y_coord', z='z_coord', color='chain_id')
fig.update_traces(marker_size = 4)
fig.show()
Només podem mirar el complex format per les cadenes A i B. Cada àtom del marc de dades està vinculat a una cadena específica amb el chain_id atribut.
df = pd.concat((df[df['chain_id']=='A'], df[df['chain_id']=='B']))
>>> df['chain_id'].unique()
array(['A', 'B'], dtype=object)
Això torna a ressaltar el fàcil que és manipular dades de proteïnes amb Pandas. Representació del marc de dades actualitzat df utilitzant el mateix codi anterior: Extracció d'interfícies de proteïnes mitjançant Pandas
Les interfícies de proteïnes tenen un paper crucial en la comprensió de la funció i les interaccions de les proteïnes dins dels sistemes biològics. Per il·lustrar el treball amb proteïnes multicadenes, podem extreure la interfície o el contacte entre dues cadenes. La funció següent mostra com es pot aconseguir fàcilment amb numpy.
import numpy as np
def get_contact_atoms(df1: pd.DataFrame, df2:pd.DataFrame = None , threshold:float = 7., coord_names=['x_coord', 'y_coord', 'z_coord']):
# Extract coordinates from dataframes
coords1 = df1[coord_names].to_numpy()
coords2 = df2[coord_names].to_numpy()
# Compute pairwise distances between atoms
dist_matrix = np.sqrt(((coords1[:, None] - coords2) ** 2).sum(axis=2))
# Create a new dataframe containing pairs of atoms whose distance is below the threshold
pairs = np.argwhere(dist_matrix < threshold)
atoms1, atoms2 = df1.iloc[pairs[:, 0]], df2.iloc[pairs[:, 1]]
atoms1_id = atoms1['chain_id'].map(str) + ":" + atoms1['residue_name'].map(str) + ":" + atoms1['residue_number'].map(str)
atoms2_id = atoms2['chain_id'].map(str) + ":" + atoms2['residue_name'].map(str) + ":" + atoms2['residue_number'].map(str)
node_pairs = np.vstack((atoms1_id.values, atoms2_id.values)).T
result = pd.concat([df1.iloc[np.unique(pairs[:, 0])], df2.iloc[np.unique(pairs[:, 1])]])
return result, node_pairs
En aquest exemple obtindrem tots els àtoms entre les cadenes A i B que tenen una diferència de 7 Angstrom:
df_A = df[df['chain_id']=='A']
df_B = df[df['chain_id']=='B']
contact_atoms, node_pairs = get_contact_atoms(df_A, df_B, 7.)
Traçant això a Plotly, la interfície es ressalta en taronja:
import plotly.express as px
import plotly.graph_objects as go
# Create 3D scatter plots for df_A, df_B, and contact_atoms
fig = go.Figure()
# Add trace for df_A
fig.add_trace(
go.Scatter3d(
name='Chain A',
x=df_A['x_coord'],
y=df_A['y_coord'],
z=df_A['z_coord'],
mode='markers',
marker=dict(size=4, color='blue', opacity=0.5), # Adjust opacity here
)
)
# Add trace for df_B
fig.add_trace(
go.Scatter3d(
name='Chain B',
x=df_B['x_coord'],
y=df_B['y_coord'],
z=df_B['z_coord'],
mode='markers',
marker=dict(size=4, color='red', opacity=0.5), # Adjust opacity here
)
)
# Add trace for contact_atoms
fig.add_trace(
go.Scatter3d(
name='Contact Atoms',
x=contact_atoms['x_coord'],
y=contact_atoms['y_coord'],
z=contact_atoms['z_coord'],
mode='markers',
marker=dict(size=6, color='orange'), # You can adjust the color and opacity here
)
)
# Customize the layout
fig.update_layout(
scene=dict(
aspectmode="cube", # To maintain equal axis scaling
),
margin=dict(l=0, r=0, b=0, t=0),
)
# Show the plot
fig.show()