Home  · Classes  · Annotated Classes  · Modules  · Members  · Namespaces  · Related Pages

OfflinePrecursorIonSelection.h

Go to the documentation of this file.
00001 // --------------------------------------------------------------------------
00002 //                   OpenMS -- Open-Source Mass Spectrometry
00003 // --------------------------------------------------------------------------
00004 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
00005 // ETH Zurich, and Freie Universitaet Berlin 2002-2012.
00006 //
00007 // This software is released under a three-clause BSD license:
00008 //  * Redistributions of source code must retain the above copyright
00009 //    notice, this list of conditions and the following disclaimer.
00010 //  * Redistributions in binary form must reproduce the above copyright
00011 //    notice, this list of conditions and the following disclaimer in the
00012 //    documentation and/or other materials provided with the distribution.
00013 //  * Neither the name of any author or any participating institution
00014 //    may be used to endorse or promote products derived from this software
00015 //    without specific prior written permission.
00016 // For a full list of authors, refer to the file AUTHORS.
00017 // --------------------------------------------------------------------------
00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00019 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
00022 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00023 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00024 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00025 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00026 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00027 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00028 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 //
00030 // --------------------------------------------------------------------------
00031 // $Maintainer: Alexandra Zerck $
00032 // $Authors: Alexandra Zerck $
00033 // --------------------------------------------------------------------------
00034 
00035 #ifndef OPENMS_ANALYSIS_TARGETED_OFFLINEPRECURSORIONSELECTION_H
00036 #define OPENMS_ANALYSIS_TARGETED_OFFLINEPRECURSORIONSELECTION_H
00037 
00038 
00039 #include <OpenMS/KERNEL/FeatureMap.h>
00040 #include <OpenMS/KERNEL/MSExperiment.h>
00041 #include <OpenMS/ANALYSIS/ID/IDMapper.h>
00042 #include <OpenMS/FORMAT/FeatureXMLFile.h>
00043 #include <OpenMS/ANALYSIS/TARGETED/PSLPFormulation.h>
00044 
00045 namespace OpenMS
00046 {
00047   class PeptideIdentification;
00048   class ProteinIdentification;
00049   class String;
00050 
00051 
00061   class OPENMS_DLLAPI OfflinePrecursorIonSelection :
00062     public DefaultParamHandler
00063   {
00064 public:
00065     typedef PSLPFormulation::IndexTriple IndexTriple;
00066 
00067     OfflinePrecursorIonSelection();
00068     virtual ~OfflinePrecursorIonSelection();
00069 
00079     template <typename InputPeakType>
00080     void makePrecursorSelectionForKnownLCMSMap(const FeatureMap<> & features,
00081                                                const MSExperiment<InputPeakType> & experiment,
00082                                                MSExperiment<InputPeakType> & ms2,
00083                                                std::set<Int> & charges_set,
00084                                                bool feature_based);
00085 
00093     template <typename InputPeakType>
00094     void getMassRanges(const FeatureMap<> & features,
00095                        const MSExperiment<InputPeakType> & experiment,
00096                        std::vector<std::vector<std::pair<Size, Size> > > & indices);
00097 
00098     void createProteinSequenceBasedLPInclusionList(String include, String rt_model_file, String pt_model_file, FeatureMap<> & precursors);
00099 
00100     void setLPSolver(LPWrapper::SOLVER solver)
00101     {
00102       solver_ = solver;
00103       std::cout << " LPSolver set to " << solver_ << std::endl;
00104     }
00105 
00106     LPWrapper::SOLVER getLPSolver()
00107     {
00108       return solver_;
00109     }
00110 
00111 private:
00115     template <typename InputPeakType>
00116     void calculateXICs_(const FeatureMap<> & features,
00117                         const std::vector<std::vector<std::pair<Size, Size> > > & mass_ranges,
00118                         const MSExperiment<InputPeakType> & experiment,
00119                         const std::set<Int> & charges_set,
00120                         std::vector<std::vector<std::pair<Size, DoubleReal> > > & xics);
00121 
00125     template <typename InputPeakType>
00126     void checkMassRanges_(std::vector<std::vector<std::pair<Size, Size> > > & mass_ranges,
00127                           const MSExperiment<InputPeakType> & experiment);
00128 
00129     template <typename T>
00130     void updateExclusionList_(std::vector<std::pair<T, Size> > & exclusion_list);
00131 
00132     void updateExclusionList_(std::map<std::pair<DoubleReal, DoubleReal>, Size, PairComparatorSecondElement<std::pair<DoubleReal, DoubleReal> > > & exclusion_list);
00133 
00134     LPWrapper::SOLVER solver_;
00135   };
00136 
00137   template <typename InputPeakType>
00138   bool enclosesBoundingBox(const Feature & f, typename MSExperiment<InputPeakType>::CoordinateType rt, typename MSExperiment<InputPeakType>::CoordinateType mz)
00139   {
00140     bool enclose_hit = false;
00141     const std::vector<ConvexHull2D> & hulls = f.getConvexHulls();
00142     for (Size i = 0; i < hulls.size(); ++i)
00143     {
00144       if (hulls[i].getBoundingBox().encloses(rt, mz))
00145       {
00146         enclose_hit = true;
00147         return enclose_hit;
00148       }
00149     }
00150     return enclose_hit;
00151   }
00152 
00153   template <typename InputPeakType>
00154   void OfflinePrecursorIonSelection::getMassRanges(const FeatureMap<> & features,
00155                                                    const MSExperiment<InputPeakType> & experiment,
00156                                                    std::vector<std::vector<std::pair<Size, Size> > > & indices)
00157   {
00158     if (experiment.empty())
00159       throw Exception::InvalidSize(__FILE__, __LINE__, __PRETTY_FUNCTION__, 0);
00160     for (Size f = 0; f < features.size(); ++f)
00161     {
00162       std::vector<std::pair<Size, Size> > vec;
00163 
00164       for (Size rt = 0; rt < experiment.size(); ++rt)
00165       {
00166         // is scan relevant?
00167         if (!enclosesBoundingBox<InputPeakType>(features[f], experiment[rt].getRT(), features[f].getMZ()))
00168           continue;
00169 
00170         std::pair<Size, Size> start;
00171         std::pair<Size, Size> end;
00172         bool start_found = false;
00173         bool end_found = false;
00174         typename MSSpectrum<InputPeakType>::ConstIterator mz_iter = experiment[rt].MZBegin(features[f].getMZ());
00175         typename MSSpectrum<InputPeakType>::ConstIterator mz_end = mz_iter;
00176         if (mz_iter == experiment[rt].end())
00177           continue;
00178         // check to the left
00179         while (enclosesBoundingBox<InputPeakType>(features[f], experiment[rt].getRT(), mz_iter->getMZ()))
00180         {
00181           start_found = true;
00182           start.first = rt;
00183           start.second = distance(experiment[rt].begin(), mz_iter);
00184           if (mz_iter == experiment[rt].begin())
00185             break;
00186           --mz_iter;
00187           end_found = true;
00188           end.first = rt;
00189           end.second = start.second;
00190         }
00191         // and now to the right
00192         while (mz_end != experiment[rt].end() && enclosesBoundingBox<InputPeakType>(features[f], experiment[rt].getRT(), mz_end->getMZ()))
00193         {
00194           end_found = true;
00195           end.first = rt;
00196           end.second = distance(experiment[rt].begin(), mz_end);
00197           ++mz_end;
00198         }
00199         if (start_found && end_found)
00200         {
00201           vec.push_back(start);
00202           vec.push_back(end);
00203         }
00204 #ifdef DEBUG_OPS
00205         else if (start_found || end_found)
00206         {
00207           std::cout << "start " << start_found << " end " << end_found << std::endl;
00208           std::cout << "feature: " << f << " rt: " << rt << std::endl;
00209         }
00210 #endif
00211       }
00212 #ifdef DEBUG_OPS
00213       if (vec.size() > 0)
00214       {
00215         std::cout << vec.size() << " / 2 scans" << std::endl;
00216         for (Size i = 0; i < vec.size(); i += 2)
00217         {
00218           std::cout << "Feature " << f << " RT : " << vec[i].first
00219                     << " MZ : " << experiment[vec[i].first][vec[i].second].getMZ() << " "
00220                     << experiment[vec[i + 1].first][vec[i + 1].second].getMZ() << std::endl;
00221         }
00222       }
00223 #endif
00224       if (vec.empty())
00225       {
00226 #ifdef DEBUG_OPS
00227         std::cout << "According to the convex hulls no mass traces found for this feature->estimate!"
00228                   << features[f].getRT() << " " << features[f].getMZ() << " " << features[f].getCharge() << std::endl;
00229 #endif
00230         // we estimate the convex hull
00231         typename MSExperiment<InputPeakType>::ConstIterator spec_iter = experiment.RTBegin(features[f].getRT());
00232         if (spec_iter == experiment.end())
00233           --spec_iter;
00234 
00235         DoubleReal dist1 = fabs(spec_iter->getRT() - features[f].getRT());
00236         DoubleReal dist2 = std::numeric_limits<DoubleReal>::max();
00237         DoubleReal dist3 = std::numeric_limits<DoubleReal>::max();
00238         if ((spec_iter + 1) != experiment.end())
00239         {
00240           dist2 = fabs((spec_iter + 1)->getRT() - features[f].getRT());
00241         }
00242         if (spec_iter != experiment.begin())
00243         {
00244           dist3 = fabs((spec_iter - 1)->getRT() - features[f].getRT());
00245         }
00246         if (dist3 <= dist1 && dist3 <= dist2)
00247         {
00248           --spec_iter;
00249         }
00250         else if (dist2 <= dist3 && dist2 <= dist1)
00251         {
00252           ++spec_iter;
00253         }
00254         std::pair<Size, Size> start;
00255         std::pair<Size, Size> end;
00256         start.first = distance(experiment.begin(), spec_iter);
00257         end.first = start.first;
00258 
00259         typename MSSpectrum<InputPeakType>::ConstIterator mz_iter = spec_iter->MZBegin(features[f].getMZ());
00260         if (spec_iter->begin() == spec_iter->end())
00261         {
00262           indices.push_back(vec);
00263           continue;
00264         }
00265         if (mz_iter == spec_iter->end() || (mz_iter->getMZ() > features[f].getMZ() && mz_iter != spec_iter->begin()))
00266           --mz_iter;
00267         while (mz_iter != spec_iter->begin())
00268         {
00269           if (fabs((mz_iter - 1)->getMZ() - features[f].getMZ()) < 0.5)
00270             --mz_iter;
00271           else
00272             break;
00273         }
00274         start.second = distance(spec_iter->begin(), mz_iter);
00275         typename MSSpectrum<InputPeakType>::ConstIterator mz_end = mz_iter;
00276 #ifdef DEBUG_OPS
00277         std::cout << features[f].getMZ() << " Start: " << experiment[start.first].getRT() << " " << experiment[start.first][start.second].getMZ();
00278 #endif
00279         Int charge = features[f].getCharge();
00280         if (charge == 0)
00281           charge = 1;
00282         while (mz_end + 1 != spec_iter->end())
00283         {
00284           if (fabs((mz_end + 1)->getMZ() - features[f].getMZ()) < 3.0 / (DoubleReal)charge)
00285             ++mz_end;
00286           else
00287             break;
00288         }
00289         end.second = distance(spec_iter->begin(), mz_end);
00290 #ifdef DEBUG_OPS
00291         std::cout << "\tEnd: " << experiment[end.first].getRT() << " " << experiment[end.first][end.second].getMZ() << std::endl;
00292 #endif
00293         vec.push_back(start);
00294         vec.push_back(end);
00295       }
00296 
00297       indices.push_back(vec);
00298     }
00299     // eliminate nearby peaks
00300     if (param_.getValue("exclude_overlapping_peaks") == "true")
00301       checkMassRanges_(indices, experiment);
00302   }
00303 
00304   template <typename InputPeakType>
00305   void OfflinePrecursorIonSelection::calculateXICs_(const FeatureMap<> & features,
00306                                                     const std::vector<std::vector<std::pair<Size, Size> > > & mass_ranges,
00307                                                     const MSExperiment<InputPeakType> & experiment,
00308                                                     const std::set<Int> & charges_set,
00309                                                     std::vector<std::vector<std::pair<Size, DoubleReal> > > & xics)
00310   {
00311     xics.clear();
00312     xics.resize(experiment.size());
00313     // for each feature
00314     for (Size f = 0; f < mass_ranges.size(); ++f)
00315     {
00316       // is charge valid
00317       if (charges_set.count(features[f].getCharge()) < 1)
00318       {
00319         continue;
00320       }
00321       // go through all scans where the feature occurs
00322       for (Size s = 0; s < mass_ranges[f].size(); s += 2)
00323       {
00324         // sum intensity over all raw datapoints belonging to the feature in the current scan
00325         DoubleReal weight = 0.;
00326         for (Size j = mass_ranges[f][s].second; j <= mass_ranges[f][s + 1].second; ++j)
00327         {
00328           weight += experiment[mass_ranges[f][s].first][j].getIntensity();
00329         }
00330         // enter xic in the vector for scan
00331         xics[mass_ranges[f][s].first].push_back(std::make_pair(f, weight));
00332       }
00333     }
00334 
00335     for (Size s = 0; s < xics.size(); ++s)
00336     {
00337       sort(xics[s].begin(), xics[s].end(), PairComparatorSecondElement<std::pair<Size, DoubleReal> >());
00338     }
00339   }
00340 
00341   template <typename InputPeakType>
00342   void OfflinePrecursorIonSelection::makePrecursorSelectionForKnownLCMSMap(const FeatureMap<> & features,
00343                                                                            const MSExperiment<InputPeakType> & experiment,
00344                                                                            MSExperiment<InputPeakType> & ms2,
00345                                                                            std::set<Int> & charges_set,
00346                                                                            bool feature_based)
00347   {
00348 
00349     const DoubleReal window = param_.getValue("selection_window");
00350     const DoubleReal excl_window = param_.getValue("min_peak_distance");
00351 
00352     // get the mass ranges for each features for each scan it occurs in
00353     std::vector<std::vector<std::pair<Size, Size> > >  indices;
00354     getMassRanges(features, experiment, indices);
00355     DoubleReal rt_dist = 0.;
00356     if (experiment.size() > 1)
00357     {
00358       rt_dist = experiment[1].getRT() - experiment[0].getRT();
00359     }
00360 
00361     // feature based selection (e.g. with LC-MALDI)
00362     if (feature_based)
00363     {
00364       // create ILP
00365       PSLPFormulation ilp_wrapper;
00366 
00367       std::vector<IndexTriple> variable_indices;
00368       std::vector<int> solution_indices;
00369       ilp_wrapper.createAndSolveILPForKnownLCMSMapFeatureBased(features, experiment, variable_indices,
00370                                                                indices, charges_set,
00371                                                                param_.getValue("ms2_spectra_per_rt_bin"),
00372                                                                solution_indices);
00373 
00374       sort(variable_indices.begin(), variable_indices.end(), PSLPFormulation::IndexLess());
00375 #ifdef DEBUG_OPS
00376       std::cout << "best_solution " << std::endl;
00377 #endif
00378       // print best solution
00379       // create inclusion list
00380       for (Size i = 0; i < solution_indices.size(); ++i)
00381       {
00382         Size feature_index = variable_indices[solution_indices[i]].feature;
00383         Size feature_scan_idx = variable_indices[solution_indices[i]].scan;
00384         typename MSExperiment<InputPeakType>::ConstIterator scan = experiment.begin() + feature_scan_idx;
00385         typename MSExperiment<InputPeakType>::SpectrumType ms2_spec;
00386         Precursor p;
00387         std::vector<Precursor> pcs;
00388         p.setIntensity(features[feature_index].getIntensity());
00389         p.setMZ(features[feature_index].getMZ());
00390         p.setCharge(features[feature_index].getCharge());
00391         pcs.push_back(p);
00392         ms2_spec.setPrecursors(pcs);
00393         ms2_spec.setRT(scan->getRT() + rt_dist / 2.0);
00394         ms2_spec.setMSLevel(2);
00395         // link ms2 spectrum with features overlapping its precursor
00396         // Warning: this depends on the current order of features in the map
00397         // Attention: make sure to name ALL features that overlap, not only one!
00398         ms2_spec.setMetaValue("parent_feature_ids", IntList::create(String(feature_index)));
00399         ms2.push_back(ms2_spec);
00400         std::cout << " MS2 spectra generated at: " << scan->getRT() << " x " << p.getMZ() << "\n";
00401 
00402       }
00403 #ifdef DEBUG_OPS
00404       std::cout << solution_indices.size() << " out of " << features.size()
00405                 << " precursors are in best solution.\n";
00406 #endif
00407     }
00408     else     // scan based selection (take the x highest signals for each spectrum)
00409     {
00410 #ifdef DEBUG_OPS
00411       std::cout << "scan based precursor selection" << std::endl;
00412 #endif
00413       // if the highest signals for each scan shall be selected we don't need an ILP formulation
00414 
00415       //cache the values for each feature
00416       std::vector<DoubleList> feature_elution_bounds;
00417       std::vector<DoubleList> elution_profile_intensities;
00418       std::vector<DoubleList> isotope_intensities;
00419 
00420       bool meta_values_present = false;
00421 
00422       if (!features.empty() &&
00423           features[0].metaValueExists("elution_profile_bounds") &&
00424           features[0].metaValueExists("elution_profile_intensities") &&
00425           features[0].metaValueExists("isotope_intensities"))
00426       {
00427         for (Size feat = 0; feat < features.size(); ++feat)
00428         {
00429           feature_elution_bounds.push_back(features[feat].getMetaValue("elution_profile_bounds"));
00430           elution_profile_intensities.push_back(features[feat].getMetaValue("elution_profile_intensities"));
00431           isotope_intensities.push_back(features[feat].getMetaValue("isotope_intensities"));
00432         }
00433         meta_values_present = true;
00434       }
00435 
00436       //for each feature cache for which scans it has to be considered
00437       std::vector<std::vector<Size> > scan_features(experiment.size());
00438 
00439       for (Size feat = 0; feat < features.size(); ++feat)
00440       {
00441         if (charges_set.count(features[feat].getCharge()))
00442         {
00443           Size lower_rt = features[feat].getConvexHull().getBoundingBox().minX();
00444           Size upper_rt = features[feat].getConvexHull().getBoundingBox().maxX();
00445           typename MSExperiment<InputPeakType>::ConstIterator it;
00446           for (it = experiment.RTBegin(lower_rt); it != experiment.RTEnd(upper_rt); ++it)
00447           {
00448             scan_features[it - experiment.begin()].push_back(feat);
00449           }
00450         }
00451       }
00452 
00453       bool dynamic_exclusion = param_.getValue("Exclusion:use_dynamic_exclusion") == "true" ? true : false;
00454       typedef std::map<std::pair<DoubleReal, DoubleReal>, Size, PairComparatorSecondElement<std::pair<DoubleReal, DoubleReal> > > ExclusionListType;
00455       ExclusionListType exclusion_list;
00456       Size exclusion_specs = (Size)(floor((DoubleReal)param_.getValue("Exclusion:exclusion_time") / (DoubleReal) rt_dist));
00457       if (!dynamic_exclusion)
00458       {
00459         //if the dynamic exclusion if not active we use the eclusion list to guarantee no two peaks within min_peak_distance are selected for single scan
00460         exclusion_specs = 0;
00461       }
00462 
00463       //cache bounding boxes of features and mass traces (mass trace bb are also widened for effective discovery of enclosing peaks in intervalls)
00464       std::map<Size, typename OpenMS::DBoundingBox<2> > bounding_boxes_f;
00465       std::map<std::pair<Size, Size>, typename OpenMS::DBoundingBox<2> > bounding_boxes;
00466       for (Size feature_num = 0; feature_num < features.size(); ++feature_num)
00467       {
00468         if (charges_set.count(features[feature_num].getCharge()))
00469         {
00470           bounding_boxes_f.insert(std::make_pair(feature_num, features[feature_num].getConvexHull().getBoundingBox()));
00471           const std::vector<ConvexHull2D> mass_traces = features[feature_num].getConvexHulls();
00472           for (Size mass_trace_num = 0; mass_trace_num < mass_traces.size(); ++mass_trace_num)
00473           {
00474             typename OpenMS::DBoundingBox<2> tmp_bbox = mass_traces[mass_trace_num].getBoundingBox();
00475             tmp_bbox.setMinY(tmp_bbox.minY() - window);
00476             tmp_bbox.setMaxY(tmp_bbox.maxY() + window);
00477             bounding_boxes.insert(std::make_pair(std::make_pair(feature_num, mass_trace_num), tmp_bbox));
00478           }
00479         }
00480       }
00481 
00482       Size max_spec = (Int)param_.getValue("ms2_spectra_per_rt_bin");
00483       // get best x signals for each scan
00484       for (Size i = 0; i < experiment.size(); ++i)
00485       {
00486 #ifdef DEBUG_OPS
00487         std::cout << "scan " << experiment[i].getRT() << ":";
00488 #endif
00489 
00490         updateExclusionList_(exclusion_list);
00491         MSSpectrum<InputPeakType> scan = experiment[i];
00492         scan.sortByIntensity(true);
00493         Size selected_peaks = 0, j = 0;
00494 
00495         while (selected_peaks < max_spec && j < scan.size())
00496         {
00497           DoubleReal peak_mz = scan[j].getMZ();
00498           DoubleReal peak_rt = scan.getRT();
00499 
00500           ExclusionListType::iterator it_low = exclusion_list.lower_bound(std::make_pair(peak_mz, peak_mz));
00501           if (it_low != exclusion_list.end() && it_low->first.first <= peak_mz)
00502           {
00503             ++j;
00504             continue;
00505           }
00506           ++selected_peaks;
00507 
00508           //find all features (mass traces that are in the window around peak_mz)
00509           typename MSExperiment<InputPeakType>::SpectrumType ms2_spec;
00510           std::vector<Precursor> pcs;
00511           std::set<std::pair<Size, Size> > selected_mt;
00512           IntList parent_feature_ids;
00513 
00514           DoubleReal local_mz = peak_mz;
00515           //std::cerr<<"MZ pos: "<<local_mz<<std::endl;
00516           for (Size scan_feat_id = 0; scan_feat_id < scan_features[i].size(); ++scan_feat_id)
00517           {
00518             Size feature_num = scan_features[i][scan_feat_id];
00519             if (bounding_boxes_f[feature_num].encloses(peak_rt, local_mz))
00520             {
00521               //find a mass trace enclosing the point
00522               DoubleReal feature_intensity = 0;
00523               for (Size mass_trace_num = 0; mass_trace_num < features[feature_num].getConvexHulls().size(); ++mass_trace_num)
00524               {
00525                 if (bounding_boxes[std::make_pair(feature_num, mass_trace_num)].encloses(DPosition<2>(peak_rt, local_mz)))
00526                 {
00527                   DoubleReal elu_factor = 1.0, iso_factor = 1.0;
00528                   //get the intensity factor for the position in the elution profile
00529                   if (meta_values_present)
00530                   {
00531                     DoubleList xxx = elution_profile_intensities[feature_num];
00532                     DoubleList yyy = feature_elution_bounds[feature_num];
00533 //                  std::cout << "PEAKRT: " << peak_rt << std::endl;
00534 //                  std::cout << "Max: " << yyy[3] << "  vs.  " << bounding_boxes_f[feature_num].maxX() << std::endl;
00535 //                  std::cout << "Min: " << yyy[1] << "  vs.  " << bounding_boxes_f[feature_num].minX() << std::endl;
00536                     OPENMS_PRECONDITION(i - yyy[0] < xxx.size(), "Tried to access invalid index for elution factor");
00537                     elu_factor = xxx[i - yyy[0]];                     // segfault here: "i-yyy[0]" yields invalid index
00538                     iso_factor = isotope_intensities[feature_num][mass_trace_num];
00539                   }
00540                   feature_intensity += features[feature_num].getIntensity() * iso_factor * elu_factor;
00541                 }
00542               }
00543               Precursor p;
00544               p.setIntensity(feature_intensity);
00545               p.setMZ(features[feature_num].getMZ());
00546               p.setCharge(features[feature_num].getCharge());
00547               pcs.push_back(p);
00548               parent_feature_ids.push_back((Int)feature_num);
00549             }
00550           }
00551 
00552           if (!pcs.empty())
00553           {
00554             //std::cerr<<"scan "<<i<<"  added spectrum for features:  "<<parent_feature_ids<<std::endl;
00555             ms2_spec.setPrecursors(pcs);
00556             ms2_spec.setMSLevel(2);
00557             ms2_spec.setRT(experiment[i].getRT() + rt_dist / 2.0);           //(selected_peaks+1)*rt_dist/(max_spec+1) );
00558             ms2_spec.setMetaValue("parent_feature_ids", parent_feature_ids);
00559             ms2.push_back(ms2_spec);
00560           }
00561 
00562           //add m/z window to exclusion list
00563           exclusion_list.insert(std::make_pair(std::make_pair(peak_mz - excl_window, peak_mz + excl_window), exclusion_specs + 1));
00564 
00565           ++j;
00566         }
00567       }
00568     }
00569   }
00570 
00571   template <typename InputPeakType>
00572   void OfflinePrecursorIonSelection::checkMassRanges_(std::vector<std::vector<std::pair<Size, Size> > > & mass_ranges,
00573                                                       const MSExperiment<InputPeakType> & experiment)
00574   {
00575     std::vector<std::vector<std::pair<Size, Size> > > checked_mass_ranges;
00576     DoubleReal min_peak_distance = param_.getValue("min_peak_distance");
00577     checked_mass_ranges.reserve(mass_ranges.size());
00578     for (Size f = 0; f < mass_ranges.size(); ++f)
00579     {
00580       std::vector<std::pair<Size, Size> > checked_mass_ranges_f;
00581       for (Size s_idx = 0; s_idx < mass_ranges[f].size(); s_idx += 2)
00582       {
00583         Size s = mass_ranges[f][s_idx].first;
00584         bool overlapping_features = false;
00586         // check if other features overlap with this feature in the current scan
00588         const InputPeakType & peak_left_border = experiment[s][mass_ranges[f][s_idx].second];
00589         const InputPeakType & peak_right_border = experiment[s][mass_ranges[f][s_idx + 1].second];
00590         for (Size fmr = 0; fmr < mass_ranges.size(); ++fmr)
00591         {
00592           if (fmr == f)
00593             continue;
00594           for (Size mr = 0; mr < mass_ranges[fmr].size(); mr += 2)
00595           {
00596             if (mass_ranges[fmr][mr].first ==  s)                             // same spectrum
00597             {
00598               const InputPeakType & tmp_peak_left = experiment[s][mass_ranges[fmr][mr].second];
00599               const InputPeakType & tmp_peak_right = experiment[s][mass_ranges[fmr][mr + 1].second];
00600 #ifdef DEBUG_OPS
00601               std::cout << tmp_peak_left.getMZ() << " < "
00602                         << peak_left_border.getMZ() - min_peak_distance << " && "
00603                         << tmp_peak_right.getMZ() << " < "
00604                         << peak_left_border.getMZ() - min_peak_distance << " ? "
00605                         << (tmp_peak_left.getMZ() < peak_left_border.getMZ() - min_peak_distance &&
00606                   tmp_peak_right.getMZ() < peak_left_border.getMZ() - min_peak_distance)
00607                         << " || "
00608                         << tmp_peak_left.getMZ() << " > "
00609                         << peak_right_border.getMZ() + min_peak_distance << " && "
00610                         << tmp_peak_right.getMZ() << " > "
00611                         << peak_right_border.getMZ() + min_peak_distance << " ? "
00612                         << (tmp_peak_left.getMZ() > peak_right_border.getMZ() + min_peak_distance &&
00613                   tmp_peak_right.getMZ() > peak_right_border.getMZ() + min_peak_distance)
00614                         << std::endl;
00615 #endif
00616               // all other features have to be either completely left or
00617               // right of the current feature
00618               if (!((tmp_peak_left.getMZ() < peak_left_border.getMZ() - min_peak_distance &&
00619                      tmp_peak_right.getMZ() < peak_left_border.getMZ() - min_peak_distance) ||
00620                     (tmp_peak_left.getMZ() > peak_right_border.getMZ() + min_peak_distance &&
00621                      tmp_peak_right.getMZ() > peak_right_border.getMZ() + min_peak_distance)))
00622               {
00623 #ifdef DEBUG_OPS
00624                 std::cout << "found overlapping peak" << std::endl;
00625 #endif
00626                 overlapping_features = true;
00627                 break;
00628               }
00629             }
00630           }
00631         }
00632         if (!overlapping_features)
00633         {
00634 #ifdef DEBUG_OPS
00635           std::cout << "feature in spec ok" << mass_ranges[f][s_idx].second << " in spec "
00636                     << mass_ranges[f][s_idx].first << std::endl;
00637 #endif
00638           checked_mass_ranges_f.insert(checked_mass_ranges_f.end(),
00639                                        mass_ranges[f].begin() + s_idx,
00640                                        mass_ranges[f].begin() + s_idx + 2);
00641         }
00642       }
00643       checked_mass_ranges.push_back(checked_mass_ranges_f);
00644     }
00645     mass_ranges.swap(checked_mass_ranges);
00646   }
00647 
00648   template <typename T>
00649   void OfflinePrecursorIonSelection::updateExclusionList_(std::vector<std::pair<T, Size> > & exclusion_list)
00650   {
00651     for (Size i = 0; i < exclusion_list.size(); ++i)
00652     {
00653       if (exclusion_list[i].second > 0)
00654         --exclusion_list[i].second;
00655     }
00656     sort(exclusion_list.begin(), exclusion_list.end(), PairComparatorSecondElementMore<std::pair<T, Size> >());
00657     typename std::vector<std::pair<T, Size> >::iterator iter = exclusion_list.begin();
00658     while (iter != exclusion_list.end() && iter->second != 0)
00659       ++iter;
00660     exclusion_list.erase(iter, exclusion_list.end());
00661   }
00662 
00663   inline  void OfflinePrecursorIonSelection::updateExclusionList_(std::map<std::pair<DoubleReal, DoubleReal>, Size, PairComparatorSecondElement<std::pair<DoubleReal, DoubleReal> > > & exclusion_list)
00664   {
00665     std::map<std::pair<DoubleReal, DoubleReal>, Size, PairComparatorSecondElement<std::pair<DoubleReal, DoubleReal> > >::iterator it;
00666 
00667     it = exclusion_list.begin();
00668 
00669     while (it != exclusion_list.end())
00670     {
00671       if ((it->second--) == 1)
00672       {
00673         exclusion_list.erase(it++);
00674       }
00675       else
00676       {
00677         ++it;
00678       }
00679     }
00680   }
00681 
00682 }
00683 
00684 #endif //  OPENMS_ANALYSIS_ID_OFFLINEPRECURSORIONSELECTION_H

OpenMS / TOPP release 1.10.0 Documentation generated on Thu Mar 7 2013 09:42:43 using doxygen 1.7.1