Desarrollo de una base de datos bioinformática para la investigación de enlaces disulfuro

Publicado: 2022-03-11

La base de datos bioinformática de Protein Data Bank (PDB) es el repositorio más grande del mundo de estructuras determinadas experimentalmente de proteínas, ácidos nucleicos y ensamblajes complejos. Todos los datos se recopilan utilizando métodos experimentales como rayos X, espectroscopia, cristalografía, RMN, etc.

Este artículo explica cómo extraer, filtrar y limpiar datos de la PDB. Esto, a su vez, permite el tipo de análisis que se explica en el artículo Ocurrencia de enlaces disulfuro de proteínas en diferentes dominios de la vida: una comparación de proteínas del Banco de datos de proteínas, publicado en Ingeniería, diseño y selección de proteínas, Volumen 27, Número 3, 1 de marzo de 2014, págs. 65–72.

El PDB tiene muchas estructuras repetitivas con diferentes resoluciones, métodos, mutaciones, etc. Hacer un experimento con proteínas iguales o similares puede producir sesgos en cualquier análisis de grupo, por lo que deberemos elegir la estructura correcta entre cualquier conjunto de duplicados. . Para ese propósito, necesitamos usar un conjunto de proteínas no redundantes (NR).

Para fines de normalización, recomiendo descargar el diccionario de compuestos químicos para importar nombres de átomos a una base de datos que use 3NF o use un esquema de estrella y modelado dimensional. (También he usado DSSP para ayudar a eliminar estructuras problemáticas. No lo cubriré en este artículo, pero tenga en cuenta que no usé ninguna otra característica de DSSP).

Los datos utilizados en esta investigación contienen proteínas de una sola unidad que contienen al menos un enlace disulfuro tomado de diferentes especies. Para realizar un análisis, todos los enlaces disulfuro se clasifican primero como consecutivos o no consecutivos, por dominio (arqueas, procariotas, virales, eucariotas u otros) y también por longitud.

Estructuras proteicas primarias y terciarias

Estructuras de proteínas primarias y terciarias, antes y después del plegamiento de proteínas.
Fuente: Ingeniería, diseño y selección de proteínas , como se mencionó al principio de este artículo.

Producción

Para estar listo para la entrada en R, SPSS o alguna otra herramienta, un analista necesitará que los datos estén en una tabla de base de datos con esta estructura:

Columna Escribe Descripción
code character(4) ID del experimento (alfanumérico, no distingue entre mayúsculas y minúsculas y no puede comenzar con cero)
title character varying(1000) Título del experimento, como referencia (el campo también puede tener formato de texto)
ss_bonds integer Número de enlaces disulfuro en la cadena elegida
ssbonds_overlap integer Número de enlaces disulfuro superpuestos
intra_count integer Número de enlaces formados dentro de la misma cadena.
sci_name_src character varying(5000) Nombre científico del organismo del que se toma la secuencia.
tax_path character varying Camino en el árbol de clasificación de Linneo
src_class character varying(20) Clase de organismo de nivel superior (eucariota, procariota, virus, arqueas, otros)
has_reactives7 boolean Verdadero si y solo si la secuencia contiene centros reactivos
len_class7 integer Longitud de la secuencia en el conjunto 7 (conjunto con valor p 10e-7 calculado por explosión)

Materiales y métodos

Para lograr este objetivo, el primer paso es recopilar datos de rcsb.org. Ese sitio contiene estructuras PDB descargables de experimentos en varios formatos.

Aunque los datos se almacenan en varios formatos, en este ejemplo, solo se utilizará el formato de texto delimitado por espacios fijos (PDB). Una alternativa al formato de texto PDB es su versión XML, PDBML, pero a veces contiene entradas de nombres de posiciones de átomos con formato incorrecto, lo que puede causar problemas para el análisis de datos. El mmCIF más antiguo y otros formatos también pueden estar disponibles, pero no se explicarán en este artículo.

El formato PDB

El formato PDB es un formato textual fragmentado de ancho fijo que se puede analizar fácilmente mediante consultas SQL, complementos de Java o módulos Perl, por ejemplo. Cada tipo de datos en el contenedor de archivos se representa como una línea que comienza con la etiqueta adecuada; repasaremos cada tipo de etiqueta en las siguientes subsecciones. La longitud de la línea es menor o igual a 80 caracteres, donde una etiqueta tiene seis o menos caracteres más uno o más espacios que juntos ocupan ocho bytes. También hay casos sin espacios entre etiquetas y datos, generalmente para etiquetas CONECT .

TITLE

La etiqueta TITLE marca una línea como (parte de) el título del experimento, que contiene el nombre de la molécula y otros datos relevantes como la inserción, mutación o eliminación de un aminoácido específico.

 12345678901234567890123456789012345678901234567890123456789012345678901234567890 TITLE A TWO DISULFIDE DERIVATIVE OF CHARYBDOTOXIN WITH DISULFIDE TITLE 2 13-33 REPLACED BY TWO ALPHA-AMINOBUTYRIC ACIDS, NMR, 30 TITLE 3 STRUCTURES

En el caso de que haya varias líneas en un registro de TITLE , entonces el título debe concatenarse, ordenándose por un número de continuación, que se coloca, alineado a la derecha, en los bytes 9 y 10 (dependiendo del número de estas líneas).

ATOM

