需要Perl中峰值信号检测的帮助吗

需要Perl中峰值信号检测的帮助吗,perl,signal-processing,bioinformatics,Perl,Signal Processing,Bioinformatics,大家好,我有一些酵母菌落平板图像的强度值。我需要能够从强度值中找到峰值。下面是一个示例图像,显示了绘制图形时值的外观 某些值的示例 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 5.7 5.3 8.2

大家好,我有一些酵母菌落平板图像的强度值。我需要能够从强度值中找到峰值。下面是一个示例图像,显示了绘制图形时值的外观

某些值的示例

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 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处显示两个峰值,可以看到值先增大后减小。变化并不总是一样的

强度值图表

从…起 我想做的一件事是将每个组(即山)存储在散列中,然后查找组中的最大值。我看到的一个问题是如何确定每个群体的边界

以下是到目前为止我所掌握的代码的链接:

以下是指向完整数据集的链接:


我正在用Perl编写代码。任何帮助都将不胜感激。谢谢你

你需要决定你想要的山峰的局部性。这里的方法可以在数据的广泛区域内找到波峰和波谷

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),
    ;

请注意,这将第一个值视为局部最大值,也将值71.4和69视为局部最大值。我不确定您是如何区分要包括哪些数据的。

您有控制数据集吗?如果是这样,我建议您使用酵母强度和对照图像之间的简单对数比率来规范化数据

然后,您可以使用获取显著峰值,这听起来比搜索局部/全局最大值等更为稳健

ChiPOTle“是一种用于分析芯片微阵列数据的峰值查找算法”,但我已经在许多其他应用中成功地使用了它(比如ChIP seq,无可否认,它比您的情况更接近其原始目的)

产生的对数(酵母/对照)负值将用于建立高斯背景模型进行显著性估计。然后,该算法使用错误发现率进行多次测试校正


.

我相信,如果你能展示出你目前遇到问题的代码,而不是让别人为你提供算法和代码,你会得到更多的帮助。您的样本代码可能包含样本数据数组,以及您希望返回的峰值的预期结果。仅供参考,您从原始数据的开头删除了几个数据点。嗨,Pedro,我所做的是拍摄酵母平板的照片,将其转换为矩阵,然后查看强度值。然后将这些值绘制成图表,峰值表示有菌落的区域。在这种情况下,没有控制数据集。我正在看ChiPOTle谢谢!
   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  ==>  ..
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];
    }
}