00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef OPENMS_ANALYSIS_OPENSWATH_MRMTRANSITIONGROUPPICKER_H
00036 #define OPENMS_ANALYSIS_OPENSWATH_MRMTRANSITIONGROUPPICKER_H
00037
00038 #include <OpenMS/KERNEL/MRMTransitionGroup.h>
00039 #include <OpenMS/KERNEL/MRMFeature.h>
00040 #include <OpenMS/KERNEL/MSSpectrum.h>
00041 #include <OpenMS/KERNEL/MSChromatogram.h>
00042 #include <OpenMS/KERNEL/ChromatogramPeak.h>
00043
00044 #include <OpenMS/FILTERING/NOISEESTIMATION/SignalToNoiseEstimatorMedian.h>
00045 #include <OpenMS/FILTERING/SMOOTHING/SavitzkyGolayFilter.h>
00046 #include <OpenMS/FILTERING/SMOOTHING/GaussFilter.h>
00047
00048 #include <OpenMS/FILTERING/TRANSFORMERS/LinearResampler.h>
00049 #include <OpenMS/FILTERING/TRANSFORMERS/LinearResamplerAlign.h>
00050
00051 #include <OpenMS/TRANSFORMATIONS/RAW2PEAK/PeakPickerHiRes.h>
00052
00053
00054
00055 namespace OpenMS
00056 {
00057
00076 class OPENMS_DLLAPI MRMTransitionGroupPicker :
00077 public DefaultParamHandler
00078 {
00079
00080 public:
00081
00082
00083 typedef MSSpectrum<ChromatogramPeak> RichPeakChromatogram;
00084
00085 protected:
00086 UInt sgolay_frame_length_;
00087 UInt sgolay_polynomial_order_;
00088 DoubleReal gauss_width_;
00089 bool use_gauss_;
00090
00091 String background_subtraction_;
00092
00093 DoubleReal peak_width_;
00094 DoubleReal signal_to_noise_;
00095
00096 DoubleReal sn_win_len_;
00097 UInt sn_bin_count_;
00098
00099 int stop_after_feature_;
00100 DoubleReal stop_after_intensity_ratio_;
00101
00102 std::vector<RichPeakChromatogram> picked_chroms_;
00103 std::vector<RichPeakChromatogram> smoothed_chroms_;
00104
00106
00107
00108 template <typename SpectrumT, typename TransitionT>
00109 void prepareMasterContainer_(MRMTransitionGroup<SpectrumT, TransitionT> & transition_group,
00110 SpectrumT & master_peak_container, int chr_idx, double best_left, double best_right)
00111 {
00112 const SpectrumT & ref_chromatogram = transition_group.getChromatograms()[chr_idx];
00113
00114
00115 typename SpectrumT::const_iterator begin = ref_chromatogram.begin();
00116 while (begin != ref_chromatogram.end() && begin->getMZ() < best_left) {begin++; }
00117 if (begin != ref_chromatogram.begin()) {begin--; }
00118
00119 typename SpectrumT::const_iterator end = begin;
00120 while (end != ref_chromatogram.end() && end->getMZ() < best_right) {end++; }
00121 if (end != ref_chromatogram.end()) {end++; }
00122
00123
00124 master_peak_container.resize(distance(begin, end));
00125 typename SpectrumT::iterator it = master_peak_container.begin();
00126 for (typename SpectrumT::const_iterator chrom_it = begin; chrom_it != end; chrom_it++, it++)
00127 {
00128 it->setMZ(chrom_it->getMZ());
00129 }
00130 }
00131
00133 template <typename SpectrumT>
00134 SpectrumT resampleChromatogram_(const SpectrumT & chromatogram,
00135 SpectrumT & master_peak_container, double best_left, double best_right)
00136 {
00137
00138
00139
00140 typename SpectrumT::const_iterator begin = chromatogram.begin();
00141 while (begin != chromatogram.end() && begin->getMZ() < best_left) {begin++; }
00142 if (begin != chromatogram.begin()) {begin--; }
00143
00144 typename SpectrumT::const_iterator end = begin;
00145 while (end != chromatogram.end() && end->getMZ() < best_right) {end++; }
00146 if (end != chromatogram.end()) {end++; }
00147
00148 SpectrumT resampled_peak_container = master_peak_container;
00149 LinearResamplerAlign lresampler;
00150 lresampler.raster(begin, end, resampled_peak_container.begin(), resampled_peak_container.end());
00151
00152 #if DEBUG_TRANSITIONGROUPPICKER
00153 {
00154 std::cout << "=========================================================================== " << std::endl;
00155 double tot;
00156 tot = 0;
00157 for (typename SpectrumT::const_iterator it = begin; it != end; it++)
00158 {
00159 std::cout << " before resampl " << *it << std::endl;
00160 tot += it->getIntensity();
00161 }
00162 std::cout << " total " << tot << std::endl;
00163
00164 tot = 0;
00165 for (typename SpectrumT::iterator it = resampled_peak_container.begin(); it != resampled_peak_container.end(); it++)
00166 {
00167 std::cout << " resampl " << *it << std::endl;
00168 tot += it->getIntensity();
00169 }
00170 std::cout << " total " << tot << std::endl;
00171 std::cout << " resampled size " << resampled_peak_container.size() << std::endl;
00172 }
00173 #endif
00174 return resampled_peak_container;
00175 }
00176
00178
00180 double calculateBgEstimation_(const RichPeakChromatogram& smoothed_chromat, double best_left, double best_right);
00181
00183 void updateMembers_();
00184
00186 MRMTransitionGroupPicker& operator=(const MRMTransitionGroupPicker& rhs);
00187
00188 public:
00189
00191
00192 MRMTransitionGroupPicker();
00193
00195 ~MRMTransitionGroupPicker();
00197
00201 template <typename SpectrumT, typename TransitionT>
00202 void pickTransitionGroup(MRMTransitionGroup<SpectrumT, TransitionT> & transition_group)
00203 {
00204
00205 picked_chroms_.clear();
00206 for (Size k = 0; k < transition_group.getChromatograms().size(); k++)
00207 {
00208 RichPeakChromatogram& chromatogram = transition_group.getChromatograms()[k];
00209 if (!chromatogram.isSorted()) { chromatogram.sortByPosition(); }
00210
00211
00212 RichPeakChromatogram picked_chrom, smoothed_chrom;
00213 pickChromatogram(chromatogram, smoothed_chrom, picked_chrom);
00214 picked_chrom.sortByIntensity();
00215 picked_chroms_.push_back(picked_chrom);
00216 smoothed_chroms_.push_back(smoothed_chrom);
00217 }
00218
00219
00220
00221
00222
00223 int chr_idx, peak_idx, cnt = 0;
00224 while (true)
00225 {
00226 chr_idx = -1; peak_idx = -1;
00227 findLargestPeak(picked_chroms_, chr_idx, peak_idx);
00228 if (chr_idx == -1 && peak_idx == -1) break;
00229
00230
00231
00232
00233
00234
00235
00236
00237 MRMFeature mrm_feature = createMRMFeature(transition_group, picked_chroms_, chr_idx, peak_idx);
00238 if (mrm_feature.getIntensity() > 0)
00239 {
00240 transition_group.addFeature(mrm_feature);
00241 }
00242
00243 cnt++;
00244 if ((stop_after_feature_ > 0 && cnt > stop_after_feature_) && mrm_feature.getIntensity() / (double)mrm_feature.getMetaValue("total_xic") < stop_after_intensity_ratio_)
00245 {
00246 break;
00247 }
00248 }
00249 }
00250
00252
00253 void pickChromatogram(const RichPeakChromatogram& chromatogram, RichPeakChromatogram& smoothed_chrom, RichPeakChromatogram& picked_chrom);
00254
00256 template <typename SpectrumT, typename TransitionT>
00257 MRMFeature createMRMFeature(MRMTransitionGroup<SpectrumT, TransitionT> & transition_group,
00258 std::vector<SpectrumT> & picked_chroms, int & chr_idx, int & peak_idx)
00259 {
00260 MRMFeature mrmFeature;
00261 const double best_left = picked_chroms[chr_idx].getFloatDataArrays()[1][peak_idx];
00262 const double best_right = picked_chroms[chr_idx].getFloatDataArrays()[2][peak_idx];
00263 const double peak_apex = picked_chroms[chr_idx][peak_idx].getRT();
00264
00265
00266
00267
00268 remove_overlapping_features(picked_chroms, best_left, best_right);
00269 picked_chroms[chr_idx][peak_idx].setIntensity(0.0);
00270
00271
00272
00273
00274 SpectrumT master_peak_container;
00275 prepareMasterContainer_(transition_group, master_peak_container, chr_idx, best_left, best_right);
00276
00277 double total_intensity = 0; double total_peak_apices = 0; double total_xic = 0;
00278 for (Size k = 0; k < transition_group.getChromatograms().size(); k++)
00279 {
00280 const SpectrumT& chromatogram = transition_group.getChromatograms()[k];
00281 for (typename SpectrumT::const_iterator it = chromatogram.begin(); it != chromatogram.end(); it++)
00282 {
00283 total_xic += it->getIntensity();
00284 }
00285
00286
00287 const SpectrumT used_chromatogram = resampleChromatogram_(chromatogram, master_peak_container, best_left, best_right);
00288
00289
00290 Feature f;
00291 double quality = 0;
00292 f.setQuality(0, quality);
00293 f.setOverallQuality(quality);
00294
00295 ConvexHull2D::PointArrayType hull_points;
00296 DoubleReal intensity_sum(0.0), rt_sum(0.0);
00297 double peak_apex_int = -1;
00298 double peak_apex_dist = std::fabs(used_chromatogram.begin()->getMZ() - peak_apex);
00299
00300 for (typename SpectrumT::const_iterator it = used_chromatogram.begin(); it != used_chromatogram.end(); it++)
00301 {
00302 if (it->getMZ() > best_left && it->getMZ() < best_right)
00303 {
00304 DPosition<2> p;
00305 p[0] = it->getMZ();
00306 p[1] = it->getIntensity();
00307 hull_points.push_back(p);
00308 if (std::fabs(it->getMZ() - peak_apex) <= peak_apex_dist)
00309 {
00310 peak_apex_int = p[1];
00311 peak_apex_dist = std::fabs(it->getMZ() - peak_apex);
00312 }
00313 rt_sum += it->getMZ();
00314 intensity_sum += it->getIntensity();
00315 }
00316 }
00317
00318 if (background_subtraction_ != "none")
00319 {
00320 double background = 0;
00321
00322 if (background_subtraction_ == "smoothed")
00323 {
00324 if (smoothed_chroms_.size() <= k)
00325 {
00326 std::cerr << "Tried to calculate background estimation without any smoothed chromatograms" << std::endl;
00327 background = 0;
00328 }
00329 else
00330 {
00331 background = calculateBgEstimation_(smoothed_chroms_[k], best_left, best_right);
00332 }
00333 }
00334 else if (background_subtraction_ == "original")
00335 {
00336 background = calculateBgEstimation_(used_chromatogram, best_left, best_right);
00337 }
00338 intensity_sum -= background;
00339 if (intensity_sum < 0)
00340 {
00341 std::cerr << "Warning: Intensity was below 0 after background subtraction: " << intensity_sum << ". Setting it to 0." << std::endl;
00342 intensity_sum = 0;
00343 }
00344 }
00345
00346 f.setRT(picked_chroms[chr_idx][peak_idx].getMZ());
00347 f.setMZ(chromatogram.getMetaValue("product_mz"));
00348 f.setIntensity(intensity_sum);
00349 ConvexHull2D hull;
00350 hull.setHullPoints(hull_points);
00351 f.getConvexHulls().push_back(hull);
00352 f.setMetaValue("MZ", chromatogram.getMetaValue("product_mz"));
00353 f.setMetaValue("native_id", chromatogram.getNativeID());
00354 f.setMetaValue("peak_apex_int", peak_apex_int);
00355
00356
00357
00358 total_intensity += intensity_sum;
00359 total_peak_apices += peak_apex_int;
00360 mrmFeature.addFeature(f, chromatogram.getNativeID());
00361 }
00362 mrmFeature.setRT(picked_chroms[chr_idx][peak_idx].getMZ());
00363 mrmFeature.setIntensity(total_intensity);
00364 mrmFeature.setMetaValue("PeptideRef", transition_group.getTransitionGroupID());
00365 mrmFeature.setMetaValue("leftWidth", best_left);
00366 mrmFeature.setMetaValue("rightWidth", best_right);
00367 mrmFeature.setMetaValue("total_xic", total_xic);
00368 mrmFeature.setMetaValue("peak_apices_sum", total_peak_apices);
00369
00370 return mrmFeature;
00371 }
00372
00373
00374
00376 template <typename SpectrumT>
00377 void remove_overlapping_features(std::vector<SpectrumT> & picked_chroms, double best_left, double best_right)
00378 {
00379
00380 for (Size k = 0; k < picked_chroms.size(); k++)
00381 {
00382 for (Size i = 0; i < picked_chroms[k].size(); i++)
00383 {
00384 if (picked_chroms[k][i].getMZ() >= best_left && picked_chroms[k][i].getMZ() <= best_right)
00385 {
00386 picked_chroms[k][i].setIntensity(0.0);
00387 }
00388 }
00389 }
00390
00391
00392 for (Size k = 0; k < picked_chroms.size(); k++)
00393 {
00394 for (Size i = 0; i < picked_chroms[k].size(); i++)
00395 {
00396 double left = picked_chroms[k].getFloatDataArrays()[1][i];
00397 double right = picked_chroms[k].getFloatDataArrays()[2][i];
00398 if ((left >= best_left && left <= best_right)
00399 || (right >= best_left && right <= best_right))
00400 {
00401 picked_chroms[k][i].setIntensity(0.0);
00402 }
00403 }
00404 }
00405 }
00406
00408 void findLargestPeak(std::vector<RichPeakChromatogram>& picked_chroms, int& chr_idx, int& peak_idx);
00409 };
00410 }
00411
00412 #endif