Los datos almacenados en las líneas ATOM son datos de coordenadas para cada átomo en un experimento. A veces, un experimento tiene inserciones, mutaciones, ubicaciones alternativas o varios modelos. Esto da como resultado la repetición del mismo átomo varias veces. La elección de los átomos correctos se explicará más adelante.

 12345678901234567890123456789012345678901234567890123456789012345678901234567890 ATOM 390 N GLY A 26 -1.120 -2.842 4.624 1.00 0.00 N ATOM 391 CA GLY A 26 -0.334 -2.509 3.469 1.00 0.00 C ATOM 392 C GLY A 26 0.682 -1.548 3.972 1.00 0.00 C ATOM 393 O GLY A 26 0.420 -0.786 4.898 1.00 0.00 O ATOM 394 H GLY A 26 -0.832 -2.438 5.489 1.00 0.00 H ATOM 395 HA2 GLY A 26 0.163 -3.399 3.111 1.00 0.00 H ATOM 396 HA3 GLY A 26 -0.955 -2.006 2.739 1.00 0.00 H

El ejemplo anterior está tomado del experimento 1BAH . La primera columna marca el tipo de registro y la segunda columna es el número de serie del átomo. Cada átomo en una estructura tiene su propio número de serie.

Junto al número de serie está la etiqueta de posición del átomo, que ocupa cuatro bytes. Desde esa posición del átomo, es posible extraer el símbolo químico del elemento, que no siempre está presente en los datos de registro en su propia columna separada.

Después del nombre del átomo hay un código de residuo de tres letras. En el caso de las proteínas, ese residuo corresponde a un aminoácido. A continuación, la cadena se codifica con una letra. Por cadena entendemos una sola cadena de aminoácidos, con o sin espacios, aunque a veces se pueden asignar ligandos a una cadena; este caso es detectable a través de espacios muy grandes en una secuencia de aminoácidos, que se encuentra en la siguiente columna. A veces, la misma estructura se puede escanear con mutaciones incluidas, en cuyo caso el código de inserción está disponible en una columna adicional después de la columna de secuencia. El código de inserción contiene una letra para ayudar a distinguir qué residuo se ve afectado.

Las siguientes tres columnas son las coordenadas espaciales de cada átomo, medidas en Angstroms (Å). Junto a estas coordenadas está la columna de ocupación, que dice cuál es la probabilidad de que el átomo esté en ese lugar, en la escala habitual de cero a uno.

La penúltima columna es el factor de temperatura, que lleva información sobre el desorden en el cristal, medido en Ų. Un valor superior a 60Ų significa desorden, mientras que uno inferior a 30Ų significa confianza. No siempre está presente en los archivos PDB porque depende del método experimental.

Las siguientes columnas, símbolo y cargo, generalmente faltan. El símbolo químico se puede recopilar de la columna de posición del átomo, como mencionamos anteriormente. Cuando la carga está presente, se agrega al símbolo como sufijo como un número entero seguido de + o - , por ejemplo, N1+ .

TER

Esto marca el final de la cadena. Incluso sin esta línea, es fácil distinguir dónde termina una cadena. Por lo tanto, a menudo falta la línea TER .

MODEL y ENDMDL

Una línea MODEL marca dónde comienza el modelo de una estructura y contiene el número de serie del modelo.

Después de todas las líneas atómicas en ese modelo, termina con una línea ENDMDL .

SSBOND

Estas líneas contienen enlaces disulfuro entre los aminoácidos de cisteína. Los enlaces disulfuro pueden estar presentes en otros tipos de residuos, pero en este artículo solo se analizarán los aminoácidos, por lo que solo se incluye la cisteína. El siguiente ejemplo es del experimento con el código 132L :

 12345678901234567890123456789012345678901234567890123456789012345678901234567890 SSBOND 1 CYS A 6 CYS A 127 1555 1555 2.01 SSBOND 2 CYS A 30 CYS A 115 1555 1555 2.05 SSBOND 3 CYS A 64 CYS A 80 1555 1555 2.02 SSBOND 4 CYS A 76 CYS A 94 1555 1555 2.02

En este ejemplo, hay cuatro enlaces disulfuro etiquetados en el archivo con su número de secuencia en la segunda columna. Todos estos enlaces usan cisteína (columnas 3 y 6), y todos ellos están presentes en la cadena A (columnas 4 y 7). Después de cada cadena hay un número de secuencia de residuos que indica la posición del enlace en la cadena peptídica. Los códigos de inserción están junto a cada secuencia de residuos, pero en este ejemplo no están presentes porque no se insertó ningún aminoácido en esa región. Las dos columnas anteriores a la última están reservadas para operaciones de simetría, y la última columna es la distancia entre los átomos de azufre, medida en Å.

Tomemos un momento para dar algo de contexto a estos datos.

Las siguientes imágenes, tomadas con el visor NGL de rcsb.org, muestran la estructura del experimento 132L . En particular, muestran una proteína sin ligandos. La primera imagen utiliza una representación de barra, con coloración CPK que muestra azufres y sus enlaces en amarillo. Las conexiones de azufre en forma de V representan conexiones de metionina, mientras que las conexiones en forma de Z son enlaces disulfuro entre cisteínas.

Representación de barra con coloración CPK que muestra enlaces de disulfuro de azufre en amarillo

En la siguiente imagen, un método simplificado de visualización de proteínas llamado visualización de la columna vertebral se muestra coloreado por aminoácidos, donde las cisteínas son amarillas. Representa la misma proteína, con su cadena lateral excluida, y solo se incluye una parte de su grupo peptídico, en este caso, el esqueleto de la proteína. Está hecho de tres átomos: N-terminal, C-alfa y C-terminal. Esta imagen no muestra enlaces disulfuro, pero está simplificada para mostrar la disposición espacial de la proteína:

Columna vertebral de proteína simplificada coloreada por aminoácidos donde las cisteínas son amarillas

