Привет мастерам Perl в мире.
У меня еще одна проблема с программированием. Я кодирую программу, которая выбирает случайные последовательности из файла proteom fasta с определенным входным номером.
Общий фаст-файл выглядит так:
> seq_ID_1 описания и т. д. ASDGDSAHSAHASDFRHGSDHSDGEWTSHSDHDSHFSDGSGASGADGHHAH ASDSADGDASHDASHSAREWAWGDASHASGASGASGSDGASDGDSAHSHAS SFASGDASGDSSDFDSFSDFSD
> seq_ID_2 описания и т. д. ASDGDSAHSAHASDFRHGSDHSDGEWTSHSDHDSHFSDGSGASGADGHHAH ASDSADGDASHDASHSAREWAWGDASHASGASGASG
и так далее.......
Буквы обозначают пептиды аминокислот.
Итак, у меня есть файл fasta с 1000 последовательностями, и я хочу получить 63,21% из них, что будет 632,1 последовательности. Но последовательность не может быть числом с плавающей запятой, поэтому, если оно превышает 0,5, я хочу округлить, а если меньше 0,5, округлить вниз.
Это мой код для генерации подмножества случайной последовательности, но он немного не так хорош в работе.
#!/usr/bin/perl
#Selecting 63.21% of random sequnces from a proteom file.
use strict;
use warnings;
use List::Util qw(shuffle);
#Give the first argument as a proteom file.
if (@ARGV != 1)
{
print "Invalid arguments\n";
print "Usage: perl randseq.pl [proteom_file]";
exit(0);
}
my $FILE = $ARGV[0];
my $i = 0;
my %protseq = {};
my $nIdx = 0;
#Extraction and counting of the all headers from a proteom file.
open(LIST,$FILE);
open(TEMP1, ">temp1");
while (my $line = <LIST>){
chomp $line;
if ($line =~ />(\S+) (.+)/){
$i++;
print TEMP1 $1,"\n";
}
}
close(LIST);
close(TEMP1);
#Selection of random headers for generating a random subset of the proteom file.
my $GET_LINES = RoundToInt ($i*0.6321);
my @line_starts;
open(my $FH,'<','temp1');
open(TEMP2, ">temp2");
do {
push @line_starts, tell $FH
} while ( <$FH> );
my $count = @line_starts;
my @shuffled_starts = (shuffle @line_starts)[1..$GET_LINES+1];
for my $start ( @shuffled_starts ) {
seek $FH, $start, 0
or die "Unable to seek to line - $!\n";
print TEMP2 scalar <$FH>;
}
close(TEMP2);
#Assigning the sequence data to randomly generated header file.
open(DATA,'<','temp2');
while(my $line = <DATA>)
{
chomp($line);
$line =~ s/[\t\s]//g;
if($line =~ /^([^\s]+)/)
{
$protseq{$1}++;
}
}
close(DATA);
open(DATA, "$FILE");
open(OUT, ">random_seqs.fasta");
while(my $line = <DATA>)
{
chomp($line);
if($line =~ /^>([^\s]+)/)
{
if($protseq{$1} ne "")
{
$nIdx = 1;
print OUT "$line\n";
}
else
{
$nIdx = 0;
}
}
else
{
if($nIdx == 1)
{
print OUT "$line\n";
}
}
}
close(DATA);
close(OUT);
#subroutine for rounding
sub RoundToInt {
int($_[0] + .5 * ($_[0] <=> 0));
}
system("erase temp1");
system("erase temp2");
exit;
Однако иногда он дает правильное количество последовательностей, а иногда и еще одну последовательность. Как я могу избавиться от этого ... какие-нибудь идеи, пожалуйста?
или может лучше код покороче?
здесь вы можете получить 75 протеомных файлов дрожжей. [http://www.peroxisomedb.org/Download/Saccharomyces_cerevisiae.fas visible[1]
Надеюсь, я скоро это исправлю ... :(
int($float + 0.5)
, как рекомендовано в этом вопросе. - person learner   schedule 21.03.2013[1..$GET_LINES+1];
? Если я что-то не понимаю,$i
- это int = length (FASTA seqs), так почему вы планируете еще одну строку? - person learner   schedule 21.03.2013$GET_LINES
сам по себе правильным номером для данного файла, просто добавив вызовprint()
. Я думаю, это будет правильно - вы начинаете с 0, и когда вы встречаетесь с первой строкой, у вас есть 1, 2 во второй и т. Д., Просто глядя на свой цикл for. - person learner   schedule 21.03.2013if ($line =~ />(\S+) (.+)/)
? - person iain   schedule 21.03.2013