I created a caching algorithm for your data set. I'll reproduce it here, with comments.
It works like so. It determines the max value over the +/- 0.3 window for each mass in the range LOW - 0.3 to HIGH + 0.3, and it also remembers WHICH mass it found that intensity at. This way, when it gets to the next number, it knows where to start looking -- there's no need to look BEFORE the highest value for a higher value, since it would've been registered as the highest value.
my $cache = cacheMaxIntensity(\%massint);
sub cacheMaxIntensity {
my $mi = shift;
my ($min, $max);
# determine the maximum and minimum masses
# in the hash
while (my ($m) = each %$mi) {
$min = $m if not defined($min) or $min > $m;
$max = $m if not defined($max) or $max < $m;
}
# the "latest mass" is defined as the mass within a
# +/- 0.3 range with the highest intensity
my $latest = $min - 0.3;
my %cache = ();
# cycle through all the masses, including
# 3 less than the min and 3 greater than the max
for (my $m = $min - 0.3; $m <= $max + 0.3; $m += 0.1) {
# ensure "ABC.D" format (icky non-integers)
$m = sprintf("%.1f", $m);
# update the value of $latest if it's too
# far away from the current mass
$latest = sprintf("%.1f", $m - 0.3)
if $m - 0.3 > $latest;
# build the range (latest .. current + 0.3)
# of other masses to examine
for my $d (
map sprintf("%.1f", $_ / 10),
(10 * $latest) .. (10 * $m + 3)
) {
# set the cached intensity for this mass
# to the intensity for $d IF:
# there is an intensity for $d
# AND
# there is no cached intensity yet
# OR
# the intensity for $d is greater than
# the cached value
$cache{$m} = [ $mi->{$d}, $latest = $d ]
if exists $mi->{$d} and (
not($cache{$m}) or
$cache{$m}[0] < $mi->{$d}
);
}
}
# return a reference to the cache
return \%cache;
}
The corollary function, to get the maximum intensity in a range of +/- 0.3 mass, is rather simple:
my $max_I = maxIntensity($cache, $mass);
sub maxIntensity {
my ($c, $m) = @_;
return $c->{sprintf "%.1f", $m}[0];
}
I hope this helps. It took a bit of time for me to write the caching function, but it appears to hold up to my testing.
japhy --
Perl and Regex Hacker