Las tuberías se crean uniendo átomos unidos a péptidos con un átomo C-alfa. El color de la cisteína es el mismo que el color del azufre en el método de coloración CPK. Cuando los cistenos se acercan lo suficiente, sus azufres crean enlaces disulfuro y eso fortalece la estructura. De lo contrario, esta proteína se uniría demasiado y su estructura sería menos estable a temperaturas más altas.

CONECT

Estos registros se utilizan para etiquetar conexiones entre átomos. A veces, estas etiquetas no están presentes en absoluto, mientras que otras veces se completan todos los datos. En el caso de analizar enlaces disulfuro, esta parte puede ser útil, pero no es necesaria. Esto se debe a que, en este proyecto, los enlaces no etiquetados se agregan midiendo distancias, por lo que esto sería una sobrecarga y también debe verificarse.

SOURCE

Estos registros contienen información sobre el organismo fuente del que se ha extraído la molécula. Contienen subregistros para facilitar la ubicación en la taxonomía y tienen la misma estructura de varias líneas que vimos con los registros de título.

 SOURCE MOL_ID: 1; SOURCE 2 ORGANISM_SCIENTIFIC: ANOPHELES GAMBIAE; SOURCE 3 ORGANISM_COMMON: AFRICAN MALARIA MOSQUITO; SOURCE 4 ORGANISM_TAXID: 7165; SOURCE 5 GENE: GST1-6; SOURCE 6 EXPRESSION_SYSTEM: ESCHERICHIA COLI; SOURCE 7 EXPRESSION_SYSTEM_TAXID: 562; SOURCE 8 EXPRESSION_SYSTEM_STRAIN: BL21(DE3)PLYSS; SOURCE 9 EXPRESSION_SYSTEM_VECTOR_TYPE: PLASMID; SOURCE 10 EXPRESSION_SYSTEM_PLASMID: PXAGGST1-6

Formato NR

Esta es una lista de conjuntos de PDB de cadena no redundantes (NR). Sus instantáneas se pueden encontrar en ftp.ncbi.nih.gov/mmdb/nrtable/. Su propósito es evitar sesgos innecesarios causados ​​por la similitud de proteínas. NR tiene tres conjuntos con diferentes niveles de valor p de identidad creados por comparación de todas las estructuras PDB. El resultado se agrega a los archivos de texto que se explicarán más adelante. No se necesitan todas las columnas para este proyecto, por lo que solo se explicarán las importantes.

Las primeras dos columnas contienen el código de experimento de PDB único y el identificador de cadena como se explicó anteriormente para los registros ATOM . Las columnas 6, 9 y C contienen información sobre la representatividad del valor p, que es el nivel de similitud de las secuencias calculado por BLAST. Si ese valor es cero, entonces no se acepta que forme parte de un conjunto; si el valor es 1, entonces lo es. Las columnas mencionadas representan la aceptación de conjuntos con puntos de corte de valores p de 10e-7, 10e-40 y 10e-80, respectivamente. Solo se utilizarán para el análisis los conjuntos con un valor de corte de p de 10e-7.

La última columna contiene información sobre la aceptabilidad de una estructura, donde a es aceptable y n no lo es.

 #--------------------------------------------------------------------------------------------------------------------------- # 1 2 3 4 5 6 7 8 9 ABCDEFGHIJKLMNOPQ #--------------------------------------------------------------------------------------------------------------------------- 3F8V A 69715 1 1 1 1 1 1 1 1 1 9427 1 1 0.00 0.00 0.00 0.00 1.08 1 6 5 164 X a 3DKE X 68132 1 2 0 1 2 0 1 2 0 39139 1 1 0.00 0.00 0.00 0.00 1.25 1 11 7 164 X a 3HH3 A 77317 1 3 0 1 3 0 1 3 0 90 1 0 0.00 0.00 0.00 0.00 1.25 1 5 4 164 X a 3HH5 A 77319 1 4 0 1 4 0 1 4 0 90 2 0 0.00 0.00 0.00 0.00 1.25 1 4 4 164 X a

Construcción de bases de datos y análisis de datos

Ahora que tenemos una idea de a lo que nos enfrentamos y de lo que debemos hacer, comencemos.

Descarga de datos

Todos los datos para este análisis se pueden encontrar en estas tres direcciones:

  • ftp.wwpdb.org/pub/pdb/data/structures/divided/pdb/
  • ftp.ncbi.nih.gov/mmdb/nrtable/
  • ftp.ncbi.nih.gov/pub/taxonomy/taxdmp.zip

Los dos primeros enlaces contienen una lista de archivos. Se debe utilizar el archivo más reciente de cada uno para evitar problemas derivados de la falta de resolución o calidad. El tercer enlace contiene directamente el archivo de taxonomía más reciente.

Análisis de datos

Por lo general, el análisis de los archivos PDB se realiza mediante complementos o módulos en Java, Perl o Python. En el caso de esta investigación, escribí una aplicación Perl personalizada sin usar un módulo de análisis de PDB escrito previamente. La razón de esto es cuando se analiza una gran cantidad de datos, en mi experiencia, el problema más común con el uso de datos experimentales son los errores en los datos. A veces hay errores con coordenadas, distancias, longitudes de línea, comentarios en lugares donde no deberían estar, etc.

La forma más efectiva de lidiar con esto es almacenar inicialmente todo en la base de datos como texto sin formato. Los analizadores comunes están escritos para manejar datos ideales que se ajustan completamente a las especificaciones. Pero en la práctica, los datos no son ideales, y eso se explicará en la sección de filtrado donde encontrará el script de importación de Perl.

Construcción de base de datos

Al construir la base de datos, tenga en cuenta que esta base de datos está construida para procesar datos. El análisis posterior se realizará en SPSS o R. Para nuestros propósitos aquí, se recomienda utilizar PostgreSQL con al menos la versión 8.4.

