IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

très gros fichier et out of memory


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 8
    Par défaut très gros fichier et out of memory
    Bonjour,

    J'ai, comme vous vous en doutez, un problème. Je dois traiter deux fichiers texte d'une taille totale de 7,5Go. Ces fichiers sont issus d'un sequenceur haut-débit, il n'y a rien que je puisse faire pour en limiter la taille. Le premier contient les sequences obtenues par le sequenceur (~2,2Go) et le deuxième les quality values pour chaques caractères de toutes les séquences du premier fichier. Mon script trie toutes les séquences pour éliminer toutes celles qui ont une quality value trop basse par rapport à un seuil defini par l'utilisateur, j'ai donc besoin des deux fichiers en même temps. Ce script marche très bien pour les petits fichiers mais j'ai une erreur out of memory dès que je passe à ses deux (énormes) fichiers. J'ai un autre script qui peut découper ce type de fichier, mais il a bien sûr le même problème. J'ai également essayé d'utiliser ultrasplitter, il me sort que mon fichier à une taille de -1. Existe-t-il un moyen pour ne pas charger la totalité de mes fichiers en même temps mais petits bouts par petits bouts?

    Merci de votre aide,
    Narrow

  2. #2
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 822
    Par défaut
    Il faut revoir l'algorithme et nous montrer ce que vous avez fait.
    Il y a peut être une autre façon de procéder pour éviter de tout mettre en mémoire, à creuser !!!

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 8
    Par défaut
    Voilà le code (très legèrement commenté)
    pour eviter de tout charger en memoire: il me faut juste les deux même lignes de chaque fichier en même temps, alors si on peut eviter de tout charger d'un coup, moi je veux bien.

    edit: oups, je l'ai mis en pièce jointe le voici en clair, sans les print commentés.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    use Data::Dumper;
    use Statistics::Lite qw(:funcs);
    #use Statistics::Descriptive;
     
     
    open (READS, $ARGV[0]) or warn "On ne peut pas lire le fichier entrant: $!\n"and next;
    undef($/);
    my $readInString = <READS>;
    close (READS);
    %transColor = (A => [A,C,G,T], T=>[T,G,C,A] , C=>[C,A,T,G], G=>[G,T,A,C]);
    @tableOfLines = split (/>/,$readInString);
     
    open (QUALV, $ARGV[1]) or warn "On ne peut pas lire le fichier entrant: $!\n"and next;
    undef($/);
    my $qualInString = <QUALV>;
    close (QUALV);
    @tableOfLines2 = split (/>/,$qualInString);
     
    $threshold=$ARGV[2];
     
    if (defined($ARGV[3])){
    	$threshold2=$ARGV[3];
    }
    else {$threshold2=100000;
    	}	
     
    if ($tableOfLines[0] eq ''){
    	shift @tableOfLines;
    }
    if ($tableOfLines2[0] eq ''){
    	shift @tableOfLines2;
    }
    $NbReads=@tableOfLines;
     
    for ($i=0; $i<$NbReads; $i++) { #parcour tout le fichier de read
    	$read = $tableOfLines[$i];
    	$qual = $tableOfLines2[$i];
    	if ($read =~ /(.*)\n(.*)/){ #recupere le nom et la sequence d'un read
    		$nam=$1;
    		$seq=$2;
    		if (($seq !~ /.*\..*/) or (index($seq,".") >= 25)) { #garde le read s'il ne contient pas de . ou alors au-delà du caractere 25
    			while ($seq =~ /(.*)\./){ #ne garde que ce qu'il y a avant le 1er point
    				$seq=$1;
    			}
    			if ($qual=~/$nam\n(.*)\n/){ #verifie le nom de read des QV associees
    										#puis trouve le minimum
    				$qValues=$1;
    				@tableQValues=split (/ /,$qValues);
    				$t=@tableQValues;
    				for ($r=length($seq); $r<$t-1;$r++){
    					pop (@tableQValues);
    				}
    				$smallest= min @tableQValues;
     
    				@readNum= split (//,$seq);
    				$tableNumSize= @readNum;
    				if ($nam=~ s/F3/.1/){ #change les fins d'en-tête de reads pour MEGAN
    					$transChar[0]=$readNum[0];
    				}
    				elsif ($nam=~ s/R3/.2/){ #change les fins d'en-tête de reads pour MEGAN
    					$transChar[0]=$readNum[0];
    				}
    				if (($smallest>$threshold)and($smallest<=$threshold2)){ # traduit, filtre si les QV sont > seuil pendant au moins 24 caracteres
    					$transString="";
    					for ($j=1;$j<$tableNumSize;$j++){ #traduit les sequences
    						$transChar[$j]=$transColor{$transChar[$j-1]}[$readNum[$j]];
    						$transString=$transString.$transChar[$j];
    					}
    					if (($transString=~ /(.*)AGAGTTTGAT$/) or ($transString=~ /^CCTGGCTCAG(.*)/) or ($transString=~/(.*)GACGGGCGGT$/) or ($transString=~/^GGTGWGTRCA(.*)/)){
    						if (length($1)>24){
    							$transString=$1;   #filtre les primers.
    						}
    						else {$discard++;
    							next;}
    					}
    					mkdir "$threshold-$threshold2";
    					open (TRANS, ">>$threshold-$threshold2/$ARGV[0]");
    					print TRANS ">$nam\n$transString\n";
    				}
    				else { $discard++;
    				}
    			}
    			else {print "ne trouve pas les qualV associees a $nam!"}
    		}
    		else {
    			$discard++;
    		}
    	}
    }
    print "threshold min: ".$threshold." threshold max: ".$threshold2." total discarded reads: ".$discard;
    Fichiers attachés Fichiers attachés

  4. #4
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 822
    Par défaut
    Rien qu'en regardant le programme, désolé de vous le dire, mais le code n'est vraiment pas propre, pas bien indenté (donc difficilement maintenable), et l'algorithme ne peut qu'amener à un out of memory.

    Voici les conseils que je peux vous donner :
    1- Tout code Perl doit commencer ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    use warnings;
    use strict;
    2- Indentez correctement votre code. Vous gagnerez en lisibilité et débogage.
    3- Revoyez vos façons de créer une table de hachage (pensez aux simple ou double quotes).
    4- En ce qui concerne la lecture de fichier, mettre tout un fichier dans une variable n'est pas judicieux, même pour de petits fichiers. Préférez toujours une lecture ligne à ligne tant que c'est possible.
    5- Pour l'algorithme, il faudrait nous montrer les 5 première lignes de chaque fichier pour que l'on puisse se donner une idée de ce que vous souhaitez faire.

    Voilà

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 8
    Par défaut
    Bonjour,

    Merci de votre réponse. Je réponds dans l'ordre:

    use warning: j'utilise l'option w à la toute première ligne du script (#!/usr/bin/perl -w), ça me paraissait tellement evident que je ne l'ai pas mise dans le code, excusez-moi.
    Use strict:... j'ai toujours vu comme un avantage de perl de ne pas avoir à déclarer les variables... mais si ça fait bugger, pas le choix.

    Indentation:J'indente à chaque if ou boucle et revient quand elle est finie.
    Que dois-je faire d'autre?

    Revoyez vos façons de créer une table de hachage (pensez aux simple ou double quotes)
    J'ai pas compris Où est-ce qu'on met les quotes, quand sont-elles simples et quand sont-elles doubles?

    Lecture ligne à ligne, je veux bien, mais on fait comment? J'ai cherché comment utiliser un fichier une fois ouvert et la plupart du temps, j'ai vu qu'on met tout dans un tableau.

    Voilà les 5 premiers reads de chaque fichier, donc les sequences et les qualités associées. Il peut également y avoir des points dans les séquences, dans ce cas la qualité associée est -1.

    séquences:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >186_731_1299_F3
    T11323102323103230233310232120131311331202311330330
    >186_731_1387_F3
    T30202013300311021002201120003023002330332010100123
    >186_731_1421_F3
    T11020223331332132320303001011131102022033200113300
    >186_731_1446_F3
    T11201001220231300220312312112202033301012103102132
    >186_731_1474_F3
    T22133233101231022330131201321332233220233203131001
    qualités:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >186_731_1299_F3
    32 33 33 33 30 33 33 33 33 29 33 33 32 31 31 32 27 31 31 28 33 32 31 28 29 27 32 31 29 21 33 32 32 31 29 33 31 32 32 31 29 30 32 30 28 30 29 16 16 16 
    >186_731_1387_F3
    18 10 8 10 8 17 10 20 14 17 4 33 6 12 20 27 17 8 21 14 22 10 14 33 10 12 6 8 17 29 16 14 10 31 21 4 22 12 30 33 4 8 25 20 27 14 21 21 13 23 
    >186_731_1421_F3
    33 33 32 25 33 32 33 33 26 33 33 33 32 33 33 29 32 31 28 31 32 31 33 16 33 29 33 29 9 31 29 32 27 20 29 33 29 23 24 33 33 28 12 8 30 26 31 14 15 31 
    >186_731_1446_F3
    33 33 33 33 33 32 33 33 32 33 33 33 33 33 30 33 32 33 31 28 32 22 33 26 31 20 28 31 32 32 30 18 32 11 33 19 31 31 31 30 10 24 31 16 30 32 22 32 4 24 
    >186_731_1474_F3
    33 33 33 33 33 33 33 33 33 32 32 33 33 32 33 31 29 33 33 33 33 33 32 28 32 32 33 28 32 32 32 25 19 31 33 26 26 29 26 31 33 32 31 31 24 33 11 13 22 25
    Merci

  6. #6
    Rédactrice

    Avatar de stoyak
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    408
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 408
    Par défaut
    Bonjour,

    Donc la première étape est de te familiariser avec le parsing de fichier, qui est le point central de tout travail bioinformatique.
    On ne met JAMAIS un fichier dans une unique variable!

    Donc voici une des manières d'écrire le traitement ligne à ligne d'un fichier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    my $File = "FileToRead.txt";
    open(FILE,'<',$File) || die "Impossible de lire le fichier $File\n";
    while (my $Line = <FILE>) {
        # Traitement ligne à ligne du fichier
    }
    close(FILE);

Discussions similaires

  1. Gros fichier mysql : out of memory
    Par xavier_dcf dans le forum Administration et Installation
    Réponses: 6
    Dernier message: 21/02/2013, 15h26
  2. Réponses: 16
    Dernier message: 03/05/2012, 14h22
  3. [SimpleXML] Analyser un très gros fichier XML
    Par Paulux1 dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 20/02/2008, 02h53
  4. Ouvrir un très gros fichier XML
    Par strat0 dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 02/11/2007, 13h29
  5. Transformer un très gros fichier XML avec XSL
    Par wozzz dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 30/05/2006, 10h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo