OpenMS
Loading...
Searching...
No Matches
MRMTransitionGroupPicker.h
Go to the documentation of this file.
1// Copyright (c) 2002-present, OpenMS Inc. -- EKU Tuebingen, ETH Zurich, and FU Berlin
2// SPDX-License-Identifier: BSD-3-Clause
3//
4// --------------------------------------------------------------------------
5// $Maintainer: Hannes Roest $
6// $Authors: Hannes Roest $
7// --------------------------------------------------------------------------
8
9#pragma once
10
17
20
23
24// Cross-correlation
27
28#include <numeric>
29
30//#define DEBUG_TRANSITIONGROUPPICKER
31
32namespace OpenMS
33{
34
53 class OPENMS_DLLAPI MRMTransitionGroupPicker :
55 {
56
57public:
58
60
62
66
86 template <typename SpectrumT, typename TransitionT>
88 {
89 OPENMS_PRECONDITION(transition_group.isInternallyConsistent(), "Consistent state required")
90 OPENMS_PRECONDITION(transition_group.chromatogramIdsMatch(), "Chromatogram native IDs need to match keys in transition group")
91
92 std::vector<MSChromatogram > picked_chroms;
93 std::vector<MSChromatogram > smoothed_chroms;
94
95 // Pick fragment ion chromatograms
96 for (Size k = 0; k < transition_group.getChromatograms().size(); k++)
97 {
98 MSChromatogram& chromatogram = transition_group.getChromatograms()[k];
99 String native_id = chromatogram.getNativeID();
100
101 // only pick detecting transitions (skip all others)
102 if (transition_group.getTransitions().size() > 0 &&
103 transition_group.hasTransition(native_id) &&
104 !transition_group.getTransition(native_id).isDetectingTransition() )
105 {
106 continue;
107 }
108
109 MSChromatogram picked_chrom, smoothed_chrom;
110 smoothed_chrom.setNativeID(native_id);
111 picker_.pickChromatogram(chromatogram, picked_chrom, smoothed_chrom);
112 picked_chrom.sortByIntensity();
113 picked_chroms.push_back(std::move(picked_chrom));
114 smoothed_chroms.push_back(std::move(smoothed_chrom));
115 }
116
117 // Pick precursor chromatograms
118 if (use_precursors_)
119 {
120 for (Size k = 0; k < transition_group.getPrecursorChromatograms().size(); k++)
121 {
122 SpectrumT picked_chrom, smoothed_chrom;
123 SpectrumT& chromatogram = transition_group.getPrecursorChromatograms()[k];
124
125 picker_.pickChromatogram(chromatogram, picked_chrom, smoothed_chrom);
126 picked_chrom.sortByIntensity();
127 picked_chroms.push_back(picked_chrom);
128 smoothed_chroms.push_back(smoothed_chrom);
129 }
130 }
131
132 // Find features (peak groups) in this group of transitions.
133 // While there are still peaks left, one will be picked and used to create
134 // a feature. Whenever we run out of peaks, we will get -1 back as index
135 // and terminate.
136 int chr_idx, peak_idx, cnt = 0;
137 std::vector<MRMFeature> features;
138 while (true)
139 {
140 chr_idx = -1; peak_idx = -1;
141
142 if (boundary_selection_method_ == "largest")
143 {
144 findLargestPeak(picked_chroms, chr_idx, peak_idx);
145 }
146 else if (boundary_selection_method_ == "widest")
147 {
148 findWidestPeakIndices(picked_chroms, chr_idx, peak_idx);
149 }
150
151 if (chr_idx == -1 && peak_idx == -1)
152 {
153 OPENMS_LOG_DEBUG << "**** No more peaks left. Nr. chroms: " << picked_chroms.size() << std::endl;
154 break;
155 }
156
157 // Compute a feature from the individual chromatograms and add non-zero features
158 MRMFeature mrm_feature = createMRMFeature(transition_group, picked_chroms, smoothed_chroms, chr_idx, peak_idx);
159 double total_xic = 0;
160 double intensity = mrm_feature.getIntensity();
161 if (intensity > 0)
162 {
163 total_xic = mrm_feature.getMetaValue("total_xic");
164 features.push_back(std::move(mrm_feature));
165 cnt++;
166 }
167
168 if (stop_after_feature_ > 0 && cnt > stop_after_feature_) {
169 // If you set this, you only expect one feature anyway. No logging necessary why it stopped.
170 break;
171 }
172 if (intensity > 0 && intensity / total_xic < stop_after_intensity_ratio_)
173 {
174 OPENMS_LOG_DEBUG << "**** Minimum intensity ratio reached. Nr. chroms: " << picked_chroms.size() << std::endl;
175 break;
176 }
177 }
178
179 // Check for completely overlapping features
180 for (Size i = 0; i < features.size(); i++)
181 {
182 MRMFeature& mrm_feature = features[i];
183 bool skip = false;
184 for (Size j = 0; j < i; j++)
185 {
186 if ((double)mrm_feature.getMetaValue("leftWidth") >= (double)features[j].getMetaValue("leftWidth") &&
187 (double)mrm_feature.getMetaValue("rightWidth") <= (double)features[j].getMetaValue("rightWidth") )
188 { skip = true; }
189 }
190 if (mrm_feature.getIntensity() > 0 && !skip)
191 {
192 transition_group.addFeature(mrm_feature);
193 }
194 }
195
196 }
197
199 template <typename SpectrumT, typename TransitionT>
201 std::vector<SpectrumT>& picked_chroms,
202 const std::vector<SpectrumT>& smoothed_chroms,
203 const int chr_idx,
204 const int peak_idx)
205 {
206 OPENMS_PRECONDITION(transition_group.isInternallyConsistent(), "Consistent state required")
207 OPENMS_PRECONDITION(transition_group.chromatogramIdsMatch(), "Chromatogram native IDs need to match keys in transition group")
208
209 MRMFeature mrmFeature;
210 mrmFeature.setIntensity(0.0);
211 double best_left = picked_chroms[chr_idx].getFloatDataArrays()[PeakPickerChromatogram::IDX_LEFTBORDER][peak_idx];
212 double best_right = picked_chroms[chr_idx].getFloatDataArrays()[PeakPickerChromatogram::IDX_RIGHTBORDER][peak_idx];
213 double peak_apex = picked_chroms[chr_idx][peak_idx].getRT();
214 OPENMS_LOG_DEBUG << "**** Creating MRMFeature for peak " << peak_idx << " in chrom. " << chr_idx << " with " <<
215 picked_chroms[chr_idx][peak_idx] << " and borders " << best_left << " " <<
216 best_right << " (" << best_right - best_left << ")" << std::endl;
217
218 if (use_consensus_ && recalculate_peaks_)
219 {
220 // This may change best_left / best_right
221 recalculatePeakBorders_(picked_chroms, best_left, best_right, recalculate_peaks_max_z_);
222 if (peak_apex < best_left || peak_apex > best_right)
223 {
224 // apex fell out of range, lets correct it
225 peak_apex = (best_left + best_right) / 2.0;
226 }
227 }
228
229 std::vector< double > left_edges;
230 std::vector< double > right_edges;
231 double min_left = best_left;
232 double max_right = best_right;
233 if (use_consensus_)
234 {
235 // Remove other, overlapping, picked peaks (in this and other
236 // chromatograms) and then ensure that at least one peak is set to zero
237 // (the currently best peak).
238 remove_overlapping_features(picked_chroms, best_left, best_right);
239 }
240 else
241 {
242 pickApex(picked_chroms, best_left, best_right, peak_apex,
243 min_left, max_right, left_edges, right_edges);
244
245 } // end !use_consensus_
246 picked_chroms[chr_idx][peak_idx].setIntensity(0.0); // ensure that we set at least one peak to zero
247
248 // Check for minimal peak width -> return empty feature (Intensity zero)
249 if (use_consensus_)
250 {
251 if (min_peak_width_ > 0.0 && std::fabs(best_right - best_left) < min_peak_width_)
252 {
253 return mrmFeature;
254 }
255
256 if (compute_peak_quality_)
257 {
258 String outlier = "none";
259 double qual = computeQuality_(transition_group, picked_chroms, chr_idx, best_left, best_right, outlier);
260 if (qual < min_qual_)
261 {
262 return mrmFeature;
263 }
264 mrmFeature.setMetaValue("potentialOutlier", outlier);
265 mrmFeature.setMetaValue("initialPeakQuality", qual);
266 mrmFeature.setOverallQuality(qual);
267 }
268 }
269
270 // Prepare linear resampling of all the chromatograms, here creating the
271 // empty master_peak_container with the same RT (m/z) values as the
272 // reference chromatogram. We use the overall minimal left boundary and
273 // maximal right boundary to prepare the container.
274 SpectrumT master_peak_container;
275 const SpectrumT& ref_chromatogram = selectChromHelper_(transition_group, picked_chroms[chr_idx].getNativeID());
276 prepareMasterContainer_(ref_chromatogram, master_peak_container, min_left, max_right);
277
278 // Iterate over initial transitions / chromatograms (note that we may
279 // have a different number of picked chromatograms than total transitions
280 // as not all are detecting transitions).
281 double total_intensity = 0; double total_peak_apices = 0; double total_xic = 0; double total_mi = 0;
282 pickFragmentChromatograms(transition_group, picked_chroms, mrmFeature, smoothed_chroms,
283 best_left, best_right, use_consensus_,
284 total_intensity, total_xic, total_mi, total_peak_apices,
285 master_peak_container, left_edges, right_edges,
286 chr_idx, peak_idx);
287
288 // Also pick the precursor chromatogram(s); note total_xic is not
289 // extracted here, only for fragment traces
290 pickPrecursorChromatograms(transition_group,
291 picked_chroms, mrmFeature, smoothed_chroms,
292 best_left, best_right, use_consensus_,
293 total_intensity, master_peak_container, left_edges, right_edges,
294 chr_idx, peak_idx);
295
296 mrmFeature.setRT(peak_apex);
297 mrmFeature.setIntensity(total_intensity);
298 mrmFeature.setMetaValue("PeptideRef", transition_group.getTransitionGroupID());
299 mrmFeature.setMetaValue("leftWidth", best_left);
300 mrmFeature.setMetaValue("rightWidth", best_right);
301 mrmFeature.setMetaValue("total_xic", total_xic);
302 if (compute_total_mi_)
303 {
304 mrmFeature.setMetaValue("total_mi", total_mi);
305 }
306 mrmFeature.setMetaValue("peak_apices_sum", total_peak_apices);
307
308 mrmFeature.ensureUniqueId();
309 return mrmFeature;
310 }
311
324 template <typename SpectrumT>
325 void pickApex(std::vector<SpectrumT>& picked_chroms,
326 const double best_left, const double best_right, const double peak_apex,
327 double &min_left, double &max_right,
328 std::vector< double > & left_edges, std::vector< double > & right_edges)
329 {
330 for (Size k = 0; k < picked_chroms.size(); k++)
331 {
332 double peak_apex_dist_min = std::numeric_limits<double>::max();
333 int min_dist = -1;
334 for (Size i = 0; i < picked_chroms[k].size(); i++)
335 {
336 PeakIntegrator::PeakArea pa_tmp = pi_.integratePeak( // get the peak apex
337 picked_chroms[k],
338 picked_chroms[k].getFloatDataArrays()[PeakPickerChromatogram::IDX_LEFTBORDER][i],
339 picked_chroms[k].getFloatDataArrays()[PeakPickerChromatogram::IDX_RIGHTBORDER][i]);
340 if (pa_tmp.apex_pos > 1e-11 && std::fabs(pa_tmp.apex_pos - peak_apex) < peak_apex_dist_min)
341 { // update best candidate
342 peak_apex_dist_min = std::fabs(pa_tmp.apex_pos - peak_apex);
343 min_dist = (int)i;
344 }
345 }
346
347 // Select master peak boundaries, or in the case we found at least one peak, the local peak boundaries
348 double l = best_left;
349 double r = best_right;
350 if (min_dist >= 0)
351 {
352 l = picked_chroms[k].getFloatDataArrays()[PeakPickerChromatogram::IDX_LEFTBORDER][min_dist];
353 r = picked_chroms[k].getFloatDataArrays()[PeakPickerChromatogram::IDX_RIGHTBORDER][min_dist];
354 picked_chroms[k][min_dist].setIntensity(0.0); // only remove one peak per transition
355 }
356
357 left_edges.push_back(l);
358 right_edges.push_back(r);
359 // ensure we remember the overall maxima / minima
360 if (l < min_left) {min_left = l;}
361 if (r > max_right) {max_right = r;}
362 }
363 }
364
365 template <typename SpectrumT, typename TransitionT>
367 const std::vector<SpectrumT>& picked_chroms,
368 MRMFeature& mrmFeature,
369 const std::vector<SpectrumT>& smoothed_chroms,
370 const double best_left, const double best_right,
371 const bool use_consensus_,
372 double & total_intensity,
373 double & total_xic,
374 double & total_mi,
375 double & total_peak_apices,
376 const SpectrumT & master_peak_container,
377 const std::vector< double > & left_edges,
378 const std::vector< double > & right_edges,
379 const int chr_idx,
380 const int peak_idx)
381 {
382 for (Size k = 0; k < transition_group.getTransitions().size(); k++)
383 {
384
385 double local_left = best_left;
386 double local_right = best_right;
387 if (!use_consensus_)
388 {
389 // We cannot have any non-detecting transitions (otherwise we have
390 // too few left / right edges) as we skipped those when doing peak
391 // picking and smoothing.
392 if (!transition_group.getTransitions()[k].isDetectingTransition())
393 {
394 throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
395 "When using non-consensus peak picker, all transitions need to be detecting transitions.");
396 }
397 local_left = left_edges[k];
398 local_right = right_edges[k];
399 }
400
401 const SpectrumT& chromatogram = selectChromHelper_(transition_group, transition_group.getTransitions()[k].getNativeID());
402 if (transition_group.getTransitions()[k].isDetectingTransition())
403 {
404 for (typename SpectrumT::const_iterator it = chromatogram.begin(); it != chromatogram.end(); it++)
405 {
406 total_xic += it->getIntensity();
407 }
408 }
409
410 // Compute total intensity on transition-level
411 double transition_total_xic = 0;
412
413 for (typename SpectrumT::const_iterator it = chromatogram.begin(); it != chromatogram.end(); it++)
414 {
415 transition_total_xic += it->getIntensity();
416 }
417
418 // Compute total mutual information on transition-level.
419 double transition_total_mi = 0;
420 if (compute_total_mi_)
421 {
422 std::vector<unsigned int> chrom_vect_id_ranked, chrom_vect_det_ranked;
423 std::vector<double> chrom_vect_id, chrom_vect_det;
424 for (typename SpectrumT::const_iterator it = chromatogram.begin(); it != chromatogram.end(); it++)
425 {
426 chrom_vect_id.push_back(it->getIntensity());
427 }
428 unsigned int max_rank_det = OpenSwath::Scoring::computeAndAppendRank(chrom_vect_id, chrom_vect_det_ranked);
429 // compute baseline mutual information
430 int transition_total_mi_norm = 0;
431 for (Size m = 0; m < transition_group.getTransitions().size(); m++)
432 {
433 if (transition_group.getTransitions()[m].isDetectingTransition())
434 {
435 const SpectrumT& chromatogram_det = selectChromHelper_(transition_group, transition_group.getTransitions()[m].getNativeID());
436 chrom_vect_det.clear();
437 for (typename SpectrumT::const_iterator it = chromatogram_det.begin(); it != chromatogram_det.end(); it++)
438 {
439 chrom_vect_det.push_back(it->getIntensity());
440 }
441 unsigned int max_rank_id = OpenSwath::Scoring::computeAndAppendRank(chrom_vect_det, chrom_vect_id_ranked);
442 transition_total_mi += OpenSwath::Scoring::rankedMutualInformation(chrom_vect_id_ranked, chrom_vect_det_ranked, max_rank_id, max_rank_det);
443 transition_total_mi_norm++;
444 }
445 }
446 if (transition_total_mi_norm > 0) { transition_total_mi /= transition_total_mi_norm; }
447
448 if (transition_group.getTransitions()[k].isDetectingTransition())
449 {
450 // sum up all transition-level total MI and divide by the number of detection transitions to have peak group level total MI
451 total_mi += transition_total_mi / transition_total_mi_norm;
452 }
453 }
454
455 SpectrumT used_chromatogram;
456 // resample the current chromatogram
457 if (peak_integration_ == "original")
458 {
459 used_chromatogram = resampleChromatogram_(chromatogram, master_peak_container, local_left, local_right);
460 }
461 else if (peak_integration_ == "smoothed")
462 {
463 if (smoothed_chroms.size() <= k)
464 {
465 throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
466 "Tried to calculate peak area and height without any smoothed chromatograms");
467 }
468 used_chromatogram = resampleChromatogram_(smoothed_chroms[k], master_peak_container, local_left, local_right);
469 }
470 else
471 {
472 throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
473 String("Peak integration chromatogram ") + peak_integration_ + " is not a valid method for MRMTransitionGroupPicker");
474 }
475
476 Feature f;
477 double quality = 0;
478 f.setQuality(0, quality);
479 f.setOverallQuality(quality);
480
481 PeakIntegrator::PeakArea pa = pi_.integratePeak(used_chromatogram, local_left, local_right);
482 double peak_integral = pa.area;
483 double peak_apex_int = pa.height;
484 f.setMetaValue("peak_apex_position", pa.apex_pos);
485
486 // In non-consensus mode, override hull_points with the full resampled
487 // chromatogram so all transitions produce equal-sized intensity vectors
488 // for cross-correlation scoring. Area/height/apex are already correct
489 // from the per-transition integration above.
490 if (!use_consensus_)
491 {
492 pa.hull_points.clear();
493 for (const auto& p : used_chromatogram)
494 {
495 pa.hull_points.push_back(DPosition<2>(p.getPos(), p.getIntensity()));
496 }
497 }
498
499 if (background_subtraction_ != "none")
500 {
501 double background{0};
502 double avg_noise_level{0};
503 if (background_subtraction_ == "original")
504 {
505 const double intensity_left = chromatogram.PosBegin(local_left)->getIntensity();
506 const double intensity_right = (chromatogram.PosEnd(local_right) - 1)->getIntensity();
507 const UInt n_points = std::distance(chromatogram.PosBegin(local_left), chromatogram.PosEnd(local_right));
508 avg_noise_level = (intensity_right + intensity_left) / 2;
509 background = avg_noise_level * n_points;
510 }
511 else if (background_subtraction_ == "exact")
512 {
513 PeakIntegrator::PeakBackground pb = pi_.estimateBackground(used_chromatogram, local_left, local_right, pa.apex_pos);
514 background = pb.area;
515 avg_noise_level = pb.height;
516 }
517 peak_integral -= background;
518 peak_apex_int -= avg_noise_level;
519 if (peak_integral < 0) {peak_integral = 0;}
520 if (peak_apex_int < 0) {peak_apex_int = 0;}
521
522 f.setMetaValue("area_background_level", background);
523 f.setMetaValue("noise_background_level", avg_noise_level);
524 } // end background
525
526 f.setRT(picked_chroms[chr_idx][peak_idx].getPos());
527 f.setIntensity(peak_integral);
528 ConvexHull2D hull;
529 hull.setHullPoints(pa.hull_points);
530 f.getConvexHulls().push_back(hull);
531
532 f.setMZ(chromatogram.getProduct().getMZ());
533 mrmFeature.setMZ(chromatogram.getPrecursor().getMZ());
534
535 if (chromatogram.metaValueExists("product_mz")) // legacy code (ensures that old tests still work)
536 {
537 f.setMetaValue("MZ", chromatogram.getMetaValue("product_mz"));
538 f.setMZ(chromatogram.getMetaValue("product_mz"));
539 }
540
541 f.setMetaValue("native_id", chromatogram.getNativeID());
542 f.setMetaValue("peak_apex_int", peak_apex_int);
543 f.setMetaValue("total_xic", transition_total_xic);
544 if (compute_total_mi_)
545 {
546 f.setMetaValue("total_mi", transition_total_mi);
547 }
548
549 if (transition_group.getTransitions()[k].isQuantifyingTransition())
550 {
551 total_intensity += peak_integral;
552 total_peak_apices += peak_apex_int;
553 }
554
555 // for backwards compatibility with TOPP tests
556 // Calculate peak shape metrics that will be used for later QC
557 PeakIntegrator::PeakShapeMetrics psm = pi_.calculatePeakShapeMetrics(used_chromatogram, local_left, local_right, peak_apex_int, pa.apex_pos);
558 f.setMetaValue("width_at_50", psm.width_at_50);
559 if (compute_peak_shape_metrics_)
560 {
561 f.setMetaValue("width_at_5", psm.width_at_5);
562 f.setMetaValue("width_at_10", psm.width_at_10);
563 f.setMetaValue("start_position_at_5", psm.start_position_at_5);
564 f.setMetaValue("start_position_at_10", psm.start_position_at_10);
565 f.setMetaValue("start_position_at_50", psm.start_position_at_50);
566 f.setMetaValue("end_position_at_5", psm.end_position_at_5);
567 f.setMetaValue("end_position_at_10", psm.end_position_at_10);
568 f.setMetaValue("end_position_at_50", psm.end_position_at_50);
569 f.setMetaValue("total_width", psm.total_width);
570 f.setMetaValue("tailing_factor", psm.tailing_factor);
571 f.setMetaValue("asymmetry_factor", psm.asymmetry_factor);
572 f.setMetaValue("slope_of_baseline", psm.slope_of_baseline);
573 f.setMetaValue("baseline_delta_2_height", psm.baseline_delta_2_height);
574 f.setMetaValue("points_across_baseline", psm.points_across_baseline);
575 f.setMetaValue("points_across_half_height", psm.points_across_half_height);
576 }
577
578 mrmFeature.addFeature(f, chromatogram.getNativeID()); //map index and feature
579 }
580 }
581
582 template <typename SpectrumT, typename TransitionT>
584 const std::vector<SpectrumT>& picked_chroms,
585 MRMFeature& mrmFeature,
586 const std::vector<SpectrumT>& smoothed_chroms,
587 const double best_left, const double best_right,
588 const bool use_consensus_,
589 double & total_intensity,
590 const SpectrumT & master_peak_container,
591 const std::vector< double > & left_edges,
592 const std::vector< double > & right_edges,
593 const int chr_idx,
594 const int peak_idx)
595 {
596 for (Size k = 0; k < transition_group.getPrecursorChromatograms().size(); k++)
597 {
598 const SpectrumT& chromatogram = transition_group.getPrecursorChromatograms()[k];
599
600 // Identify precursor index
601 // note: this is only valid if all transitions are detecting transitions
602 Size prec_idx = transition_group.getChromatograms().size() + k;
603
604 double local_left = best_left;
605 double local_right = best_right;
606 if (!use_consensus_ && right_edges.size() > prec_idx && left_edges.size() > prec_idx)
607 {
608 local_left = left_edges[prec_idx];
609 local_right = right_edges[prec_idx];
610 }
611
612 SpectrumT used_chromatogram;
613 // resample the current chromatogram
614 if (peak_integration_ == "original")
615 {
616 used_chromatogram = resampleChromatogram_(chromatogram, master_peak_container, local_left, local_right);
617 // const SpectrumT& used_chromatogram = chromatogram; // instead of resampling
618 }
619 else if (peak_integration_ == "smoothed" && smoothed_chroms.size() <= prec_idx)
620 {
621 throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
622 "Tried to calculate peak area and height without any smoothed chromatograms for precursors");
623 }
624 else if (peak_integration_ == "smoothed")
625 {
626 used_chromatogram = resampleChromatogram_(smoothed_chroms[prec_idx], master_peak_container, local_left, local_right);
627 }
628 else
629 {
630 throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
631 String("Peak integration chromatogram ") + peak_integration_ + " is not a valid method for MRMTransitionGroupPicker");
632 }
633
634 Feature f;
635 double quality = 0;
636 f.setQuality(0, quality);
637 f.setOverallQuality(quality);
638
639 PeakIntegrator::PeakArea pa = pi_.integratePeak(used_chromatogram, local_left, local_right);
640 double peak_integral = pa.area;
641 double peak_apex_int = pa.height;
642
643 // In non-consensus mode, override hull_points with the full resampled
644 // chromatogram so all precursors produce equal-sized intensity vectors
645 // for cross-correlation scoring (see pickFragmentChromatograms).
646 if (!use_consensus_)
647 {
648 pa.hull_points.clear();
649 for (const auto& p : used_chromatogram)
650 {
651 pa.hull_points.push_back(DPosition<2>(p.getPos(), p.getIntensity()));
652 }
653 }
654
655 if (background_subtraction_ != "none")
656 {
657 double background{0};
658 double avg_noise_level{0};
659 if ((peak_integration_ == "smoothed") && smoothed_chroms.size() <= prec_idx)
660 {
661 throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
662 "Tried to calculate background estimation without any smoothed chromatograms");
663 }
664 else if (background_subtraction_ == "original")
665 {
666 const double intensity_left = chromatogram.PosBegin(local_left)->getIntensity();
667 const double intensity_right = (chromatogram.PosEnd(local_right) - 1)->getIntensity();
668 const UInt n_points = std::distance(chromatogram.PosBegin(local_left), chromatogram.PosEnd(local_right));
669 avg_noise_level = (intensity_right + intensity_left) / 2;
670 background = avg_noise_level * n_points;
671 }
672 else if (background_subtraction_ == "exact")
673 {
674 PeakIntegrator::PeakBackground pb = pi_.estimateBackground(used_chromatogram, local_left, local_right, pa.apex_pos);
675 background = pb.area;
676 avg_noise_level = pb.height;
677 }
678 peak_integral -= background;
679 peak_apex_int -= avg_noise_level;
680 if (peak_integral < 0) {peak_integral = 0;}
681 if (peak_apex_int < 0) {peak_apex_int = 0;}
682
683 f.setMetaValue("area_background_level", background);
684 f.setMetaValue("noise_background_level", avg_noise_level);
685 }
686
687 f.setMZ(chromatogram.getPrecursor().getMZ());
688 if (k == 0) {mrmFeature.setMZ(chromatogram.getPrecursor().getMZ());} // only use m/z if first (monoisotopic) isotope
689
690 if (chromatogram.metaValueExists("precursor_mz")) // legacy code (ensures that old tests still work)
691 {
692 f.setMZ(chromatogram.getMetaValue("precursor_mz"));
693 if (k == 0) {mrmFeature.setMZ(chromatogram.getMetaValue("precursor_mz"));} // only use m/z if first (monoisotopic) isotope
694 }
695
696 f.setRT(picked_chroms[chr_idx][peak_idx].getPos());
697 f.setIntensity(peak_integral);
698 ConvexHull2D hull;
699 hull.setHullPoints(pa.hull_points);
700 f.getConvexHulls().push_back(hull);
701 f.setMetaValue("native_id", chromatogram.getNativeID());
702 f.setMetaValue("peak_apex_int", peak_apex_int);
703
704 if (use_precursors_ && transition_group.getTransitions().empty())
705 {
706 total_intensity += peak_integral;
707 }
708
709 mrmFeature.addPrecursorFeature(f, chromatogram.getNativeID());
710 }
711 }
712
713 // maybe private, but we have tests
714
726 template <typename SpectrumT>
727 void remove_overlapping_features(std::vector<SpectrumT>& picked_chroms, double best_left, double best_right)
728 {
729 // delete all seeds that lie within the current seed
730 Size count_inside = 0;
731 for (Size k = 0; k < picked_chroms.size(); k++)
732 {
733 for (Size i = 0; i < picked_chroms[k].size(); i++)
734 {
735 if (picked_chroms[k][i].getPos() >= best_left && picked_chroms[k][i].getPos() <= best_right)
736 {
737 picked_chroms[k][i].setIntensity(0.0);
738 count_inside++;
739 }
740 }
741 }
742
743 Size count_overlap = 0;
744 // delete all seeds that overlap within the current seed
745 for (Size k = 0; k < picked_chroms.size(); k++)
746 {
747 for (Size i = 0; i < picked_chroms[k].size(); i++)
748 {
749 if (picked_chroms[k][i].getIntensity() <= 1e-11) {continue; }
750
751 double left = picked_chroms[k].getFloatDataArrays()[PeakPickerChromatogram::IDX_LEFTBORDER][i];
752 double right = picked_chroms[k].getFloatDataArrays()[PeakPickerChromatogram::IDX_RIGHTBORDER][i];
753 if ((left > best_left && left < best_right)
754 || (right > best_left && right < best_right))
755 {
756 picked_chroms[k][i].setIntensity(0.0);
757 count_overlap++;
758 }
759 }
760 }
761 OPENMS_LOG_DEBUG << " ** Removed " << count_inside << " peaks enclosed in and " <<
762 count_overlap << " peaks overlapping with added feature." << std::endl;
763 }
764
766 void findLargestPeak(const std::vector<MSChromatogram >& picked_chroms, int& chr_idx, int& peak_idx);
767
776 void findWidestPeakIndices(const std::vector<MSChromatogram>& picked_chroms, Int& chrom_idx, Int& point_idx) const;
777
778protected:
779
781 void updateMembers_() override;
782
785
789 template <typename SpectrumT, typename TransitionT>
790 const SpectrumT& selectChromHelper_(const MRMTransitionGroup<SpectrumT, TransitionT>& transition_group, const String& native_id)
791 {
792 if (transition_group.hasChromatogram(native_id))
793 {
794 return transition_group.getChromatogram(native_id);
795 }
796 else if (transition_group.hasPrecursorChromatogram(native_id))
797 {
798 return transition_group.getPrecursorChromatogram(native_id);
799 }
800 else
801 {
802 throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "Did not find chromatogram for id '" + native_id + "'.");
803 }
804 }
805
822 template <typename SpectrumT, typename TransitionT>
824 const std::vector<SpectrumT>& picked_chroms,
825 const int chr_idx,
826 const double best_left,
827 const double best_right,
828 String& outlier)
829 {
830 // Resample all chromatograms around the current estimated peak and
831 // collect the raw intensities. For resampling, use a bit more on either
832 // side to correctly identify shoulders etc.
833 double resample_boundary = resample_boundary_; // sample 15 seconds more on each side
834 SpectrumT master_peak_container;
835 const SpectrumT& ref_chromatogram = selectChromHelper_(transition_group, picked_chroms[chr_idx].getNativeID());
836 prepareMasterContainer_(ref_chromatogram, master_peak_container, best_left - resample_boundary, best_right + resample_boundary);
837 std::vector<std::vector<double> > all_ints;
838 for (Size k = 0; k < picked_chroms.size(); k++)
839 {
840 const SpectrumT& chromatogram = selectChromHelper_(transition_group, picked_chroms[k].getNativeID());
841 const SpectrumT used_chromatogram = resampleChromatogram_(chromatogram,
842 master_peak_container, best_left - resample_boundary, best_right + resample_boundary);
843
844 std::vector<double> int_here;
845 for (const auto& peak : used_chromatogram) int_here.push_back(peak.getIntensity());
846 // Remove chromatograms without a single peak
847 double tic = std::accumulate(int_here.begin(), int_here.end(), 0.0);
848 if (tic > 1e-11) all_ints.push_back(int_here);
849 }
850
851 // Compute the cross-correlation for the collected intensities
852 std::vector<double> mean_shapes;
853 std::vector<double> mean_coel;
854 for (Size k = 0; k < all_ints.size(); k++)
855 {
856 std::vector<double> shapes;
857 std::vector<double> coel;
858 for (Size i = 0; i < all_ints.size(); i++)
859 {
860 if (i == k) {continue;}
862 all_ints[k], all_ints[i], boost::numeric_cast<int>(all_ints[i].size()), 1);
863
864 // the first value is the x-axis (retention time) and should be an int -> it show the lag between the two
865 double res_coelution = std::abs(OpenSwath::Scoring::xcorrArrayGetMaxPeak(res)->first);
866 double res_shape = std::abs(OpenSwath::Scoring::xcorrArrayGetMaxPeak(res)->second);
867
868 shapes.push_back(res_shape);
869 coel.push_back(res_coelution);
870 }
871
872 // We have computed the cross-correlation of chromatogram k against
873 // all others. Use the mean of these computations as the value for k.
875 msc = std::for_each(shapes.begin(), shapes.end(), msc);
876 double shapes_mean = msc.mean();
877 msc = std::for_each(coel.begin(), coel.end(), msc);
878 double coel_mean = msc.mean();
879
880 // mean shape scores below 0.5-0.6 should be a real sign of trouble ... !
881 // mean coel scores above 3.5 should be a real sign of trouble ... !
882 mean_shapes.push_back(shapes_mean);
883 mean_coel.push_back(coel_mean);
884 }
885
886 // find the chromatogram with the minimal shape score and the maximal
887 // coelution score -> if it is the same chromatogram, the chance is
888 // pretty good that it is different from the others...
889 int min_index_shape = std::distance(mean_shapes.begin(), std::min_element(mean_shapes.begin(), mean_shapes.end()));
890 int max_index_coel = std::distance(mean_coel.begin(), std::max_element(mean_coel.begin(), mean_coel.end()));
891
892 // Look at the picked peaks that are within the current left/right borders
893 int missing_peaks = 0;
894 int multiple_peaks = 0;
895
896 // collect all seeds that lie within the current seed
897 std::vector<double> left_borders;
898 std::vector<double> right_borders;
899 for (Size k = 0; k < picked_chroms.size(); k++)
900 {
901 double l_tmp;
902 double r_tmp;
903 double max_int = -1;
904
905 int pfound = 0;
906 l_tmp = -1;
907 r_tmp = -1;
908 for (Size i = 0; i < picked_chroms[k].size(); i++)
909 {
910 if (picked_chroms[k][i].getPos() >= best_left && picked_chroms[k][i].getPos() <= best_right)
911 {
912 pfound++;
913 if (picked_chroms[k][i].getIntensity() > max_int)
914 {
915 max_int = picked_chroms[k][i].getIntensity() > max_int;
916 l_tmp = picked_chroms[k].getFloatDataArrays()[PeakPickerChromatogram::IDX_LEFTBORDER][i];
917 r_tmp = picked_chroms[k].getFloatDataArrays()[PeakPickerChromatogram::IDX_RIGHTBORDER][i];
918 }
919 }
920 }
921
922 if (l_tmp > 1e-11) left_borders.push_back(l_tmp);
923 if (r_tmp > 1e-11) right_borders.push_back(r_tmp);
924
925 if (pfound == 0) missing_peaks++;
926 if (pfound > 1) multiple_peaks++;
927 }
928
929 // Check how many chromatograms had exactly one peak picked between our
930 // current left/right borders -> this would be a sign of consistency.
931 OPENMS_LOG_DEBUG << " Overall found missing : " << missing_peaks << " and multiple : " << multiple_peaks << std::endl;
932
934
935 // Is there one transitions that is very different from the rest (e.g.
936 // the same element has a bad shape and a bad coelution score) -> potential outlier
937 if (min_index_shape == max_index_coel)
938 {
939 OPENMS_LOG_DEBUG << " Element " << min_index_shape << " is a candidate for removal ... " << std::endl;
940 outlier = String(picked_chroms[min_index_shape].getNativeID());
941 }
942 else
943 {
944 outlier = "none";
945 }
946
947 // For the final score (larger is better), consider these scores:
948 // - missing_peaks (the more peaks are missing, the worse)
949 // - multiple_peaks
950 // - mean of the shapes (1 is very good, 0 is bad)
951 // - mean of the co-elution scores (0 is good, 1 is ok, above 1 is pretty bad)
952 double shape_score = std::accumulate(mean_shapes.begin(), mean_shapes.end(), 0.0) / mean_shapes.size();
953 double coel_score = std::accumulate(mean_coel.begin(), mean_coel.end(), 0.0) / mean_coel.size();
954 coel_score = (coel_score - 1.0) / 2.0;
955
956 double score = shape_score - coel_score - 1.0 * missing_peaks / picked_chroms.size();
957
958 OPENMS_LOG_DEBUG << " Computed score " << score << " (from " << shape_score <<
959 " - " << coel_score << " - " << 1.0 * missing_peaks / picked_chroms.size() << ")" << std::endl;
960
961 return score;
962 }
963
973 template <typename SpectrumT>
974 void recalculatePeakBorders_(const std::vector<SpectrumT>& picked_chroms, double& best_left, double& best_right, double max_z)
975 {
976 // 1. Collect all seeds that lie within the current seed
977 // - Per chromatogram only the most intense one counts, otherwise very
978 // - low intense peaks can contribute disproportionally to the voting
979 // - procedure.
980 // TODO Especially with DDA MS1 "transitions" from FFID, you often have exactly the same
981 // borders and the logs get confusing and you get -Nan CVs. You also might save time if you use a set here.
982 std::vector<double> left_borders;
983 std::vector<double> right_borders;
984 for (Size k = 0; k < picked_chroms.size(); k++)
985 {
986 double max_int = -1;
987 double left = -1;
988 double right = -1;
989 for (Size i = 0; i < picked_chroms[k].size(); i++)
990 {
991 if (picked_chroms[k][i].getPos() >= best_left && picked_chroms[k][i].getPos() <= best_right)
992 {
993 if (picked_chroms[k].getFloatDataArrays()[PeakPickerChromatogram::IDX_ABUNDANCE][i] > max_int)
994 {
995 max_int = picked_chroms[k].getFloatDataArrays()[PeakPickerChromatogram::IDX_ABUNDANCE][i];
996 left = picked_chroms[k].getFloatDataArrays()[PeakPickerChromatogram::IDX_LEFTBORDER][i];
997 right = picked_chroms[k].getFloatDataArrays()[PeakPickerChromatogram::IDX_RIGHTBORDER][i];
998 }
999 }
1000 }
1001 if (max_int > -1 )
1002 {
1003 left_borders.push_back(left);
1004 right_borders.push_back(right);
1005 OPENMS_LOG_DEBUG << " * peak " << k << " left boundary " << left_borders.back() << " with inty " << max_int << std::endl;
1006 OPENMS_LOG_DEBUG << " * peak " << k << " right boundary " << right_borders.back() << " with inty " << max_int << std::endl;
1007 }
1008 }
1009
1010 // Return for empty peak list
1011 if (right_borders.empty())
1012 {
1013 return;
1014 }
1015
1016 // FEATURE IDEA: instead of Z-score use modified Z-score for small data sets
1017 // http://d-scholarship.pitt.edu/7948/1/Seo.pdf
1018 // http://www.itl.nist.gov/div898/handbook/eda/section3/eda35h.htm
1019 // 1. calculate median
1020 // 2. MAD = calculate difference to median for each value -> take median of that
1021 // 3. Mi = 0.6745*(xi - median) / MAD
1022
1023 // 2. Calculate mean and standard deviation
1024 // If the coefficient of variation is too large for one border, we use a
1025 // "pseudo-median" instead of the border of the most intense peak.
1026 double mean, stdev;
1027
1028 // Right borders
1029 mean = std::accumulate(right_borders.begin(), right_borders.end(), 0.0) / (double) right_borders.size();
1030 stdev = std::sqrt(std::inner_product(right_borders.begin(), right_borders.end(), right_borders.begin(), 0.0)
1031 / right_borders.size() - mean * mean);
1032 std::sort(right_borders.begin(), right_borders.end());
1033
1034 OPENMS_LOG_DEBUG << " - Recalculating right peak boundaries " << mean << " mean / best "
1035 << best_right << " std " << stdev << " : " << std::fabs(best_right - mean) / stdev
1036 << " coefficient of variation" << std::endl;
1037
1038 // Compare right borders of best transition with the mean
1039 if (std::fabs(best_right - mean) / stdev > max_z)
1040 {
1041 best_right = right_borders[right_borders.size() / 2]; // pseudo median
1042 OPENMS_LOG_DEBUG << " - CV too large: correcting right boundary to " << best_right << std::endl;
1043 }
1044
1045 // Left borders
1046 mean = std::accumulate(left_borders.begin(), left_borders.end(), 0.0) / (double) left_borders.size();
1047 stdev = std::sqrt(std::inner_product(left_borders.begin(), left_borders.end(), left_borders.begin(), 0.0)
1048 / left_borders.size() - mean * mean);
1049 std::sort(left_borders.begin(), left_borders.end());
1050
1051 OPENMS_LOG_DEBUG << " - Recalculating left peak boundaries " << mean << " mean / best "
1052 << best_left << " std " << stdev << " : " << std::fabs(best_left - mean) / stdev
1053 << " coefficient of variation" << std::endl;
1054
1055 // Compare left borders of best transition with the mean
1056 if (std::fabs(best_left - mean) / stdev > max_z)
1057 {
1058 best_left = left_borders[left_borders.size() / 2]; // pseudo median
1059 OPENMS_LOG_DEBUG << " - CV too large: correcting left boundary to " << best_left << std::endl;
1060 }
1061
1062 }
1063
1065
1066
1081 template <typename PeakContainerT>
1082 void prepareMasterContainer_(const PeakContainerT& ref_chromatogram,
1083 PeakContainerT& master_peak_container,
1084 double left_boundary,
1085 double right_boundary)
1086 {
1087 OPENMS_PRECONDITION(master_peak_container.empty(), "Master peak container must be empty")
1088
1089 // get the start / end point of this chromatogram => then add one more
1090 // point beyond the two boundaries to make the resampling accurate also
1091 // at the edge.
1092 auto begin = ref_chromatogram.begin();
1093 while (begin != ref_chromatogram.end() && begin->getPos() < left_boundary) {begin++; }
1094 if (begin != ref_chromatogram.begin()) { begin--; }
1095
1096 auto end = begin;
1097 while (end != ref_chromatogram.end() && end->getPos() < right_boundary) {end++; }
1098 if (end != ref_chromatogram.end()) { end++; }
1099
1100 // resize the master container and set the m/z values to the ones of the master container
1101 master_peak_container.resize(distance(begin, end)); // initialize to zero
1102 auto it = master_peak_container.begin();
1103 for (auto chrom_it = begin; chrom_it != end; chrom_it++, it++)
1104 {
1105 it->setPos(chrom_it->getPos());
1106 }
1107 }
1108
1119 template <typename PeakContainerT>
1120 PeakContainerT resampleChromatogram_(const PeakContainerT& chromatogram,
1121 const PeakContainerT& master_peak_container,
1122 double left_boundary,
1123 double right_boundary)
1124 {
1125 // get the start / end point of this chromatogram => then add one more
1126 // point beyond the two boundaries to make the resampling accurate also
1127 // at the edge.
1128 auto begin = chromatogram.begin();
1129 while (begin != chromatogram.end() && begin->getPos() < left_boundary) {begin++;}
1130 if (begin != chromatogram.begin()) { begin--; }
1131
1132 auto end = begin;
1133 while (end != chromatogram.end() && end->getPos() < right_boundary) {end++;}
1134 if (end != chromatogram.end()) { end++; }
1135
1136 auto resampled_peak_container = master_peak_container; // copy the master container, which contains the RT values
1137 LinearResamplerAlign lresampler;
1138 lresampler.raster(begin, end, resampled_peak_container.begin(), resampled_peak_container.end());
1139
1140 return resampled_peak_container;
1141 }
1142
1144
1145 // Members
1155
1161
1168
1171 };
1172}
1173
1174
#define OPENMS_LOG_DEBUG
Macro for debug information - includes file and line info.
Definition LogStream.h:558
const String & getNativeID() const
returns the native identifier for the spectrum, used by the acquisition software.
void setNativeID(const String &native_id)
sets the native identifier for the spectrum, used by the acquisition software.
Definition ConvexHull2D.h:49
void setHullPoints(const PointArrayType &points)
accessor for the outer(!) points (no checking is performed if this is actually a convex hull)
Representation of a coordinate in D-dimensional space.
Definition DPosition.h:32
A base class for all classes handling default parameters.
Definition DefaultParamHandler.h:66
A method or algorithm argument contains illegal values.
Definition Exception.h:630
An LC-MS feature.
Definition Feature.h:46
const std::vector< ConvexHull2D > & getConvexHulls() const
Non-mutable access to the convex hulls.
void setQuality(Size index, QualityType q)
Set the quality in dimension c.
void setOverallQuality(QualityType q)
Set the overall quality.
Linear Resampling of raw data with alignment.
Definition LinearResamplerAlign.h:33
void raster(PeakContainerT &container)
Applies the resampling algorithm to a container (MSSpectrum or MSChromatogram).
Definition LinearResamplerAlign.h:54
A multi-chromatogram MRM feature.
Definition MRMFeature.h:26
void addFeature(const Feature &feature, const String &key)
Adds an feature from a single chromatogram into the feature.
void addPrecursorFeature(const Feature &feature, const String &key)
Adds a precursor feature from a single chromatogram into the feature.
The MRMTransitionGroupPicker finds peaks in chromatograms that belong to the same precursors.
Definition MRMTransitionGroupPicker.h:55
void findLargestPeak(const std::vector< MSChromatogram > &picked_chroms, int &chr_idx, int &peak_idx)
Find largest peak in a vector of chromatograms.
void prepareMasterContainer_(const PeakContainerT &ref_chromatogram, PeakContainerT &master_peak_container, double left_boundary, double right_boundary)
Create an empty master peak container that has the correct mz / RT values set.
Definition MRMTransitionGroupPicker.h:1082
String boundary_selection_method_
Which method to use for selecting peaks' boundaries.
Definition MRMTransitionGroupPicker.h:1167
const SpectrumT & selectChromHelper_(const MRMTransitionGroup< SpectrumT, TransitionT > &transition_group, const String &native_id)
Select matching precursor or fragment ion chromatogram.
Definition MRMTransitionGroupPicker.h:790
String peak_integration_
Definition MRMTransitionGroupPicker.h:1146
bool compute_total_mi_
Definition MRMTransitionGroupPicker.h:1153
String background_subtraction_
Definition MRMTransitionGroupPicker.h:1147
bool compute_peak_quality_
Definition MRMTransitionGroupPicker.h:1151
bool use_precursors_
Definition MRMTransitionGroupPicker.h:1149
PeakContainerT resampleChromatogram_(const PeakContainerT &chromatogram, const PeakContainerT &master_peak_container, double left_boundary, double right_boundary)
Resample a container at the positions indicated by the master peak container.
Definition MRMTransitionGroupPicker.h:1120
void pickApex(std::vector< SpectrumT > &picked_chroms, const double best_left, const double best_right, const double peak_apex, double &min_left, double &max_right, std::vector< double > &left_edges, std::vector< double > &right_edges)
Apex-based peak picking.
Definition MRMTransitionGroupPicker.h:325
double min_peak_width_
Definition MRMTransitionGroupPicker.h:1158
void remove_overlapping_features(std::vector< SpectrumT > &picked_chroms, double best_left, double best_right)
Remove overlapping features.
Definition MRMTransitionGroupPicker.h:727
void recalculatePeakBorders_(const std::vector< SpectrumT > &picked_chroms, double &best_left, double &best_right, double max_z)
Recalculate the borders of the peak.
Definition MRMTransitionGroupPicker.h:974
int stop_after_feature_
Definition MRMTransitionGroupPicker.h:1156
PeakPickerChromatogram picker_
Definition MRMTransitionGroupPicker.h:1169
double recalculate_peaks_max_z_
Definition MRMTransitionGroupPicker.h:1159
PeakIntegrator pi_
Definition MRMTransitionGroupPicker.h:1170
void findWidestPeakIndices(const std::vector< MSChromatogram > &picked_chroms, Int &chrom_idx, Int &point_idx) const
Given a vector of chromatograms, find the indices of the chromatogram containing the widest peak and ...
double min_qual_
Definition MRMTransitionGroupPicker.h:1154
double resample_boundary_
Definition MRMTransitionGroupPicker.h:1160
MRMFeature createMRMFeature(const MRMTransitionGroup< SpectrumT, TransitionT > &transition_group, std::vector< SpectrumT > &picked_chroms, const std::vector< SpectrumT > &smoothed_chroms, const int chr_idx, const int peak_idx)
Create feature from a vector of chromatograms and a specified peak.
Definition MRMTransitionGroupPicker.h:200
~MRMTransitionGroupPicker() override
Destructor.
void updateMembers_() override
Synchronize members with param class.
double computeQuality_(const MRMTransitionGroup< SpectrumT, TransitionT > &transition_group, const std::vector< SpectrumT > &picked_chroms, const int chr_idx, const double best_left, const double best_right, String &outlier)
Compute transition group quality (higher score is better)
Definition MRMTransitionGroupPicker.h:823
double stop_after_intensity_ratio_
Definition MRMTransitionGroupPicker.h:1157
void pickTransitionGroup(MRMTransitionGroup< SpectrumT, TransitionT > &transition_group)
Pick a group of chromatograms belonging to the same peptide.
Definition MRMTransitionGroupPicker.h:87
MRMTransitionGroupPicker & operator=(const MRMTransitionGroupPicker &rhs)
Assignment operator is protected for algorithm.
bool use_consensus_
Definition MRMTransitionGroupPicker.h:1150
void pickFragmentChromatograms(const MRMTransitionGroup< SpectrumT, TransitionT > &transition_group, const std::vector< SpectrumT > &picked_chroms, MRMFeature &mrmFeature, const std::vector< SpectrumT > &smoothed_chroms, const double best_left, const double best_right, const bool use_consensus_, double &total_intensity, double &total_xic, double &total_mi, double &total_peak_apices, const SpectrumT &master_peak_container, const std::vector< double > &left_edges, const std::vector< double > &right_edges, const int chr_idx, const int peak_idx)
Definition MRMTransitionGroupPicker.h:366
bool recalculate_peaks_
Definition MRMTransitionGroupPicker.h:1148
void pickPrecursorChromatograms(const MRMTransitionGroup< SpectrumT, TransitionT > &transition_group, const std::vector< SpectrumT > &picked_chroms, MRMFeature &mrmFeature, const std::vector< SpectrumT > &smoothed_chroms, const double best_left, const double best_right, const bool use_consensus_, double &total_intensity, const SpectrumT &master_peak_container, const std::vector< double > &left_edges, const std::vector< double > &right_edges, const int chr_idx, const int peak_idx)
Definition MRMTransitionGroupPicker.h:583
bool compute_peak_shape_metrics_
Definition MRMTransitionGroupPicker.h:1152
The representation of a group of transitions in a targeted proteomics experiment.
Definition MRMTransitionGroup.h:42
const String & getTransitionGroupID() const
Definition MRMTransitionGroup.h:104
const std::vector< TransitionType > & getTransitions() const
Definition MRMTransitionGroup.h:116
bool hasPrecursorChromatogram(const String &key) const
Definition MRMTransitionGroup.h:242
bool isInternallyConsistent() const
Check whether internal state is consistent, e.g. same number of chromatograms and transitions are pre...
Definition MRMTransitionGroup.h:291
ChromatogramType & getPrecursorChromatogram(const String &key)
Definition MRMTransitionGroup.h:247
bool chromatogramIdsMatch() const
Ensure that chromatogram native ids match their keys in the map.
Definition MRMTransitionGroup.h:300
bool hasTransition(const String &key) const
Definition MRMTransitionGroup.h:144
bool hasChromatogram(const String &key) const
Definition MRMTransitionGroup.h:188
const TransitionType & getTransition(const String &key)
Definition MRMTransitionGroup.h:149
void addFeature(const MRMFeature &feature)
Definition MRMTransitionGroup.h:275
ChromatogramType & getChromatogram(const String &key)
Definition MRMTransitionGroup.h:193
std::vector< ChromatogramType > & getPrecursorChromatograms()
Definition MRMTransitionGroup.h:211
std::vector< ChromatogramType > & getChromatograms()
Definition MRMTransitionGroup.h:160
The representation of a chromatogram.
Definition MSChromatogram.h:30
void sortByIntensity(bool reverse=false)
Lexicographically sorts the peaks by their intensity.
void setMetaValue(const String &name, const DataValue &value)
Sets the DataValue corresponding to a name.
const DataValue & getMetaValue(const String &name) const
Returns the value corresponding to a string, or DataValue::EMPTY if not found.
void setMZ(CoordinateType coordinate)
Mutable access to the m/z coordinate (index 1)
Definition Peak2D.h:179
void setRT(CoordinateType coordinate)
Mutable access to the RT coordinate (index 0)
Definition Peak2D.h:191
IntensityType getIntensity() const
Definition Peak2D.h:143
void setIntensity(IntensityType intensity)
Sets data point intensity (height)
Definition Peak2D.h:149
Compute the area, background and shape metrics of a peak.
Definition PeakIntegrator.h:87
Int points_across_half_height
Definition PeakIntegrator.h:224
double apex_pos
Definition PeakIntegrator.h:111
ConvexHull2D::PointArrayType hull_points
Definition PeakIntegrator.h:115
double width_at_5
Definition PeakIntegrator.h:146
Int points_across_baseline
Definition PeakIntegrator.h:220
double width_at_50
Definition PeakIntegrator.h:154
double end_position_at_50
Definition PeakIntegrator.h:178
double baseline_delta_2_height
Definition PeakIntegrator.h:216
double height
Definition PeakIntegrator.h:107
double end_position_at_10
Definition PeakIntegrator.h:174
double width_at_10
Definition PeakIntegrator.h:150
double total_width
Definition PeakIntegrator.h:182
double end_position_at_5
Definition PeakIntegrator.h:170
double start_position_at_50
Definition PeakIntegrator.h:166
double tailing_factor
Definition PeakIntegrator.h:196
double slope_of_baseline
Definition PeakIntegrator.h:211
double start_position_at_10
Definition PeakIntegrator.h:162
double asymmetry_factor
Definition PeakIntegrator.h:206
double start_position_at_5
Definition PeakIntegrator.h:158
double area
Definition PeakIntegrator.h:103
Definition PeakIntegrator.h:99
Definition PeakIntegrator.h:124
Definition PeakIntegrator.h:142
The PeakPickerChromatogram finds peaks a single chromatogram.
Definition PeakPickerChromatogram.h:44
A more convenient string class.
Definition String.h:32
Size ensureUniqueId()
Assigns a valid unique id, but only if the present one is invalid. Returns 1 if the unique id was cha...
functor to compute the mean and stddev of sequence using the std::foreach algorithm
Definition StatsHelpers.h:147
double mean() const
Definition StatsHelpers.h:184
int Int
Signed integer type.
Definition Types.h:72
unsigned int UInt
Unsigned integer type.
Definition Types.h:64
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition Types.h:97
#define OPENMS_PRECONDITION(condition, message)
Precondition macro.
Definition openms/include/OpenMS/CONCEPT/Macros.h:94
Main OpenMS namespace.
Definition openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19
OPENSWATHALGO_DLLAPI XCorrArrayType normalizedCrossCorrelation(std::vector< double > &data1, std::vector< double > &data2, const int maxdelay, const int lag)
OPENSWATHALGO_DLLAPI unsigned int computeAndAppendRank(const std::vector< double > &v, std::vector< unsigned int > &ranks)
OPENSWATHALGO_DLLAPI double rankedMutualInformation(std::vector< unsigned int > &ranked_data1, std::vector< unsigned int > &ranked_data2, const unsigned int max_rank1, const unsigned int max_rank2)
OPENSWATHALGO_DLLAPI XCorrArrayType::const_iterator xcorrArrayGetMaxPeak(const XCorrArrayType &array)
Find best peak in an cross-correlation (highest apex)
Definition Scoring.h:46