La estructura de la tabla se copia directamente de los archivos descargados con solo unos pequeños cambios. En este caso, la cantidad de registros es demasiado pequeña para que valga la pena dedicar nuestro tiempo a la normalización. Como se mencionó, esta base de datos es de un solo uso: estas tablas no están diseñadas para servir en un sitio web, solo están ahí para procesar datos. Una vez que haya terminado, se pueden descartar o respaldar como datos complementarios, tal vez para repetir el proceso por parte de otro investigador.

En este caso, el resultado final será una tabla que luego se puede exportar a un archivo para usar con alguna herramienta estadística como SPSS o R.

Mesas

La extracción de datos de los registros ATOM debe conectarse a los registros HEADER o TITLE . La jerarquía de datos se explica en la siguiente imagen.

La jerarquía natural de los datos de enlaces disulfuro que darían como resultado una base de datos en tercera forma normal

Dado que esta imagen es una representación simplificada de una base de datos en la tercera forma normal (3NF), para nuestros propósitos contiene demasiada sobrecarga. La razón: para calcular la distancia entre átomos para la detección de enlaces disulfuro, necesitaríamos hacer uniones. En este caso, tendríamos una tabla unida a sí misma dos veces, y también unida a una estructura secundaria y primaria dos veces cada una, lo cual es un proceso muy lento. Dado que no todos los análisis necesitan información de estructura secundaria, se propone otro esquema en caso de que necesite reutilizar datos o analizar mayores cantidades de enlaces disulfuro:

Un modelo más detallado de un esquema de base de datos que no utiliza estructuras secundarias (3NF)

Los enlaces disulfuro no son tan frecuentes como otros enlaces covalentes, por lo que no se necesita un modelo de almacén, aunque podría utilizarse. El esquema en estrella y el modelado dimensional a continuación tomará demasiado tiempo para desarrollarse y hará que las consultas sean más complejas:

El diseño de la base de datos utilizando el esquema de estrella y el modelado dimensional.

En los casos en que se deben procesar todos los bonos, recomiendo el esquema de estrella.

(De lo contrario, no es necesario, porque los enlaces disulfuro no son tan comunes como otros enlaces. En el caso de este trabajo, la cantidad de enlaces disulfuro es cercana a los 30,000, lo que puede ser lo suficientemente rápido en 3NF, pero decidí procesarlo a través de una tabla no normalizada, por lo que no se muestra aquí).

El número total esperado de todos los enlaces covalentes es al menos el doble del número de átomos en la estructura terciaria, y en ese caso 3NF sería muy lento, por lo que se necesita la desnormalización utilizando la forma de esquema de estrella. En ese esquema, algunas tablas tienen dos controles de clave externa, y eso se debe a que se crea un enlace entre dos átomos, por lo que cada átomo debe tener su propio primary_structure_id , atom_name_id y residue_id .

Hay dos formas de llenar la tabla de dimensiones d_atom_name : a partir de datos y de otra fuente, el diccionario de componentes químicos que mencioné anteriormente. Su formato es similar al formato PDB: Solo las líneas CONECT RESIDUE útiles. Esto se debe a que la primera columna de CONECT RESIDUE el nombre del átomo y sus conexiones, que también son nombres de átomos. Entonces, desde este archivo, podemos analizar todos los nombres de átomos e incluirlos en nuestra base de datos, aunque le recomiendo que permita la posibilidad de que la base de datos contenga nombres de átomos no listados.

 RESIDUE PRO 17 CONECT N 3 CA CD H CONECT CA 4 NC CB HA CONECT C 3 CA O OXT CONECT O 1 C CONECT CB 4 CA CG HB2 HB3 CONECT CG 4 CB CD HG2 HG3 CONECT CD 4 N CG HD2 HD3 CONECT OXT 2 C HXT CONECT H 1 N CONECT HA 1 CA CONECT HB2 1 CB CONECT HB3 1 CB CONECT HG2 1 CG CONECT HG3 1 CG CONECT HD2 1 CD CONECT HD3 1 CD CONECT HXT 1 OXT END HET PRO 17 HETNAM PRO PROLINE FORMUL PRO C5 H9 N1 O2

En este proyecto, la velocidad de codificación es más relevante que la velocidad de ejecución y el consumo de almacenamiento. Decidí no normalizar; después de todo, nuestro objetivo es generar una tabla con las columnas mencionadas en la introducción.

En esta parte, solo se explicarán las tablas más importantes.

Las tablas principales son:

  • proteins : Tabla con nombres y códigos de experimentos.
  • ps : tabla de estructura primaria que contendrá sequence , chain_id y code .
  • ts : Tabla que contiene la estructura terciaria/cuaternaria extraída de datos sin procesar y transformada en formato de registro ATOM . Esto se usará como una mesa de preparación y se puede quitar después de la extracción. Los ligandos están excluidos.
  • sources : La lista de organismos de los cuales se derivaron los datos experimentales.
  • tax_names , taxonomy_path , taxonomy_paths : nombres de taxonomía de Linne de la base de datos de taxonomía del NCBI, utilizados para obtener rutas de taxonomía de los organismos enumerados en las sources .
  • nr : Lista de proteínas no redundantes de NCBI extraídas del conjunto NR.
  • pdb_ssbond : Lista de enlaces disulfuro en un archivo PDB dado.

Filtrado y procesamiento de datos

Los datos se recuperan de las instantáneas del depósito RCSB PDB.

Cada archivo se importa a una sola tabla raw_pdb en nuestra base de datos PostgreSQL utilizando un script Perl. El script usa transacciones de 10.000 inserciones por fragmento.

La estructura de raw_pdb es esta:

