48 arma::vec &peak_magnitudes)
50 arma::uvec peak_indices;
51 arma::uvec peak_locations;
52 peak_magnitudes = arma::zeros(X.n_rows, 1);
54 dX.elem( find(dX == 0) ).fill(-arma::datum::eps);
55 double minimum_magnitude = X.min();
56 double left_min = X(0);
57 arma::uword length = X.n_elem;
58 arma::uword temporary_location = 0;
61 arma::uvec extrema_indices = find( (dX.subvec(0, length - 2) % dX.subvec(1, length - 1) )< 0);
62 arma::vec X_extrema = X.elem(extrema_indices);
63 length = X_extrema.n_elem;
64 double temporary_magnitude = minimum_magnitude;
65 bool peak_found =
false;
77 temporary_magnitude = minimum_magnitude;
81 if ( (X_extrema(ii) > temporary_magnitude) && (X_extrema(ii) > left_min + sel) ){
82 std::cout <<
"temporary_location = " << ii << std::endl;
83 temporary_magnitude = X_extrema(ii);
91 if (!peak_found && (temporary_magnitude > sel + X_extrema(ii) ) ){
93 std::cout <<
"peak found!" << std::endl;
94 left_min = X_extrema(ii);
95 peak_locations << temporary_location;
97 else if(X(ii) < left_min)
98 left_min = X_extrema(ii);
106 arma::vec results = arma::zeros(X.n_elem, 1);
107 peak_indices = extrema_indices.elem(peak_locations);
108 results.elem(peak_indices).ones();
109 peak_magnitudes.elem(peak_indices) = X(peak_indices);
113 arma::uvec indices = find(peak_magnitudes <= threshold);
114 peak_magnitudes.elem(indices).zeros();
115 results.elem(indices).zeros();
133 arma::mat peak_locations(X.n_rows, X.n_cols);
134 peak_magnitudes.set_size(X.n_rows, X.n_cols);
138 arma::vec thresh(X.n_cols);
139 arma::vec sels(X.n_cols);
140 if (std::isnan(sel)){
141 for (arma::uword i = 0; i < X.n_cols; ++i){
142 sels(i) = (X.col(i).max() - X.col(i).min() ) / 16.0;
149 if (std::isnan(threshold)){
150 arma::uword k = (X.n_rows % 2 == 0 ? (X.n_rows / 2) : (X.n_rows + 1 / 2 ));
151 arma::vec buffer(X.n_rows);
155 for (arma::uword i = 0; i < X.n_cols; ++i){
157 sorted = stable_sort_index(buffer);
158 thresh(i) = buffer(sorted(k));
162 thresh.fill(threshold);
164 arma::vec current_spectrum;
165 arma::vec current_derivative;
166 arma::vec current_magnitudes;
167 arma::vec current_peaks;
168 for (arma::uword i = 0; i < X.n_cols; ++i){
169 current_spectrum = X.col(i);
170 current_derivative = derivatized.col(i);
172 peak_locations.col(i) = current_peaks;
173 peak_magnitudes.col(i) = current_magnitudes;
175 return peak_locations;
203 std::string threshold_method,
204 arma::vec &peak_magnitudes)
210 d2X.insert_rows(0, 1,
true);
211 }
catch(std::exception e){
212 std::cerr <<
"error in Vespucci::Math::PeakFinding::FindPeakPositions" << std::endl;
215 if (threshold_method ==
"count" && threshold <= 0){
216 throw std::runtime_error(
"Invalid threshold value for given method");
218 if ((threshold_method ==
"countpercentage" || threshold_method ==
"ratio") && threshold > 1){
219 throw std::runtime_error(
"Invalid threshold value for given method");
223 arma::uvec extrema_indices = find( (dX.subvec(0, X.n_rows - 2) % dX.subvec(1, X.n_rows - 1) )< 0);
224 arma::vec d2X_extrema = d2X(extrema_indices);
225 arma::uvec maxima_indices = find(d2X_extrema < 0);
226 arma::umat results(maxima_indices.n_elem, 3);
227 arma::uvec buffer(3);
228 peak_magnitudes.set_size(maxima_indices.n_elem);
232 arma::uword center_index = 0;
233 arma::uword left_index = 0;
234 arma::uword right_index = 0;
239 for (i = 0; i < maxima_indices.n_elem; ++i){
241 if(maxima_indices(i) == 0){
243 center_index = extrema_indices(maxima_indices(i));
244 right_index = extrema_indices(maxima_indices(i) + 1);
245 left_index = center_index;
248 else if(maxima_indices(i) + 1 >= extrema_indices.n_elem){
250 center_index = extrema_indices(maxima_indices(i));
251 left_index = extrema_indices(maxima_indices(i) - 1);
252 right_index = center_index;
257 center_index = extrema_indices(maxima_indices(i));
258 left_index = extrema_indices(maxima_indices(i) - 1);
259 right_index = extrema_indices(maxima_indices(i) + 1);
263 peak_magnitudes(i) = (2.0*X(center_index) - X(left_index) - X(right_index))/2.0;
264 buffer(0) = center_index;
265 buffer(1) = left_index;
266 buffer(2) = right_index;
267 results.row(i) = buffer.t();
269 }
catch(std::exception e){
270 std::cout <<
"Exception!" << std::endl;
271 std::cout << e.what() << std::endl;
272 std::cout <<
"iterator index = " << i << std::endl;
273 std::cout <<
"maxima index = " << maxima_indices(i) << std::endl;
274 std::cout <<
"extrema_indices.n_rows = " << extrema_indices.n_rows << std::endl;
275 std::cout <<
"center_index = " << center_index << std::endl;
276 std::cout <<
"left_index = " << left_index << std::endl;
277 std::cout <<
"right_index = " << right_index << std::endl;
278 throw std::runtime_error(e.what());
283 arma::uvec sorted_peak_indices = stable_sort_index(peak_magnitudes,
"descend");
284 peak_magnitudes = peak_magnitudes.rows(sorted_peak_indices);
285 results = results.rows(sorted_peak_indices);
287 if (threshold_method ==
"magnitude"){
288 arma::uvec indices = find(peak_magnitudes > threshold);
289 peak_magnitudes = peak_magnitudes.rows(indices);
290 return results.rows(indices);
292 else if (threshold_method ==
"count"){
293 arma::uword uthresh = (std::ceil(threshold) < results.n_rows - 1 ? std::ceil(threshold) : results.n_rows - 1);
294 peak_magnitudes = peak_magnitudes.rows(0, uthresh);
295 return results.rows(0, uthresh);
297 else if (threshold_method ==
"ratio"){
299 peak_magnitudes = peak_magnitudes.row(0);
300 return results.row(0);
303 double cutoff = peak_magnitudes(0) * threshold;
304 arma::uvec indices = find(peak_magnitudes > cutoff);
305 peak_magnitudes = peak_magnitudes.rows(indices);
306 return results.rows(indices);
310 arma::uword count = std::floor(threshold*results.n_rows);
311 peak_magnitudes = peak_magnitudes.rows(0, count);
312 return results.rows(0, count);
320 arma::uvec peaks = peak_positions.col(0);
321 arma::vec population = arma::zeros(vector_size);
322 population.elem(peaks) = arma::ones(peaks.n_elem);
329 if (peak_positions.n_cols != 3){
330 return arma::zeros(vector_size);
333 arma::vec extrema = arma::zeros(vector_size);
334 arma::uvec peak_centers = peak_positions.col(0);
335 arma::uvec left_boundaries = peak_positions.col(1);
336 arma::uvec right_boundaries = peak_positions.col(2);
337 extrema.elem(peak_centers) = arma::ones(peak_centers.n_elem);
338 extrema.elem(left_boundaries) = -1 * arma::ones(left_boundaries.n_elem);
339 extrema.elem(right_boundaries) = -1 * arma::ones(right_boundaries.n_elem);
353 arma::uword window_size)
355 if (window_size % 2 == 0){
357 std::cerr <<
"invalid window_size, using one less" << std::endl;
360 arma::vec baseline = X;
361 arma::uword start, end, center, size;
365 for (i = 0; i < peaks.n_rows; ++i){
366 center = peaks(i, 0);
375 if (start == center){
376 baseline.subvec(start, end-1) = X(end) * arma::ones(size);
378 else if (end == center){
379 baseline.subvec(start, end-1) = X(start) * arma::ones(size);
382 baseline.subvec(start, end-1) = arma::linspace(X(start), X(end), size);
386 }
catch(std::exception e){
387 std::cout <<
"Exception! (peak exclusion)" << std::endl;
388 std::cout <<
"size of peaks = " << peaks.n_rows <<
" " << peaks.n_cols << std::endl;
389 std::cout <<
"i = " << i << std::endl;
390 throw std::runtime_error(e.what());
395 arma::uword k = (window_size - 1) / 2;
397 arma::vec filtered(baseline.n_elem);
399 for (arma::uword i = k; i < (X.n_rows - k); ++i){
400 buffer = baseline.subvec(i-k, i+k);
401 filtered(i) = buffer.min();
404 for (arma::uword i = 0; i < k; ++i){
405 filtered(i) = filtered(k);
407 for (arma::uword i = filtered.n_rows - k; i < filtered.n_elem; ++i){
408 filtered(i) = filtered(filtered.n_rows - k - 2);
410 }
catch(std::exception e){
411 std::cout <<
"Exception! (filtering)" << std::endl;
412 std::cout <<
"i = " << i << std::endl;
413 throw std::runtime_error(e.what());
VESPUCCI_EXPORT arma::mat sgolayfilt(const arma::mat &x, arma::uword poly_order, arma::uword window_size, arma::uword deriv_order, arma::uword scaling_factor)
sgolayfilt Apply Savitzky-Golay smoothing to each column of a arma::matrix
T diff(const T &X, arma::uword deriv_order=1)
Vespucci::Math::diff.
VESPUCCI_EXPORT arma::vec PeakExtrema(arma::uword vector_size, arma::umat peak_positions)
VESPUCCI_EXPORT arma::vec FindPeaks(arma::vec X, arma::vec dX, double sel, double threshold, arma::vec &peak_magnitudes)
Vespucci::Math::PeakFinding::FindPeaks an implementation of the peakfinder arma::mat routine...
VESPUCCI_EXPORT arma::mat FindPeaksMat(arma::mat X, double sel, double threshold, arma::uword poly_order, arma::uword window_size, arma::mat &peak_magnitudes)
Vespucci::Math::PeakFinding::FindPeaksMat Performs FindPeaks on a spectra arma::matrix.
VESPUCCI_EXPORT arma::vec PeakPopulation(arma::uword vector_size, arma::umat peak_positions)
VESPUCCI_EXPORT arma::vec EstimateBaseline(arma::vec X, arma::umat peaks, arma::uword window_size)
EstimateBaseline.
VESPUCCI_EXPORT arma::uvec FindPeakPositions(arma::vec X, arma::vec dX, double sel, double threshold, arma::uvec &local_minima)