Mostrando entradas con la etiqueta anotación. Mostrar todas las entradas
Mostrando entradas con la etiqueta anotación. Mostrar todas las entradas

1 de noviembre de 2019

Cómo identificar pseudogenes en plantas


Hola,
hoy comparto un artículo publicado hace unos meses por Jianbo Xie y colaboradores donde explican su estrategia para anotar pseudogenes en genomas de plantas.

Puedes ver la definición completa de pseudogen en wikipedia, yo la resumo así:

Un pseudogén es un segmento de ADN que deriva de otro gen y que ha perdido al menos parte de su función original en cuanto a su expresión o la codificación de una proteína por acumulación de mutaciones. Se generan por recombinaciones imprecisas,  duplicaciones o retrotransposición y en principio pueden confundirse con neogenes al inicio de su ciclo.

El algoritmo de Xie et al para identificar pseudogenes en zonas intergénicas enmascaradas, donde se supone que no hay genes, se resume en este diagrama:


http://www.plantcell.org/content/31/3/563.long

Como podéis ver utiliza exonerate y tfasty (más preciso) para alinear secuencias de proteínas conocidas contra ADN genómico, BLASTP y Orthomcl para grupar los pseudogenes en familias, y finalmente MCScanX para localizar parejas de pseudogenes posiblemente relacioanas por duplicación.

Un saludo,
Bruno

30 de mayo de 2018

Identificar tránscritos no codificantes

Hola,
recientemente he leído diferentes trabajos sobre cómo solamente una fracción de los tránscritos totales humanos realmente son codificantes. Estas observaciones tienen consecuencias prácticas que supongo se pueden extrapolar a otras especies.

1. Cómo identificar la isoforma principal de un gen
La base de datos APPRIS (http://appris-tools.org) aplica una serie de filtros para identificar las isoformas principales de cada gen humano en base a la combinación de varios criterios (leer artículo):
  • conservación de la estructura de exones
  • evolución no neutral
  • alineamiento sin inserciones con estructuras homólogas
  • conservación de residuos funcionales
  • alineamiento completo con secuencias de otros vertebrados
Anotación de 3 isoformas según APPRIS, tomada de https://academic.oup.com/nar/article/46/D1/D213/4561658
2. Como identificar un transcrito no codificante
Una vez hemos ensamblado tránscritos de uno o más tejidos o condiciones puede ser útil clasificarlos como codificantes o no. En un trabajo nuestro (leer aquí) lo hacíamos con CPC y el script transcripts2cdsCPP.pl de GET_HOMOLOGUES-EST. Ahora, un trabajo reciente (leer aquí) propone los siguientes criterios, que comento en algunos casos:
  • El tránscrito debe abarcar al menos un intrón y tener un nivel de expresión > 1 tránscrito por millón (TPM).
  • Si sólo comprende un exón debe expresarse al menos igual que los  tránscritos mejor descritos (TPM > 13.87 en humanos).
  • No debe estar contenido en otro tránscrito.
  • Debe codificar un marco de lectura (ORF) de al menos 60 aminoácidos. OJO: esto podría dejar fuera proteínas pequeñas importantes.
  • El ORF no debe solapar con elementos repetidos/transposones (LINe, LTR, etc) ni loci rRNA.
  • El E-valor producido por BLASTX al comparar el transcrito con proteínas de mamíferos en GenBank y UniProt debe ser < 10E-15. OJO: el E-valor cambiará a medida que crezcan las bases de datos, este criterio debería expresarse mejor como cobertura o bit score. Ver siguiente criterio.
  • El mejor ORF del tránscrito debe alinear al menos el 75% de otras proteínas conocidas, para eliminar pseudogenes, que suelen estar truncados.
  • Si dos tránscritos de hebras contrarias solapan, nos quedaremos con el que se parezca a proteínas con función conocida.
Espero que esto os sea útil, un saludo,
Bruno



24 de abril de 2015

Diferentes formas de poblar una lista en R

Hola,

trabajando con Gene Ontologies (GOs) he empezado a hacer unas pruebas con una biblioteca de Bioconductor llamada topGO. Esta sirve para comprobar si los términos de GOs de un conjunto de genes son diferentes de los que encontramos en otro conjunto.

Por ejemplo, si tenemos los genes de un organismo y nos interesan los que en nuestro tratamiento aumentan su expresión, podemos comprobar si los términos GO asociados a estos últimos son diferentes de los que tenemos para el conjunto de todos los genes del organismo.

Pero uno de los pasos previos, antes de hacer tests estadísticos con topGO, es asociar nuestros genes a términos GO. En Bioconductor y otras bases de datos hay listas ya precalculadas que podemos utilizar. Sin embargo, por distintos motivos (por ejemplo, al trabajar con un organismo para el cual no está tan estudiada la anotación funcional), podemos querer cargar nuestras propias asociaciones para que topGO trabaje sobre ellas.

Ya que un gen puede tener asociado más de un término GO, los desarrolladores de topGO han decidido que la estructura de datos a utilizar sea una lista de vectores de caracteres (técnicamente una "named list of character vectors"). Dicho de otra forma, una lista de genes, con cada una de las entradas de la lista asociada a un vector de nombres de términos GO. Una opción, si queremos trabajar con nuestra propia anotación, es utilizar la función 'readMappings' de topGO, que crea esta estructura si le damos un formato de fichero adecuado:

"It consists of one line for each gene with the following syntax:
gene_ID/TAB/GO_ID1, GO_ID2, GO_ID3, ...."

La otra opción es que creemos nosotros mismos la lista de vectores a partir de los datos que queramos. A veces, cuesta menos transformar un fichero de datos a otro formato (y usar la función 'readMappings', por ejemplo), y otras es más conveniente mantener nuestro formato de fichero y manipularlo como estructura de datos, sin crear otro fichero. En este caso, es además una buena oportunidad para probar algunas estructuras de datos y sentencias de R, que es lo que haremos nosotros.

¿Cómo es el formato de datos que tenemos en el fichero inicial? Obviamente no es el formato requerido por topGO (pues usaríamos la función 'readMappings' sin más). Nosotros vamos a partir de una tabla con 2 columnas (separadas por tabulador): una para el identificador del gen, la otra para un identificador de término GO. De esta forma, los distintos términos GO de cada gen quedan realmente en varias líneas:

gene_1    GO:000001
gene_1    GO:000004
gene_2    GO:000003
...

Esto obviamente puede cambiar según el origen de los datos, con qué programa se hayan obtenido las anotaciones, etc.

No vamos a entrar en detalles aquí sobre cómo leer el fichero con R o en dar ejemplos concretos de los datos. Es muy fácil generarlos y no es el objetivo de esta entrada. Lo importante para entender el código es que vamos a trabajar con la salida de read.table, en la variable 'go_tab', que será de tipo data.frame. En 'go_tab', los campos de las dos columnas se llaman 'identifier' (la columna con genes) y 'GOterm' (la columna con términos GO).

Vamos a ver varias alternativas para transformar éste 'data.frame' en una lista de vectores. En primer lugar, probaremos creando directamente una lista que iremos poblando con un bucle 'for'. Éste código es muy legible e intuitivo y programadores de muchos lenguajes diferentes pueden entenderlo fácilmente con solo echarle un vistazo.

El código completo de éste fragmento:

 gene2GO = list()  
 for (i in seq(1:nrow(go_tab))) {  
  identifier = go_tab$identifier[i]  
  go_term = go_tab$GOterm[i]  
  if (identifier %in% names(gene2GO)){  
   gene2GO[[identifier]] = c(gene2GO[[identifier]], as.character(go_term))  
  } else {  
   gene2GO[[identifier]] = as.character(go_term)  
  }  
 }  

En éste ejemplo, por tanto, vamos a recorrer la tabla de datos (go_tab) importada del fichero, e iremos construyendo nuestra lista final (gene2GO) concatenando nuevos términos GO para cada gen:

 gene2GO[[identifier]] = c(gene2GO[[identifier]], as.character(go_term))  

Vemos aquí una de las peculiaridades de R en el manejo de listas, que es el uso de corchetes dobles '[['. Si hay dudas de por qué se usa aquí '[[' en lugar de '[', la explicación rápida es que en R para acceder a datos en una lista hay que usar '[['. Para ampliar esto, está detallado en http://adv-r.had.co.nz/Subsetting.html

Sin embargo, éste método es bastante lento en mi equipo (Dell Optiplex 9010) y con mis datos (unas 90.000 filas en el fichero de entrada). Pongamos, por referencia y para comparar con métodos que veremos a continuación, que éste ejemplo en el que usamos una lista y un bucle 'for' tarda 1' (54'' en promedio, realmente).

Parte de por qué es así puede tener que ver con el bucle 'for'. Más adelante veremos alguna alternativa al bucle. Sin embargo, también tiene que ver el rendimiento de la búsqueda de los elementos en la lista.

Una alternativa al operador '%in%' podría ser:

 if (exists(identifier, gene2GO)){  

Pero en principio esta opción es más lenta, en mi caso unos 2' (1'57'').

En ambos casos, la comprobación la hacemos para acceder después al gen en cuestión. Por tanto, se está buscando 2 veces el mismo elemento en la lista: una en la comprobación, otra al obtener el elemento. Una forma de evitar esto sería cogiendo directamente el objeto (1 sola búsqueda) y comprobando si existe o no (NULL):

 current = gene2GO[[identifier]]  
 if (is.null(current)){  

(Nota: ojo que ahora el if comprueba si NO existe, no si existe como en los ejemplos anteriores).

Vemos que con esta otra forma tenemos un tiempo promedio de unos 26''. Aproximadamente la mitad que con el uso de '%in%', como esperaríamos.

Sin embargo, ya hemos comentado antes que el uso de un bucle 'for' en R también puede tener algo que ver con la velocidad de nuestro código (por ejemplo ver: http://faculty.nps.edu/sebuttre/home/R/apply.html). En R se suele preferir utilizar funciones que van recorriendo las estructuras de datos y aplicando una función sobre cada elemento de la estructura. Es el caso de la familia de funciones 'apply' (ver por ejemplo https://nsaunders.wordpress.com/2010/08/20/a-brief-introduction-to-apply-in-r/). Veamos el equivalente al código anterior usando la función 'apply':

 gene2GO = list()  
 add_to_list <- function(go_tab){   
  identifier = go_tab[[1]]  
  go_term = go_tab[[2]]  
  current = gene2GO[[identifier]]  
  if (is.null(current)){  
   gene2GO[[identifier]] <<- as.character(go_term)  
  } else {  
   gene2GO[[identifier]] <<- c(gene2GO[[identifier]], as.character(go_term))  
  }  
 }  
 invisible(apply(go_tab, 1, add_to_list))  

Ahora está tardando unos 21'' en mi máquina. Una ligera mejora respecto al uso del bucle 'for', que podría tener impacto en conjuntos de datos muy grandes o cuando queremos correr muchos análisis.

Vemos varias peculiaridades en el código anterior. La función 'apply' va a recorrer nuestra lista y llamará a la función 'add_to_list' para cada elemento. Sin embargo, en nuestro caso no queremos simplemente transformar los elementos de la lista (por ejemplo, formateando el nombre del gen), si no que queremos poblar una estructura de datos diferente a partir de los valores de la lista recorrida. Por eso se utiliza el operador <<-:

"The operators are normally only used in functions, and cause a search to made through parent environments for an existing definition of the variable being assigned."

Otra posible opción sería utilizar un parámetro opcional en la función, pero no me queda claro que vaya a funcionar para escribir en él, ya que el parámetro (la lista de vectores que estamos creando) necesitaría pasarse por referencia, y me suena que en R no he pasado parámetros así anteriormente ¿Os suena? ¿Algún consejo sobre esto? ¿Alguna otra opción?

La otra peculiaridad es la función 'invisible'. Ya que las funciones en R devuelven un valor y 'apply' lo propaga para obtener la posible transformación de 'go_tab' en otra cosa, si no asignamos el resultado de 'apply' a una variable tendremos el resultado en nuestra salida. Para evitar esto, podemos asignar el resultado a una variable "dummy" o utilizar el método 'invisible', que a mi me ha parecido más adecuado y legible.

Otra diferencia, más básica, es cómo accedemos a nuestros datos originales. En el primer ejemplo, lo que hacíamos es acceder a los campos del 'data.frame' y, en un campo dado, obtener el dato correspondiente según el bucle for:

identifier = go_tab$identifier[i]

Con 'apply' en cambio estamos recibiendo cada una de las líneas del 'data.frame' como un 'vector', por lo que accedemos directamente a los datos en éste vector:

identifier = go_tab[[1]]

Por ahora hemos mejorado nuestro algoritmo cambiando la forma de comprobar la existencia de un elemento en la lista para luego obtenerlo, y pasando de un bucle 'for' a usar la función 'apply'. Pero aún podemos ir más allá. ¿Por qué utilizar una lista? Quizás podamos mejorar el rendimiento utilizando un entorno con un mapeado "hash" (https://stat.ethz.ch/R-manual/R-devel/library/base/html/environment.html).

 gene2GO = new.env()  
 add_to_list <- function(go_tab){  
  identifier = go_tab[[1]]  
  go_term = go_tab[[2]]  
  current = gene2GO[[identifier]]  
  if (is.null(current)){  
   gene2GO[[identifier]] <<- as.character(go_term)  
  } else {  
   gene2GO[[identifier]] <<- c(gene2GO[[identifier]], as.character(go_term))  
  }  
 }  
 invisible(apply(go_tab, 1, add_to_list))  
 gene2GO = as.list(gene2GO)  

Aquí, en lugar de una lista creamos un entorno ('environment'), que por defecto utiliza una función "hash" para mapear su contenido. Por lo demás, como vemos, lo estamos manejando aquí de forma muy similar a la lista, aunque hemos añadido al final una conversión a formato de lista (en una sola línea pasamos de nuestro "hash" a una lista de vectores).

Éste código tarda unos 7'', incluída la conversión. Hay que tener en cuenta que el uso de un "hash" puede ser más o menos aconsejable según el volumen de datos con el que se trabaje. Desde luego, con nuestros datos, hemos mejorado bastante el rendimiento prestando atención a distintas alternativas que ofrece R y cuál sería la mejor combinación de las que hemos probado.

Y ya tendríamos nuestra lista creada. Nuestra intención era utilizar esta lista para informar a topGO de qué términos de GOs se relacionan con nuestros genes ¿recordáis? Le pasaremos esta lista a topGO como parámetro 'gene2GO' en la función en la creamos el primer objeto necesario con éste paquete, e indicaremos que la función de anotación es del tipo "annFun.gene2GO". Para eso, y terminar así la preparación de los datos, tendríamos que importar las listas de genes a comparar, o una sola lista con todos pero con algún criterio que permita diferenciar un subconjunto de otro. Crearíamos entonces el objeto con:

 GOdata <- new("topGOdata", description="whatever", ontology = "BP", allGenes = background, geneSel = test,   
          annot = annFUN.gene2GO, gene2GO = gene2GO, nodeSize = 10)  

Donde:
'background' es nuestro conjunto de genes de referencia.
'test' es el grupo de genes que estamos interesados en comparar con la referencia.
'gene2GO' la lista que hemos generado.

Seguiríamos entonces con las siguientes fases de topGO: los test de enriquecimiento y el análisis de los resultados. Si te ha entrado el gusanillo de probar, topGO está perfectamente documentado:

http://www.bioconductor.org/packages/release/bioc/vignettes/topGO/inst/doc/topGO.pdf

Un saludo!


10 de octubre de 2014

Apuntes de genómica microbiana

Hola,
esta semana hemos participado en un taller de 6 días organizado por Mirko Rossi (Universidad de Helsinki, Finlandia) donde hemos repasado los principales aspectos de la genómica comparativa de bacterias. Todo esto desde un punto de vista muy aplicado, dado que la mayor parte de los alumnos eran investigadores de la esfera veterinaria. Nuestra aportación fue una sesión de tres horas y media dedicada a la determinación del pangenoma de un grupo de bacterias de interés, con la ayuda de nuestro software GET_HOMOLOGUES.

Estimación de las dimensiones del core-genoma (izq) y pan-genoma (der)
de una colección de 12 plásmidos plncA/C, genomas de ejemplo en el capítulo
"Robust identification of orthologues and paralogues for microbial pan-genomics
using GET_HOMOLOGUES: a case study of pIncA/C plasmids
", parte del libro

http://www.springer.com/biomed/medical+microbiology/book/978-1-4939-1719-8 .





A parte de esto, en esta entrada quería sobre todo contar algunas de las cosas que otros profesores a los que pude escuchar contaron, por si os pueden ayudar en vuestros proyectos:
  • Con Andrey Prjibelski, del Algorithmic Biology Lab de San Petersburgo, aprendimos a ensamblar genomas bacterianos con el software SPAdes, y luego a comparar y a evaluar distintos ensamblajes con ayuda de QUAST. Nos recomendó http://nucleotid.es para comparar de una manera objetiva las virtudes y defectos de distintos ensambladores disponibles ahora mismo, aunque comentó que dada la variedad de escenarios de los usuarios y de los tipos de lecturas/reads existentes no hay ahora mismo ninguno claramente superior a los demás. Sí remarcó que algunos están mal documentados y son por tanto más difíciles de utilizar. Me quedé un poco con la idea de que Velvet y SPAdes son los mejores para genomas bacterianos. Del primero menciona que es muy estable, de calidad moderada, pero muy limitado con lecturas del tipo mate pair. El segundo es el que desarrollan ellos y fue el que usamos en la sesión. SPAdes trabaja siempre sobre una base de lecturas Illumina/IonTorrent, que por defecto se corrigen antes de ser utilizadas, pero puede hacer ensamblajes híbridos con secuencias de otras plataformas, incluso Sanger, útiles para resolver secuencias repetidas, como mate pairs convencionales o Nextera (hqmp, de alta calidad). El programa tiene además un módulo (--careful) para corregir por mapeo errores (indels,mismatches) en los contigs generados al ensamblar. Su mayor ventaja respecto a Velvet es probablemente que ensambla iterativamente con K-meros diferentes para superar las limitaciones de K pequeños (ciclos) con los grandes y viceversa (falta de solapamientos cortos, ver este blog y este otro para una comparación más amplia).  
  • Bastien Chevreux, de DSM Nutritional Products AG, filosofó acerca de distintos problemas y estrategias para secuenciar y ensamblar genomas bacterianos con su software MIRA. La diferencia fundamental de este ensamblador respecto a los anteriores es que no se basa en grafos de De Bruijn, como Velvet o SPAdes, si no en la acumulación y alineamiento de lecturas solapantes, razón por la que es menos escalable y por tanto más lento que ellos. Este software a mi me parece sin duda más complejo de usar que SPAdes, pero tiene a su favor una lista de correo muy activa y documentación extensa. MIRA se ejecuta simplemente sobre un fichero manifiesto, editado por el usuario, que puede tener una sintaxis bastante compleja, pero que para un mapeo es algo sencillo, como por ejemplo:
    project= nombre_de_proyecto
    job= mapping,genome,accurate
    
    #input data comes next
    readgroup
    is_reference
    data= /path/to/file.gbk
    strain= Ecoli_strainA
    
    readgroup
    technology= solexa
    autopairing # busca PEs por ti
    data= /path/to/reads?.fastq
    strain= Ecoli_strainK12
     
  • Rauni Kivistö, de la Universidad de Helsinki, nosexplicó el uso de los programas ACT y BRIG para visualizar datos de comparación de genomas basados en BLAST.
  •  Veronika Vonstein y Ross  Overbeek, de la Fellowship for the Integration of Genomes, presentaron su plataforma para la anotación automática de genomas RAST que se construye sobre SEED, una colección de componentes, algo parecido a operones o trozos de rutas metabólicas, que llevan curando a mano desde hace dos décadas y que les permiten proyectar en tiempo real, según se van secuenciando nuevos genomas, anotaciones de alta calidad, que tienen en cuenta el contexto genómico y no se basan en BLAST, sino en eficientes búsquedas de K-meros específicos de familias de proteínas prealineadas que llaman FIGFams. Me sorprendió que un trabajo de esta envergadura no tuviera más repercusión, de hecho yo no lo conocía, pero se explica porque durante mucho tiempo trabajaron en el sector privado. Ahora mismo tienen financiación pública y se apoyan en hardware del Argonne National Laboratory.
Creo que esto es todo, un saludo y hasta la próxima,
Bruno



27 de febrero de 2014

contrato: Anotación y diagnóstico molecular de polimorfismos en secuencias genómicas

Anotación y diagnóstico molecular de polimorfismos en secuencias genómicas

El Grupo de Biología Computacional y Estructural de la EEAD-CSIC oferta un CONTRATO de personal investigador PREDOCTORAL para la formación de doctores, renovable hasta 4 años, cofinanciado por el Gobierno de Aragón.

Plazo de solicitud finaliza el 10 de marzo de 2014.

El proyecto plantea el desarrollo de un entorno bioinformático eficiente, escalable y sencillo para el usuario final, para la anotación de secuencias genómicas obtenidas de cualquier especie y los polimorfismos observados. Por medio de algoritmos de inteligencia artificial este software deberá además aprender de las secuencias analizadas previamente para hacer predicciones de fenotipo, por ejemplo de mutaciones en un gen. Los resultados del proyecto serán directamente aplicables a los trabajos del laboratorio  en genómica de plantas y también a enfermedades humanas donde el diagnóstico molecular es una herramienta clave, como el cáncer de mama o la fibrosis quística. Para ello esta propuesta cuenta con la participación de la empresa local Blackhills Diagnostic Resources, que desarrolla este tipo de kits en Zaragoza, y que suministrará experiencia y secuencias para el adecuado desarrollo del proyecto en su vertiente clínica.

Los candidatos deben cumplir los requisitos de la convocatoria publicada en el BOA 17.02.2014 (http://tinyurl.com/nfulqbe) y estar empadronados en la Comunidad Autónoma de Aragón. Buscamos i) ingenieros o licenciados con Máster o ii) graduados con 300 créditos ECTS en Biología, Bioquímica, Biotecnología, Química, Veterinaria o Farmacia, Informática o Agronomía.

Para más información sobre el grupo consulta:
www.eead.csic.es/compbio , bioinfoperl.blogspot.com.es (este blog)

Contacto

Bruno Contreras      (bcontreras at eead.csic.es)                            
Inmaculada Yruela  (yruela at eead.csic.es)

Ubicación
Estación Experimental de Aula Dei-CSIC,
Av Montañana 1005, Zaragoza

21 de noviembre de 2013

GET_HOMOLOGUES for pan-genome analysis

Hola,
en el último número de Applied and Environmental Microbiology mi colega Pablo Vinuesa y yo publicamos un artículo describiendo el software GET_HOMOLOGUES, que tiene como abstract:
GET_HOMOLOGUES is an open source software package that builds upon popular orthology-calling approaches making highly customizable and detailed pan-genome analyses of microorganisms accessible to non-bioinformaticians. It can cluster homologous gene families using the bidirectional best-hit, COGtriangles or OrthoMCL clustering algorithms. Clustering stringency can be adjusted by scanning the domain-composition of proteins using the HMMER3 package, by imposing desired pair-wise alignment coverage cut-offs or by selecting only syntenic genes. Resulting homologous gene families can be made even more robust by computing consensus clusters from those generated by any combination of the clustering algorithms and filtering criteria. Auxiliary scripts make the construction, interrogation and graphical display of core and pan-genome sets easy to perform. Exponential and binomial mixture models can be fitted to the data to estimate theoretical core and pan-genome sizes, and high quality graphics generated. Furthermore, pan-genome trees can be easily computed and basic comparative genomics performed to identify lineage-specific genes or gene family expansions. The software is designed to take advantage of modern multiprocessor personal computers as well as computer clusters to parallelize time-consuming tasks. To demonstrate some of these capabilities, we survey a set of 50 Streptococcus genomes annotated in the Orthologous Matrix Browser as a benchmark case.
El  software  se puede descargar de http://www.eead.csic.es/compbio/soft/gethoms.php y también de http://maya.ccg.unam.mx/soft/gethoms.php y está escrito mayoritariamente en Perl, aunque contiene también trozos en R.
El manual del programa describe en detalle ejemplos de uso y está disponible en http://www.eead.csic.es/compbio/soft/manual.pdf .

Este paquete de programas se diseñó para el estudio de los pan y core-genomas de grupos de microorganismos, que es con lo que trabaja el grupo de Pablo fundamentalmente, y permite generar figuras como éstas:


Un saludo,
Bruno