Script BioPerl:

Fermé
new_26 Messages postés 15 Date d'inscription samedi 9 août 2014 Statut Membre Dernière intervention 14 septembre 2015 - 14 août 2014 à 16:39
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 - 18 août 2014 à 17:48
Bonjour,

je souhaiterai utiliser le script suivant pour extraire des séquences fasta (sequences.fa) à partir d'une liste d'identifiants (ids.txt).

#!/usr/bin/perl -w

use strict;
use Bio::DB::Fasta;

my $database;
my $fasta_library;
my %records;
open IDFILE, "ids.txt" or die $!;
open OUTPUT, "test_output" or die $!;
# name of the library file - (here it is hardcoded)
$fasta_library = 'sequences.fa';

# creates the database of the library, based on the file
$database = Bio::DB::Fasta->new("$fasta_library") or die "Failed to creat Fasta DP object on fasta library\n";


# now, it parses the file with the fasta headers you want to get
while (<IDFILE>) {



my ($id) = (/^>*(\S+)/); # capture the id string (without the initial ">")
my $header = $database->header($id);
#print "$header\n";
print ">$header\n", $database->seq( $id ), "\n";
print OUTPUT ">$header\n", $database->seq( $id ), "\n";
}

exit;


Il fonctionne et me sort les bonnes séquences par contre j'ai le message suivant:
"Filehandle OUTPUT opened only for input at ./test_bioperl.pl line 27."
et les séquences s'affichent mais ne sont pas stockées dans test_output

Je commence à peine à utiliser des scripts et il y a sûrement quelque chose qui m'échappe, quelqu'un peut-il m'expliquer?

Merci d'avance
A voir également:

3 réponses

