Go to the documentation of this file.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
00036 #ifndef OPENMS_FILTERING_CALIBRATION_INTERNALCALIBRATION_H
00037 #define OPENMS_FILTERING_CALIBRATION_INTERNALCALIBRATION_H
00038 #include <OpenMS/KERNEL/FeatureMap.h>
00039 #include <OpenMS/KERNEL/MSExperiment.h>
00040 #include <OpenMS/DATASTRUCTURES/DefaultParamHandler.h>
00041 #include <OpenMS/ANALYSIS/MAPMATCHING/TransformationDescription.h>
00042 #include <OpenMS/CONCEPT/ProgressLogger.h>
00043 #include <OpenMS/FORMAT/MzMLFile.h>
00044 #include <OpenMS/FORMAT/TransformationXMLFile.h>
00045
00046 #include <gsl/gsl_fit.h>
00047
00048 namespace OpenMS
00049 {
00050
00062 class OPENMS_DLLAPI InternalCalibration :
00063 public DefaultParamHandler,
00064 public ProgressLogger
00065 {
00066 public:
00068 InternalCalibration();
00069
00071 ~InternalCalibration(){}
00072
00085 template <typename InputPeakType>
00086 void calibrateMapSpectrumwise(const MSExperiment<InputPeakType> & exp, MSExperiment<InputPeakType> & calibrated_exp, std::vector<DoubleReal> & ref_masses);
00087
00100 template <typename InputPeakType>
00101 void calibrateMapGlobally(const MSExperiment<InputPeakType> & exp, MSExperiment<InputPeakType> & calibrated_exp, std::vector<DoubleReal> & ref_masses, String trafo_file_name = "");
00102
00116 template <typename InputPeakType>
00117 void calibrateMapGlobally(const MSExperiment<InputPeakType> & exp, MSExperiment<InputPeakType> & calibrated_exp, std::vector<PeptideIdentification> & ref_ids, String trafo_file_name = "");
00118
00127 void calibrateMapGlobally(const FeatureMap<> & feature_map, FeatureMap<> & calibrated_feature_map, String trafo_file_name = "");
00128
00138 void calibrateMapGlobally(const FeatureMap<> & feature_map, FeatureMap<> & calibrated_feature_map, std::vector<PeptideIdentification> & ref_ids, String trafo_file_name = "");
00139
00140
00141
00142 template <typename InputPeakType>
00143 void calibrateMapList(std::vector<MSExperiment<InputPeakType> > & exp_list, std::vector<MSExperiment<InputPeakType> > & calibrated_exp_list, std::vector<DoubleReal> & ref_masses, std::vector<DoubleReal> & detected_background_masses);
00144
00145
00146 protected:
00147
00149 void makeLinearRegression_(std::vector<DoubleReal> & observed_masses, std::vector<DoubleReal> & theoretical_masses);
00150
00152 void checkReferenceIds_(std::vector<PeptideIdentification> & pep_ids);
00153
00155 void checkReferenceIds_(const FeatureMap<> & feature_map);
00156
00158 void applyTransformation_(const FeatureMap<> & feature_map, FeatureMap<> & calibrated_feature_map);
00159
00161 TransformationDescription trafo_;
00162 };
00163
00164
00165 template <typename InputPeakType>
00166 void InternalCalibration::calibrateMapSpectrumwise(const MSExperiment<InputPeakType> & exp, MSExperiment<InputPeakType> & calibrated_exp, std::vector<DoubleReal> & ref_masses)
00167 {
00168 #ifdef DEBUG_CALIBRATION
00169 std::cout.precision(writtenDigits<DoubleReal>());
00170 #endif
00171 if (exp.empty())
00172 {
00173 std::cout << "Input is empty." << std::endl;
00174 return;
00175 }
00176
00177 if (exp[0].getType() != SpectrumSettings::PEAKS)
00178 {
00179 std::cout << "Attention: this function is assuming peak data." << std::endl;
00180 }
00181 calibrated_exp = exp;
00182
00183 Size num_ref_peaks = ref_masses.size();
00184 bool use_ppm = (param_.getValue("mz_tolerance_unit") == "ppm") ? true : false;
00185 DoubleReal mz_tol = param_.getValue("mz_tolerance");
00186 startProgress(0, exp.size(), "calibrate spectra");
00187
00188 for (Size spec = 0; spec < exp.size(); ++spec)
00189 {
00190
00191 if (exp[spec].getMSLevel() != 1)
00192 {
00193 continue;
00194 }
00195
00196
00197 std::vector<DoubleReal> corr_masses, rel_errors, found_ref_masses;
00198 UInt corr_peaks = 0;
00199 for (Size peak = 0; peak < exp[spec].size(); ++peak)
00200 {
00201 for (Size ref_peak = 0; ref_peak < num_ref_peaks; ++ref_peak)
00202 {
00203 if (!use_ppm && fabs(exp[spec][peak].getMZ() - ref_masses[ref_peak]) < mz_tol)
00204 {
00205 found_ref_masses.push_back(ref_masses[ref_peak]);
00206 corr_masses.push_back(exp[spec][peak].getMZ());
00207 ++corr_peaks;
00208 break;
00209 }
00210 else if (use_ppm && fabs(exp[spec][peak].getMZ() - ref_masses[ref_peak]) / ref_masses[ref_peak] * 1e6 < mz_tol)
00211 {
00212 found_ref_masses.push_back(ref_masses[ref_peak]);
00213 corr_masses.push_back(exp[spec][peak].getMZ());
00214 ++corr_peaks;
00215 break;
00216 }
00217 }
00218 }
00219 if (corr_peaks < 2)
00220 {
00221 std::cout << "spec: " << spec
00222 << " less than 2 reference masses were detected within a reasonable error range\n";
00223 std::cout << "This spectrum cannot be calibrated!\n";
00224 continue;
00225 }
00226
00227
00228 for (Size ref_peak = 0; ref_peak < found_ref_masses.size(); ++ref_peak)
00229 {
00230 rel_errors.push_back((found_ref_masses[ref_peak] - corr_masses[ref_peak]) / corr_masses[ref_peak] * 1e6);
00231 }
00232
00233 makeLinearRegression_(corr_masses, found_ref_masses);
00234
00235
00236 for (unsigned int peak = 0; peak < calibrated_exp[spec].size(); ++peak)
00237 {
00238 #ifdef DEBUG_CALIBRATION
00239 std::cout << calibrated_exp[spec][peak].getMZ() << "\t";
00240 #endif
00241 DoubleReal mz = calibrated_exp[spec][peak].getMZ();
00242 mz = trafo_.apply(mz);
00243 calibrated_exp[spec][peak].setMZ(mz);
00244 #ifdef DEBUG_CALIBRATION
00245 std::cout << calibrated_exp[spec][peak].getMZ() << std::endl;
00246 #endif
00247
00248 }
00249 setProgress(spec);
00250 }
00251 endProgress();
00252 }
00253
00254 template <typename InputPeakType>
00255 void InternalCalibration::calibrateMapGlobally(const MSExperiment<InputPeakType> & exp,
00256 MSExperiment<InputPeakType> & calibrated_exp,
00257 std::vector<PeptideIdentification> & ref_ids, String trafo_file_name)
00258 {
00259 bool use_ppm = param_.getValue("mz_tolerance_unit") == "ppm" ? true : false;
00260 DoubleReal mz_tolerance = param_.getValue("mz_tolerance");
00261 if (exp.empty())
00262 {
00263 std::cout << "Input is empty." << std::endl;
00264 return;
00265 }
00266
00267 if (exp[0].getType() != SpectrumSettings::PEAKS)
00268 {
00269 std::cout << "Attention: this function is assuming peak data." << std::endl;
00270 }
00271
00272 checkReferenceIds_(ref_ids);
00273
00274 std::vector<DoubleReal> theoretical_masses, observed_masses;
00275 for (Size p_id = 0; p_id < ref_ids.size(); ++p_id)
00276 {
00277 for (Size p_h = 0; p_h < ref_ids[p_id].getHits().size(); ++p_h)
00278 {
00279 Int charge = ref_ids[p_id].getHits()[p_h].getCharge();
00280 DoubleReal theo_mass = ref_ids[p_id].getHits()[p_h].getSequence().getMonoWeight(Residue::Full, charge) / (DoubleReal)charge;
00281
00282 typename MSExperiment<InputPeakType>::ConstIterator rt_iter = exp.RTBegin(ref_ids[p_id].getMetaValue("RT"));
00283 while (rt_iter != exp.begin() && rt_iter->getMSLevel() != 1)
00284 {
00285 --rt_iter;
00286 }
00287
00288 typename MSSpectrum<InputPeakType>::ConstIterator mz_iter = rt_iter->MZBegin(ref_ids[p_id].getMetaValue("MZ"));
00289
00290 DoubleReal dist = (DoubleReal)ref_ids[p_id].getMetaValue("MZ") - mz_iter->getMZ();
00291
00292 if ((mz_iter + 1) != rt_iter->end()
00293 && fabs((mz_iter + 1)->getMZ() - (DoubleReal)ref_ids[p_id].getMetaValue("MZ")) < fabs(dist)
00294 && mz_iter != rt_iter->begin()
00295 && fabs((mz_iter - 1)->getMZ() - (DoubleReal)ref_ids[p_id].getMetaValue("MZ")) < fabs((mz_iter + 1)->getMZ() - (DoubleReal)ref_ids[p_id].getMetaValue("MZ")))
00296 {
00297 if ((use_ppm &&
00298 fabs((mz_iter + 1)->getMZ() - (DoubleReal)ref_ids[p_id].getMetaValue("MZ")) / (DoubleReal)ref_ids[p_id].getMetaValue("MZ") * 1e06 < mz_tolerance) ||
00299 (!use_ppm && fabs((mz_iter + 1)->getMZ() - (DoubleReal)ref_ids[p_id].getMetaValue("MZ")) < mz_tolerance))
00300 {
00301
00302 observed_masses.push_back((mz_iter + 1)->getMZ());
00303 theoretical_masses.push_back(theo_mass);
00304
00305
00306 }
00307 }
00308 else if (mz_iter != rt_iter->begin()
00309 && fabs((mz_iter - 1)->getMZ() - (DoubleReal)ref_ids[p_id].getMetaValue("MZ")) < fabs(dist))
00310 {
00311 if ((use_ppm &&
00312 fabs((mz_iter - 1)->getMZ() - (DoubleReal)ref_ids[p_id].getMetaValue("MZ")) / (DoubleReal)ref_ids[p_id].getMetaValue("MZ") * 1e06 < mz_tolerance) ||
00313 (!use_ppm && fabs((mz_iter - 1)->getMZ() - (DoubleReal)ref_ids[p_id].getMetaValue("MZ")) < mz_tolerance))
00314 {
00315
00316 observed_masses.push_back((mz_iter - 1)->getMZ());
00317 theoretical_masses.push_back(theo_mass);
00318
00319
00320 }
00321 }
00322 else
00323 {
00324 if ((use_ppm &&
00325 fabs((mz_iter)->getMZ() - (DoubleReal)ref_ids[p_id].getMetaValue("MZ")) / (DoubleReal)ref_ids[p_id].getMetaValue("MZ") * 1e06 < mz_tolerance) ||
00326 (!use_ppm && fabs((mz_iter)->getMZ() - (DoubleReal)ref_ids[p_id].getMetaValue("MZ")) < mz_tolerance))
00327 {
00328
00329 observed_masses.push_back(mz_iter->getMZ());
00330 theoretical_masses.push_back(theo_mass);
00331
00332
00333 }
00334 }
00335 }
00336 }
00337
00338 makeLinearRegression_(observed_masses, theoretical_masses);
00339 static_cast<ExperimentalSettings &>(calibrated_exp) = exp;
00340 calibrated_exp.resize(exp.size());
00341
00342
00343 for (Size spec = 0; spec < exp.size(); ++spec)
00344 {
00345
00346 if (exp[spec].getMSLevel() != 1)
00347 {
00348 calibrated_exp[spec] = exp[spec];
00349 continue;
00350 }
00351
00352 calibrated_exp[spec] = exp[spec];
00353
00354 for (unsigned int peak = 0; peak < exp[spec].size(); ++peak)
00355 {
00356 #ifdef DEBUG_CALIBRATION
00357 std::cout << exp[spec][peak].getMZ() << "\t";
00358 #endif
00359 DoubleReal mz = exp[spec][peak].getMZ();
00360 mz = trafo_.apply(mz);
00361 calibrated_exp[spec][peak].setMZ(mz);
00362 #ifdef DEBUG_CALIBRATION
00363 std::cout << calibrated_exp[spec][peak].getMZ() << std::endl;
00364 #endif
00365
00366 }
00367 }
00368 if (trafo_file_name != "")
00369 {
00370 TransformationXMLFile().store(trafo_file_name, trafo_);
00371 }
00372 }
00373
00374 template <typename InputPeakType>
00375 void InternalCalibration::calibrateMapGlobally(const MSExperiment<InputPeakType> & exp, MSExperiment<InputPeakType> & calibrated_exp, std::vector<DoubleReal> & ref_masses, String trafo_file_name)
00376 {
00377 if (exp.empty())
00378 {
00379 std::cout << "Input is empty." << std::endl;
00380 return;
00381 }
00382
00383 if (exp[0].getType() != SpectrumSettings::PEAKS)
00384 {
00385 std::cout << "Attention: this function is assuming peak data." << std::endl;
00386 }
00387
00388
00389 Size num_ref_peaks = ref_masses.size();
00390 bool use_ppm = (param_.getValue("mz_tolerance_unit") == "ppm") ? true : false;
00391 DoubleReal mz_tol = param_.getValue("mz_tolerance");
00392 startProgress(0, exp.size(), "calibrate spectra");
00393 std::vector<DoubleReal> corr_masses, rel_errors, found_ref_masses;
00394 UInt corr_peaks = 0;
00395
00396 for (Size spec = 0; spec < exp.size(); ++spec)
00397 {
00398
00399 if (exp[spec].getMSLevel() != 1)
00400 continue;
00401 for (Size peak = 0; peak < exp[spec].size(); ++peak)
00402 {
00403 for (Size ref_peak = 0; ref_peak < num_ref_peaks; ++ref_peak)
00404 {
00405 if (!use_ppm && fabs(exp[spec][peak].getMZ() - ref_masses[ref_peak]) < mz_tol)
00406 {
00407 found_ref_masses.push_back(ref_masses[ref_peak]);
00408 corr_masses.push_back(exp[spec][peak].getMZ());
00409 ++corr_peaks;
00410 break;
00411 }
00412 else if (use_ppm && fabs(exp[spec][peak].getMZ() - ref_masses[ref_peak]) / ref_masses[ref_peak] * 1e6 < mz_tol)
00413 {
00414 found_ref_masses.push_back(ref_masses[ref_peak]);
00415 corr_masses.push_back(exp[spec][peak].getMZ());
00416 ++corr_peaks;
00417 break;
00418 }
00419 }
00420 }
00421 }
00422 if (corr_peaks < 2)
00423 {
00424 std::cout << "Less than 2 reference masses were detected within a reasonable error range\n";
00425 std::cout << "This spectrum cannot be calibrated!\n";
00426 return;
00427 }
00428
00429
00430 makeLinearRegression_(corr_masses, found_ref_masses);
00431 static_cast<ExperimentalSettings &>(calibrated_exp) = exp;
00432 calibrated_exp.resize(exp.size());
00433
00434
00435 for (Size spec = 0; spec < exp.size(); ++spec)
00436 {
00437
00438 if (exp[spec].getMSLevel() != 1)
00439 {
00440 calibrated_exp[spec] = exp[spec];
00441 continue;
00442 }
00443
00444
00445 calibrated_exp[spec] = exp[spec];
00446
00447 for (unsigned int peak = 0; peak < exp[spec].size(); ++peak)
00448 {
00449 #ifdef DEBUG_CALIBRATION
00450 std::cout << exp[spec][peak].getMZ() << "\t";
00451 #endif
00452 DoubleReal mz = exp[spec][peak].getMZ();
00453 mz = trafo_.apply(mz);
00454 calibrated_exp[spec][peak].setMZ(mz);
00455
00456 #ifdef DEBUG_CALIBRATION
00457 std::cout << calibrated_exp[spec][peak].getMZ() << std::endl;
00458 #endif
00459
00460 }
00461 setProgress(spec);
00462 }
00463 endProgress();
00464 if (trafo_file_name != "")
00465 {
00466 TransformationXMLFile().store(trafo_file_name, trafo_);
00467 }
00468 }
00469
00470 }
00471
00472 #endif // OPENMS_FILTERING_CALIBRATION_INTERNALCALIBRATION_H