5 de septiembre de 2017

one-liner for insert size histogram from BAM

Hola,
ayer necesitábamos obtener rápidamente un histograma con el tamaño de los insertos de una librería de lecturas/reads paired-end. Lo logramos con este one-liner que requiere haber instalado R:

$ samtools view -q 30 -F 3916 mapped_reads.bam | cut -f 9 | \
   Rscript -e 'data=abs(scan(file="stdin")); pdf("hist.pdf"); hist(data,xlab="insert size (bp)")'

$ evince hist.pdf

Lo explico por pasos:

1) Previamente habíamos alineado/mapeado las lecturas contra una referencia y convertido el alineamiento a formato BAM. Podemos hacernos una idea qué mapeos contiene el fichero mapped_reads.bam con ayuda de samtools:

$ samtools flagstat mapped_reads.bam 

497656 + 0 in total (QC-passed reads + QC-failed reads)
0 + 0 duplicates
497409 + 0 mapped (99.95%:-nan%)
497656 + 0 paired in sequencing
248828 + 0 read1
248828 + 0 read2
492706 + 0 properly paired (99.01%:-nan%)
...

2) con -q 30 le pedimos a samtools que nos devuelve solamente lecturas con calidad de mapeo (MAPQ) >= 30

3) con -F 3916 le pedimos que ignore, según podemos averiguar aquí, los siguientes tipos de lecturas: "read unmapped, mate unmapped, first in pair, not primary alignment, read fails platform/vendor quality checks, read is PCR or optical duplicate, supplementary alignment"

NOTA1: Si el fichero BAM es muy grande se puede hacer lo mismo con una muestra al azar de las lecturas, por ejemplo el 10%, con samtools view -s 0.10.

NOTA2: Si la distribución de mapeos contiene algunos insertos anormalmente grandes el histograma por defecto puede quedar demasiado ancho. En ese caso puede ser buena idea probar algo como:

hist(data[data < quantile(data,0.99)])

Hasta luego,
Bruno

28 de agosto de 2017

mean sequence length in FASTA

Hola,
para calcular la longitud promedio de las secuencias de un fichero FASTA estábamos usando el siguiente comando de Perl en el terminal, modificado de otro en https://eead-csic-compbio.github.io/perl_bioinformatica/node90.html:

$ time perl -lne 'if(/^(>.*)/){$h=$1}else{$fa{$h}.=$_} END{ foreach $h (keys(%fa)){$m+=length($fa{$h})}; printf("%1.0f\n",$m/scalar(keys(%fa))) }' ~/db/swissprot
376

real 0m4.943s
user 0m4.488s
sys 0m0.452s

Sin embargo, para ficheros de metagenomas era muy lento, y lo hemos reemplazado por este otro, que no guarda las secuencias en memoria (en un hash llamado %fa):

$ time perl -lne 'if(/^(>.*)/){$nseq++;$m+=$l;$l=0}else{$l+=length($_)} END{ $m+=$l; printf("%1.0f\n",$m/$nseq) }' ~/db/swissprot

376

real 0m2.013s
user 0m1.880s
sys 0m0.132s

Hasta luego,
Bruno

9 de agosto de 2017

semillas con licencia Open Source

Hola,

los que programamos en entornos académicos llevamos muchos años usando software distribuido con licencias de tipo Open Source (OS). De hecho, ahora mismo el canal de distribución de software más popular es GitHub, donde para alojar un nuevo proyecto debes elegir qué tipo de licencia OS le otorgas como creador.

A pesar de las controversias y del debate sobre la propiedad intelectual, este modelo ha tenido la ventaja de permitir que otros creadores aprovechen de manera eficiente los avances hechos por otros y creen soluciones mejores de las que al final todos nos beneficiamos. Una condición general de estas licencias es que el producto resultante sea también OS. Así funcionan las distribuciones Linux, por ejemplo, o gran parte del sistema operativo Mac OS X.

Variedad de tomate Sunviva del catálogo Open Source Seeds. Foto tomada de http://www.nature.com/nbt/journal/v35/n8/full/nbt0817-700.html.
Leo en Nature Biotechnology que estas licencias se están empezando a usar ahora para distribuir variedades y semillas, bajo el amparo de http://osseeds.org, como manera de acelerar y facilitar el intercambio legal de materiales vegetales. Veremos en los próximos años si también en este contexto las licencias OS son un motor de innovación, y como conviven con las empresas y cooperativas de semillas convencionales,
hasta luego,
Bruno


28 de julio de 2017

Tabla de estabilidad de sustituciones de aminoácidos

Hola,
a menudo nos preguntamos qué efecto puede tener un cambio de aminoácido sobre la estabilidad de una proteína. Una pregunta relacionada es si tendrá fenotipo una sustitución no sinónima (missense). De hecho hay toda una colección de herramientas que se han desarrollado para esto (ver por ejemplo el curso de bioinformática estructural). El trabajo reciente de Rocklin et al (2017), donde estudian la estabilidad de miles de miniproteínas (hasta 50aa) sintéticas y unas 500 naturales del PDB, nos proporciona la mejor respuesta hasta la fecha. Aunque es un artículo complejo, en esencia lo que hacen es medir la estabilidad de miles de proteínas expresándolas y exponiéndolas a proteasas en levadura.
De esa manera pueden estimar el efecto que tienen mutaciones individuales dependiendo de su contexto de estructura secundaria, ya sea una alfa-hélice, una lámina beta o un lazo o loop:
Efecto sobre la estabilidad de mutaciones en diferentes contextos estructurales. Los valores negativos, como los de la prolina en general, son desestabilizadores. Adaptada de http://science.sciencemag.org/content/357/6347/168.full.

En la siguiente figura se muestran ejemplos de mutaciones desestabilizadoras en amarillo:

Adaptada de http://science.sciencemag.org/content/357/6347/168.full.

Hasta pronto,
Bruno

4 de julio de 2017

rooting and laddering Newick trees

Buenas,
esta entrada es para compartir un script Perl para enraizar árboles, muchos árboles, de manera automática, y ordenar los nodos por distancia. Pongo el título en inglés para los buscadores.
Rubén Sancho y yo estamos probando el software GRAMPA, que requiere una colección de árboles de genes precalculados en formato Newick, pero además los quiere enraizados y ordenados de manera ascendente. Como son más de mil árboles no lo queríamos hacer uno a uno con FigTree, por poner un ejemplo; queríamos automatizarlo y para ello aprovechamos los módulos Bio::TreeIO y Bio::Phylo. El primero es de Bioperl y ya lo tenía instalado, el segundo lo instalé con: $ sudo cpanm Bio::Phylo

El árbol de ejemplo, contenido en el fichero unrooted.ph, es:

(1_Sbic:0.047,2_Osat:0.068,(((((((((((3_B422:0.007,(((4_Barb:0.000,((5_Bret:0.003,(6_BsyE:0.000,7_BsyE:0.000):0.000):0.000,8_BsyC:0.000):0.000):0.000,9_Bpho:0.002):0.000,(10_BsyC:0.000,11_BsyC:0.000):0.001):0.000):0.008,((12_B422:0.005,13_Bpho:0.005):0.002,14_Barb:0.000):0.005):0.000,((((15_Bdis:0.000,16_Bdis:0.000):0.000,17_Bmex:0.033):0.013,18_Bhyb:0.001):0.014,(19_Bboi:0.021,((20_Bmex:0.017,21_Bsta:0.034):0.012,22_Bsta:0.000):0.003):0.020):0.012):0.002,23_Barb:0.000):0.000,24_Brup:0.012):0.000,25_BsyG:0.000):0.000,(26_Bpin:0.000,27_BsyG:0.000):0.000):0.011,28_Bsta:0.000):0.053,29_BsyG:0.000):0.036,(30_Barb:0.005,(31_Bpho:0.024,(32_BsyC:0.000,33_BsyE:0.000):0.027):0.029):0.000):0.005,34_Bboi:0.030):0.035);

Invocando el script lo enraizamos con el taxón elegido, el outgroup '_Sbic':

$ perl reroot_tree.pl unrooted.ph > rooted.ph

Obtenemos el fichero rooted.ph, que podemos visualizar con FigTree:

Árbol enraizado y con orden creciente de nodos.
Éste es el código de reroot_tree.pl :

 #!/usr/bin/perl -w  
   
 # Re-roots an input Newick tree with a user-defined outgroup and   
 # prints the resulting tree in ascending or descending node order.  
 # Based on https://github.com/phac-nml/snvphyl-tools/blob/master/rearrange_snv_matrix.pl  
   
 use strict;  
 use Bio::TreeIO;  
 use Bio::Phylo::IO;  
 use Bio::Phylo::Forest::Tree;  
    
 my $OUTGROUPSTRING = '_Sbic'; # change as needed  
 my $NODEORDER = 1; # 1:increasing, 0:decreasing  
 my ($outfound,$outnode,$sorted_newick) = (0);  
   
 die "# usage: $0 <tree.newick>\n" if(!$ARGV[0]);  
   
 # read input tree  
 my $input = new Bio::TreeIO(-file=>$ARGV[0],-format=>'newick');  
 my $intree = $input->next_tree();  
   
 # find outgroup taxon  
 for my $node ( $intree->get_nodes() ) {   
  if(defined($node->id()) && $node->id() =~ m/$OUTGROUPSTRING/) {  
   $outnode = $node;   
   $outfound = 1;  
   last;  
  }  
 }  
 if($outfound == 0) {  
  die "# cannot find outgroup $OUTGROUPSTRING in input tree $ARGV[0]\n";  
 }  
   
 # root in outgroup and sort in increasing order  
 $intree->reroot_at_midpoint($outnode);  
   
 # sort nodes in defined order and print  
 my $unsorted_tree = Bio::Phylo::IO->parse(  
  '-string' => $intree->as_text('newick'),  
  '-format' => 'newick'  
 )->first();  
   
 $unsorted_tree->ladderize($NODEORDER);  
   
 $sorted_newick = $unsorted_tree->to_newick();  
 $sorted_newick =~ s/'//g;  
   
 print $sorted_newick;  


Un saludo,
Bruno