2013-03-04 9 views
5

Jestem nowym użytkownikiem języka Perl i chciałbym zrobić coś, co moim zdaniem jest podstawową manipulacją ciągami do sekwencji DNA przechowywanych w pliku rtf.podstawowe manipulowanie ciągiem i ciągiem dla analizy DNA przy użyciu perl

Zasadniczo mój plik czyta (plik jest w formacie FASTA):

>LM1 
AAGTCTGACGGAGCAACGCCGCGTGTATGAAGAAGGTTTTCGGATCGTAA 
AGTACTGTCCGTTAGAGAAGAACAAGGATAAGAGTAACTGCTTGTCCCTT 
GACGGTATCTAACCAGAAAGCCACGGCTAACTACGTGCCAGCAGCCGCGG 
TAATACGTAGGTGGCAAGCGTTGTCCGGATTTATTGGGCGTAAAGCGCGC 
GCAGGCGGTCTTTTAAGTCTGATGTGAAAGCCCCCGGCTTAACCGGGGAG 
GGTCATTGGAAACTGGAAGACTGGAGTGCAGAAGAGGAGAGTGGAATTCC 
ACGTGTAGCGGTGAAATGCGTAGATATGTGGAGGAACACCAGTGGCGAAG 
GCGACTCTCTGGTCTGTAACTGACGCTGAGGCGCGAAAGCGTGGGGAGCA 
AACAGGATTAGATACCCTGGTAGTCCACGCCGT 

Co chciałbym zrobić, to przeczytać w moim pliku i drukować nagłówek (header jest> LM1), a następnie dopasować następujący DNA sekwencja GTGCCAGCAGCCGC, a następnie wydrukuj poprzednią sekwencję DNA.
Więc moje wyjście będzie wyglądać następująco:

>LM1 
AAGTCTGACGGAGCAACGCCGCGTGTATGAAGAAGGTTTTCGGATCGTAA 
AGTACTGTCCGTTAGAGAAGAACAAGGATAAGAGTAACTGCTTGTCCCTT 
GACGGTATCTAACCAGAAAGCCACGGCTAACTAC 

Napisałem następujący program:

#!/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); 

Problem polega na tym, że mój program odczytuje pliku linia po linii, a wyjście otrzymuję jest co następuje:

>LM1 
GACGGTATCTAACCAGAAAGCCACGGCTAACTAC 

w zasadzie nie wiem jak przypisać całą sekwencję DNA do mojego zmiennej $ DNA i ostatecznie nie wiem jak aby uniknąć czytania sekwencji sekwencji DNA po linii. Otrzymuję również ostrzeżenie: Użycie niezainicjowanej wartości $ dna w dopasowaniu wzorca (m //) w linii stacked.pl 14, wiersz 1113.

Jeśli ktoś mógłby mi pomóc w napisaniu lepszego kodu lub wskazaniu mi w odpowiednim kierunku byłoby to bardzo cenne.

+0

Czy nie bioinformatyki faceci mają biblioteki już istniejące, aby robić te rzeczy? Otrzymujemy wiele pytań dotyczących + regex DNA i myślę, że istniałyby już przetestowane biblioteki, które poradzą sobie z tym już. –

+0

Spróbuj wyszukać StackOverflow dla "fasta perl". Jest wiele pytań, które wydają się być od osób zajmujących się dokładnie twoimi problemami. http://stackoverflow.com/search?q=fasta+perl –

+0

@AndyLester To prawda, że ​​biblioteki zajmujące się tymi sprawami istnieją, ale tak wiele bioinformatyki musi być dostosowanych do twoich konkretnych wymagań, co utrudnia znalezienie optymalnego programu. Dzięki za twoją sugestię, zajrzę pod fasta perl. – cebach561

Odpowiedz

3

Używanie 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 

można przetworzyć plik z wieloma wpisami tak:

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

Dziękuję, perreal. Działa to bardzo dobrze, gdy mam jedną sekwencję, na przykład> LM1 AAGT ... Kupuję, jak mogę zmienić program, aby obsługiwał wiele nagłówków i sekwencji, takich jak:> LM1 AAGT ...> LM2 AGTC ...> LM3 ACGG .. . i tak dalej? – cebach561

+0

zaktualizował odpowiedź – perreal

+0

Nie widzę, jak to możliwe, aby dostać się do drugiego "elsif". Zwykle linie plików fasta zaczynają się od znaku ">", (id) lub serii znaków "ATGC". W pliku fasta nie powinny być puste linie. –

0

przeczytać cały plik do pamięci, a następnie szukać regexp

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

Edytowałem odpowiedź, ponieważ brakowało nawiasu klamrowego. Niezależnie od tego musisz wydrukować pogrupowane dopasowanie wyrażenia regularnego, "$ 1", a nie "$ dna". Ciąg tracił format bez oryginalnych znaków '\ n'. Nie wiem, czy to ma znaczenie dla rozwiązania problemu, ale może być problemem dla PO. – Birei

+0

dzięki birei, poprawiłem go, aby nie drukować $ dna – Vorsprung

2

Instrukcja Your while czyta do końca pliku. Oznacza to, że przy każdej iteracji pętli, $ _ jest następną linią w <FASTA>. Tak więc $dna = <FASTA> nie robi tego, co myślisz, że jest. Czyta więcej niż prawdopodobnie tego chcesz.

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 
} 

Teraz należy przeczytać sekwencję w swoim numerze $dna. Możesz zaktualizować pętlę while za pomocą instrukcji else. Więc jeśli jest to linia nagłówkowa, wydrukuj ją, w przeciwnym razie dodamy ją do $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 .= $_; 
    } 
} 

Po pętli możesz zrobić swoje wyrażenie regularne.

Uwaga: to rozwiązanie zakłada, że ​​w pliku fasta znajduje się tylko 1 sekwencja. Jeśli masz więcej niż jeden, twoja zmienna $dna będzie miała wszystkie sekwencje jako jedna.

Edycja: Dodawanie prosty sposób obsługiwać wiele sekwencji

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, dziękuję za odpowiedź. Co jeśli mam więcej niż jedną sekwencję w pliku fasta? Wygląda więc tak:> LM1 ATGC ...> LM2 ACGG ...> LM3 ATTG ... i tak dalej. – cebach561

+0

@ user2133248 - Dodałem prosty sposób, aby to zrobić. Pomysł polega na sprawdzeniu, czy sekwencja '$ dna' pasuje do wyrażenia regularnego za każdym razem, gdy zobaczysz'> '. Następnie robisz to jeszcze raz po pętli, aby sprawdzić ostatnią sekwencję. – Nate

2

wymyśliłem rozwiązanie używając BioSeqIO (i metody trunc z BioSeq z dystrybucją BioPerl użyłem również index znaleźć podciąg raczej. niż przy użyciu wyrażenia regularnego:

To rozwiązanie nie drukuje id, (linia zaczyna się od>), jeśli podciąg nie został znaleziony lub podciąg zaczyna się od pierwszej pozycji (a więc bez poprzedzających znaków).

#!/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

Hej Chris, dzięki za pomoc. Nie mam zainstalowanego BioPerl na moim komputerze, ale gdy to zrobię, sprawdzę ten program. – cebach561

Powiązane problemy