Columna Escribe Modificadores
código carácter variable(20) no nulo
núm_línea entero no nulo
line_cont carácter variable(80) no nulo

El script de importación se ve así:

 #!/usr/bin/perl -w use FindBin '$Bin'; use DBI; $dbName = 'bioinf'; $dbLogin = 'ezop'; $dbPass = 'XYZ'; $conn = DBI->connect("DBI:Pg:database=$dbName;host=localhost", "$dbLogin", "$dbPass", {'RaiseError' => 1, 'AutoCommit' => 0}); die "./pdb_lines_unos.pl <table> <file>" if not defined($ARGV[0]); $recordCount = 0; $table = $ARGV[0]; $fName = $ARGV[1]; open F, "zcat $fName|"; while (<F>) { chomp; $linija = $_; $recordCount += 1; $sql = "insert into $table (code, line_num, line_cont) values (?, ?, ?)"; $conn->do($sql, undef, $fName, $recordCount, $linija); $conn->commit() if ($recordCount%10000 == 0); } close F; $conn->commit(); 1;

Una vez que se importan las líneas, se analizan utilizando las funciones que definiremos a continuación.

A partir de los datos raw_pdb , generamos las tablas ts , ps , proteins , sources , sources_organela y ss_bond analizando los registros correspondientes.

La tabla ps tiene tres columnas importantes: chain , length y sequence . La secuencia de proteínas se genera utilizando átomos C-alfa para cada cadena y para cada residuo ordenado por secuencia de residuos, tomando solo la primera inserción y la primera ubicación alternativa. chain se toma de la columna TS.chain y length es simplemente la longitud precalculada de la cadena de sequence . Dado que este artículo está destinado a analizar solo cadenas simples y conexiones intracadena, las proteínas de cadena múltiple se omiten en nuestro análisis aquí.

Dentro de los registros SSBOND , todos los enlaces disulfuro se almacenan en la tabla pdb_ssbond , que hereda de la tabla pdb_ssbond_extended . pdb_ssbond se ve así:

Columna Escribe anulable Por defecto Descripción
identificación entero no nulo nextval('pdb_ssbond_id_seq'::regclass)
código personaje(4) código de cuatro letras
núm_ser entero número de serie de ssbond
residuo1 personaje(3) primer residuo en enlace
cadena_id1 personaje(1) primera cadena en enlace
res_seq1 entero número secuencial del primer residuo
i_code1 personaje(1) código de inserción del primer residuo
residuo2 personaje(3) segundo residuo en enlace
cadena_id2 personaje(1) segunda cadena en enlace
res_seq2 entero número secuencial del segundo residuo
i_code2 personaje(1) código de inserción del segundo residuo
sim1 personaje(6) primer operador de simetría
sim2 personaje(6) segundo operador de simetría
dist numérico (5,2) distancia entre átomos
es_reactivo booleano no nulo falso marca de reactividad (a configurar)
es_consecutivo booleano no nulo cierto marca para bonos consecutivos (por establecer)
rep7 booleano no nulo falso marca para estructuras set-7 (a configurar)
rep40 booleano no nulo falso marca para estructuras set-40 (a definir)
rep80 booleano no nulo falso marca para estructuras set-80 (a configurar)
es_de_pdb booleano cierto se toma de PDB como fuente (a configurar)

También agregué estos índices:

 "pdb_ssbond_pkey" PRIMARY KEY, btree (id) "ndxcode1" btree (code, chain_id1, res_seq1) "ndxcode2" btree (code, chain_id2, res_seq2)

Se supone que la distribución de los enlaces disulfuro antes del límite es gaussiana (sin probar con, por ejemplo, la prueba KS), por lo que se calcularon las desviaciones estándar en cada distancia entre las cisteínas en la misma proteína para descubrir el rango de longitudes de enlace permitidas y compararlas. al corte. El límite fue el mismo que la media calculada más menos tres desviaciones estándar. Hemos ampliado el rango para introducir más enlaces disulfuro posibles que no estaban incluidos en el archivo PDB en las filas SSBOND pero que hemos insertado nosotros mismos calculando las distancias entre los registros ATOM . El rango elegido para los ssbonds está entre 1,6175344456264 y 2,48801947642267 Å, ​​que es la media (2,05) más menos cuatro desviaciones estándar:

 select count(1) as cnt , stddev(dist) as std_dev , avg(dist) as avg_val , -stddev(dist) + avg(dist) as left1 , stddev(dist) + avg(dist) as right1 , -2 * stddev(dist) + avg(dist) as left2 , 2 * stddev(dist) + avg(dist) as right2 , -3 * stddev(dist) + avg(dist) as left3 , 3 * stddev(dist) + avg(dist) as right3 , -4 * stddev(dist) + avg(dist) as left4 , 4 * stddev(dist) + avg(dist) as right4 , min(dist) , max(dist) from pdb_ssbond_tmp where dist > 0 and dist < 20;

La tabla TS contiene las coordenadas de todos los átomos, pero solo se utilizarán las cisteínas, con su azufre denominado " SG " . Por lo tanto, se crea otra tabla de etapas con átomos de azufre " SG " para acelerar el proceso al reducir la cantidad de registros para buscar. Cuando se seleccionan solo azufres, el número de combinaciones es mucho menor que en el caso de todos los átomos: 194.574 de los primeros frente a 122.761.100 de los últimos. Dentro de esta tabla unida a sí misma, las distancias se calculan utilizando la distancia euclidiana y los resultados se importan a la tabla pdb_ssbond pero solo donde la distancia está entre las longitudes definidas calculadas anteriormente. La razón para hacer esta aceleración es disminuir la cantidad de tiempo para ejecutar todo el proceso nuevamente, con fines de verificación, manteniéndolo dentro de un día.

