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_CHROMATOGRAMEXTRACTOR_H
00036 #define OPENMS_ANALYSIS_OPENSWATH_CHROMATOGRAMEXTRACTOR_H
00037
00038 #include <OpenMS/KERNEL/MSExperiment.h>
00039 #include <OpenMS/ANALYSIS/TARGETED/TargetedExperiment.h>
00040
00041
00042 #include <OpenMS/FORMAT/TransformationXMLFile.h>
00043 #include <OpenMS/FORMAT/MzMLFile.h>
00044
00045 #ifdef _OPENMP
00046 #include <omp.h>
00047 #endif
00048
00049 namespace OpenMS
00050 {
00051
00061 class OPENMS_DLLAPI ChromatogramExtractor :
00062 public ProgressLogger
00063 {
00064
00065 public:
00066
00068 ChromatogramExtractor()
00069 {
00070 }
00071
00073 ~ChromatogramExtractor()
00074 {
00075 }
00076
00078 template <typename ExperimentT>
00079 void extractChromatograms(const ExperimentT& input, ExperimentT& output, OpenMS::TargetedExperiment& transition_exp, double extract_window, bool ppm,
00080 TransformationDescription trafo, double rt_extraction_window, String filter)
00081 {
00082
00083
00084 trafo.invert();
00085
00086 Size input_size = input.size();
00087 if (input_size < 1)
00088 {
00089 return;
00090 }
00091 SpectrumSettings settings = input[0];
00092 int used_filter = -1;
00093 if (filter == "tophat")
00094 {
00095 used_filter = 1;
00096 }
00097 else if (filter == "bartlett")
00098 {
00099 used_filter = 2;
00100 }
00101 else
00102 {
00103 throw Exception::IllegalArgument(__FILE__, __LINE__, __PRETTY_FUNCTION__,
00104 "Filter either needs to be tophat or bartlett");
00105 }
00106
00107
00108 PeptideRTMap_.clear();
00109 for (Size i = 0; i < transition_exp.getPeptides().size(); i++)
00110 {
00111 const TargetedExperiment::Peptide& pep = transition_exp.getPeptides()[i];
00112 if (pep.rts.empty() || pep.rts[0].getCVTerms()["MS:1000896"].empty())
00113 {
00114
00115
00116 if (rt_extraction_window >= 0)
00117 {
00118 throw Exception::IllegalArgument(__FILE__, __LINE__, __PRETTY_FUNCTION__,
00119 "Error: Peptide " + pep.id + " does not have normalized retention times (term 1000896) which are necessary to perform an RT-limited extraction");
00120 }
00121 continue;
00122 }
00123 PeptideRTMap_[pep.id] = pep.rts[0].getCVTerms()["MS:1000896"][0].getValue().toString().toDouble();
00124 }
00125
00126
00127
00128 transition_exp.sortTransitionsByProductMZ();
00129
00130
00131 std::vector<typename ExperimentT::ChromatogramType> chromatograms;
00132 prepareSpectra_(settings, chromatograms, transition_exp);
00133
00134
00135 startProgress(0, input_size, "Extracting chromatograms");
00136 for (Size scan_idx = 0; scan_idx < input_size; ++scan_idx)
00137 {
00138 setProgress(scan_idx);
00139
00140 if (input[scan_idx].size() == 0)
00141 continue;
00142
00143 Size peak_idx = 0;
00144
00145 double mz;
00146 double integrated_intensity = 0;
00147
00148
00149
00150
00151
00152 for (Size k = 0; k < chromatograms.size(); ++k)
00153 {
00154
00155 double current_rt = input[scan_idx].getRT();
00156 if (outsideExtractionWindow_(transition_exp.getTransitions()[k], current_rt, trafo, rt_extraction_window))
00157 {
00158 continue;
00159 }
00160
00161 typename ExperimentT::ChromatogramType::PeakType p;
00162 mz = transition_exp.getTransitions()[k].getProductMZ();
00163
00164 if (used_filter == 1)
00165 {
00166 extract_value_tophat(input[scan_idx], mz, peak_idx, integrated_intensity, extract_window, ppm);
00167 }
00168 else if (used_filter == 2)
00169 {
00170 extract_value_bartlett(input[scan_idx], mz, peak_idx, integrated_intensity, extract_window, ppm);
00171 }
00172
00173 p.setRT(current_rt);
00174 p.setIntensity(integrated_intensity);
00175 chromatograms[k].push_back(p);
00176 }
00177 }
00178 endProgress();
00179
00180
00181 output.setChromatograms(chromatograms);
00182 }
00183
00184 public:
00185
00186 template <typename SpectrumT>
00187 void extract_value_tophat(const SpectrumT& input, const double& mz, Size& peak_idx, double& integrated_intensity, const double& extract_window, const bool ppm)
00188 {
00189 integrated_intensity = 0;
00190 if (input.size() == 0)
00191 {
00192 return;
00193 }
00194
00195
00196 double left, right;
00197 if (ppm)
00198 {
00199 left = mz - mz * extract_window / 2.0 * 1.0e-6;
00200 right = mz + mz * extract_window / 2.0 * 1.0e-6;
00201 }
00202 else
00203 {
00204 left = mz - extract_window / 2.0;
00205 right = mz + extract_window / 2.0;
00206 }
00207
00208 Size walker;
00209
00210
00211 while (peak_idx < input.size() && input[peak_idx].getMZ() < mz)
00212 {
00213 peak_idx++;
00214 }
00215
00216 integrated_intensity = 0;
00217
00218
00219 walker = peak_idx;
00220
00221 if (peak_idx >= input.size())
00222 {
00223 walker = input.size() - 1;
00224 }
00225
00226
00227 if (input[walker].getMZ() > left && input[walker].getMZ() < right)
00228 {
00229 integrated_intensity += input[walker].getIntensity();
00230 }
00231
00232
00233 walker = peak_idx;
00234 if (walker > 0)
00235 {
00236 walker--;
00237 }
00238 while (walker > 0 && input[walker].getMZ() > left && input[walker].getMZ() < right)
00239 {
00240 integrated_intensity += input[walker].getIntensity(); walker--;
00241 }
00242 walker = peak_idx;
00243 if (walker < input.size() )
00244 {
00245 walker++;
00246 }
00247 while (walker<input.size() && input[walker].getMZ()> left && input[walker].getMZ() < right)
00248 {
00249 integrated_intensity += input[walker].getIntensity(); walker++;
00250 }
00251 }
00252
00253 template <typename SpectrumT>
00254 void extract_value_bartlett(const SpectrumT& input, const double& mz, Size& peak_idx, double& integrated_intensity, const double& extract_window, const bool ppm)
00255 {
00256 integrated_intensity = 0;
00257 if (input.size() == 0)
00258 {
00259 return;
00260 }
00261
00262
00263 double left, right, half_window_size, weight;
00264 if (ppm)
00265 {
00266 half_window_size = mz * extract_window / 2.0 * 1.0e-6;
00267 left = mz - mz * extract_window / 2.0 * 1.0e-6;
00268 right = mz + mz * extract_window / 2.0 * 1.0e-6;
00269 }
00270 else
00271 {
00272 half_window_size = extract_window / 2.0;
00273 left = mz - extract_window / 2.0;
00274 right = mz + extract_window / 2.0;
00275 }
00276
00277 Size walker;
00278
00279
00280 while (peak_idx < input.size() && input[peak_idx].getMZ() < mz)
00281 {
00282 peak_idx++;
00283 }
00284
00285
00286
00287 walker = peak_idx;
00288
00289 if (peak_idx >= input.size())
00290 {
00291 walker = input.size() - 1;
00292 }
00293
00294
00295 if (input[walker].getMZ() > left && input[walker].getMZ() < right)
00296 {
00297 weight = 1 - fabs(input[walker].getMZ() - mz) / half_window_size;
00298 integrated_intensity += input[walker].getIntensity() * weight;
00299 }
00300
00301
00302 walker = peak_idx;
00303 if (walker > 0 )
00304 {
00305 walker--;
00306 }
00307 while (walker > 0 && input[walker].getMZ() > left && input[walker].getMZ() < right)
00308 {
00309 weight = 1 - fabs(input[walker].getMZ() - mz) / half_window_size;
00310 integrated_intensity += input[walker].getIntensity() * weight; walker--;
00311 }
00312 walker = peak_idx;
00313 if (walker < input.size() )
00314 {
00315 walker++;
00316 }
00317 while (walker<input.size() && input[walker].getMZ()> left && input[walker].getMZ() < right)
00318 {
00319 weight = 1 - fabs(input[walker].getMZ() - mz) / half_window_size;
00320 integrated_intensity += input[walker].getIntensity() * weight; walker++;
00321 }
00322 }
00323
00324 void extract_value_tophat(const std::vector<double>::const_iterator& mz_start, std::vector<double>::const_iterator& mz_it,
00325 const std::vector<double>::const_iterator& mz_end, std::vector<double>::const_iterator& int_it,
00326 const double& mz, double& integrated_intensity, double& extract_window, bool ppm)
00327 {
00328 integrated_intensity = 0;
00329 if (mz_start == mz_end)
00330 {
00331 return;
00332 }
00333
00334
00335 double left, right;
00336 if (ppm)
00337 {
00338 left = mz - mz * extract_window / 2.0 * 1.0e-6;
00339 right = mz + mz * extract_window / 2.0 * 1.0e-6;
00340 }
00341 else
00342 {
00343 left = mz - extract_window / 2.0;
00344 right = mz + extract_window / 2.0;
00345 }
00346
00347 std::vector<double>::const_iterator mz_walker;
00348 std::vector<double>::const_iterator int_walker;
00349
00350
00351 while (mz_it != mz_end && (*mz_it) < mz)
00352 {
00353 mz_it++; int_it++;
00354 }
00355
00356
00357 mz_walker = mz_it;
00358 int_walker = int_it;
00359
00360
00361 if (mz_it == mz_end)
00362 {
00363 mz_walker--; int_walker--;
00364 }
00365
00366
00367 if ((*mz_walker) > left && (*mz_walker) < right)
00368 {
00369 integrated_intensity += (*int_walker);
00370 }
00371
00372
00373 mz_walker = mz_it;
00374 int_walker = int_it;
00375 if (mz_it != mz_start)
00376 {
00377 mz_walker--;
00378 int_walker--;
00379 }
00380 while (mz_walker != mz_start && (*mz_walker) > left && (*mz_walker) < right)
00381 {
00382 integrated_intensity += (*int_walker); mz_walker--; int_walker--;
00383 }
00384 mz_walker = mz_it;
00385 int_walker = int_it;
00386 if (mz_it != mz_end)
00387 {
00388 mz_walker++;
00389 int_walker++;
00390 }
00391 while (mz_walker != mz_end && (*mz_walker) > left && (*mz_walker) < right)
00392 {
00393 integrated_intensity += (*int_walker); mz_walker++; int_walker++;
00394 }
00395 }
00396
00397 private:
00398
00400 template <class SpectrumSettingsT, class ChromatogramT>
00401 void prepareSpectra_(SpectrumSettingsT& settings, std::vector<ChromatogramT>& chromatograms, OpenMS::TargetedExperiment& transition_exp)
00402 {
00403
00404
00405 for (Size i = 0; i < transition_exp.getTransitions().size(); i++)
00406 {
00407 const ReactionMonitoringTransition* transition = &transition_exp.getTransitions()[i];
00408
00409 ChromatogramT chrom;
00410
00411
00412
00413
00414 Precursor prec;
00415 prec.setMZ(transition->getPrecursorMZ());
00416 if (settings.getPrecursors().size() > 0)
00417 {
00418 prec.setIsolationWindowLowerOffset(settings.getPrecursors()[0].getIsolationWindowLowerOffset());
00419 prec.setIsolationWindowUpperOffset(settings.getPrecursors()[0].getIsolationWindowUpperOffset());
00420 }
00421
00422
00423 String pepref = transition->getPeptideRef();
00424 for (Size pep_idx = 0; pep_idx < transition_exp.getPeptides().size(); pep_idx++)
00425 {
00426 const OpenMS::TargetedExperiment::Peptide* pep = &transition_exp.getPeptides()[pep_idx];
00427 if (pep->id == pepref)
00428 {
00429 prec.setMetaValue("peptide_sequence", pep->sequence);
00430 break;
00431 }
00432 }
00433
00434 chrom.setPrecursor(prec);
00435
00436
00437 Product prod;
00438 prod.setMZ(transition->getProductMZ());
00439 chrom.setProduct(prod);
00440
00441
00442 chrom.setInstrumentSettings(settings.getInstrumentSettings());
00443 chrom.setAcquisitionInfo(settings.getAcquisitionInfo());
00444 chrom.setSourceFile(settings.getSourceFile());
00445
00446 for (Size i = 0; i < settings.getDataProcessing().size(); ++i)
00447 {
00448 DataProcessing dp = settings.getDataProcessing()[i];
00449 dp.setMetaValue("performed_on_spectra", "true");
00450 chrom.getDataProcessing().push_back(dp);
00451 }
00452
00453
00454 chrom.setNativeID(transition->getNativeID());
00455 chrom.setChromatogramType(ChromatogramSettings::SELECTED_REACTION_MONITORING_CHROMATOGRAM);
00456 chromatograms.push_back(chrom);
00457 }
00458
00459 }
00460
00461 bool outsideExtractionWindow_(const ReactionMonitoringTransition& transition, double current_rt,
00462 const TransformationDescription& trafo, double rt_extraction_window)
00463 {
00464 if (rt_extraction_window < 0)
00465 {
00466 return false;
00467 }
00468
00469
00470
00471
00472
00473
00474 double expected_rt = PeptideRTMap_[transition.getPeptideRef()];
00475 double de_normalized_experimental_rt = trafo.apply(expected_rt);
00476 if (current_rt < de_normalized_experimental_rt - rt_extraction_window || current_rt > de_normalized_experimental_rt + rt_extraction_window)
00477 {
00478 return true;
00479 }
00480 return false;
00481 }
00482
00483 std::map<OpenMS::String, double> PeptideRTMap_;
00484
00485 };
00486
00487 }
00488
00489 #endif