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:

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

iCn3D

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)
  1. 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
                                    )
  1. 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'))
  1. 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()