meta
Structure
Evolution
Et
Diversité des microbiotes des semences
Deux scripts pour rapatrier et décompresser les fichiers .sra
On fournit ici deux scripts écrits en PERL pour aider à la gestion des fichiers .sra. Le premier script automatise le rapatriement de fichiers .sra à partir de leurs URLs et le second script vient décompresser ces fichiers .sra pour fournir des fichiers .fastq pairés.
Pour un(e) informaticien(ne) chevronné(e), ces scripts sont sans doute inutiles : la commande wget sait rapatrier une liste de fichiers et une simple boucle en commande shell peut assurer la décompression. Toutefois certain(e)s biologistes ne savent pas exécuter ces commandes. De plus, le temps de réalisation de ces opérations de rapatriement et décompression peut durer plusieurs heures. Fournir des scripts qui peuvent s'exécuter en tache de fond avec ou sans nohup et avec des affichages soignés en cours d'exécution comme fichier 3/10 nous parait utile pour la communauté et peut servir d'exemple pour aider à écrire d'autres scripts.
Table des matières cliquable
1. Un script pour rapatrier des fichiers .sra
2. Un script pour décompresser les fichiers .sra
3. Configuration de l'environnement et utilisation des scripts
1. Un script pour rapatrier des fichiers .sra
Ce premier script se nomme getSra.pl et ne requiert aucune configuration. Il est conseillé de le mettre dans un chemin accessible par le path ou de simplement le recopier dans le répertoire courant.
Le script getSra.pl utilise un paramètre, le nom d'un fichier texte qui contient des URL de fichiers .sra, comme par exemple le fichier sraOttesen.txt dont voici le contenu simplifié (le fichier original contient 54 lignes) :
ftp://ftp-trace.ncbi.nlm.nih.gov/sra/sra-instant/reads/ByExp/sra/SRX/SRX101/SRX1011066/SRR1999023/SRR1999023.sra ftp://ftp-trace.ncbi.nlm.nih.gov/sra/sra-instant/reads/ByExp/sra/SRX/SRX101/SRX1011065/SRR1999022/SRR1999022.sra ftp://ftp-trace.ncbi.nlm.nih.gov/sra/sra-instant/reads/ByExp/sra/SRX/SRX101/SRX1011034/SRR1998991/SRR1998991.sra ftp://ftp-trace.ncbi.nlm.nih.gov/sra/sra-instant/reads/ByExp/sra/SRX/SRX101/SRX1011061/SRR1999018/SRR1999018.sra [..] ftp://ftp-trace.ncbi.nlm.nih.gov/sra/sra-instant/reads/ByExp/sra/SRX/SRX101/SRX1011033/SRR1998990/SRR1998990.sraLe script getSra.pl commence par utiliser la commande wget en mode --spider afin de connaitre la taille des fichiers avant de les rapatrier. Voici un extrait du listing de l'exécution, sachant que la durée totale du script, dans nos environnements, est d'à peu près 10 minutes sur un ordinateur et d'environ une demi-heure sur un autre ordinateur :
@ghchu3-ET2700I~/Tmp/Otte|(~gH) > perl ~/Bin/getSra.pl ../sraOttesen.txt getSra.pl (gH) version 1.03 1. retrieving the file sizes for ../sraOttesen.txt. file 1 / 54 : SRR1999023.sra SIZE 8213807 8 Mo -- total 8213807 8 Mo file 2 / 54 : SRR1999022.sra SIZE 68426 67 kO -- total 8282233 8 Mo file 3 / 54 : SRR1998991.sra SIZE 1886463 2 Mo -- total 10168696 10 Mo [..] file 53 / 54 : SRR1999012.sra SIZE 35063542 34 Mo -- total 1145686814 2 Go file 54 / 54 : SRR1998990.sra SIZE 310900992 297 Mo -- total 1456587806 2 Go you can consult expected_sizes.txt to check the size of the files. 2. retrieving the 54 files defined by their URL in ../sraOttesen.txt. 15/06/2016 10:50.08 file 1 / 54 : SRR1999023.sra processing... done. 15/06/2016 10:50.16 file 2 / 54 : SRR1999022.sra processing... done. 15/06/2016 10:50.21 file 3 / 54 : SRR1998991.sra processing... done. [..] 15/06/2016 11:06.12 file 53 / 54 : SRR1999012.sra processing... done. 15/06/2016 11:06.40 file 54 / 54 : SRR1998990.sra processing... done. Start: 15/06/2016 10:46.23 ; end: 15/06/2016 11:10.45.2. Un script pour décompresser les fichiers .sra
Dans la mesure où les fichiers .sra sont des archives -- donc des fichiers illisibles directement -- dont le format est assez technique (voir par exemple leur description ici au NCBI), il est est recommandé de passer par l'utilitaire fastq-dump pour décompresser ces archives en vue d'en extraires des fichiers .fastq pairés.
Contrairement au script précédent, le script convertSra.pl ne demande aucun fichier paramètre car il décompresse tous les fichiers .sra (ou .SRA) présents dans le répertoire.
Voici un extrait du listing de l'exécution, sachant que la durée totale du script, dans notre environnement, est de moins d'une minute parce que le volume des données n'est pas gros. Pour un ensemble de fichiers plus conséquents comme ceux de sraOfek.txt (20 fichiers .sra, pour un total de 91 Go soit un téléchargement via getSra.pl de 4 h et 30 minutes), il faut compter environ XXX 6 h pour produire 40 fichiers .fastq de YYY 450 Go en tout.
@ghchu~/Rch/Metaseed/getSraFiles/09_Ottesen|(~gH) > perl ../convertSra.pl convertSra.pl (gH) version 1.01 1. retrieving the file names and sizes in /home/gh/Rch/Metaseed/getSraFiles/09_Ottesen. file 1 / 54 : SRR1998985.sra 23824251 23 Mo file 2 / 54 : SRR1998986.sra 46968525 45 Mo file 3 / 54 : SRR1998987.sra 79198436 76 Mo [..] file 53 / 54 : SRR1999037.sra 41717125 40 Mo file 54 / 54 : SRR1999038.sra 43373490 42 Mo 2. uncompressing the 54 files in /home/gh/Rch/Metaseed/getSraFiles/09_Ottesen. 15/06/2016 13:45.50 file 1 / 54 : SRR1998985.sra Read 25861 spots Written 25861 spots 15/06/2016 13:45.51 file 2 / 54 : SRR1998986.sra Read 51524 spots Written 51524 spots 15/06/2016 13:45.51 file 3 / 54 : SRR1998987.sra Read 91522 spots Written 91522 spots [..] 15/06/2016 13:46.28 file 53 / 54 : SRR1999037.sra Read 30463 spots Written 30463 spots 15/06/2016 13:46.29 file 54 / 54 : SRR1999038.sra Read 31102 spots Written 31102 spots you can consult sizes_and_reads.txt to check the size of the files. Start: 15/06/2016 13:45.50 ; end: 15/06/2016 13:46.29 ; elapsed time: 39 sec.3. Configuration de l'environnement et utilisation des scripts
Comme ces scripts sont écrits en PERL, il faut bien sûr que PERL soit installé.
Nous fournissons ces scripts tels quels, pour un environnement Unix/Ubuntu. Sachant que le premier script utilise wget tout système qui implémente cette commande (donc Windows avec wget installé) peut utiliser ce script.
Pour le deuxième script, il faut avoir installé fastq-dump qui fait partie de la suite logicielle nommée sra-tools et dont la documentation et l'installation sont décrites ici. Tout système qui implémente la commande fastq-dump et la commande find peut utiliser ce script.
L'utilisation de ces scripts peut se faire en ligne de commande classique, en mode tache de fond ou pas, avec nohup ou pas. Voici ce que nous recommandons :
pour un ordinateur personnel que l'on laisse allumé en permanence, un appel en ligne de commande classique sachant que cela peut durer longtemps et remplir le disque dur :
$gh> perl ~/Bin/getSra.pl FIC $gh> perl ~/Bin/convertSra.plpour une exécution sur serveur distant avec beaucoup d'espace disque, un appel via nohup en tache de fond (nos affichages sont visibles dans nohup.out pendant l'exécution puis dans les fichiers log) :
$gh> nohup perl ~/Bin/getSra.pl FIC & $gh> nohup perl ~/Bin/convertSra.pl &4. Contenu des fichiers
Fichier getSra.pl
# # (gH) -_- getSra.pl ; TimeStamp (unix) : 13 Juin 2016 vers 18:44 ################################################################################# # # this script download all the sra files found in the parameter # # for instance, if the files mySrafiles.txt contains # # ftp://ftp-trace.ncbi.nlm.nih.gov/sra/sra-instant/reads/ByExp/sra/SRX/SRX101/SRX1011066/SRR1999023/SRR1999023.sra # ftp://ftp-trace.ncbi.nlm.nih.gov/sra/sra-instant/reads/ByExp/sra/SRX/SRX101/SRX1011065/SRR1999022/SRR1999022.sra # # the script will download these two files # # ################################################################################# print "\n getSra.pl (gH) version 1.03\n" ; use strict ; use warnings ; use POSIX qw/ceil/; if ($#ARGV==-1) { print "\n" ; print " the script getSra.pl download all the files found in the parameter file \n" ; print " syntax : perl getSra.pl FILE \n" ; print " example : perl getSra.pl mySraFiles.txt \n" ; print " where mySraFiles.txt contains lines like \n" ; print " ftp://ftp-trace.ncbi.nlm.nih.gov/sra/.../SRR1999023.sra" ; print "\n\n" ; exit(-1) ; } ; # end if # store date and time to be able to compute duration my $date1 = &dateEtHeure() ; my $time1 = time() ; system("echo $date1 > time.start") ; #################################################################### #################################################################### # let's check the parameter file is present my $inFile = $ARGV[0] ; if (!-e $inFile) { print " file $inFile not found.STOP.\n\n" ; exit(-2) ; } ; # end if #################################################################### #################################################################### # 1. get the expected size of the files #################################################################### #################################################################### print "\n" ; print " 1. retrieving the file sizes for $inFile.\n\n" ; print "\n" ; my $expsFile = "expected_sizes.txt" ; open(ESFILE,">$expsFile") or die ("\n\n! Unable to write to $expsFile\n\n") ; print ESFILE "Start: ".&dateEtHeure()."\n" ; # loop over all the URLs and get the sizes using wget --spider open(INFILE,"<$inFile") or die ("\n\n! Unable to read from $inFile\n\n") ; my $nbf = 0 ; # nombre de fichiers while (my $lig=<INFILE>) { $nbf++ ; } ; # fin de tant que close(INFILE) ; my @tdm ; # tableau des mots my @wgTdm ; # tableau des mots my $wgetLst = "wget.lst" ; my $wgetErr = "wget_err.lst" ; my $resCmd = "" ; my $fSize = 0 ; my $tailleh = 0 ; my $total = 0 ; my $totalh = 0 ; my $ligRes = "" ; my $ligRes1 = "" ; my $ligRes2 = "" ; my $ligRes3 = "" ; my $ligRes4 = "" ; my $ligRes5 = "" ; open(INFILE,"<$inFile") or die ("\n\n! Unable to read from $inFile\n\n") ; my $idf = 0 ; # nombre de fichiers while (my $lig=<INFILE>) { chomp($lig) ; $idf++ ; $ligRes1 = "file ".sprintf("%4d",$idf)." / $nbf : " ; print $ligRes1 ; @tdm = split(/\//,$lig) ; $ligRes2 = $tdm[$#tdm] ; print $ligRes2 ; $resCmd = `wget --spider $lig > $wgetLst 2> $wgetLst ` ; open(WGFILE,"<$wgetLst") or die ("\n\n! Unable to read from $wgetLst\n\n") ; while (my $wgLine = <WGFILE>) { @wgTdm = split(/\s+/,$wgLine) ; if ($wgTdm[1]) { if ($wgTdm[1] eq 'SIZE') { print " ".$wgTdm[1]." " ; $fSize = 0 ; $tailleh = 0 ; if ($wgTdm[4] =~ /[0-9]+/) { $fSize = $wgTdm[4] ; $tailleh = &tailleH($fSize) ; } ; # fin si sur numérique $ligRes3 = sprintf("%12s",$fSize) ; $ligRes3 .= sprintf("%10s",$tailleh) ; print $ligRes3 ; $total += $fSize ; } ; # fin de si sur size } ; # fin de si sur non vide } ; # fin de tant que close(WGFILE) ; $ligRes4 = " -- total " ; print $ligRes4 ; $totalh = &tailleH($total) ; $ligRes5 = sprintf("%12s",$total).sprintf("%10s",$totalh)."\n" ; print $ligRes5 ; print ESFILE $ligRes1.$ligRes2.$ligRes3.$ligRes4.$ligRes5 ; } ; # fin de tant que close(INFILE) ; print ESFILE "-- all $nbf file sizes retrieved.\n" ; print ESFILE "End: ".&dateEtHeure()."\n" ; close(ESFILE) ; print "\n you can consult $expsFile to check the size of the files.\n\n" ; #################################################################### #################################################################### # 2. wget all the files in a loop + progressive display #################################################################### #################################################################### print "\n" ; print " 2. retrieving the $nbf files defined by their URL in $inFile.\n\n" ; print "\n" ; my $logFile = "getSra_log.txt" ; system("rm -rf $logFile"); my $wgTmp = "wget_tmp.txt" ; # check if K to write to log open(LOGFILE,">$logFile") or die ("\n\n! Unable to write in $logFile\n\n") ; print LOGFILE "getSra.pl : retrieving $nbf files defined in $inFile.\n\n" ; print LOGFILE "Start: ".&dateEtHeure()."\n" ; close(LOGFILE) ; # let's write in the log file for the first time open(INFILE,"<$inFile") or die ("\n\n! Unable to read from $inFile\n\n") ; $idf = 0 ; # nombre de fichiers while (my $lig=<INFILE>) { chomp($lig) ; $idf++ ; $ligRes1 = &dateEtHeure()." file ".sprintf("%4d",$idf)." / $nbf : " ; print $ligRes1 ; @tdm = split(/\//,$lig) ; $ligRes2 = $tdm[$#tdm] ; print $ligRes2 ; $ligRes3 = " processing... " ; print $ligRes3 ; system("wget $lig 2> $wgTmp") ; $ligRes4 = "done.\n"; print $ligRes4 ; open(LOGFILE,">>$logFile") or die ("\n\n! Unable to write in $logFile\n\n") ; print LOGFILE $ligRes1.$ligRes2.$ligRes3.$ligRes4 ; close(LOGFILE) ; } ; # fin de tant que sur infile # write in the log file to say we're done open(LOGFILE,">>$logFile") or die ("\n\n! Unable to write in $logFile\n\n") ; print LOGFILE "-- all $nbf files retrieved.\n" ; print LOGFILE "End: ".&dateEtHeure()."\n\n" ; close(LOGFILE) ; #################################################################### #################################################################### # at last, compute global duration print "\n" ; my $date2 = &dateEtHeure() ; system("echo $date2 > time.stop") ; my $time2 = time() ; my $duree = $time2 - $time1 ; print " Start: $date1 ; end: $date2 ; elapsed time: $duree sec" ; if ($duree>60) { print " (" ; my $hrs = int($duree/(24*60.0)) ; if ($hrs>0) { print "$hrs h " ; } ; # fin si my $rst = $duree - (24*60.0)*$hrs ; my $min = int($rst / 60.0) ; my $sec = $rst - 60* $min ; print "$min min $sec sec)" ; } ; # fin si print ".\n" ; exit(-1) ; #################################################################### #################################################################### sub dateEtHeure { #################################################################### my ($sec,$min,$hour,$mday,$mmon,$year)=localtime(); $mmon = $mmon + 1 ; $year = $year + 1900 ; if (length($sec)<2) { $sec = "0$sec" } ; if (length($min)<2) { $min = "0$min" } ; if (length($mday)<2) { $mday = "0$mday" } ; if (length($mmon)<2) { $mmon = "0$mmon" } ; my $now = $mday."/".$mmon."/".$year; $now .= " ".$hour.":".$min.".".$sec ; return $now ; } ; # fin sub dateEtHeure #################################################################### sub tailleH { # affiche lisiblement une taille de fichier my $nbOctets = $_[0] ; my @lstUnit = ("","kO","Mo","Go","To","Po") ; my $p = 1 ; my $basep = 1024 ; my $limInf = 1 ; my $limSup = $basep**$p ; my $idu = 0 ; while ($nbOctets>$limSup) { #cat("p=",p," : ",nbOctets,">",limSup,"\n") #cat("limInf",limInf,",","limSup",limSup,"\n") #cat("n/limInf",nbOctets/limInf,"\n") $idu = $idu + 1 ; $p = $p+1 ; $limInf = $limSup ; $limSup = $basep**$p ; } ; # fin tant que #cat("donc p=",p," : ",nbOctets,"<",limSup," et idu vaut ",idu,"\n") #cat("n/limInf",nbOctets/limInf,"\n") my $th = ($nbOctets*1.0)/$limInf ; #cat("th=",th,"\n") $th = ceil($th) ; $th .= " $lstUnit[$idu]" ; return($th) } ; # fin sub dateEtHeure #################################################################### # # normal end of script # ####################################################################Fichier convertSra.pl
# # (gH) -_- convertSra.pl ; TimeStamp (unix) : 14 Juin 2016 vers 18:20 ################################################################################# # # this script uncompress all the .sra files in the current directory # # ################################################################################# print "\n convertSra.pl (gH) version 1.03\n" ; use strict ; use warnings ; use POSIX qw/ceil/; # store date and time to be able to compute duration my $date1 = &dateEtHeure() ; my $time1 = time() ; system("echo $date1 > time.start") ; #################################################################### #################################################################### # 1. get the name and size of all the .sra files in the current directory #################################################################### #################################################################### my $curDir = `pwd` ; chomp $curDir ; print "\n" ; print " 1. retrieving the file names and sizes in $curDir.\n\n" ; print "\n" ; my $expsFile = "sizes_and_reads.txt" ; open(ESFILE,">$expsFile") or die ("\n\n! Unable to write to $expsFile\n\n") ; print ESFILE "Start: ".&dateEtHeure()."\n" ; my @files = `find *.SRA *.sra 2> /dev/null ` ; my $nbf = @files ; # nombre de fichiers my $idf = 0 ; foreach my $file (sort @files) { $idf++; chomp($file) ; my $fileSize = -s $file ; print " file ".sprintf("%4d",$idf)." / $nbf : ".sprintf("%15s",$file) ; my $tailleh = &tailleH($fileSize) ; print sprintf("%12s",$fileSize) ; print sprintf("%10s",$tailleh) ; print "\n" ; } ; # fin de foreach #################################################################### #################################################################### # 2. uncompress all the .sra files #################################################################### #################################################################### print "\n" ; print " 2. uncompressing the $nbf files in $curDir.\n\n" ; print "\n" ; my $fqDump = "fastq-dump_log.txt" ; $idf = 0 ; foreach my $file (sort @files) { $idf++; chomp($file) ; print &dateEtHeure()." file ".sprintf("%4d",$idf)." / $nbf : ".sprintf("%15s",$file) ; `fastq-dump --split-files ./$file > $fqDump ` ; `cat $fqDump` ; open(FQDUMP,"<$fqDump") or die ("\n\n! Unable to read from $fqDump\n\n") ; while(my $lig = <FQDUMP>) { my @tdm = split(/\s+/,$lig) ; print(" ".$tdm[0]) ; print(sprintf("%15d",$tdm[1])) ; print(" ".$tdm[2]) ; } ; # fin tant que close(FQDUMP) ; print "\n" ; } ; # fin de foreach print ESFILE "-- all $nbf files uncompressed.\n" ; print ESFILE "End: ".&dateEtHeure()."\n" ; close(ESFILE) ; print "\n you can consult $expsFile to check the size of the files.\n\n" ; #################################################################### #################################################################### # at last, compute global duration print "\n" ; my $date2 = &dateEtHeure() ; system("echo $date2 > time.stop") ; my $time2 = time() ; my $duree = $time2 - $time1 ; print " Start: $date1 ; end: $date2 ; elapsed time: $duree sec" ; if ($duree>60) { print " (" ; my $hrs = int($duree/(24*60.0)) ; if ($hrs>0) { print "$hrs h " ; } ; # fin si my $rst = $duree - (24*60.0)*$hrs ; my $min = int($rst / 60.0) ; my $sec = $rst - 60* $min ; print "$min min $sec sec)" ; } ; # fin si print ".\n" ; exit(-1) ; #################################################################### #################################################################### sub dateEtHeure { #################################################################### my ($sec,$min,$hour,$mday,$mmon,$year)=localtime(); $mmon = $mmon + 1 ; $year = $year + 1900 ; if (length($sec)<2) { $sec = "0$sec" } ; if (length($min)<2) { $min = "0$min" } ; if (length($mday)<2) { $mday = "0$mday" } ; if (length($mmon)<2) { $mmon = "0$mmon" } ; my $now = $mday."/".$mmon."/".$year; $now .= " ".$hour.":".$min.".".$sec ; return $now ; } ; # fin sub dateEtHeure #################################################################### sub tailleH { # affiche lisiblement une taille de fichier my $nbOctets = $_[0] ; my @lstUnit = ("","kO","Mo","Go","To","Po") ; my $p = 1 ; my $basep = 1024 ; my $limInf = 1 ; my $limSup = $basep**$p ; my $idu = 0 ; while ($nbOctets>$limSup) { #cat("p=",p," : ",nbOctets,">",limSup,"\n") #cat("limInf",limInf,",","limSup",limSup,"\n") #cat("n/limInf",nbOctets/limInf,"\n") $idu = $idu + 1 ; $p = $p+1 ; $limInf = $limSup ; $limSup = $basep**$p ; } ; # fin tant que #cat("donc p=",p," : ",nbOctets,"<",limSup," et idu vaut ",idu,"\n") #cat("n/limInf",nbOctets/limInf,"\n") my $th = ($nbOctets*1.0)/$limInf ; #cat("th=",th,"\n") $th = ceil($th) ; $th .= " $lstUnit[$idu]" ; return($th) } ; # fin sub dateEtHeure #################################################################### # # normal end of script # ####################################################################
Retour à la page principale de (gH)