Para limpiar los enlaces disulfuro, usamos el siguiente algoritmo:

  • Eliminar cuando ambos lados de la conexión apuntan al mismo aminoácido
  • Eliminar bonos cuya longitud no esté entre 1.6175344456264 y 2.48801947642267
  • Eliminar inserciones
  • Elimina los enlaces causados ​​por ubicaciones alternas de átomos, pero dejando la primera ubicación

El código para esto (tomando la tabla pdb_ssbond como primer argumento) es:

 CREATE OR REPLACE FUNCTION pdb_ssbond_clean2( clean_icodes boolean, clean_altloc boolean, mark_reactive boolean, mark_consecutive boolean) RETURNS void AS $$ declare _res integer; BEGIN delete from pdb_ssbond b where exists ( select a.id from pdb_ssbond a where a.code = b.code and a.id > b.id and ( ( a.chain_id1 = b.chain_id1 and a.res_seq1 = b.res_seq1 and a.chain_id2 = b.chain_id2 and a.res_seq2 = b.res_seq2) or ( a.chain_id1 = b.chain_id2 and a.res_seq1 = b.res_seq2 and a.chain_id2 = b.chain_id1 and a.res_seq2 = b.res_seq1) ) ) ; delete from pdb_ssbond where chain_id1 = chain_id2 and res_seq1 = res_seq2 and i_code1 = i_code2; update pdb_ssbond set is_consecutive = true , is_reactive = false; delete from pdb_ssbond where not dist between 1.6175344456264 and 2.48801947642267; if clean_icodes then delete from pdb_ssbond where i_code1 not in ('', ' ', 'A') or i_code2 not in ('', ' ', 'A') ; end if; if clean_altloc then delete from pdb_ssbond a where exists ( select 1 from pdb_ssbond b where b.code = a.code and b.chain_id1 = a.chain_id1 and b.res_seq1 = a.res_seq1 and b.i_code1 = a.i_code1 and b.ser_num < a.ser_num ) ; delete from pdb_ssbond a where exists ( select 1 from pdb_ssbond b where b.code = a.code and b.chain_id2 = a.chain_id2 and b.res_seq2 = a.res_seq2 and b.i_code2 = a.i_code2 and b.ser_num < a.ser_num ) ; end if; if mark_reactive then update pdb_ssbond set is_reactive = false ; update pdb_ssbond set is_reactive = true where exists ( select 1 from pdb_ssbond b where b.code = pdb_ssbond.code and b.chain_id1 = pdb_ssbond.chain_id1 and b.res_seq1 = pdb_ssbond.res_seq1 and b.i_code1 = pdb_ssbond.i_code1 and b.ser_num < pdb_ssbond.ser_num ) ; update pdb_ssbond set is_reactive = true where exists ( select 1 from pdb_ssbond b where b.code = pdb_ssbond.code and b.chain_id2 = pdb_ssbond.chain_id2 and b.res_seq2 = pdb_ssbond.res_seq2 and b.i_code2 = pdb_ssbond.i_code2 and b.ser_num < pdb_ssbond.ser_num ) ; update pdb_ssbond set is_reactive = true where (code, chain_id1, res_seq1, i_code1) in ( select code, chain_id1 as c, res_seq1 as r, i_code1 as i from pdb_ssbond intersect select code, chain_id2 as c, res_seq2 as r, i_code2 as i from pdb_ssbond ) ; update pdb_ssbond set is_reactive = true where (code, chain_id2, res_seq2, i_code2) in ( select code, chain_id1 as c, res_seq1 as r, i_code1 as i from pdb_ssbond intersect select code, chain_id2 as c, res_seq2 as r, i_code2 as i from pdb_ssbond ); end if; if mark_consecutive then update pdb_ssbond set is_consecutive = false; update pdb_ssbond set is_consecutive = true where not exists ( select 1 from pdb_ssbond a where a.code = pdb_ssbond.code and ( (a.chain_id1 = pdb_ssbond.chain_id1 and a.chain_id2 = pdb_ssbond.chain_id2) or (a.chain_id1 = pdb_ssbond.chain_id2 and a.chain_id2 = pdb_ssbond.chain_id1) ) and ( (a.res_seq1 between pdb_ssbond.res_seq1 and pdb_ssbond.res_seq2) or (a.res_seq2 between pdb_ssbond.res_seq1 and pdb_ssbond.res_seq2) or (pdb_ssbond.res_seq1 between a.res_seq1 and a.res_seq2) or (pdb_ssbond.res_seq2 between a.res_seq1 and a.res_seq2) ) and not ( a.code = pdb_ssbond.code and a.chain_id1 = pdb_ssbond.chain_id1 and a.chain_id2 = pdb_ssbond.chain_id2 and a.res_seq1 = pdb_ssbond.res_seq1 and a.res_seq2 = pdb_ssbond.res_seq2 ) ); end if; END; $$ LANGUAGE plpgsql;

Con esto, el conjunto no redundante de proteínas se importa a la tabla nr que se une a las tablas ps y proteins , y se marcan los conjuntos ( set7 , set40 y set80 ). Al final, según la cantidad de proteína, solo se analizará un conjunto. Las cadenas no coincidentes entre PDB y NR se eliminan del análisis.

Las proteínas sin enlaces disulfuro están excluidas de la investigación, junto con las proteínas que no pertenecen a ningún conjunto. Los datos se procesan con DSSP, y también se excluyen estos archivos que tenían problemas con la resolución o demasiados átomos para procesar. Solo las proteínas con cadenas simples se usan como resultado para el análisis porque no se mantuvieron las conexiones entre cadenas, aunque se calculan fácilmente a partir de la tabla ssbond contando el número de conexiones que tienen cadenas diferentes.

Para las proteínas restantes, se realiza una actualización del número total de enlaces y el número de enlaces superpuestos, y esto se realiza para cada uno de los conjuntos.

El organismo fuente se extrae de los registros SOURCE . En los casos en que sea desconocido, sintético, diseñado, artificial o híbrido, se descarta de la investigación. Las proteínas de baja resolución también se excluyen solo cuando su cadena lateral no es visible.

Los registros SOURCE se almacenan en la tabla de sources , que contiene filas de taxonomía. En algunos casos, la taxonomía falta o es incorrecta. En estos casos, se necesita la corrección manual de expertos.

A partir de la fuente y la taxonomía descargada de NCBI, la clase se asigna a cada estructura primaria. En caso de que no se pueda asignar una clase, la proteína se elimina de la lista de análisis. Sabiendo que se están utilizando bases de datos biológicas, se recomienda que un biólogo realice una verificación adicional de todos los registros de origen y las clases de taxonomía del NCBI; de lo contrario, podría haber problemas con las clasificaciones entre diferentes dominios. Para hacer coincidir las ubicaciones celulares de origen con los ID de taxonomía, los datos de la tabla de origen se extraen en la tabla sources_organela , donde todos los datos se escriben como código, etiqueta y valor. Su formato se muestra a continuación:

 select * from sources_organela where code = '1rav';
código mol_id etiqueta valor
1rav 0 MOL_ID 1
1rav 7 UBICACIÓN_CELULAR CITOPLASMA (BLANCO)

El archivo de taxonomía que queremos usar es un archivo ZIP que contiene siete archivos de volcado. Entre estos archivos, dos de los más importantes son names.dmp y merged.dmp . Ambos archivos son archivos CSV delimitados por tabuladores como se detalla en la documentación:

  • El archivo merged.dmp contiene una lista de ID de taxonomía anteriores y los ID de taxonomía actuales en los que se fusionó cada uno.
  • names.dmp contiene estas importantes columnas en este orden:
    • tax_id : El ID de la taxonomía
    • name_txt : el nombre de la especie y, si corresponde, el nombre único (donde las especies se pueden encontrar con varios nombres, esto ayuda a eliminar la ambigüedad)
  • division.dmp contiene los nombres de los dominios de nivel superior que usaremos como nuestras clases.
  • nodes.dmp es la tabla que contiene una estructura jerárquica de organismos que utilizan ID de taxonomía.
    • Contiene una ID de taxonomía principal, una clave externa que se puede encontrar en names.dmp .
    • También contiene una ID de división que es importante para que almacenemos correctamente los datos relevantes del dominio superior.

Con todos estos datos y correcciones manuales (estableciendo dominios de vida correctos) pudimos crear la estructura de la tabla taxonomy_path . Una muestra de datos se ve así:

 select * from taxonomy_path order by length(path) limit 20 offset 2000;
Identificación del impuesto sendero es_viral es_eucariota is_archaea es_otro es_procarionte
142182 organismos celulares; Bacterias; Gemmatimonadetes F F F F t
136087 organismos celulares; Eucariota; Malawimonadidae F t F F F
649454 Virus;fagos no clasificados;Cyanophage G1168 t F F F F
321302 Virus;virus no clasificados;virus Tellina 1 t F F F F
649453 Virus;fagos no clasificados;Cyanophage G1158 t F F F F
536461 Virus;fagos no clasificados;Cyanophage S-SM1 t F F F F
536462 Virus;fagos no clasificados;Cyanophage S-SM2 t F F F F
77041 Virus;virus no clasificados;virus Stealth 4 t F F F F
77042 Virus;virus no clasificados;virus Stealth 5 t F F F F
641835 Virus; fagos no clasificados; Vibrio phage 512 t F F F F
1074427 Virus;virus no clasificados;Rosavirus del ratón t F F F F
1074428 Virus; virus no clasificados; Mosavirus del ratón t F F F F
480920 otras secuencias; plásmidos; IncP-1 plásmido 6-S1 F F F t F
2441 otras secuencias;plásmidos;Plásmido ColBM-Cl139 F F F t F
168317 otras secuencias; plásmidos; IncQ plásmido pIE723 F F F t F
536472 Viruses;unclassified phages;Cyanophage Syn10 t F F F F
536474 Viruses;unclassified phages;Cyanophage Syn30 t F F F F
2407 other sequences;transposons;Transposon Tn501 F F F t F
227307 Viruses;ssDNA viruses;Circoviridae;Gyrovirus t F F F F
687247 Viruses;unclassified phages;Cyanophage ZQS-7 t F F F F

Before any analysis, to avoid biases, sequences have to be checked for their level of identity. Although the NR set contains sequences which are already compared between each other, an extra check is always recommended.

For each disulfide bond's prior statistical analysis, data is marked if it is reactive or overlapping. After marking overlaps, that information automatically reveals how many consecutive and non-consecutive bonds are inside each protein, and that data is stored in the proteins table from which all protein complexes are excluded in final result.

Each disulfide bond is marked also for its association to sets, by checking both bond sides to see if they belong to the same NR set. Where that is not the case, the disulfide bond is skipped for that set analysis.

To analyze the quantity of bonds by their variance, each length has to be put in a specific class. In this case, only five classes are chosen as written in the function below.

 CREATE OR REPLACE FUNCTION len2class(len integer) RETURNS integer AS $BODY$ BEGIN return case when len <= 100 then 1 when len > 100 and len <= 200 then 2 when len > 200 and len <= 300 then 3 when len > 300 and len <= 400 then 4 else 5 end; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100;

