2013-03-04 5 views
5

Sono nuovo di perl e vorrei fare ciò che ritengo sia una manipolazione di stringa di base alle sequenze di DNA memorizzate in un file rtf.regex di base e manipolazione di stringhe per l'analisi del DNA utilizzando perl

In sostanza, il mio file legge (file è in formato FASTA):

>LM1 
AAGTCTGACGGAGCAACGCCGCGTGTATGAAGAAGGTTTTCGGATCGTAA 
AGTACTGTCCGTTAGAGAAGAACAAGGATAAGAGTAACTGCTTGTCCCTT 
GACGGTATCTAACCAGAAAGCCACGGCTAACTACGTGCCAGCAGCCGCGG 
TAATACGTAGGTGGCAAGCGTTGTCCGGATTTATTGGGCGTAAAGCGCGC 
GCAGGCGGTCTTTTAAGTCTGATGTGAAAGCCCCCGGCTTAACCGGGGAG 
GGTCATTGGAAACTGGAAGACTGGAGTGCAGAAGAGGAGAGTGGAATTCC 
ACGTGTAGCGGTGAAATGCGTAGATATGTGGAGGAACACCAGTGGCGAAG 
GCGACTCTCTGGTCTGTAACTGACGCTGAGGCGCGAAAGCGTGGGGAGCA 
AACAGGATTAGATACCCTGGTAGTCCACGCCGT 

Quello che vorrei fare è leggere nel mio file e stampare l'intestazione (intestazione è> LM1) poi abbinare il seguente DNA sequenza GTGCCAGCAGCCGC e quindi stampare la sequenza di DNA precedente.
Così la mia uscita sarebbe simile a questa:

>LM1 
AAGTCTGACGGAGCAACGCCGCGTGTATGAAGAAGGTTTTCGGATCGTAA 
AGTACTGTCCGTTAGAGAAGAACAAGGATAAGAGTAACTGCTTGTCCCTT 
GACGGTATCTAACCAGAAAGCCACGGCTAACTAC 

Ho scritto il seguente programma:

#!/usr/bin/perl 

use strict; use warnings; 

open(FASTA, "<seq_V3_V6_130227.rtf") or die "The file could not be found.\n"; 

while(<FASTA>) { 
    chomp($_); 
    if ($_ =~ m/^>/) { 
     my $header = $_; 
     print "$header\n"; 
    } 

    my $dna = <FASTA>; 
    if ($dna =~ /(.*?)GTGCCAGCAGCCGC/) { 
     print "$dna"; 
    } 

} 
close(FASTA); 

Il problema è che il mio programma legge il file riga per riga e l'output che sto ricevendo è la seguente:

>LM1 
GACGGTATCTAACCAGAAAGCCACGGCTAACTAC 

Fondamentalmente io non so come assegnare l'intera sequenza del DNA per la mia variabile $ DNA e in ultima analisi, non so come per evitare di leggere la sequenza del DNA riga per riga. Sto ricevendo questo avviso: Uso del valore non inizializzato $ dna nella corrispondenza del modello (m //) nella riga stacked.pl 14, riga 1113.

Se qualcuno potrebbe darmi un aiuto con la scrittura di codice migliore o punto me nella direzione corretta sarebbe molto apprezzato.

+0

Non sei bioinformatico i ragazzi hanno già delle librerie già esistenti per fare queste cose? Riceviamo molte domande di regex sul DNA + e penserei che ci sarebbero già delle librerie testate per far fronte a questo già. –

+0

Prova a cercare StackOverflow per "fasta perl". Ci sono molte domande che sembrano essere da persone che si occupano esattamente dei tuoi problemi. http://stackoverflow.com/search?q=fasta+perl –

+0

@AndyLester È vero che esistono biblioteche che si occupano di questa roba ma tanta parte della bioinformatica deve essere adattata alle tue esigenze specifiche, il che rende difficile trovare il programma ottimale. Grazie per il tuo suggerimento, guarderò sotto Fasta Perl. – cebach561

risposta

3

Utilizzando la pos function:

use strict; 
use warnings; 

my $dna = ""; 
my $seq = "GTGCCAGCAGCCGC"; 
while (<DATA>) { 
    if (/^>/) { 
    print; 
    } else { 
    if (/^[AGCT]/) { 
     $dna .= $_; 
    } 
    } 

} 

