• Publicidad

Problemas al leer FASTA y hacer BLAST

Perl aplicado a la bioinformática

Problemas al leer FASTA y hacer BLAST

Notapor Giskard » 2014-02-24 05:43 @279

Muy buenas.

He empezado con Perl hace relativamente poco, y estoy tratando de hacer el primer script de algo que sea útil y que no sea solo un ejemplo chorra.

Lo que intento conseguir con esto, es que este programa ejecute él solo varios BLAST a partir de un archivo de secuencias en FASTA, compruebe que resultados son comunes entre varias secuencias y te digas cuáles son, número de acceso, descripción y con qué longitud aparean cada una de las secuencias.

Para ello he usado BioPerl y he canibalizado un par de programas que nos pasó un profesor que nos estaba explicando esto (de hecho aún están los comentarios originales por ahí xD) para que lea las secuencias de FASTA y lance los BLAST, ya que no me llevo muy bien aún con BioPerl y con los objetos; y luego la parte de las comparaciones ya las he hecho yo.

Pues bien, cuando lo ejecuto me da el error:

Not a GLOB reference at comparacion.pl line 37.

He buscado por qué puede ser y no acabo de entender lo de los GLOB, y como es una parte de las que no he hecho yo, puede que, o bien la esté cagando y me falte algo, o me haya colado o lo que sea, por lo que si me podéis echar una mano en cómo solucionarlo os lo agradecería infinitamente. Aquí va el código, no seáis muy duros con él :(

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use strict;
  2. use Bio::Tools::Run::RemoteBlast;
  3.  
  4. #  use strict;
  5. my $ficherosalida = "loquesea.txt";
  6. my $prog          = 'blastp';
  7. my $db            = 'swissprot';
  8. my $e_val         = '1e-10';
  9. my @secuencia_name;
  10. my @secuencia_length;
  11. my @secuencia_accesion;
  12. my @secuencia_description;
  13. my @params = (
  14.     '-prog'       => $prog,
  15.     '-data'       => $db,
  16.     '-expect'     => $e_val,
  17.     '-readmethod' => 'SearchIO'
  18. );
  19.  
  20. my $factory = Bio::Tools::Run::RemoteBlast->new(@params);
  21.  
  22. #change a paramter
  23. #  $Bio::Tools::Run::RemoteBlast::HEADER{'ENTREZ_QUERY'} = 'Homo sapiens [ORGN]';
  24.  
  25. #remove a parameter
  26. # delete $Bio::Tools::Run::RemoteBlast::HEADER{'FILTER'};
  27.  
  28. my $v = 1;
  29. my %hits_name;
  30. my %hits_length;
  31. my %hits_accesion;
  32. my %hits_description;
  33.  
  34. #$v is just to turn on and off the messages
  35.  
  36. my $str = Bio::SeqIO->new( -file => 'sequences.fasta', '-format' => 'fasta' );
  37. my @seq_array_name = <$str>;
  38. for ( my $i = 0; $i < int(@seq_array_name); $i++ ) {
  39.     my @array_name;
  40.     my @array_length;
  41.     my @array_accesion;
  42.     my @array_description;
  43.  
  44.     while ( my $input = $str->next_seq() ) {
  45.  
  46.         #Blast a sequence against a database:
  47.  
  48.         #Alternatively, you could  pass in a file with many
  49.         #sequences rather than loop through sequence one at a time
  50.         #Remove the loop starting 'while (my $input = $str->next_seq())'
  51.         #and swap the two lines below for an example of that.
  52.         my $r = $factory->submit_blast($input);
  53.  
  54.         #my $r = $factory->submit_blast('amino.fa');
  55.  
  56.         print STDERR "waiting..." if ( $v > 0 );
  57.         while ( my @rids = $factory->each_rid ) {
  58.             foreach my $rid (@rids) {
  59.                 my $rc = $factory->retrieve_blast($rid);
  60.                 if ( !ref($rc) ) {
  61.                     if ( $rc < 0 ) {
  62.                         $factory->remove_rid($rid);
  63.                     }
  64.                     print STDERR "." if ( $v > 0 );
  65.                     sleep 5;
  66.                 }
  67.                 else {
  68.                     my $result = $rc->next_result();
  69.  
  70.                     #save the output
  71.                     my $filename = $result->query_name() . "\.out";
  72.                     $factory->save_output($filename);
  73.                     $factory->remove_rid($rid);
  74.                     $secuencia_name[$i]        = $result->query_name();
  75.                     $secuencia_accesion[$i]    = $result->query_accesion();
  76.                     $secuencia_length[$i]      = $result->query_length;
  77.                     $secuencia_description[$i] = $result->query_description();
  78.                     while ( my $hit = $result->next_hit ) {
  79.                         next unless ( $v > 0 );
  80.                         push( @array_name,        $hit->name );
  81.                         push( @array_length,      $hit->length );
  82.                         push( @array_accesion,    $hit->accesion );
  83.                         push( @array_description, $hit->description );
  84.                         print "\nhit name is ", $hit->name, "\n";
  85.                     }
  86.                 }
  87.             }
  88.         }
  89.  
  90.     }
  91.     $hits_name{$i}        = join( ";", @array_name );
  92.     $hits_length{$i}      = join( ";", @array_length );
  93.     $hits_accesion{$i}    = join( ";", @array_accesion );
  94.     $hits_description{$i} = join( ";", @array_description );
  95. }
  96.  
  97. my $tamano = scalar( keys %hits_name );
  98. my @final;
  99. for ( my $i = 0; $i < $tamano; $i++ ) {
  100.     my @comparar = [];
  101.     my @resultados1 = split /;/ => $hits_name{$i};
  102.     for ( my $j = $i++; $j = $tamano; $j++ ) {
  103.         my @resultados2 = split /;/ => $hits_name{$j};
  104.         @comparar = comparar( $i, $j, @resultados1, @resultados2 );
  105.  
  106.         if ( $j == $tamano - 1 ) {
  107.             my @igualados = igualdades(@comparar);
  108.             @final = ( @final, redaccion(@igualados) );
  109.         }
  110.  
  111.     }
  112. }
  113. guardar_datos( $ficherosalida, @final );
  114.  
  115. #################################
  116. ###########FUNCIONES#############
  117. #################################
  118.  
  119. #Compara si los hits son el mismo y guarda la posición de los mismos dentro de la línea de datos del hash de guardado
  120. sub comparar {
  121.     my ( $cadena1, $cadena2, @result1, @result2 ) = shift;
  122.     my @comparacion = [];
  123.     my $tamres1     = int @result1;
  124.     my $tamres2     = int @result2;
  125.     for ( my $i = 0; $i < $tamres1; $i++ ) {
  126.         for ( my $j = 0; $j < $tamres2; $j++ ) {
  127.             if ( $result1[$i] eq $result2[$j] ) {
  128.                 my $a = int @comparacion;
  129.                 $comparacion[$a] = "$cadena1" . ";" . "$i" . ";" . "$cadena2" . ";" . "$j";
  130.             }
  131.  
  132.         }
  133.     }
  134.     return @comparacion;
  135. }
  136.  
  137. #Ve si hay más de un hit igual para algún gen y los ordena en un único resultado
  138. sub igualdades {
  139.     my (@resultados) = shift;
  140.     my $tam = ( int @resultados ) - 1;
  141.  
  142.     for ( my $i = 0; $i < $tam; $i++ ) {
  143.         my @res1 = split /;/ => $resultados[$i];
  144.  
  145.         for ( my $j = $i + 1; $j < $tam; $j++ ) {
  146.  
  147.             if ( $resultados[$j] != 0 ) {
  148.                 my @res2 = split /;/ => $resultados[$j];
  149.  
  150.                 if ( $res1[1] == $res2[1] ) {
  151.                     $resultados[$i] = $resultados[$i] . ";" . "$res2[2]" . ";" . "$res2[3]";
  152.                     $resultados[$j] = 0;
  153.                 }
  154.             }
  155.         }
  156.     }
  157.     return @resultados;
  158. }
  159.  
  160. #Con los datos de los hits comunes redacta una salida de datos para cada hit
  161. sub redaccion {
  162.     my @datos     = shift;
  163.     my @redaccion = [];
  164.     my $h         = 0;
  165.     foreach my $resultado (@datos) {
  166.         my @informacion = split /;/ => $resultado;
  167.         my $tam = int @informacion;
  168.         my @queries;
  169.         my $hit;
  170.         my $acceso;
  171.         my $descripcion;
  172.         my @longitudes;
  173.         my $j = 0;
  174.  
  175.         for ( my $i = 0; $i < $tam; $i = $i + 2 ) {
  176.             my $secuencia  = $informacion[$i];
  177.             my $tama       = $informacion[ $i + 1 ];
  178.             my $longitud   = $hits_length{$secuencia};
  179.             my @todas_long = split /;/ => $longitud;
  180.             $queries[$j]    = $secuencia_description[$secuencia];
  181.             $longitudes[$j] = $todas_long[$tama];
  182.             $j++;
  183.         }
  184.         my $sec1            = $informacion[0];
  185.         my $pos1            = $informacion[1];
  186.         my $hit_comun       = $hits_name{$sec1};
  187.         my $hit_acceso      = $hits_accesion{$sec1};
  188.         my $hit_descripcion = $hits_description{$sec1};
  189.         my @hitcom          = split /;/ => $hit_comun;
  190.         my @hitacc          = split /;/ => $hit_acceso;
  191.         my @hitdes          = split /;/ => $hit_descripcion;
  192.         my $nombrehit       = $hitcom[$pos1];
  193.         my $nombreacc       = $hitacc[$pos1];
  194.         my $nombredes       = $hitdes[$pos1];
  195.         my $numerosecu      = int @queries;
  196.         my $secredactado    = "";
  197.         my $lonredactado    = "";
  198.  
  199.         for ( my $k = 0; $k < $numerosecu; $k++ ) {
  200.             $secredactado = $secredactado . " y " . $queries[$k];
  201.             $lonredactado = $lonredactado . " y " . $longitudes[$k];
  202.         }
  203.         $redaccion[$h]
  204.             = "Las secuencias $secredactado tienen en comun el gen $nombrehit\n"
  205.             . "cuya descripcion es $nombredes , su numero de acceso $nombreacc \n;"
  206.             . "y cada uno de ellos aparea las siguientes longitudes respectivamente: $lonredactado ";
  207.         $h++;
  208.     }
  209.     return @redaccion;
  210. }
  211.  
  212. #Guarda los datos en un fichero de salida
  213. sub guardar_datos {
  214.     my ( $b, @salida ) = shift;
  215.     ( open Fichero, ">$b" );
  216.     my $N = int @salida;
  217.     for ( my $i = 0; $i < $N; $i++ ) {
  218.         print Fichero $salida[$i] . "\n";
  219.     }
  220.     close Fichero;
  221. }
Coloreado en 0.007 segundos, usando GeSHi 1.0.8.4
Última edición por explorer el 2014-02-24 11:40 @527, editado 2 veces en total
Razón: Formateado de código con Perltidy y poner marcas Perl
Giskard
Perlero nuevo
Perlero nuevo
 
Mensajes: 5
Registrado: 2014-02-24 05:32 @272

Publicidad

Re: Problemas al leer FASTA y hacer BLAST

Notapor explorer » 2014-02-24 09:42 @445

Bienvenido a los foros de Perl en Español, Giskard.

Por favor, revisa el código publicado en el mensaje anterior, y dinos a qué línea corresponde el mensaje de error. Según parece es alrededor de la línea 34, pero ahí veo un comentario.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Problemas al leer FASTA y hacer BLAST

Notapor Giskard » 2014-02-24 10:52 @494

Cierto, no contaba con que al ponerlo aquí se descuadrase con respecto a mi ordenador: sería la línea 37.

Por lo que entiendo, lo que hace es un bucle para que se repita tantas veces como secuencias haya leído. Por ello le he puesto un bucle como el while de la línea 44 para recoger "a mano" las secuencias que hay, y luego meter ese número en el for, aunque no sé si estaría bien.
Giskard
Perlero nuevo
Perlero nuevo
 
Mensajes: 5
Registrado: 2014-02-24 05:32 @272

Re: Problemas al leer FASTA y hacer BLAST

Notapor explorer » 2014-02-24 11:48 @533

El error indica que en la línea 37 estás intentando usar $str como un gestor de archivo para leer el contenido del fasta, pero... no lo es.

Según la documentación, para obtener un gestor de archivo a través de Bio::SeqIO, se debe usar el método newFh(), con lo que la línea 36 debería quedar así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $str = Bio::SeqIO->newFh( -file => 'sequences.fasta', '-format' => 'fasta' );
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Problemas al leer FASTA y hacer BLAST

Notapor Giskard » 2014-02-25 05:36 @275

Pero por lo que puedo ver, new() y newFh() no es lo mismo, ¿no? De hecho, por lo que he leído aqui el objeto que crean los dos no es el mismo. De hecho, habiéndolo cambiado, ahora el error me da en la línea 44, de que no se puede usar next_seq en esa línea:

Can't locate object method "next_seq" via package "IO::File" at comparacionx.pl line 41, <GEN0> line 2.

Y cuando he probado ese comando habiendo usado new no me daba el problema.
Giskard
Perlero nuevo
Perlero nuevo
 
Mensajes: 5
Registrado: 2014-02-24 05:32 @272

Re: Problemas al leer FASTA y hacer BLAST

Notapor explorer » 2014-02-25 07:06 @337

Vale... se puede arreglar eso, pero... yo veo un problema.

En la línea 37 se leen todas las secuencias, ¿no? Entonces, ¿qué es lo que se pretende en la línea 44? Leer la siguiente secuencia, ¿de dónde? Si suponemos que las hemos leído todas, entonces están almacenadas en @seq_array_name. Y no se puede leer más.

¿O estoy equivocado?

¿Cual es el propósito del doble bucle de las líneas 38 y 44?

En cuanto a lo de los errores...

Para poder ejecutar la línea 37 -¡ojo!, escrita de esa manera-, es necesario el uso de newFh(). En cambio, para poder usar la línea 44, es necesario usar new().

Se puede solventar con el método fh():
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $str  = Bio::SeqIO->new(
  2.             -file    => 'sequences.fasta',
  3.            '-format' => 'fasta',
  4. );                                           # Crear un flujo de objetos de secuencias FASTA
  5. my $fh   = $str->fh();                       # Obtención del gestor de flujo asociado a $str
  6. ...;
  7. my $seq  = <$fh>;                            # Forma de acceder al flujo, en forma de lectura de archivo, con $fh
  8. ...;
  9. my $next = $str->next_seq();                 # Forma de acceder al flujo, en forma orientado a objetos, con $str
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Yo creo que sí se pueden mezclar los dos métodos de lectura, pero sigo sin ver claro que queden secuencias posibles por leer, si se leen todas de golpe y se meten en un array.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Problemas al leer FASTA y hacer BLAST

Notapor Giskard » 2014-02-26 06:33 @315

Joder, muchísimas gracias.

Lo del bucle cuando lo puse ya me pareció raro, pero era de esas partes que comentaba que estaban en otros programas que he reciclado y no lo toqué, aunque claro, sí que debería haberlo quitado. Lo he cambiado como me has dicho, tal que así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.   my $str  = Bio::SeqIO->new(
  2.             -file    => 'sequences.fasta',
  3.            '-format' => 'fasta',
  4.   );                                           # Crear un flujo de objetos de secuencias FASTA
  5.   my $fh   = $str->fh();                       # Obtención del gestor de flujo asociado a $str
  6.   my $seq  = <$fh>;                            # Forma de acceder al flujo, en forma de lectura de archivo, con $fh
  7.   my $numero_secuencias = 1;
  8.   my @array_name;
  9.   my @array_length;
  10.   my @array_accession;
  11.   my @array_description;
  12.   my $i = 0;
  13.     while (my $input = $str->next_seq()){
  14.       #Blast a sequence against a database:
  15.  
  16.       #Alternatively, you could  pass in a file with many
  17.       #sequences rather than loop through sequence one at a time
  18.       #Remove the loop starting 'while (my $input = $str->next_seq())'
  19.       #and swap the two lines below for an example of that.
  20.       my $r = $factory->submit_blast($input);
  21.       #my $r = $factory->submit_blast('amino.fa');
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Y toda esa parte funciona. Ahora me estoy peleando con la parte de abajo, pero eso ya es más fácil xD

En serio, me has salvado, porque con esto voy a poder acortar gran parte de mi trabajo fin de máster una barbaridad, que si no me tocaba hacer 1000 BLAST o así, a mano, y mirar yo los resultados de uno en uno xD (sí, mi tutor es un poco bruto...).
Giskard
Perlero nuevo
Perlero nuevo
 
Mensajes: 5
Registrado: 2014-02-24 05:32 @272

Re: Problemas al leer FASTA y hacer BLAST

Notapor Giskard » 2014-02-27 04:54 @245

¡Puffff!, siento ser tan plasta, de verdad.

Me he puesto a comprobar los resultados del BLAST con dos secuencias, porque cada vez que hago alguna prueba se me eterniza esto, así que quería copiar y pegar los resultados, para luego modificar las funciones y cosas de más abajo sin tener que lanzar el BLAST. El caso es que me he dado cuenta de que no lanza, o al menos no obtiene los resultados de las dos secuencias, sino solo de la segunda, la cual además no se queda en la posición 2 (bueno, 1 si empezamos a contar de 0) sino que se queda el 1º (vamos, en la posición 0). Vuelvo a poner el código como lo tengo después de las modificaciones y lo que saca al final:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use strict;
  2. use Bio::Tools::Run::RemoteBlast;
  3. #  use strict;
  4.   my $ficherosalida = "loquesea.txt";
  5.   my $prog = 'blastp';
  6.   my $db   = 'swissprot';
  7.   my $e_val= '1e-10';
  8.   my @secuencia_name;
  9.   my @secuencia_length;
  10.   my @secuencia_accession;
  11.   my @secuencia_description;
  12.   my @params = ( '-prog' => $prog,
  13.          '-data' => $db,
  14.          '-expect' => $e_val,
  15.          '-readmethod' => 'SearchIO' );
  16.  
  17.   my $factory = Bio::Tools::Run::RemoteBlast->new(@params);
  18.  
  19.   #change a paramter
  20. #  $Bio::Tools::Run::RemoteBlast::HEADER{'ENTREZ_QUERY'} = 'Homo sapiens [ORGN]';
  21.  
  22.   #remove a parameter
  23.  # delete $Bio::Tools::Run::RemoteBlast::HEADER{'FILTER'};
  24.  
  25.   my $v = 1;
  26.   my %hits_name;
  27.   my %hits_length;
  28.   my %hits_accession;
  29.   my %hits_description;
  30.   #$v is just to turn on and off the messages
  31.  
  32.   my $str  = Bio::SeqIO->new(
  33.             -file    => 'sequences.fasta',
  34.            '-format' => 'fasta',
  35.   );                                           # Crear un flujo de objetos de secuencias FASTA
  36.   my $fh   = $str->fh();                       # Obtención del gestor de flujo asociado a $str
  37.   my $seq  = <$fh>;                            # Forma de acceder al flujo, en forma de lectura de archivo, con $fh
  38.   my $numero_secuencias = 1;
  39.   my @array_name;
  40.   my @array_length;
  41.   my @array_accession;
  42.   my @array_description;
  43.   my $i = 0;
  44.     while (my $input = $str->next_seq()){
  45.       #Blast a sequence against a database:
  46.  
  47.       #Alternatively, you could  pass in a file with many
  48.       #sequences rather than loop through sequence one at a time
  49.       #Remove the loop starting 'while (my $input = $str->next_seq())'
  50.       #and swap the two lines below for an example of that.
  51.       my $r = $factory->submit_blast($input);
  52.       #my $r = $factory->submit_blast('amino.fa');
  53.  
  54.       print STDERR "waiting..." if( $v > 0 );
  55.       while ( my @rids = $factory->each_rid ) {
  56.         foreach my $rid ( @rids ) {
  57.           my $rc = $factory->retrieve_blast($rid);
  58.           if( !ref($rc) ) {
  59.             if( $rc < 0 ) {
  60.               $factory->remove_rid($rid);
  61.             }
  62.             print STDERR "." if ( $v > 0 );
  63.             sleep 5;
  64.           } else {
  65.             my $result = $rc->next_result();
  66.             #save the output
  67.             my $filename = $result->query_name()."\.out";
  68.             $factory->save_output($filename);
  69.             $factory->remove_rid($rid);
  70.             $secuencia_name[$i] = $result->query_name();
  71.             $secuencia_accession[$i] = $result->query_accession();
  72.             $secuencia_length[$i] = $result->query_length;
  73.             $secuencia_description[$i] = $result->query_description();
  74.             while ( my $hit = $result->next_hit ) {
  75.               next unless ( $v > 0);
  76.               push(@array_name,$hit->name);
  77.               push(@array_length,$hit->length);
  78.               push(@array_accession,$hit->accession);
  79.               push(@array_description,$hit->description);
  80.               print "\nhit name is ", $hit->name, "\n";
  81.             }
  82.           }
  83.         }
  84.        
  85.       }
  86.     $hits_name{$i}= join(";",@array_name);
  87.     print "para la clave $i da $hits_name{$i}";
  88.     $hits_length{$i}= join(";",@array_length);
  89.     $hits_accession{$i}= join(";",@array_accession);
  90.     $hits_description{$i}= join(";",@array_description);
  91.     $numero_secuencias = $numero_secuencias + 1;
  92.     $i++;
  93.     }
  94.    
  95.  
  96.  
  97.  
  98.   my @final;
  99.   print "los hits name 0 son", $hits_name{0},"\n";
  100.   print "los hits name 1 son", $hits_name{1}, "\n";
  101.   print "los hits length 0 son", $hits_length{0}, "\n";
  102.   print "los hits length 1 son", $hits_length{1}, "\n";
  103.   print "los hits accession 0 son", $hits_accession{0}, "\n";
  104.   print "los hits accession 1 son", $hits_accession{1}, "\n";
  105.   print "los hits description 0 son", $hits_description{0}, "\n";
  106.   print "los hits description 1 son", $hits_description{1}, "\n";
  107.   print "los query name 0 son", $secuencia_name[0], "\n";
  108.   print "los query name 1 son", $secuencia_name[1], "\n";
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4
Giskard
Perlero nuevo
Perlero nuevo
 
Mensajes: 5
Registrado: 2014-02-24 05:32 @272


Volver a Bioinformática

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron