3 %> @brief Peak detector.
5 %> This algorithm is a simplified version of [1]. What is referred to
as "noise" in the publication can be considered
as the @c minhei parameter.
8 %> [1] K. R. Coombes et al., Quality control and peak finding
for proteomics data collected from nipple aspirate fluid by surface-enhanced
9 %> laser desorption and ionization.,” Clinical chemistry, vol. 49, no. 10, pp. 1615-23, Oct. 2003.
12 %> @param y Vector of values.
13 %> @param minalt=0 Minimum altitude (distance from zero to montain top).
14 %> @param minhei=0 Minimum height (distance from highest foot (either left or right)) to mountain top.
15 %> @param mindist=1 Minimum horizontal distance between two peaks. Peak pruning based on
this is done in an iterative
16 %> way to keep the highest peak of a set of peaks too close to each other.
17 %> @
return Indexes of detected peaks
19 if ~exist('mindist', 'var')
22 if ~exist('minalt', 'var')
25 if ~exist('minhei', 'var')
35 if sum(y == Inf) == length(y)
38 y(y == Inf) = max(y(y ~= Inf));
53 if trend_ == 0 && i > 2
63 if trend > 0 && trend_last < 0
66 if y(idx_maybe)-y(i-1) > minhei
67 % last maximum will be a peak (unless not enough altitude, see below) because both feet are low
68 % enough (left foot already checked below).
70 % right foot becomes left foot for next peak. Left foot is only re-assigned when a peak is found.
71 % It is reassigned regardless of the peak being at enough altitude.
74 flag_maybe = 0; % last maximum found is not going to be a peak because right foot is too high
77 elseif trend < 0 && trend_last > 0
79 if y(i-1)-y(idx_foot1) > minhei
80 idx_maybe = i-1-floor(cnt0/2);
81 flag_maybe = 1; % the previous point may be a peak
89 if y(idx_maybe) >= minalt
90 no_peaks = no_peaks+1;
92 % efficient way to make idxs grow
96 idxs(no_peaks) = idx_maybe;
108 idxs = idxs(1:no_peaks);
113 %eliminates redundant peaks (too close to each other)
116 % idxs2(i) contains the distance between the i-th index and its predecessor
117 % idid contains the indexes of the indexes of the peaks that need to be checked
118 idxs2 = [Inf, diff(idxs)];
119 idid = find(idxs2 < mindist);
123 idid = union(idid, idid-1);
126 % Peaks will be checked per
block of adjacend peaks too close to each other
128 for i = numel(idid):-1:1
129 if idxs2(idid(i)) >= mindist
134 [dummy, idxmax] = max(y(idxs(idid(i1:i2))));
135 % once maximum is found, it will engulf its left and right peaks
137 idxs(idid(i1-1+idxmax+1)) = [];
140 idxs(idid(i1-1+idxmax-1)) = [];
154 idxs = idxs-1; % A zero element has been added at the beginning, hence the "-1"
function detect_peaks(in y, in minalt, in minhei, in mindist)
Analysis Session (AS) base class.