大家好我从酵母菌落板的图像中得到一些强度值。我需要能够从强度值中找到峰值。下面是一个示例图像,显示绘制时值的外观。
某些值的示例
5.7 5.3 8.2 16.5 34.2 58.8 **75.4** 75 65.9 62.6 58.6 66.4 71.4 53.5 40.5 26.8 14.2 8.6 5.9 7.7 14.9 30.5 49.9 69.1 **75.3** 69.8 58.8 57.2 56.3 67.1 69 45.1 27.6 13.4 8 5
这些值在75.4和75.3处显示两个峰值,您可以看到值增加然后减小。这种变化并不总是一样的。
强度值图表
http://lh4.ggpht.com/_aEDyS6ECO8s/THKTLgDPhaI/AAAAAAAAAio/HQW7Ut-HBhA/s400/peaks.png来自research我正在考虑的事情之一是将每个组(即哈希值)存储在哈希中,然后查找组中的最大值。如果我看到的问题是如何确定每个群体的边界,那就是一个。
这是我到目前为止的代码的链接: http://paste-it.net/public/y485822/
以下是指向完整数据集的链接: http://paste-it.net/public/ub121b4/
我在Perl中编写代码。任何帮助将不胜感激。谢谢
答案 0 :(得分:6)
您需要决定您希望峰值的本地化程度。这种方法可以在数据的广泛区域内找到峰值和谷值。
use strict;
use warnings;
my @data = (
5.7, 5.3, 8.2, 16.5, 34.2, 58.8, 75.4, 75, 65.9, 62.6,
58.6, 66.4, 71.4, 53.5, 40.5, 26.8, 14.2, 8.6, 5.9, 7.7,
14.9, 30.5, 49.9, 69.1, 75.3, 69.8, 58.8, 57.2, 56.3, 67.1,
69, 45.1, 27.6, 13.4, 8, 5,
);
# Determine mean. Or use Statistics::Descriptive.
my $sum;
$sum += $_ for @data;
my $mean = $sum / @data;
# Make a pass over the data to find contiguous runs of values
# that are either less than or greater than the mean. Also
# keep track of the mins and maxes within those groups.
my $group = -1;
my $gt_mean_prev = '';
my @mins_maxs;
my $i = -1;
for my $d (@data){
$i ++;
my $gt_mean = $d > $mean ? 1 : 0;
unless ($gt_mean eq $gt_mean_prev){
$gt_mean_prev = $gt_mean;
$group ++;
$mins_maxs[$group] = $d;
}
if ($gt_mean){
$mins_maxs[$group] = $d if $d > $mins_maxs[$group];
}
else {
$mins_maxs[$group] = $d if $d < $mins_maxs[$group];
}
$d = {
i => $i,
val => $d,
group => $group,
gt_mean => $gt_mean,
};
}
# A fun picture.
for my $d (@data){
printf
"%6.1f %2d %1s %1d %3s %s\n",
$d->{val},
$d->{i},
$d->{gt_mean} ? '+' : '-',
$d->{group},
$d->{val} == $mins_maxs[$d->{group}] ? '==>' : '',
'.' x ($d->{val} / 2),
;
}
输出:
5.7 0 - 0 ..
5.3 1 - 0 ==> ..
8.2 2 - 0 ....
16.5 3 - 0 ........
34.2 4 - 0 .................
58.8 5 + 1 .............................
75.4 6 + 1 ==> .....................................
75.0 7 + 1 .....................................
65.9 8 + 1 ................................
62.6 9 + 1 ...............................
58.6 10 + 1 .............................
66.4 11 + 1 .................................
71.4 12 + 1 ...................................
53.5 13 + 1 ..........................
40.5 14 - 2 ....................
26.8 15 - 2 .............
14.2 16 - 2 .......
8.6 17 - 2 ....
5.9 18 - 2 ==> ..
7.7 19 - 2 ...
14.9 20 - 2 .......
30.5 21 - 2 ...............
49.9 22 + 3 ........................
69.1 23 + 3 ..................................
75.3 24 + 3 ==> .....................................
69.8 25 + 3 ..................................
58.8 26 + 3 .............................
57.2 27 + 3 ............................
56.3 28 + 3 ............................
67.1 29 + 3 .................................
69.0 30 + 3 ..................................
45.1 31 + 3 ......................
27.6 32 - 4 .............
13.4 33 - 4 ......
8.0 34 - 4 ....
5.0 35 - 4 ==> ..
答案 1 :(得分:2)
my @data = ...;
# filter out sequential duplicate values
my @orig_index = 0;
my @deduped = $data[0];
for my $index ( 1..$#data ) {
if ( $data[$index] != $data[$index-1] ) {
push @deduped, $data[$index];
push @orig_index, $index;
}
}
# add a sentinel (works for both ends)
push @deduped, -9**9**9;
my @local_maxima_indexes;
for my $index ( 0..$#deduped-1 ) {
if ( $deduped[$index] > $deduped[$index-1] && $deduped[$index] > $deduped[$index+1] ) {
push @local_maxima_indexes, $orig_index[$index];
}
}
请注意,这会将第一个值视为局部最大值,也会将值视为71.4和69.我不确定您如何区分要包含的值。
答案 2 :(得分:2)
你有控制数据集吗?如果是这样,我建议使用say,酵母强度和对照图像之间的简单对数比例来标准化数据。
然后你可以使用perl port of ChiPOTle来获取重要的峰值,这听起来比搜索局部/全局最大值等更强大。
ChiPOTle“是一种用于分析ChIP芯片微阵列数据的峰值发现算法”,但我已经在许多其他应用中成功使用它(如ChIP-seq,它确实比您的情况更接近其原始用途) )。
得到的对数(酵母/对照)负值将用于构建用于显着性估计的高斯背景模型。然后,算法使用错误发现率进行多次测试校正。