此代码的总体目标是在每个DNA序列中找到基序(较小序列),该基序将基于对数奇数评分矩阵报告最大对数奇数分数。我正在搜索的.txt文件如下所示:
>Sequence 1
TCGACGATCAGACAG
>Sequence 2
TGGGACTTGCACG
....依此类推。
目前,我正在代码的最大化步骤上,我正在努力计算DNA序列中基序的对数比分。我有创建对数得分矩阵的代码-参见以下内容:
#!/usr/bin/perl -w
#Above line used in Unix and Linux
#Grome Programming Assignment 2
#E-M
use strict;
use warnings;
# usage: script.pl {motif_width} {dnafile}
#USER SPECIFICATIONS
print "Please enter the filename of the fasta sequence data: ";
my $filename1 = <STDIN>;
#Remove newline from file
chomp $filename1;
#Open the file and store each dna seq in hash
my %id2seq = ();
my $id = '';
open (FILE, '<', $filename1) or die "Cannot open $filename1.",$!;
my $dna;
while (<FILE>)
{
if($_ =~ /^>(.+)/)
{
$id = $1;
}
else
{
$id2seq{$id} .= $_;
}
}
close FILE;
foreach $id (keys %id2seq)
{
print "$id2seq{$id}\n\n";
}
#User specifies motif width
print "Please enter the motif width:\n";
my $width = <STDIN>;
#Remove newline from file
chomp $width;
#Default width is 3 (arbitrary number chosen)
if ($width eq '')
{
$width = 3;
}
elsif ($width <=0)
{
print "Please enter a number greater than zero:\n";
$width = <STDIN>;
chomp $width;
}
#User specifies number of initial random
#starting alignments
print "Please enter the number of initial random
starting alignments:\n";
my $start = <STDIN>;
#Remove newline from file
chomp $start;
#Default start is 50
if ($start eq '')
{
$start = 50;
}
elsif ($start <=0)
{
print "Please enter a number greater than zero:\n";
$start = <STDIN>;
chomp $start;
}
#User specifies number of iterations to
#perform expectation-maximization
print "Please enter the number of iterations for
expectation-maximization:\n";
my $iteration = <STDIN>;
#Remove newline from file
chomp $iteration;
#Default iteration = 500
if($iteration eq '')
{
$iteration = 500;
}
elsif ($iteration <=0)
{
print "Please enter a number greater than zero:\n";
$iteration = <STDIN>;
chomp $iteration;
}
#EXPECTATION
#Initialize counts for motif positions
#Incorporate pseudocounts initially
my %mot = map { $_ => [ (1) x $width ] } qw( A C G T );
# Initialize background counts
my %bg = map { $_ => 0 } qw( A C G T );
#Fill background and motif counts
foreach $id (keys %id2seq)
{
#Generate random start site in the sequence
#for motif to start from
my $ms = int(rand(length($id2seq{$id})-$width));
# Within a motif, count the bases at the positions
for my $pos (0..length($id2seq{$id})-1)
{
my $base = substr($id2seq{$id}, $pos, 1);
if ($pos >= $ms && $pos < $ms + $width)
{
++$mot{$base}[$pos-$ms]
if exists($mot{$base});
}
else
{
++$bg{$base}
if exists($bg{$base});
}
}
}
#Print the background and motif counts
for my $base (qw( A C G T ))
{
print "$base @{$mot{$base}}\n";
}
print "\n";
for my $base (qw( A C G T ))
{
print "bg$base = $bg{$base}\n";
}
#Create frequency table of the motifs
#Get sum of the background
my $bgsum = 0;
for my $base (qw( A C G T))
{
$bgsum = $bgsum + $bg{$base};
}
print "\n$bgsum\n\n";
#Create background frequency table
my %bgfreq = map { $_ => 0 } qw( A C G T );
for my $base (qw( A C G T))
{
$bgfreq{$base} = $bg{$base} / $bgsum;
print "bgfreq$base = $bgfreq{$base}\n";
}
#Get sum of each motif position
my @motsum = ( (0) x $width );
for my $base (qw( A C G T))
{
for my $arrpos (0.. ($width-1))
{
$motsum[$arrpos] = $motsum[$arrpos] + @{$mot{$base}}[$arrpos];
}
}
#Create motif frequency table
my %motfreq = map { $_ => [ (0) x $width ]} qw( A C G T );
for my $base (qw( A C G T))
{
for my $arrpos (0.. ($width-1))
{
$motfreq{$base}[$arrpos] = $mot{$base}[$arrpos] / $motsum[$arrpos];
}
print "motfreq$base @{$motfreq{$base}}\n";
}
#Create odds table of motifs
my %odds = map { $_ => [ (0) x ($width) ]} qw( A C G T );
for my $base (qw( A C G T))
{
for my $arrpos (0.. ($width-1))
{
$odds{$base}[$arrpos] = $motfreq{$base}[$arrpos] / $bgfreq{$base};
}
print "odds$base @{$odds{$base}}\n";
}
#Create log-odds table of motifs
my %logodds = map { $_ => [ (0) x ($width) ]} qw( A C G T );
for my $base (qw( A C G T))
{
for my $arrpos (0.. ($width-1))
{
$logodds{$base}[$arrpos] = log2($odds{$base}[$arrpos]);
}
print "logodds$base @{$logodds{$base}}\n";
}
#####################################################
sub log2
{
my $n = shift;
return log($n)/log(2);
}
现在,我需要计算每个DNA序列中基序的对数比分。然后,我将遍历序列中所有可能的位置,并找到每个序列的最高分。未来的工作需要我回忆起具有最高分的主题,但是我还没有尝试过(只是想给这些最高分提供范围)。
策略:我将创建一个对数分数和最高分数的哈希值,以保留迭代时每个序列的最高分数。为了计算对数得分,我将看到对数得分矩阵中的哪个元素与主题中的元素匹配。
#MAXIMIZATION
#Determine location for each sequence that maximally
#aligns to the motif pattern
#Calculate logodds for the motif
#Create hash of logodds scores and hash of maxscores
#so each id has a logodds score and max score
my %loscore = map { $_ => [ (0) x (length($id2seq{$id})-$width) ]} qw( $id ); #Not sure if $id is correct, but I want a loscore for each $id
my %maxscore = map { $_ => [ (0) x (length($id2seq{$id})-$width) ]} qw( $id ); #Not sure if $id is correct, but I want a maxscore for each $id
foreach $id (keys %loscore, %maxscore, %id2seq)
{
my $len = length($id2seq{$id});
for my $base (qw( A C G T ))
{
for my $pos (0..$len-1)
{
if ($id2seq{$id}[$pos] = $mot{$base})
{
for my $motpos (0..$width-1)
{
$loscore{$id} = $loscore{$id} + $logodds{$base}[$motpos];
if ($loscore{$id} > $maxscore{$id})
{
$maxscore{$id} = $loscore{$id};
}
}
}
}
}
print "$id2seq{$id} logodds score: $maxscore{$id}\n";
}
#####################################################
sub log2
{
my $n = shift;
return log($n)/log(2);
}
当我从运行中取消注释最大化步骤时,没有显示任何内容。我没有收到任何错误,但是没有新的打印。我知道可以简化我的期望步骤(在工作完成后,我会清理所有内容),但是我首先关注此最大化步骤。我知道最大化代码中存在很多缺陷,尤其是在尝试创建对数得分和最大得分哈希值时。任何输入都可以帮助您!预先感谢您的耐心和建议。让我知道您是否需要任何澄清。
答案 0 :(得分:0)
foreach $id (keys %loscore, %maxscore, %id2seq)
不会遍历所有三个哈希。您可能是说foreach $id (keys %loscore, keys %maxscore, keys %id2seq)
if ($id2seq{$id}[$pos] = $mot{$base})
将该值分配给$id2seq{$id}[$pos]
。要检查是否相等,您需要if ($id2seq{$id}[$pos] eq $mot{$base})
。但这也可能是错误的,因为$id2seq{$id}
应该是字符串,而$mot{$base}
是数组。
尚不清楚代码应如何工作,很难在如此长的代码示例中发现错误。