if ($dna =~ /$seq/g) { 
    print substr($dna, 0, pos($dna) - length($seq)), "\n"; 
} 

__DATA__ 
>LM1 

AAGTCTGACGGAGCAACGCCGCGTGTATGAAGAAGGTTTTCGGATCGTAA 
AGTACTGTCCGTTAGAGAAGAACAAGGATAAGAGTAACTGCTTGTCCCTT 
GACGGTATCTAACCAGAAAGCCACGGCTAACTACGTGCCAGCAGCCGCGG 
TAATACGTAGGTGGCAAGCGTTGTCCGGATTTATTGGGCGTAAAGCGCGC 
GCAGGCGGTCTTTTAAGTCTGATGTGAAAGCCCCCGGCTTAACCGGGGAG 
GGTCATTGGAAACTGGAAGACTGGAGTGCAGAAGAGGAGAGTGGAATTCC 
ACGTGTAGCGGTGAAATGCGTAGATATGTGGAGGAACACCAGTGGCGAAG 
GCGACTCTCTGGTCTGTAACTGACGCTGAGGCGCGAAAGCGTGGGGAGCA 
AACAGGATTAGATACCCTGGTAGTCCACGCCGT 

È possibile elaborare un file con più voci in questo modo:

while (<DATA>) { 
    if (/^>/) { 
    if ($dna =~ /$seq/g) { 
     print substr($dna, 0, pos($dna) - length($seq)), "\n"; 
     $dna = ""; 
    } 
    print; 
    } elsif (/^[AGCT]/) { 
    $dna .= $_; 
    } 
} 

if ($dna && $dna =~ /$seq/g) { 
    print substr($dna, 0, pos($dna) - length($seq)), "\n"; 
} 
+0

Grazie, perreal. Funziona molto bene quando ho una sequenza come> LM1 AAGT ... Compra come posso cambiare il programma per gestire più intestazioni e sequenze come:> LM1 AAGT ...> LM2 AGTC ...> LM3 ACGG .. . e così via? – cebach561

+0

aggiornato la risposta – perreal

+0

Non vedo come si arriva al secondo 'elsif '. Solitamente le file file fasta iniziano con un '>', (un id) o una serie di caratteri 'ATGC'. Non ci dovrebbero essere righe vuote in un file fasta. –

0

leggere l'intero file in memoria per poi cercare l'espressione regolare

while(<FASTA>) { 
    chomp($_); 
    if ($_ =~ m/^>/) { 
     my $header = $_; 
     print "$header\n"; 
    } else { 
    $dna .= $_; 
    } 
} 
if ($dna =~ /(.*?)GTGCCAGCAGCCGC/) { 
    print $1; 
} 
+0

Ho modificato la risposta perché mancava una parentesi graffa di chiusura. Indipendentemente da ciò, è necessario stampare la corrispondenza raggruppata della regex, '$ 1', non' $ dna'. E la stringa ha perso il formato senza caratteri '\ n' originali. Non lo so che è importante per risolvere il problema, ma potrebbe essere un problema per l'OP. – Birei

+0

grazie birei, l'ho ottimizzato per non stampare $ dna – Vorsprung

2

L'istruzione while dura fino alla fine del file. Ciò significa che ad ogni ciclo iterativo, $ _ è la riga successiva in <FASTA>. Quindi $dna = <FASTA> non sta facendo quello che pensi sia. Sta leggendo più di quanto tu probabilmente lo desideri.

while(<FASTA>) { #Reads a line here 
    chomp($_); 
    if ($_ =~ m/^>/) { 
    my $header = $_; 
    print "$header\n"; 
    } 
    $dna = <FASTA> # reads another line here - Causes skips over every other line 
} 

Ora, è necessario leggere la sequenza nella vostra $dna. Puoi aggiornare il tuo ciclo while con un'istruzione else. Quindi se è una linea principale, stampala, altrimenti la aggiungiamo a $dna.

while(<FASTA>) { 
    chomp($_); 
    if ($_ =~ m/^>/) { 
    # It is a header line, so print it 
    my $header = $_; 
    print "$header\n"; 
    } else { 
    # if it is not a header line, add to your dna sequence. 
    $dna .= $_; 
    } 
} 

Dopo il ciclo, è possibile eseguire l'espressione regolare.