Most of the protein sizes are less than 400 amino acids, so length classification is done by splitting lengths into five ranges, each taking 100 amino acids, except the last one which takes the rest. Below you can see how to use this function to extract data for analysis:

 SELECT p.code, p.title, p.ss_bonds, p.ssbonds_overlap, p.intra_count, p.sci_name_src, p.len, p.tax_path, p.pfam_families, p.src_class, ( SELECT s.id FROM src_classes s WHERE s.src_class::text = p.src_class::text) AS src_class_id, p.len_class7, ( SELECT s.val FROM sources_organela s WHERE s.code = p.code::bpchar AND s.tag::text = 'EXPRESSION_SYSTEM_CELLULAR_LOCATION'::text) AS expression_system_cellular_location, ( SELECT s.val FROM sources_organela s WHERE s.code = p.code::bpchar AND s.tag::text = 'CELLULAR_LOCATION'::text) AS cellular_location, ps.sequence, ps.uniprot_code, ps.accession_code, ps.cc, ps.seq_uniprot, ps.chain_id FROM proteins p JOIN nr n ON n.code::text = p.code::text AND n.rep7 = true JOIN ps ps ON ps.code::text = n.code::text AND ps.chain_id = n.chain_id AND ps.het = false WHERE p.is_excluded = false AND p.chain_cnt = 1 AND p.is_set7 = true AND p.reactive_cnt7 = 0 ORDER BY p.code;

An example result with corrected titles and some manually added columns is shown below.

código PDB Número total de bonos SS Número de bonos SS no consecutivos Longitud PDB / aminoácidos Dominio ObjetivoP 1.1 TatP 1.0 SeñalP 4.1 CloroP 1.1 TMHMM 2.0 número de dominios transmembrana pi grande nucPred NetNES 1.1 PSORTb v3.0 SecretomaP 2.0 LocÁrbol2 Predicción de localización por consenso
1akp 2 0 114 bacterias DAKOTA DEL NORTE Tat-señal sin péptido señal DAKOTA DEL NORTE 0 DAKOTA DEL NORTE DAKOTA DEL NORTE DAKOTA DEL NORTE desconocido DAKOTA DEL NORTE fimbrio desconocido
1bhu 2 0 102 bacterias DAKOTA DEL NORTE Tat-señal péptido señal DAKOTA DEL NORTE 1 DAKOTA DEL NORTE DAKOTA DEL NORTE DAKOTA DEL NORTE desconocido DAKOTA DEL NORTE secretado desconocido
1c75 0 0 71 bacterias DAKOTA DEL NORTE Tat-señal sin péptido señal DAKOTA DEL NORTE 0 DAKOTA DEL NORTE DAKOTA DEL NORTE DAKOTA DEL NORTE membrana citoplasmática secreción no clásica periplasma desconocido
1c8x 0 0 265 bacterias DAKOTA DEL NORTE Tat-señal péptido señal DAKOTA DEL NORTE 1 DAKOTA DEL NORTE DAKOTA DEL NORTE DAKOTA DEL NORTE desconocido DAKOTA DEL NORTE secretado desconocido
1cx1 1 0 153 bacterias DAKOTA DEL NORTE Tat-señal péptido señal DAKOTA DEL NORTE 1 DAKOTA DEL NORTE DAKOTA DEL NORTE DAKOTA DEL NORTE extracelular DAKOTA DEL NORTE secretado desconocido
1 dab 0 0 539 bacterias DAKOTA DEL NORTE Tat-señal péptido señal DAKOTA DEL NORTE 0 DAKOTA DEL NORTE DAKOTA DEL NORTE DAKOTA DEL NORTE membrana externa DAKOTA DEL NORTE membrana externa desconocido
1dfu 0 0 94 bacterias DAKOTA DEL NORTE Tat-señal sin péptido señal DAKOTA DEL NORTE 0 DAKOTA DEL NORTE DAKOTA DEL NORTE DAKOTA DEL NORTE citoplasmático DAKOTA DEL NORTE citosol desconocido
1e8r 2 2 50 bacterias DAKOTA DEL NORTE Tat-señal péptido señal DAKOTA DEL NORTE 0 DAKOTA DEL NORTE DAKOTA DEL NORTE DAKOTA DEL NORTE desconocido DAKOTA DEL NORTE secretado secretado
1esc 3 0 302 bacterias DAKOTA DEL NORTE Tat-señal péptido señal DAKOTA DEL NORTE 1 DAKOTA DEL NORTE DAKOTA DEL NORTE DAKOTA DEL NORTE extracelular DAKOTA DEL NORTE periplasma desconocido
1g6e 1 0 87 bacterias DAKOTA DEL NORTE Tat-señal péptido señal DAKOTA DEL NORTE 1 DAKOTA DEL NORTE DAKOTA DEL NORTE DAKOTA DEL NORTE desconocido DAKOTA DEL NORTE secretado desconocido

PostgreSQL como intermediario de procesamiento

En este trabajo, mostramos cómo procesar datos, desde la obtención hasta el análisis. Cuando se trabaja con datos científicos, a veces se necesita la normalización y otras veces no. Cuando se trabaja con pequeñas cantidades de datos que no se reutilizarán para otro análisis, basta con dejarlos desnormalizados cuando el procesamiento sea lo suficientemente rápido.

La razón por la que esto se hizo todo en una base de datos de bioinformática es que PostgreSQL puede integrar muchos lenguajes. Esto incluye R, que puede realizar análisis estadísticos directamente en la base de datos, el tema de un artículo futuro sobre herramientas bioinformáticas.


Un agradecimiento especial a los colegas de Toptal Stefan Fuchs y Aldo Zelen por sus valiosas consultas.