[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié par [Dal] le 18/08/2014 à 12:50
Bonjour,

J'ignore si tu as résolu ton problème.

Pour ouvrir un fichier en écriture, tu dois spécifier à l"instruction "open" le mode l'ouverture du fichier.

Si le mode n'est pas spécifié à "open" (comme dans ton cas), Perl ouvre par défaut le fichier en lecture.

Pour ouvrir le fichier en écriture, tu peux remplacer :

open OUTPUT, "test_output" or die $!; 


par :

open(my $testoutput, ">", "test_output") or die $!; 


et utiliser
$testoutput
comme filehandle.

Tu devrais aussi fermer tes fichiers avant de terminer ton script.

close($testoutput) || die "couldn't close file: $!";


Plus d'infos sur les pages Perdoc de open et de perlopentut.

Tu peux aussi ajouter
use warnings;
à ton code, cela aide au débogage.


Dal
0
new_26 Messages postés 15 Date d'inscription samedi 9 août 2014 Statut Membre Dernière intervention 14 septembre 2015
18 août 2014 à 16:09
Bonjour Dal et merci,

j'ai modifié le code comme suit... mais:

#!/usr/bin/perl -w

use strict;
use Bio::DB::Fasta;
use warnings;

my $database;
my $fasta_library;
my %records;
open IDFILE, "liste_genes" or die $!;
open OUTPUT, (my $OUTPUT, "output.fa"), or die $!;
# name of the library file - (here it is hardcoded)
$fasta_library = 'gene_name.fa';

# creates the database of the library, based on the file
$database = Bio::DB::Fasta->new("$fasta_library") or die "Failed to creat Fasta DP object on fasta library\n";


# now, it parses the file with the fasta headers you want to get
while (<IDFILE>) {



my ($id) = (/^>*(\S+)/); # capture the id string (without the initial ">")
my $header = $database->header($id);
#print "$header\n";
print ">$header\n", $database->seq( $id ), "\n";
print $OUTPUT ">$header\n", $database->seq( $id ), "\n";

close ($OUTPUT) or die "couldn't close file: $!";


}

exit;


Mais voilà les erreurs:

Name "main::OUTPUT" used only once: possible typo at ./bio.pl line 11.
>gene_1458
MSPKAVLVGLPGSGKSTIGRRLAKALGVNVYDTDTGIETEAGRTIAQIFANDGEPEFRRIEESVIRQALDQQDGVVSLGGGAVLTPGVREALAGHTVVYLEISAAEGIRRTGGSVVRPLLAGPDRAEKYHALMSQRVPLYREVATIKVNTDRRNPGAVVRMIVSRLENPEGSAGSASSRRRRPRRRPRSRRRSAGAAAVTQTNTSGTETRERADND
Can't use an undefined value as a symbol reference at ./bio.pl line 28

je ne comprends pas ces erreurs :/
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié par [Dal] le 18/08/2014 à 17:17
Je ne dispose pas de Bio::DB::Fasta sur ma machine, ni des données que tu utilises, alors, je ne peux pas tester ton script.

Tu n'as pas effectué les modifications que j'ai suggérées mais d'autres modifications.

En Perl, il n'est plus recommandé d'utiliser des mots nus ("barewords" en anglais) en tant que filehandle (comme "OUPUT") depuis près de 15 ans, mais des variables scalaires (comme $ouput).

Les raisons sont diverses, tu en as un échantillon là :

https://wiki.sei.cmu.edu/confluence/display/perl/FIO00-PL.+Do+not+use+bareword+file+handles
https://perlmaven.com/open-files-in-the-old-way

Tu trouveras toujours du code sur Internet correspondant à l'ancienne école, mais ce n'est plus considéré la bonne façon de faire.

Si tu tiens à utiliser des mots nus (ce qu'il est possible de faire dans les versions actuelles de Perl, même avec "strict", pour des raisons de compatibilité), il faut le faire tout au long de ton code pour un filehandle donné, bien penser à fermer les fichiers et avoir à l'esprit les problèmes de sécurité que cela peut poser, et le fait que le mot nu a une portée globale.

Ton code (non testé) serait alors :

#!/usr/bin/perl -w

use strict;
use Bio::DB::Fasta;
use warnings;

my $database;
my $fasta_library;
my %records;
open IDFILE, "liste_genes" or die $!;                                                                                                                                                                              
open OUTPUT, ">", "output.fa", or die $!;
# name of the library file - (here it is hardcoded)
$fasta_library = 'gene_name.fa';

# creates the database of the library, based on the file
$database = Bio::DB::Fasta->new("$fasta_library") or die "Failed to creat Fasta DP object on fasta library\n";


# now, it parses the file with the fasta headers you want to get
while (<IDFILE>) {



my ($id) = (/^>*(\S+)/); # capture the id string (without the initial ">")
my $header = $database->header($id);
#print "$header\n";
print ">$header\n", $database->seq( $id ), "\n";
print OUTPUT ">$header\n", $database->seq( $id ), "\n";

close (OUTPUT) or die "couldn't close file: $!";


}

exit;


cependant, la façon correcte de faire serait d'utiliser des filehandles scalaires, et probablement, ton close est mal placé et devrait se situer à l'extérieur de la boucle while, ce qui donnerait :

#!/usr/bin/perl

use strict;
use warnings;
use Bio::DB::Fasta;

my $database;
my $fasta_library;
my %records;
open my $idfile, "<", "liste_genes" or die $!;
open my $output, ">", "output.fa", or die $!;                                                                                                                                                                      
# name of the library file - (here it is hardcoded)
$fasta_library = 'gene_name.fa';

# creates the database of the library, based on the file
$database = Bio::DB::Fasta->new("$fasta_library") or die "Failed to creat Fasta DP object on fasta library\n";

# now, it parses the file with the fasta headers you want to get
while (<$idfile>) {
    my ($id) = (/^>*(\S+)/); # capture the id string (without the initial ">")
    my $header = $database->header($id);
#print "$header\n";
    print ">$header\n", $database->seq( $id ), "\n";
    print $output ">$header\n", $database->seq( $id ), "\n";
}

close ($output) or die "couldn't close file: $!";
exit;


(non testé non plus, car je ne dispose pas de Bio::DB::Fasta sur ma machine, ni des données que tu utilises)


Dal
0
new_26 Messages postés 15 Date d'inscription samedi 9 août 2014 Statut Membre Dernière intervention 14 septembre 2015
18 août 2014 à 17:23
Merci beaucoup!!!

maintenant ça fonctionne!
Excusez moi mais je n'ai pas très bien compris ce qu'était un filehandle, je commence à utiliser des scripts (déjà existants) et à me former à Perl, un peu toute seule alors j'essaie de comprendre au fur et à mesure!

Encore merci!
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
18 août 2014 à 17:48
cool :-)

on peut traduire "filehandle" par "descripteur de fichier".

l'instruction
open
ouvre un fichier dont le nom est donné, selon le mode spécifié (mode lecture ou écriture) et l'associe à un descripteur, qui pourra être utilisé dans la suite du code pour manipuler le fichier. Cette "liaison" entre le descripteur de fichier et le fichier est maintenue tant que le fichier n'est pas fermé avec la fonction
close
.
0