Nota: questa soluzione presuppone che ci sia solo una sequenza nel file fasta. Se ne hai più di una, la tua variabile $dna avrà tutte le sequenze come una.

Edit: L'aggiunta di semplice un modo per gestire più sequenze

my $dna = ""; 
while(<FASTA>) { 
    chomp($_); 
    if ($_ =~ m/^>/) { 

    # Does $dna match the regex? 
    if ($dna =~ /(.*?)GTGCCAGCAGCCGC/) { 
     print "$1\n"; 
    } 

    # Reset the sequence 
    $dna = ""; 

    # It is a header line, so print it 
    my $header = $_; 
    print "$header\n"; 

    } else { 
    # if it is not a header line, add to your dna sequence. 
    $dna .= $_; 
    } 
} 

# Check the last sequence 
if ($dna =~ /(.*?)GTGCCAGCAGCCGC/) { 
    print "$1\n"; 
} 
+0

Nate, grazie per la risposta. Cosa succede se ho più di una sequenza nel file fasta? Quindi sembra questo:> LM1 ATGC ...> LM2 ACGG ...> LM3 ATTG ... e così via. – cebach561

+0

@ user2133248 - Ho aggiunto un modo semplice per farlo. L'idea è il controllo se la sequenza '$ dna' corrisponde alla regex ogni volta che vedi un'> '. Quindi lo fai ancora una volta dopo il ciclo per controllare l'ultima sequenza. – Nate

2

mi si avvicinò con una soluzione che utilizza BioSeqIO (e il metodo trunc dal BioSeq dalla distribuzione BioPerl Ho anche usato index per trovare la sottosequenza piuttosto. che usare un'espressione regolare.

Questa soluzione non stampare il id, (riga inizia con>), se la sottosequenza non è stato trovato oppure se la sottosequenza inizia alla prima posizione, (e quindi nessun carattere precedente).

#!/usr/bin/perl 
use strict; 
use warnings; 
use Bio::SeqIO; 

my $in = Bio::SeqIO->new(-file => "fasta_junk.fasta" , 
          -format => 'fasta'); 

my $out = Bio::SeqIO->new(-file => '>test.dat', 
          -format => 'fasta'); 

my $lookup = 'GTGCCAGCAGCCGC'; 

while (my $seq = $in->next_seq()) { 
    my $pos = index $seq->seq, $lookup; 

    # if $pos != -1, ($lookup not found), 
    # or $pos != 0, (found $lookup at first position, thus 
    # no preceding characters). 
    if ($pos > 0) { 
     my $trunc = $seq->trunc(1,$pos); 
     $out->write_seq($trunc); 
    } 
} 

__END__ 
*** fasta_junk.fasta 
>LM1 
AAGTCTGACGGAGCAACGCCGCGTGTATGAAGAAGGTTTTCGGATCGTAA 
AGTACTGTCCGTTAGAGAAGAACAAGGATAAGAGTAACTGCTTGTCCCTT 
GACGGTATCTAACCAGAAAGCCACGGCTAACTACGTGCCAGCAGCCGCGG 
TAATACGTAGGTGGCAAGCGTTGTCCGGATTTATTGGGCGTAAAGCGCGC 
GCAGGCGGTCTTTTAAGTCTGATGTGAAAGCCCCCGGCTTAACCGGGGAG 
GGTCATTGGAAACTGGAAGACTGGAGTGCAGAAGAGGAGAGTGGAATTCC 
ACGTGTAGCGGTGAAATGCGTAGATATGTGGAGGAACACCAGTGGCGAAG 
GCGACTCTCTGGTCTGTAACTGACGCTGAGGCGCGAAAGCGTGGGGAGCA 
AACAGGATTAGATACCCTGGTAGTCCACGCCGT 

*** contents of test.dat 
>LM1 
AAGTCTGACGGAGCAACGCCGCGTGTATGAAGAAGGTTTTCGGATCGTAAAGTACTGTCC 
GTTAGAGAAGAACAAGGATAAGAGTAACTGCTTGTCCCTTGACGGTATCTAACCAGAAAG 
CCACGGCTAACTAC 
+0

Hey Chris grazie per il tuo aiuto. Non ho BioPerl installato sul mio computer, ma una volta che lo faccio controllerò questo programma. – cebach561

Problemi correlati