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 #ifndef OPENMS_ANALYSIS_ID_IDMAPPER_H
00036 #define OPENMS_ANALYSIS_ID_IDMAPPER_H
00037
00038 #include <OpenMS/KERNEL/MSExperiment.h>
00039 #include <OpenMS/KERNEL/FeatureMap.h>
00040 #include <OpenMS/KERNEL/ConsensusMap.h>
00041 #include <OpenMS/CONCEPT/LogStream.h>
00042
00043 #include <algorithm>
00044 #include <limits>
00045
00046 namespace OpenMS
00047 {
00062 class OPENMS_DLLAPI IDMapper :
00063 public DefaultParamHandler
00064 {
00065 public:
00066 enum Measure {MEASURE_PPM = 0, MEASURE_DA};
00067
00069 IDMapper();
00070
00072 IDMapper(const IDMapper & cp);
00073
00075 IDMapper & operator=(const IDMapper & rhs);
00076
00089 template <typename PeakType>
00090 void annotate(MSExperiment<PeakType> & map, const std::vector<PeptideIdentification> & ids, const std::vector<ProteinIdentification> & protein_ids)
00091 {
00092 checkHits_(ids);
00093
00094
00095 map.getProteinIdentifications().insert(map.getProteinIdentifications().end(), protein_ids.begin(), protein_ids.end());
00096
00097
00098 std::multimap<DoubleReal, Size> experiment_precursors;
00099 for (Size i = 0; i < map.size(); i++)
00100 {
00101 experiment_precursors.insert(std::make_pair(map[i].getRT(), i));
00102 }
00103
00104
00105 std::multimap<DoubleReal, Size> identifications_precursors;
00106 for (Size i = 0; i < ids.size(); i++)
00107 {
00108 identifications_precursors.insert(std::make_pair(ids[i].getMetaValue("RT"), i));
00109 }
00110
00111
00112 std::multimap<DoubleReal, Size>::iterator experiment_iterator = experiment_precursors.begin();
00113 std::multimap<DoubleReal, Size>::iterator identifications_iterator = identifications_precursors.begin();
00114 Size matches(0);
00115 while (experiment_iterator != experiment_precursors.end() && identifications_iterator != identifications_precursors.end())
00116 {
00117 while (identifications_iterator != identifications_precursors.end())
00118 {
00119
00120 if (fabs(experiment_iterator->first - identifications_iterator->first) < rt_tolerance_)
00121 {
00122
00123 if (!map[experiment_iterator->second].getPrecursors().empty())
00124 {
00125 if (fabs((DoubleReal)(ids[identifications_iterator->second].getMetaValue("MZ")) - map[experiment_iterator->second].getPrecursors()[0].getMZ()) < mz_tolerance_)
00126 {
00127 if (!(ids[identifications_iterator->second].empty()))
00128 {
00129 map[experiment_iterator->second].getPeptideIdentifications().push_back(ids[identifications_iterator->second]);
00130 ++matches;
00131 }
00132 }
00133 }
00134 }
00135 ++identifications_iterator;
00136 }
00137 identifications_iterator = identifications_precursors.begin();
00138 ++experiment_iterator;
00139 }
00140
00141
00142 LOG_INFO << "Unassigned peptides: " << ids.size() - matches << "\n"
00143 << "Peptides assigned to a precursor: " << matches << std::endl;
00144
00145 }
00146
00164 template <typename FeatureType>
00165 void annotate(FeatureMap<FeatureType> & map, const std::vector<PeptideIdentification> & ids, const std::vector<ProteinIdentification> & protein_ids, bool use_centroid_rt = false, bool use_centroid_mz = false)
00166 {
00167
00168 checkHits_(ids);
00169
00170
00171 map.getProteinIdentifications().insert(map.getProteinIdentifications().end(), protein_ids.begin(), protein_ids.end());
00172
00173
00174
00175 if (!(use_centroid_rt && use_centroid_mz))
00176 {
00177 for (typename FeatureMap<FeatureType>::Iterator f_it = map.begin(); f_it != map.end(); ++f_it)
00178 {
00179 if (f_it->getConvexHulls().empty())
00180 {
00181 use_centroid_rt = true;
00182 use_centroid_mz = true;
00183 LOG_WARN << "IDMapper warning: at least one feature has no convex hull - using centroid coordinates for matching" << std::endl;
00184 break;
00185 }
00186 }
00187 }
00188
00189 bool use_avg_mass = false;
00190 if (use_centroid_mz && (param_.getValue("mz_reference") == "peptide"))
00191 {
00192
00193
00194 use_avg_mass = checkMassType_(map.getDataProcessing());
00195 }
00196
00197
00198 std::vector<DBoundingBox<2> > boxes;
00199 DoubleReal min_rt = std::numeric_limits<DoubleReal>::max(),
00200 max_rt = -std::numeric_limits<DoubleReal>::max();
00201
00202 boxes.reserve(map.size());
00203 for (typename FeatureMap<FeatureType>::Iterator f_it = map.begin();
00204 f_it != map.end(); ++f_it)
00205 {
00206 DBoundingBox<2> box;
00207 if (!(use_centroid_rt && use_centroid_mz))
00208 {
00209 box = f_it->getConvexHull().getBoundingBox();
00210 }
00211 if (use_centroid_rt)
00212 {
00213 box.setMinX(f_it->getRT());
00214 box.setMaxX(f_it->getRT());
00215 }
00216 if (use_centroid_mz)
00217 {
00218 box.setMinY(f_it->getMZ());
00219 box.setMaxY(f_it->getMZ());
00220 }
00221 increaseBoundingBox_(box);
00222 boxes.push_back(box);
00223
00224 min_rt = std::min(min_rt, box.minPosition().getX());
00225 max_rt = std::max(max_rt, box.maxPosition().getX());
00226 }
00227
00228
00229
00230
00231 std::vector<std::vector<SignedSize> > hash_table;
00232
00233
00234 SignedSize offset(0);
00235
00236 if (map.size() > 0)
00237 {
00238
00239 offset = SignedSize(floor(min_rt));
00240
00241 hash_table.resize(SignedSize(floor(max_rt)) - offset + 1);
00242 for (Size index = 0; index < boxes.size(); ++index)
00243 {
00244 const DBoundingBox<2> & box = boxes[index];
00245 for (SignedSize i = SignedSize(floor(box.minPosition().getX()));
00246 i <= SignedSize(floor(box.maxPosition().getX())); ++i)
00247 {
00248 hash_table[i - offset].push_back(index);
00249 }
00250 }
00251 }
00252 else
00253 {
00254 LOG_WARN << "IDMapper received an empty FeatureMap! All peptides are mapped as 'unassigned'!" << std::endl;
00255 }
00256
00257
00258 Size matches_none = 0, matches_single = 0, matches_multi = 0;
00259
00260
00261
00262 for (std::vector<PeptideIdentification>::const_iterator id_it =
00263 ids.begin(); id_it != ids.end(); ++id_it)
00264 {
00265
00266
00267 if (id_it->getHits().empty()) continue;
00268
00269 DoubleList mz_values;
00270 DoubleReal rt_value;
00271 IntList charges;
00272 getIDDetails_(*id_it, rt_value, mz_values, charges, use_avg_mass);
00273
00274 if ((rt_value < min_rt) || (rt_value > max_rt))
00275 {
00276 map.getUnassignedPeptideIdentifications().push_back(*id_it);
00277 ++matches_none;
00278 continue;
00279 }
00280
00281
00282 Size index = SignedSize(floor(rt_value)) - offset;
00283 Size matching_features = 0;
00284 for (std::vector<SignedSize>::iterator hash_it =
00285 hash_table[index].begin(); hash_it != hash_table[index].end();
00286 ++hash_it)
00287 {
00288 Feature & feat = map[*hash_it];
00289
00290
00291 bool check_charge = !ignore_charge_;
00292 if (check_charge && (mz_values.size() == 1))
00293 {
00294 if (!charges.contains(feat.getCharge())) continue;
00295 check_charge = false;
00296 }
00297
00298
00299 Size index = 0;
00300 for (DoubleList::iterator mz_it = mz_values.begin();
00301 mz_it != mz_values.end(); ++mz_it, ++index)
00302 {
00303 if (check_charge && (charges[index] != feat.getCharge()))
00304 {
00305 continue;
00306 }
00307
00308 DPosition<2> id_pos(rt_value, *mz_it);
00309 if (boxes[*hash_it].encloses(id_pos))
00310 {
00311 if (use_centroid_mz)
00312 {
00313
00314
00315 feat.getPeptideIdentifications().push_back(*id_it);
00316 ++matching_features;
00317 break;
00318 }
00319
00320 bool found_match = false;
00321 for (std::vector<ConvexHull2D>::iterator ch_it =
00322 feat.getConvexHulls().begin(); ch_it !=
00323 feat.getConvexHulls().end(); ++ch_it)
00324 {
00325 DBoundingBox<2> box = ch_it->getBoundingBox();
00326 if (use_centroid_rt)
00327 {
00328 box.setMinX(feat.getRT());
00329 box.setMaxX(feat.getRT());
00330 }
00331 increaseBoundingBox_(box);
00332 if (box.encloses(id_pos))
00333 {
00334 feat.getPeptideIdentifications().push_back(*id_it);
00335 ++matching_features;
00336 found_match = true;
00337 break;
00338 }
00339 }
00340 if (found_match) break;
00341 }
00342 }
00343 }
00344 if (matching_features == 0)
00345 {
00346 map.getUnassignedPeptideIdentifications().push_back(*id_it);
00347 ++matches_none;
00348 }
00349 else if (matching_features == 1) ++matches_single;
00350 else ++matches_multi;
00351 }
00352
00353
00354 LOG_INFO << "Unassigned peptides: " << matches_none << "\n"
00355 << "Peptides assigned to exactly one feature: "
00356 << matches_single << "\n"
00357 << "Peptides assigned to multiple features: "
00358 << matches_multi << std::endl;
00359
00360 }
00361
00375 void annotate(ConsensusMap & map, const std::vector<PeptideIdentification> & ids, const std::vector<ProteinIdentification> & protein_ids, bool measure_from_subelements = false);
00376
00377 protected:
00378 void updateMembers_();
00379
00381 DoubleReal rt_tolerance_;
00383 DoubleReal mz_tolerance_;
00385 Measure measure_;
00387 bool ignore_charge_;
00388
00392 DoubleReal getAbsoluteMZTolerance_(const DoubleReal mz) const;
00393
00395 bool isMatch_(const DoubleReal rt_distance, const DoubleReal mz_theoretical, const DoubleReal mz_observed) const;
00396
00398 void checkHits_(const std::vector<PeptideIdentification> & ids) const;
00399
00403 void getIDDetails_(const PeptideIdentification & id, DoubleReal & rt_pep, DoubleList & mz_values, IntList & charges, bool use_avg_mass = false) const;
00404
00406 void increaseBoundingBox_(DBoundingBox<2> & box);
00407
00410 bool checkMassType_(const std::vector<DataProcessing> & processing) const;
00411
00412 };
00413
00414 }
00415
00416 #endif // OPENMS_ANALYSIS_ID_IDMAPPER_H