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_TRANSFORMATIONS_FEATUREFINDER_ISOTOPEWAVELETTRANSFORM_H
00036 #define OPENMS_TRANSFORMATIONS_FEATUREFINDER_ISOTOPEWAVELETTRANSFORM_H
00037
00038 #include <OpenMS/TRANSFORMATIONS/FEATUREFINDER/IsotopeWaveletConstants.h>
00039 #include <OpenMS/TRANSFORMATIONS/FEATUREFINDER/IsotopeWavelet.h>
00040 #include <OpenMS/KERNEL/FeatureMap.h>
00041 #include <OpenMS/KERNEL/MSExperiment.h>
00042 #include <OpenMS/KERNEL/MSSpectrum.h>
00043 #include <OpenMS/CONCEPT/Exception.h>
00044 #include <OpenMS/MATH/STATISTICS/LinearRegression.h>
00045 #include <OpenMS/DATASTRUCTURES/ConstRefVector.h>
00046 #include <cmath>
00047 #include <math.h>
00048 #include <boost/math/special_functions/bessel.hpp>
00049 #include <vector>
00050 #include <map>
00051 #include <sstream>
00052 #include <fstream>
00053 #include <iomanip>
00054
00055 #ifdef OPENMS_HAS_CUDA
00056 #include <cuda.h>
00057 #include <OpenMS/TRANSFORMATIONS/FEATUREFINDER/IsotopeWaveletCudaKernel.h>
00058 #endif
00059
00060
00061 #ifndef CUDA_SAFE_CALL
00062 #define CUDA_SAFE_CALL(call) call;
00063 #endif
00064
00065 namespace OpenMS
00066 {
00067
00069 class cudaHelp
00070 {
00071 public:
00072 float getMZ()
00073 { return mz; }
00074 float getIntensity()
00075 { return intens; }
00076
00077 float mz;
00078 float intens;
00079 float score;
00080 };
00081
00082
00086 template <typename PeakType>
00087 class IsotopeWaveletTransform
00088 {
00089 public:
00090
00091
00093 struct BoxElement
00094 {
00095 DoubleReal mz;
00096 UInt c;
00097 DoubleReal score;
00098 DoubleReal intens;
00099 DoubleReal ref_intens;
00100 DoubleReal RT;
00101 UInt RT_index;
00102 UInt MZ_begin;
00103 UInt MZ_end;
00104 };
00105
00106 typedef std::multimap<UInt, BoxElement> Box;
00107
00108
00112 class TransSpectrum
00113 {
00114 friend class IsotopeWaveletTransform;
00115
00116 public:
00117
00119 TransSpectrum() :
00120 reference_(NULL), trans_intens_(NULL)
00121 {
00122 }
00123
00125 TransSpectrum(const MSSpectrum<PeakType>* reference) :
00126 reference_(reference)
00127 {
00128 trans_intens_ = new std::vector<float>(reference_->size(), 0.0);
00129 }
00130
00132 virtual ~TransSpectrum()
00133 {
00134 delete (trans_intens_);
00135 }
00136
00137 virtual void destroy()
00138 {
00139 delete (trans_intens_);
00140 trans_intens_ = NULL;
00141 delete (reference_);
00142 reference_ = NULL;
00143 }
00144
00146 inline DoubleReal getRT() const
00147 {
00148 return reference_->getRT();
00149 }
00150
00152 inline DoubleReal getMZ(const UInt i) const
00153 {
00154 return (*reference_)[i].getMZ();
00155 }
00156
00158 inline DoubleReal getRefIntensity(const UInt i) const
00159 {
00160 return (*reference_)[i].getIntensity();
00161 }
00162
00164 inline DoubleReal getTransIntensity(const UInt i) const
00165 {
00166 return (*trans_intens_)[i];
00167 }
00168
00170 inline void setTransIntensity(const UInt i, const DoubleReal intens)
00171 {
00172 (*trans_intens_)[i] = intens;
00173 }
00174
00176 inline Size size() const
00177 {
00178 return trans_intens_->size();
00179 }
00180
00182 inline const MSSpectrum<PeakType>* getRefSpectrum()
00183 {
00184 return reference_;
00185 }
00186
00188 inline const MSSpectrum<PeakType>* getRefSpectrum() const
00189 {
00190 return reference_;
00191 }
00192
00195 inline typename MSSpectrum<PeakType>::const_iterator MZBegin(const DoubleReal mz) const
00196 {
00197 return reference_->MZBegin(mz);
00198 }
00199
00202 inline typename MSSpectrum<PeakType>::const_iterator MZEnd(const DoubleReal mz) const
00203 {
00204 return reference_->MZEnd(mz);
00205 }
00206
00209 inline typename MSSpectrum<PeakType>::const_iterator end() const
00210 {
00211 return reference_->end();
00212 }
00213
00216 inline typename MSSpectrum<PeakType>::const_iterator begin() const
00217 {
00218 return reference_->begin();
00219 }
00220
00221 protected:
00222
00223 const MSSpectrum<PeakType>* reference_;
00224 std::vector<float>* trans_intens_;
00225
00226 };
00227
00228
00229
00235 IsotopeWaveletTransform(const DoubleReal min_mz, const DoubleReal max_mz, const UInt max_charge, const Size max_scan_size = 0, const bool use_cuda = false, const bool hr_data = false, const String intenstype = "ref");
00236
00238 virtual ~IsotopeWaveletTransform();
00239
00240
00245 virtual void getTransform(MSSpectrum<PeakType>& c_trans, const MSSpectrum<PeakType>& c_ref, const UInt c);
00246
00251 virtual void getTransformHighRes(MSSpectrum<PeakType>& c_trans, const MSSpectrum<PeakType>& c_ref, const UInt c);
00252
00272 virtual void identifyCharge(const MSSpectrum<PeakType>& candidates, const MSSpectrum<PeakType>& ref, const UInt scan_index, const UInt c,
00273 const DoubleReal ampl_cutoff, const bool check_PPMs);
00274
00275 virtual void initializeScan(const MSSpectrum<PeakType>& c_ref, const UInt c = 0);
00276
00277 #ifdef OPENMS_HAS_CUDA
00278
00280 virtual int initializeScanCuda(const MSSpectrum<PeakType>& scan, const UInt c = 0);
00281
00283 virtual void finalizeScanCuda();
00284
00288 virtual void getTransformCuda(TransSpectrum& c_trans, const UInt c);
00289
00305 virtual void identifyChargeCuda(const TransSpectrum& candidates, const UInt scan_index, const UInt c,
00306 const DoubleReal ampl_cutoff, const bool check_PPMs);
00307
00310 virtual int sortCuda(MSSpectrum<PeakType>& sorted);
00311 #endif
00312
00313
00320 void updateBoxStates(const MSExperiment<PeakType>& map, const Size scan_index, const UInt RT_interleave,
00321 const UInt RT_votes_cutoff, const Int front_bound = -1, const Int end_bound = -1);
00322
00323
00324 void mergeFeatures(IsotopeWaveletTransform<PeakType>* later_iwt, const UInt RT_interleave, const UInt RT_votes_cutoff);
00325
00326
00331 FeatureMap<Feature> mapSeeds2Features(const MSExperiment<PeakType>& map, const UInt RT_votes_cutoff);
00332
00334 virtual std::multimap<DoubleReal, Box> getClosedBoxes()
00335 { return closed_boxes_; }
00336
00337
00342 inline DoubleReal getLinearInterpolation(const typename MSSpectrum<PeakType>::const_iterator& left_iter, const DoubleReal mz_pos, const typename MSSpectrum<PeakType>::const_iterator& right_iter)
00343 {
00344 return left_iter->getIntensity() + (right_iter->getIntensity() - left_iter->getIntensity()) / (right_iter->getMZ() - left_iter->getMZ()) * (mz_pos - left_iter->getMZ());
00345 }
00346
00353 inline DoubleReal getLinearInterpolation(const DoubleReal mz_a, const DoubleReal intens_a, const DoubleReal mz_pos, const DoubleReal mz_b, const DoubleReal intens_b)
00354 {
00355 return intens_a + (intens_b - intens_a) / (mz_b - mz_a) * (mz_pos - mz_a);
00356 }
00357
00358 inline DoubleReal getSigma() const
00359 {
00360 return sigma_;
00361 }
00362
00363 inline void setSigma(const DoubleReal sigma)
00364 {
00365 sigma_ = sigma;
00366 }
00367
00368 virtual void computeMinSpacing(const MSSpectrum<PeakType>& c_ref);
00369
00370 inline DoubleReal getMinSpacing() const
00371 {
00372 return min_spacing_;
00373 }
00374
00375 inline Size getMaxScanSize() const
00376 {
00377 return max_scan_size_;
00378 }
00379
00380 protected:
00381
00382
00385 IsotopeWaveletTransform();
00386
00387
00388 inline void sampleTheCMarrWavelet_(const MSSpectrum<PeakType>& scan, const Int wavelet_length, const Int mz_index, const UInt charge);
00389
00390
00397 virtual DoubleReal scoreThis_(const TransSpectrum& candidate, const UInt peak_cutoff,
00398 const DoubleReal seed_mz, const UInt c, const DoubleReal ampl_cutoff);
00399
00406 virtual DoubleReal scoreThis_(const MSSpectrum<PeakType>& candidate, const UInt peak_cutoff,
00407 const DoubleReal seed_mz, const UInt c, const DoubleReal ampl_cutoff);
00408
00409
00417 virtual bool checkPositionForPlausibility_(const TransSpectrum& candidate, const MSSpectrum<PeakType>& ref, const DoubleReal seed_mz,
00418 const UInt c, const UInt scan_index, const bool check_PPMs, const DoubleReal transintens, const DoubleReal prev_score);
00419
00427 virtual bool checkPositionForPlausibility_(const MSSpectrum<PeakType>& candidate, const MSSpectrum<PeakType>& ref, const DoubleReal seed_mz,
00428 const UInt c, const UInt scan_index, const bool check_PPMs, const DoubleReal transintens, const DoubleReal prev_score);
00429
00430 virtual std::pair<DoubleReal, DoubleReal> checkPPMTheoModel_(const MSSpectrum<PeakType>& ref, const DoubleReal c_mz, const UInt c);
00431
00432
00434 inline DoubleReal getAvIntens_(const TransSpectrum& scan);
00436 inline DoubleReal getAvIntens_(const MSSpectrum<PeakType>& scan);
00437
00439 inline DoubleReal getSdIntens_(const TransSpectrum& scan, const DoubleReal mean);
00441 inline DoubleReal getSdIntens_(const MSSpectrum<PeakType>& scan, const DoubleReal mean);
00442
00453 virtual void push2Box_(const DoubleReal mz, const UInt scan, UInt c, const DoubleReal score,
00454 const DoubleReal intens, const DoubleReal rt, const UInt MZ_begin, const UInt MZ_end, const DoubleReal ref_intens);
00455
00471 virtual void push2TmpBox_(const DoubleReal mz, const UInt scan, UInt charge, const DoubleReal score,
00472 const DoubleReal intens, const DoubleReal rt, const UInt MZ_begin, const UInt MZ_end);
00473
00479 inline DoubleReal getAvMZSpacing_(const MSSpectrum<PeakType>& scan);
00480
00481
00486 void clusterSeeds_(const TransSpectrum& candidates, const MSSpectrum<PeakType>& ref,
00487 const UInt scan_index, const UInt c, const bool check_PPMs);
00488
00493 virtual void clusterSeeds_(const MSSpectrum<PeakType>& candidates, const MSSpectrum<PeakType>& ref,
00494 const UInt scan_index, const UInt c, const bool check_PPMs);
00495
00496
00501 void extendBox_(const MSExperiment<PeakType>& map, const Box box);
00502
00505 inline DoubleReal peptideMassRule_(const DoubleReal c_mass) const
00506 {
00507 DoubleReal correction_fac = c_mass / Constants::PEPTIDE_MASS_RULE_BOUND;
00508 DoubleReal old_frac_mass = c_mass - (Int)(c_mass);
00509 DoubleReal new_mass = ((Int)(c_mass)) * (1. + Constants::PEPTIDE_MASS_RULE_FACTOR) - (Int)(correction_fac);
00510 DoubleReal new_frac_mass = new_mass - (Int)(new_mass);
00511
00512 if (new_frac_mass - old_frac_mass > 0.5)
00513 {
00514 new_mass -= 1.;
00515 }
00516
00517 if (new_frac_mass - old_frac_mass < -0.5)
00518 {
00519 new_mass += 1.;
00520 }
00521
00522 return new_mass;
00523 }
00524
00528 inline DoubleReal getPPMs_(const DoubleReal mass_a, const DoubleReal mass_b) const
00529 {
00530 return fabs(mass_a - mass_b) / (0.5 * (mass_a + mass_b)) * 1e6;
00531 }
00532
00533
00534 std::multimap<DoubleReal, Box> open_boxes_, closed_boxes_, end_boxes_, front_boxes_;
00535 std::vector<std::multimap<DoubleReal, Box> >* tmp_boxes_;
00536
00537 DoubleReal av_MZ_spacing_, sigma_;
00538 std::vector<DoubleReal> c_mzs_, c_spacings_, psi_, prod_, xs_;
00539 std::vector<DoubleReal> interpol_xs_, interpol_ys_;
00540
00541 Size max_scan_size_;
00542 UInt max_num_peaks_per_pattern_, max_charge_, data_length_;
00543 bool hr_data_;
00544 String intenstype_;
00545 Int from_max_to_left_, from_max_to_right_;
00546 std::vector<int> indices_;
00547
00548 MSSpectrum<PeakType> c_sorted_candidate_;
00549 DoubleReal min_spacing_, max_mz_cutoff_;
00550 std::vector<float> scores_, zeros_;
00551
00552 #ifdef OPENMS_HAS_CUDA
00553 float* h_data_;
00554 int* h_pos_;
00555 UInt largest_array_size_, overall_size_, block_size_, to_load_, to_compute_;
00556 Int num_elements_;
00557 void* cuda_device_intens_;
00558 void* cuda_device_pos_;
00559 void* cuda_device_trans_intens_;
00560 void* cuda_device_fwd2_;
00561 void* cuda_device_posindices_sorted_;
00562 void* cuda_device_trans_intens_sorted_;
00563 void* cuda_device_scores_;
00564 std::vector<float> cuda_positions_, cuda_intensities_;
00565 dim3 dimGrid_, dimBlock_;
00566 #endif
00567 };
00568
00569
00570 bool myCudaComparator(const cudaHelp& a, const cudaHelp& b);
00571
00572 template <typename PeakType>
00573 bool intensityComparator(const PeakType& a, const PeakType& b)
00574 {
00575 return a.getIntensity() > b.getIntensity();
00576 }
00577
00578 template <typename PeakType>
00579 bool intensityAscendingComparator(const PeakType& a, const PeakType& b)
00580 {
00581 return a.getIntensity() < b.getIntensity();
00582 }
00583
00584 template <typename PeakType>
00585 bool intensityPointerComparator(PeakType* a, PeakType* b)
00586 {
00587 return a->getIntensity() > b->getIntensity();
00588 }
00589
00590 template <typename PeakType>
00591 bool positionComparator(const PeakType& a, const PeakType& b)
00592 {
00593 return a.getMZ() < b.getMZ();
00594 }
00595
00596 template <typename PeakType>
00597 IsotopeWaveletTransform<PeakType>::IsotopeWaveletTransform()
00598 {
00599 tmp_boxes_ = new std::vector<std::multimap<DoubleReal, Box> >(1);
00600 av_MZ_spacing_ = 1;
00601 max_scan_size_ = 0;
00602 max_mz_cutoff_ = 3;
00603 max_num_peaks_per_pattern_ = 3;
00604 hr_data_ = false;
00605 intenstype_ = "ref";
00606 #ifdef OPENMS_HAS_CUDA
00607 largest_array_size_ = 0;
00608 num_elements_ = 0;
00609 h_data_ = NULL;
00610 h_pos_ = NULL;
00611 #endif
00612 }
00613
00614 template <typename PeakType>
00615 IsotopeWaveletTransform<PeakType>::IsotopeWaveletTransform(const DoubleReal min_mz, const DoubleReal max_mz, const UInt max_charge, const Size max_scan_size, const bool use_cuda, const bool hr_data, String intenstype)
00616 {
00617 max_charge_ = max_charge;
00618 max_scan_size_ = max_scan_size;
00619 hr_data_ = hr_data;
00620 intenstype_ = intenstype;
00621 tmp_boxes_ = new std::vector<std::multimap<DoubleReal, Box> >(max_charge);
00622 if (max_scan_size <= 0)
00623 {
00624 IsotopeWavelet::init(max_mz, max_charge);
00625 }
00626
00627 av_MZ_spacing_ = 1;
00628 max_mz_cutoff_ = IsotopeWavelet::getMzPeakCutOffAtMonoPos(max_mz, max_charge);
00629 max_num_peaks_per_pattern_ = IsotopeWavelet::getNumPeakCutOff(max_mz, max_charge);
00630
00631 #ifdef OPENMS_HAS_CUDA
00632 if (use_cuda)
00633 {
00634 if (hr_data_)
00635 {
00636 max_scan_size_ = max_scan_size * (4 * (max_mz_cutoff_ - 1) - 1);
00637 }
00638 largest_array_size_ = pow(2, ceil(log(max_scan_size_ + Constants::CUDA_EXTENDED_BLOCK_SIZE_MAX) / log(2.0)));
00639
00640 cuda_positions_.reserve(largest_array_size_);
00641 cuda_intensities_.reserve(largest_array_size_);
00642 indices_.resize(largest_array_size_);
00643 for (UInt q = 0; q < largest_array_size_; ++q)
00644 {
00645 indices_[q] = q;
00646 }
00647
00648 h_data_ = (float*) malloc(largest_array_size_ * sizeof(float));
00649 h_pos_ = (int*) malloc(largest_array_size_ * sizeof(int));
00650 }
00651 else
00652 {
00653 h_data_ = NULL;
00654 h_pos_ = NULL;
00655 Int size_estimate((Int)ceil(max_scan_size_ / (max_mz - min_mz)));
00656 Int to_reserve((Int)ceil(size_estimate * max_num_peaks_per_pattern_ * Constants::IW_NEUTRON_MASS));
00657 psi_.reserve(to_reserve);
00658 prod_.reserve(to_reserve);
00659 xs_.reserve(to_reserve);
00660 interpol_xs_.resize(Constants::DEFAULT_NUM_OF_INTERPOLATION_POINTS);
00661 interpol_ys_.resize(Constants::DEFAULT_NUM_OF_INTERPOLATION_POINTS);
00662 }
00663 #else
00664 if (!use_cuda)
00665 {
00666 Int size_estimate((Int)ceil(max_scan_size_ / (max_mz - min_mz)));
00667 Int to_reserve((Int)ceil(size_estimate * max_num_peaks_per_pattern_ * Constants::IW_NEUTRON_MASS));
00668 psi_.reserve(to_reserve);
00669 prod_.reserve(to_reserve);
00670 xs_.reserve(to_reserve);
00671 interpol_xs_.resize(Constants::DEFAULT_NUM_OF_INTERPOLATION_POINTS);
00672 interpol_ys_.resize(Constants::DEFAULT_NUM_OF_INTERPOLATION_POINTS);
00673 }
00674 #endif
00675 }
00676
00677 template <typename PeakType>
00678 IsotopeWaveletTransform<PeakType>::~IsotopeWaveletTransform()
00679 {
00680 #ifdef OPENMS_HAS_CUDA
00681 if (h_data_ != NULL)
00682 free(h_data_);
00683 if (h_pos_ != NULL)
00684 free(h_pos_);
00685 h_data_ = NULL;
00686 h_pos_ = NULL;
00687 #endif
00688
00689 delete (tmp_boxes_);
00690 }
00691
00692 template <typename PeakType>
00693 void IsotopeWaveletTransform<PeakType>::getTransform(MSSpectrum<PeakType>& c_trans, const MSSpectrum<PeakType>& c_ref, const UInt c)
00694 {
00695 Int spec_size((Int)c_ref.size());
00696
00697
00698 UInt charge = c + 1;
00699 DoubleReal value, T_boundary_left, T_boundary_right, old, c_diff, current, old_pos, my_local_MZ, my_local_lambda, origin, c_mz;
00700
00701 for (Int my_local_pos = 0; my_local_pos < spec_size; ++my_local_pos)
00702 {
00703 value = 0; T_boundary_left = 0, T_boundary_right = IsotopeWavelet::getMzPeakCutOffAtMonoPos(c_ref[my_local_pos].getMZ(), charge) / (DoubleReal)charge;
00704 old = 0; old_pos = (my_local_pos - from_max_to_left_ - 1 >= 0) ? c_ref[my_local_pos - from_max_to_left_ - 1].getMZ() : c_ref[0].getMZ() - min_spacing_;
00705 my_local_MZ = c_ref[my_local_pos].getMZ(); my_local_lambda = IsotopeWavelet::getLambdaL(my_local_MZ * charge);
00706 c_diff = 0;
00707 origin = -my_local_MZ + Constants::IW_QUARTER_NEUTRON_MASS / (DoubleReal)charge;
00708
00709 for (Int current_conv_pos = std::max(0, my_local_pos - from_max_to_left_); c_diff < T_boundary_right; ++current_conv_pos)
00710 {
00711 if (current_conv_pos >= spec_size)
00712 {
00713 value += 0.5 * old * min_spacing_;
00714 break;
00715 }
00716
00717 c_mz = c_ref[current_conv_pos].getMZ();
00718 c_diff = c_mz + origin;
00719
00720
00721 current = c_diff > T_boundary_left && c_diff <= T_boundary_right ? IsotopeWavelet::getValueByLambda(my_local_lambda, c_diff * charge + 1.) * c_ref[current_conv_pos].getIntensity() : 0;
00722
00723 value += 0.5 * (current + old) * (c_mz - old_pos);
00724
00725 old = current;
00726 old_pos = c_mz;
00727 }
00728
00729
00730
00731 c_trans[my_local_pos].setIntensity(value);
00732 }
00733 }
00734
00735 template <typename PeakType>
00736 void IsotopeWaveletTransform<PeakType>::getTransformHighRes(MSSpectrum<PeakType>& c_trans, const MSSpectrum<PeakType>& c_ref, const UInt c)
00737 {
00738 Int spec_size((Int)c_ref.size());
00739
00740
00741 UInt charge = c + 1;
00742 DoubleReal value, T_boundary_left, T_boundary_right, c_diff, current, my_local_MZ, my_local_lambda, origin, c_mz;
00743
00744 for (Int my_local_pos = 0; my_local_pos < spec_size; ++my_local_pos)
00745 {
00746 value = 0; T_boundary_left = 0, T_boundary_right = IsotopeWavelet::getMzPeakCutOffAtMonoPos(c_ref[my_local_pos].getMZ(), charge) / (DoubleReal)charge;
00747
00748
00749 my_local_MZ = c_ref[my_local_pos].getMZ(); my_local_lambda = IsotopeWavelet::getLambdaL(my_local_MZ * charge);
00750 c_diff = 0;
00751 origin = -my_local_MZ + Constants::IW_QUARTER_NEUTRON_MASS / (DoubleReal)charge;
00752
00753 for (Int current_conv_pos = std::max(0, my_local_pos - from_max_to_left_); c_diff < T_boundary_right; ++current_conv_pos)
00754 {
00755 if (current_conv_pos >= spec_size)
00756 {
00757 break;
00758 }
00759
00760 c_mz = c_ref[current_conv_pos].getMZ();
00761 c_diff = c_mz + origin;
00762
00763
00764 current = c_diff > T_boundary_left && c_diff <= T_boundary_right ? IsotopeWavelet::getValueByLambda(my_local_lambda, c_diff * charge + 1.) * c_ref[current_conv_pos].getIntensity() : 0;
00765
00766 value += current;
00767 }
00768
00769 c_trans[my_local_pos].setIntensity(value);
00770 }
00771 }
00772
00773 template <typename PeakType>
00774 void IsotopeWaveletTransform<PeakType>::initializeScan(const MSSpectrum<PeakType>& c_ref, const UInt c)
00775 {
00776 data_length_ = (UInt) c_ref.size();
00777 computeMinSpacing(c_ref);
00778 Int wavelet_length = 0, quarter_length = 0;
00779
00780 if (hr_data_)
00781 {
00782 UInt c_mz_cutoff;
00783 typename MSSpectrum<PeakType>::const_iterator start_iter, end_iter;
00784 for (UInt i = 0; i < data_length_; ++i)
00785 {
00786 c_mz_cutoff = IsotopeWavelet::getMzPeakCutOffAtMonoPos(c_ref[i].getMZ(), c + 1);
00787 start_iter = c_ref.MZEnd(c_ref[i].getMZ());
00788 end_iter = c_ref.MZBegin(c_ref[i].getMZ() + c_mz_cutoff);
00789 wavelet_length = std::max((SignedSize) wavelet_length, distance(start_iter, end_iter) + 1);
00790 end_iter = c_ref.MZEnd(c_ref[i].getMZ() - Constants::IW_QUARTER_NEUTRON_MASS / DoubleReal(c + 1.));
00791 quarter_length = std::max((SignedSize) quarter_length, distance(end_iter, start_iter) + 1);
00792 }
00793 }
00794 else
00795 {
00796
00797 max_mz_cutoff_ = IsotopeWavelet::getMzPeakCutOffAtMonoPos(c_ref[data_length_ - 1].getMZ(), max_charge_);
00798 wavelet_length = (UInt) ceil(max_mz_cutoff_ / min_spacing_);
00799 }
00800
00801
00802
00803 if (wavelet_length > (Int) c_ref.size())
00804 {
00805 std::cout << "Warning: the extremal length of the wavelet is larger (" << wavelet_length << ") than the number of data points (" << c_ref.size() << "). This might (!) severely affect the transform." << std::endl;
00806 std::cout << "Minimal spacing: " << min_spacing_ << std::endl;
00807 std::cout << "Warning/Error generated at scan with RT " << c_ref.getRT() << "." << std::endl;
00808 }
00809
00810 Int max_index = (UInt) (Constants::IW_QUARTER_NEUTRON_MASS / min_spacing_);
00811 from_max_to_left_ = max_index;
00812 from_max_to_right_ = wavelet_length - 1 - from_max_to_left_;
00813 }
00814
00815 template <typename PeakType>
00816 void IsotopeWaveletTransform<PeakType>::computeMinSpacing(const MSSpectrum<PeakType>& c_ref)
00817 {
00818 min_spacing_ = INT_MAX;
00819 for (UInt c_conv_pos = 1; c_conv_pos < c_ref.size(); ++c_conv_pos)
00820 {
00821 min_spacing_ = std::min(min_spacing_, c_ref[c_conv_pos].getMZ() - c_ref[c_conv_pos - 1].getMZ());
00822 }
00823 }
00824
00825 #ifdef OPENMS_HAS_CUDA
00826 template <typename PeakType>
00827 void IsotopeWaveletTransform<PeakType>::finalizeScanCuda()
00828 {
00829 (cudaFree(cuda_device_pos_));
00830 (cudaFree(cuda_device_intens_));
00831 (cudaFree(cuda_device_trans_intens_));
00832 (cudaFree(cuda_device_fwd2_));
00833 (cudaFree(cuda_device_trans_intens_sorted_));
00834 (cudaFree(cuda_device_posindices_sorted_));
00835 (cudaFree(cuda_device_scores_));
00836 }
00837
00838 template <typename PeakType>
00839 int IsotopeWaveletTransform<PeakType>::initializeScanCuda(const MSSpectrum<PeakType>& scan, const UInt c)
00840 {
00841 data_length_ = scan.size();
00842
00843 std::vector<float> pre_positions(data_length_), pre_intensities(data_length_);
00844 float c_spacing;
00845 min_spacing_ = INT_MAX;
00846 pre_positions[0] = scan[0].getMZ();
00847 pre_intensities[0] = scan[0].getIntensity();
00848
00849 for (UInt i = 1; i < data_length_; ++i)
00850 {
00851 pre_positions[i] = scan[i].getMZ();
00852 c_spacing = pre_positions[i] - pre_positions[i - 1];
00853 if (c_spacing < min_spacing_)
00854 {
00855 min_spacing_ = c_spacing;
00856 }
00857 pre_intensities[i] = scan[i].getIntensity();
00858 }
00859 if (min_spacing_ == INT_MAX)
00860 {
00861 std::cout << "Scan consits of a single point. Unable to compute transform." << std::endl;
00862 return Constants::CUDA_INIT_FAIL;
00863 }
00864
00865
00866 UInt wavelet_length = 0, quarter_length = 0;
00867 if (hr_data_)
00868 {
00869 UInt c_mz_cutoff;
00870 typename MSSpectrum<PeakType>::const_iterator start_iter, end_iter;
00871 for (UInt i = 0; i < data_length_; ++i)
00872 {
00873 c_mz_cutoff = IsotopeWavelet::getMzPeakCutOffAtMonoPos(scan[i].getMZ(), c + 1);
00874 start_iter = scan.MZEnd(scan[i].getMZ());
00875 end_iter = scan.MZBegin(scan[i].getMZ() + c_mz_cutoff);
00876 wavelet_length = std::max((long int) wavelet_length, distance(start_iter, end_iter) + 1);
00877 end_iter = scan.MZEnd(scan[i].getMZ() - Constants::IW_QUARTER_NEUTRON_MASS / DoubleReal(c + 1.));
00878 quarter_length = std::max((long int) quarter_length, distance(end_iter, start_iter) + 1);
00879 }
00880 }
00881 else
00882 {
00883
00884 max_mz_cutoff_ = IsotopeWavelet::getMzPeakCutOffAtMonoPos(scan[data_length_ - 1].getMZ(), max_charge_);
00885 wavelet_length = (UInt) ceil(max_mz_cutoff_ / min_spacing_);
00886 }
00887
00888
00889 if (wavelet_length > data_length_ || wavelet_length == 1)
00890 {
00891 std::cout << "Warning: the extremal length of the wavelet is larger (" << wavelet_length << ") than the number of data points (" << data_length_ << "). This might (!) severely affect the transform." << std::endl;
00892 std::cout << "Minimal spacing: " << min_spacing_ << std::endl;
00893 std::cout << "Warning/Error generated at scan with RT " << scan.getRT() << "." << std::endl;
00894 }
00895
00896 UInt max_index;
00897 if (hr_data_)
00898 {
00899 max_index = quarter_length;
00900 }
00901 else
00902 {
00903 max_index = (UInt) (Constants::IW_QUARTER_NEUTRON_MASS / min_spacing_);
00904 }
00905 from_max_to_left_ = max_index;
00906 from_max_to_right_ = wavelet_length - 1 - from_max_to_left_;
00907
00908 Int problem_size = Constants::CUDA_BLOCK_SIZE_MAX;
00909 to_load_ = problem_size + from_max_to_left_ + from_max_to_right_;
00910
00911 UInt missing_points = problem_size - (data_length_ % problem_size);
00912 overall_size_ = wavelet_length - 1 + data_length_ + missing_points;
00913
00914 num_elements_ = overall_size_;
00915 Int dev_num_elements = 1, tmp = overall_size_ >> 1;
00916
00917
00918 while (tmp)
00919 {
00920 dev_num_elements <<= 1;
00921 tmp >>= 1;
00922 }
00923
00924 if (num_elements_ > dev_num_elements)
00925 {
00926 dev_num_elements <<= 1;
00927 }
00928
00929 if (dev_num_elements < Constants::CUDA_MIN_SORT_SIZE)
00930 {
00931 dev_num_elements = Constants::CUDA_MIN_SORT_SIZE;
00932 }
00933
00934 overall_size_ = dev_num_elements;
00935
00936 cuda_intensities_.resize(overall_size_, 0); cuda_positions_.resize(overall_size_, 0);
00937
00938 float first_pos = pre_positions[0];
00939 for (Int i = 0; i < from_max_to_left_; ++i)
00940 {
00941 cuda_positions_[i] = first_pos - (from_max_to_left_ - i) * min_spacing_;
00942 }
00943
00944 for (UInt i = 0; i < data_length_; ++i)
00945 {
00946 cuda_positions_[from_max_to_left_ + i] = pre_positions[i];
00947 cuda_intensities_[from_max_to_left_ + i] = pre_intensities[i];
00948 }
00949
00950 float last_pos = pre_positions[pre_positions.size() - 1];
00951 for (UInt i = 0; i < missing_points + from_max_to_right_ + dev_num_elements - num_elements_; ++i)
00952 {
00953 cuda_positions_[from_max_to_left_ + data_length_ + i] = last_pos + (i + 1) * min_spacing_;
00954 }
00955
00956 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
00957 std::stringstream name; name << "cuda_input_" << scan.getRT() << ".out\0";
00958 std::fstream outfile(name.str().c_str(), std::ios::out);
00959 for (size_t i = 0; i < overall_size_; ++i)
00960 outfile << cuda_positions_[i] << " " << cuda_intensities_[i] << std::endl;
00961 outfile.close();
00962 #endif
00963
00964
00965 dimBlock_ = dim3(Constants::CUDA_BLOCK_SIZE_MAX);
00966 to_compute_ = problem_size;
00967 dimGrid_ = dim3((data_length_ + missing_points) / problem_size);
00968
00969 (cudaMalloc(&cuda_device_posindices_sorted_, overall_size_ * sizeof(int)));
00970 (cudaMalloc(&cuda_device_pos_, overall_size_ * sizeof(float)));
00971 (cudaMemcpy(cuda_device_pos_, &(cuda_positions_[0]), overall_size_ * sizeof(float), cudaMemcpyHostToDevice));
00972 (cudaMalloc(&cuda_device_intens_, overall_size_ * sizeof(float)));
00973 (cudaMemcpy(cuda_device_intens_, &(cuda_intensities_[0]), overall_size_ * sizeof(float), cudaMemcpyHostToDevice));
00974 (cudaMalloc(&cuda_device_trans_intens_, overall_size_ * sizeof(float)));
00975 (cudaMalloc(&cuda_device_fwd2_, overall_size_ * sizeof(float)));
00976 (cudaMalloc(&cuda_device_trans_intens_sorted_, overall_size_ * sizeof(float)));
00977
00978 c_sorted_candidate_.resize(overall_size_);
00979 scores_.resize(data_length_);
00980 zeros_.resize(overall_size_);
00981 memset(&zeros_[0], 0., overall_size_ * sizeof(float));
00982
00983 (cudaMalloc(&cuda_device_scores_, overall_size_ * sizeof(float)));
00984
00985 return Constants::CUDA_INIT_SUCCESS;
00986 }
00987
00988 template <typename PeakType>
00989 void IsotopeWaveletTransform<PeakType>::getTransformCuda(TransSpectrum& c_trans, const UInt c)
00990 {
00991 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
00992 std::cout << "res in vector" << std::endl;
00993 std::vector<float> res(overall_size_, 0);
00994 #endif
00995 (cudaMemcpy(cuda_device_trans_intens_, &zeros_[0], overall_size_ * sizeof(float), cudaMemcpyHostToDevice));
00996
00997 (cudaMemcpy(cuda_device_fwd2_, &zeros_[0], overall_size_ * sizeof(float), cudaMemcpyHostToDevice));
00998 getExternalCudaTransforms(dimGrid_, dimBlock_, (float*)cuda_device_pos_, (float*)cuda_device_intens_, from_max_to_left_, from_max_to_right_, (float*)cuda_device_trans_intens_,
00999 c + 1, to_load_, to_compute_, data_length_, (float*)cuda_device_fwd2_, hr_data_);
01000
01001 (cudaMemcpy(cuda_device_trans_intens_sorted_, cuda_device_fwd2_, overall_size_ * sizeof(float), cudaMemcpyDeviceToDevice));
01002
01003 (cudaMemcpy(&((*c_trans.trans_intens_)[0]), (float*)cuda_device_trans_intens_ + from_max_to_left_, data_length_ * sizeof(float), cudaMemcpyDeviceToHost));
01004 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01005 (cudaMemcpy(&(res[0]), (float*)cuda_device_trans_intens_ + from_max_to_left_, data_length_ * sizeof(float), cudaMemcpyDeviceToHost));
01006 for (UInt i = 0; i < data_length_; ++i)
01007 {
01008 c_trans.setTransIntensity(i, res[i]);
01009 }
01010 #endif
01011 }
01012
01013 template <typename PeakType>
01014 int IsotopeWaveletTransform<PeakType>::sortCuda(MSSpectrum<PeakType>& sorted)
01015 {
01016 (cudaMemcpy(cuda_device_posindices_sorted_, &indices_[0], overall_size_ * sizeof(int), cudaMemcpyHostToDevice));
01017 Int gpu_index = sortOnDevice((float*)cuda_device_trans_intens_sorted_, (int*) cuda_device_posindices_sorted_, overall_size_, 0);
01018
01019 if (gpu_index < 0)
01020 {
01021 return gpu_index;
01022 }
01023
01024 (cudaMemcpy(h_data_, (float*)cuda_device_trans_intens_sorted_ + gpu_index, sizeof(float) * (overall_size_ - gpu_index), cudaMemcpyDeviceToHost));
01025 (cudaMemcpy(h_pos_, (int*)cuda_device_posindices_sorted_ + gpu_index, sizeof(int) * (overall_size_ - gpu_index), cudaMemcpyDeviceToHost));
01026
01027 for (UInt i = 0; i < (overall_size_ - gpu_index); ++i)
01028 {
01029 sorted[i].setIntensity(h_data_[i]);
01030 sorted[i].setMZ(cuda_positions_[h_pos_[i]]);
01031 }
01032
01033 return gpu_index;
01034 }
01035
01036 template <typename PeakType>
01037 void IsotopeWaveletTransform<PeakType>::identifyChargeCuda(const TransSpectrum& candidates,
01038 const UInt scan_index, const UInt c, const DoubleReal ampl_cutoff, const bool check_PPMs)
01039 {
01040 const MSSpectrum<PeakType>& ref(*candidates.getRefSpectrum());
01041 UInt index, MZ_start, MZ_end;
01042 typename MSSpectrum<PeakType>::iterator iter, bound_iter;
01043 typename MSSpectrum<PeakType>::const_iterator iter_start, iter_end, iter_p, iter2, seed_iter;
01044 DoubleReal mz_cutoff, seed_mz, c_av_intens = 0, c_score = 0, c_sd_intens = 0, threshold = 0, help_mz;
01045
01046 Int gpu_index = sortCuda(c_sorted_candidate_), c_index;
01047 if (gpu_index < 0)
01048 {
01049 return;
01050 }
01051
01052 std::vector<UInt> processed(data_length_, 0);
01053 if (ampl_cutoff < 0)
01054 {
01055 threshold = 0;
01056 }
01057 else
01058 {
01059 c_av_intens = getAvIntens_(candidates);
01060 c_sd_intens = getSdIntens_(candidates, c_av_intens);
01061 threshold = ampl_cutoff * c_sd_intens + c_av_intens;
01062 }
01063
01064 Int num_of_scores = overall_size_ - gpu_index;
01065
01066 (cudaMemcpy(cuda_device_scores_, &zeros_[0], num_of_scores * sizeof(float), cudaMemcpyHostToDevice));
01067
01068 scoreOnDevice((int*)cuda_device_posindices_sorted_, (float*)cuda_device_trans_intens_, (float*)cuda_device_pos_, (float*)cuda_device_scores_,
01069 c, num_of_scores, overall_size_, max_num_peaks_per_pattern_, threshold);
01070
01071 (cudaMemcpy(&scores_[0], cuda_device_scores_, num_of_scores * sizeof(float), cudaMemcpyDeviceToHost));
01072
01073 std::vector<float>::iterator score_iter;
01074 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01075 std::stringstream stream;
01076 stream << "sorted_gpu_" << candidates.getRT() << "_" << c + 1 << ".trans\0";
01077 std::ofstream ofile(stream.str().c_str());
01078 for (c_index = overall_size_ - gpu_index - 1, score_iter = scores_.begin() + num_of_scores - 1; c_index >= 0; --c_index, --score_iter)
01079 {
01080 ofile << c_sorted_candidate_[c_index].getMZ() << "\t" << c_sorted_candidate_[c_index].getIntensity() << "\t" << *score_iter << std::endl;
01081 }
01082 ofile.close();
01083 #endif
01084
01085 for (c_index = overall_size_ - gpu_index - 1, score_iter = scores_.begin() + num_of_scores - 1; c_index >= 0; --c_index, --score_iter)
01086 {
01087 seed_mz = c_sorted_candidate_[c_index].getMZ();
01088
01089
01090
01091
01092
01093 index = h_pos_[c_index] - from_max_to_left_;
01094 seed_iter = ref.begin() + index;
01095
01096 if (seed_iter == ref.end() || processed[distance(ref.begin(), seed_iter)] || index <= 0)
01097 {
01098 continue;
01099 }
01100
01101 mz_cutoff = IsotopeWavelet::getMzPeakCutOffAtMonoPos(seed_mz, c + 1);
01102
01103
01104
01105
01106 iter_start = ref.MZBegin(ref.begin(), seed_mz - Constants::IW_QUARTER_NEUTRON_MASS / (c + 1.), seed_iter);
01107 iter_end = ref.MZEnd(seed_iter, seed_mz + mz_cutoff / (c + 1.), ref.end());
01108
01109 if (iter_end == ref.end())
01110 {
01111 --iter_end;
01112 }
01113
01114 MZ_start = distance(ref.begin(), iter_start);
01115 MZ_end = distance(ref.begin(), iter_end);
01116
01117 memset(&(processed[MZ_start]), 1, sizeof(UInt) * (MZ_end - MZ_start + 1));
01118
01119 c_score = *score_iter;
01120
01121 if (c_score <= 0 && c_score != -1000)
01122 {
01123 continue;
01124 }
01125
01126
01127
01128
01129 push2TmpBox_(seed_mz, scan_index, c, c_score, c_sorted_candidate_[c_index].getIntensity(), ref.getRT(), MZ_start, MZ_end);
01130
01131
01132 help_mz = seed_mz - Constants::IW_NEUTRON_MASS / (c + 1.);
01133 iter2 = candidates.MZBegin(help_mz);
01134
01135 if (iter2 == candidates.end() || iter2 == candidates.begin())
01136 {
01137 continue;
01138 }
01139
01140 if (fabs(iter2->getMZ() - seed_mz) > 0.5 * Constants::IW_NEUTRON_MASS / (c + 1.))
01141 {
01142
01143 if (iter2 != candidates.end())
01144 {
01145 UInt dist = distance(candidates.begin(), iter2);
01146 push2TmpBox_(iter2->getMZ(), scan_index, c, 0,
01147 getLinearInterpolation((iter2 - 1)->getMZ(), candidates.getTransIntensity(dist - 1), help_mz, iter2->getMZ(), candidates.getTransIntensity(dist)),
01148 candidates.getRT(), MZ_start, MZ_end);
01149 }
01150 }
01151
01152 help_mz = seed_mz + Constants::IW_NEUTRON_MASS / (c + 1.);
01153 iter2 = candidates.MZBegin(help_mz);
01154
01155 if (iter2 == candidates.end() || iter2 == candidates.begin())
01156 {
01157 continue;
01158 }
01159
01160 if (fabs(iter2->getMZ() - seed_mz) > 0.5 * Constants::IW_NEUTRON_MASS / (c + 1.))
01161 {
01162
01163 if (iter2 != candidates.end())
01164 {
01165 UInt dist = distance(candidates.begin(), iter2);
01166 push2TmpBox_(iter2->getMZ(), scan_index, c, 0,
01167 getLinearInterpolation((iter2 - 1)->getMZ(), candidates.getTransIntensity(dist - 1), help_mz, iter2->getMZ(), candidates.getTransIntensity(dist)),
01168 candidates.getRT(), MZ_start, MZ_end);
01169 }
01170 }
01171 }
01172
01173 clusterSeeds_(candidates, ref, scan_index, c, check_PPMs);
01174 }
01175
01176 #endif
01177
01178
01179 template <typename PeakType>
01180 void IsotopeWaveletTransform<PeakType>::identifyCharge(const MSSpectrum<PeakType>& candidates,
01181 const MSSpectrum<PeakType>& ref, const UInt scan_index, const UInt c, const DoubleReal ampl_cutoff, const bool check_PPMs)
01182 {
01183 Size scan_size(candidates.size());
01184 typename ConstRefVector<MSSpectrum<PeakType> >::iterator iter;
01185 typename MSSpectrum<PeakType>::const_iterator iter_start, iter_end, iter_p, seed_iter, iter2;
01186 DoubleReal mz_cutoff, seed_mz, c_av_intens = 0, c_score = 0, c_sd_intens = 0, threshold = 0, help_mz, share, share_pos, bwd, fwd;
01187 UInt MZ_start, MZ_end;
01188
01189 MSSpectrum<PeakType> diffed(candidates);
01190 diffed[0].setIntensity(0); diffed[scan_size - 1].setIntensity(0);
01191
01192 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01193 std::stringstream stream;
01194 stream << "diffed_" << ref.getRT() << "_" << c + 1 << ".trans\0";
01195 std::ofstream ofile(stream.str().c_str());
01196 #endif
01197
01198 if (!hr_data_)
01199 {
01200 for (UInt i = 0; i < scan_size - 2; ++i)
01201 {
01202 share = candidates[i + 1].getIntensity(), share_pos = candidates[i + 1].getMZ();
01203 bwd = (share - candidates[i].getIntensity()) / (share_pos - candidates[i].getMZ());
01204 fwd = (candidates[i + 2].getIntensity() - share) / (candidates[i + 2].getMZ() - share_pos);
01205
01206 if (!(bwd >= 0 && fwd <= 0) || share > ref[i + 1].getIntensity())
01207 {
01208 diffed[i + 1].setIntensity(0);
01209 }
01210
01211 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01212 ofile << diffed[i + 1].getMZ() << "\t" << diffed[i + 1].getIntensity() << std::endl;
01213 #endif
01214 }
01215 }
01216 else
01217 {
01218 for (UInt i = 0; i < scan_size - 2; ++i)
01219 {
01220 share = candidates[i + 1].getIntensity(), share_pos = candidates[i + 1].getMZ();
01221 bwd = (share - candidates[i].getIntensity()) / (share_pos - candidates[i].getMZ());
01222 fwd = (candidates[i + 2].getIntensity() - share) / (candidates[i + 2].getMZ() - share_pos);
01223
01224 if (!(bwd >= 0 && fwd <= 0))
01225 {
01226 diffed[i + 1].setIntensity(0);
01227 }
01228
01229 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01230 ofile << diffed[i + 1].getMZ() << "\t" << diffed[i + 1].getIntensity() << std::endl;
01231 #endif
01232 }
01233 }
01234 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01235 ofile.close();
01236 #endif
01237
01238 ConstRefVector<MSSpectrum<PeakType> > c_sorted_candidate_(diffed.begin(), diffed.end());
01239
01240
01241 c_sorted_candidate_.sortByIntensity();
01242
01243 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01244 std::stringstream stream2;
01245 stream2 << "sorted_cpu_" << candidates.getRT() << "_" << c + 1 << ".trans\0";
01246 std::ofstream ofile2(stream2.str().c_str());
01247 for (iter = c_sorted_candidate_.end() - 1; iter != c_sorted_candidate_.begin(); --iter)
01248 {
01249 ofile2 << iter->getMZ() << "\t" << iter->getIntensity() << std::endl;
01250 }
01251 ofile2.close();
01252 #endif
01253
01254 std::vector<UInt> processed(scan_size, 0);
01255
01256 if (ampl_cutoff < 0)
01257 {
01258 threshold = 0;
01259 }
01260 else
01261 {
01262 c_av_intens = getAvIntens_(candidates);
01263 c_sd_intens = getSdIntens_(candidates, c_av_intens);
01264 threshold = ampl_cutoff * c_sd_intens + c_av_intens;
01265 }
01266
01267 for (iter = c_sorted_candidate_.end() - 1; iter != c_sorted_candidate_.begin(); --iter)
01268 {
01269 if (iter->getIntensity() <= 0)
01270 {
01271 break;
01272 }
01273
01274 seed_mz = iter->getMZ();
01275 seed_iter = ref.MZBegin(seed_mz);
01276
01277 if (seed_iter == ref.end() || processed[distance(ref.begin(), seed_iter)])
01278 {
01279 continue;
01280 }
01281
01282 mz_cutoff = IsotopeWavelet::getMzPeakCutOffAtMonoPos(seed_mz, c + 1);
01283
01284
01285
01286
01287 iter_start = ref.MZBegin(ref.begin(), seed_mz - Constants::IW_QUARTER_NEUTRON_MASS / (c + 1.), seed_iter);
01288 iter_end = ref.MZEnd(seed_iter, seed_mz + mz_cutoff / (c + 1.), ref.end());
01289 if (iter_end == ref.end())
01290 {
01291 --iter_end;
01292 }
01293
01294 MZ_start = distance(ref.begin(), iter_start);
01295 MZ_end = distance(ref.begin(), iter_end);
01296
01297 memset(&(processed[MZ_start]), 1, sizeof(UInt) * (MZ_end - MZ_start + 1));
01298
01299 c_score = scoreThis_(candidates, IsotopeWavelet::getNumPeakCutOff(seed_mz * (c + 1.)), seed_mz, c, threshold);
01300
01301 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01302 if (trunc(seed_mz) == 874)
01303 std::cout << seed_mz << "\t" << c_score << std::endl;
01304 #endif
01305
01306 if (c_score <= 0 && c_score != -1000)
01307 {
01308 continue;
01309 }
01310
01311
01312
01313 push2TmpBox_(seed_mz, scan_index, c, c_score, iter->getIntensity(), ref.getRT(), MZ_start, MZ_end);
01314
01315 help_mz = seed_mz - Constants::IW_NEUTRON_MASS / (c + 1.);
01316 iter2 = candidates.MZBegin(help_mz);
01317 if (iter2 == candidates.end() || iter2 == candidates.begin())
01318 {
01319 continue;
01320 }
01321
01322 if (fabs(iter2->getMZ() - seed_mz) > 0.5 * Constants::IW_NEUTRON_MASS / (c + 1.))
01323 {
01324
01325 if (iter2 != candidates.end())
01326 {
01327 push2TmpBox_(iter2->getMZ(), scan_index, c, 0, getLinearInterpolation(iter2 - 1, help_mz, iter2), ref.getRT(), MZ_start, MZ_end);
01328 }
01329 }
01330
01331 help_mz = seed_mz + Constants::IW_NEUTRON_MASS / (c + 1.);
01332 iter2 = candidates.MZBegin(help_mz);
01333 if (iter2 == candidates.end() || iter2 == candidates.begin())
01334 {
01335 continue;
01336 }
01337
01338 if (fabs(iter2->getMZ() - seed_mz) > 0.5 * Constants::IW_NEUTRON_MASS / (c + 1.))
01339 {
01340
01341 if (iter2 != candidates.end())
01342 {
01343 push2TmpBox_(iter2->getMZ(), scan_index, c, 0, getLinearInterpolation(iter2 - 1, help_mz, iter2), ref.getRT(), MZ_start, MZ_end);
01344 }
01345 }
01346 }
01347
01348 clusterSeeds_(candidates, ref, scan_index, c, check_PPMs);
01349 }
01350
01351 #if defined(OPENMS_HAS_TBB) && defined(OPENMS_HAS_CUDA)
01352 template <typename PeakType>
01353 void IsotopeWaveletTransform<PeakType>::mergeFeatures(IsotopeWaveletTransform<PeakType>* later_iwt, const UInt RT_interleave, const UInt RT_votes_cutoff)
01354 {
01355 typename std::multimap<DoubleReal, Box>::iterator front_iter, end_iter, best_match, help_iter;
01356
01357
01358 for (end_iter = later_iwt->closed_boxes_.begin(); end_iter != later_iwt->closed_boxes_.end(); ++end_iter)
01359 {
01360 closed_boxes_.insert(*end_iter);
01361 }
01362
01363 typename std::multimap<DoubleReal, Box>& end_container(this->end_boxes_);
01364 typename std::multimap<DoubleReal, Box>& front_container(later_iwt->front_boxes_);
01365
01366 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01367 std::cout << "FontBox: " << front_container.size() << std::endl;
01368 for (front_iter = front_container.begin(); front_iter != front_container.end(); ++front_iter)
01369 std::cout << front_iter->first << "\t" << front_iter->second.size() << std::endl;
01370
01371 std::cout << "EndBox: " << end_container.size() << std::endl;
01372 for (front_iter = end_container.begin(); front_iter != end_container.end(); ++front_iter)
01373 std::cout << front_iter->first << "\t" << front_iter->second.size() << std::endl;
01374 #endif
01375
01376 typename std::multimap<UInt, BoxElement>::iterator biter;
01377
01378 DoubleReal best_dist, c_dist; UInt c;
01379
01380 for (front_iter = front_container.begin(); front_iter != front_container.end(); )
01381 {
01382 best_match = end_container.end(); best_dist = INT_MAX;
01383
01384 for (end_iter = end_container.begin(); end_iter != end_container.end(); ++end_iter)
01385 {
01386 c = 0;
01387 for (biter = front_iter->second.begin(); biter != front_iter->second.end(); ++biter)
01388 {
01389 c = std::max(c, biter->second.c);
01390 }
01391
01392 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01393 std::cout << "Trying to match: " << end_iter->first << " to front " << front_iter->first << std::endl;
01394 #endif
01395
01396 c_dist = fabs(end_iter->first - front_iter->first);
01397 if (c_dist < Constants::IW_HALF_NEUTRON_MASS / (c + 1.) && c_dist < best_dist)
01398 {
01399 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01400 std::cout << "best match " << front_iter->second.begin()->first << "\t" << (--(end_iter->second.end()))->first << std::endl;
01401 #endif
01402 if ((front_iter->second.begin()->first - (--(end_iter->second.end()))->first) <= RT_interleave + 1)
01403 {
01404
01405 best_match = end_iter;
01406 best_dist = c_dist;
01407 }
01408 }
01409 }
01410 if (best_match == end_container.end())
01411 {
01412 if (front_iter->second.size() >= RT_votes_cutoff)
01413 {
01414 closed_boxes_.insert(*front_iter);
01415
01416 }
01417 ++front_iter;
01418 }
01419 else
01420 {
01421 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01422 std::cout << "Merging the boxes: " << front_iter->first << "\t" << best_match->first << std::endl;
01423 #endif
01424
01425 front_iter->second.insert(best_match->second.begin(), best_match->second.end());
01426 Box replacement(front_iter->second);
01427
01428
01429 DoubleReal c_mz = front_iter->first * (front_iter->second.size() - best_match->second.size()) + best_match->first * best_match->second.size();
01430 c_mz /= ((DoubleReal) (front_iter->second.size()));
01431
01432 help_iter = front_iter;
01433 ++help_iter;
01434 std::pair<DoubleReal, std::multimap<UInt, BoxElement> > help3(c_mz, replacement);
01435 closed_boxes_.insert(help3);
01436
01437 front_container.erase(front_iter);
01438 end_container.erase(best_match);
01439 front_iter = help_iter;
01440 }
01441 }
01442
01443
01444 for (end_iter = end_container.begin(); end_iter != end_container.end(); ++end_iter)
01445 {
01446 if (end_iter->second.size() >= RT_votes_cutoff)
01447 {
01448 closed_boxes_.insert(*end_iter);
01449
01450 }
01451 }
01452 }
01453
01454 #endif
01455
01456
01457 template <typename PeakType>
01458 DoubleReal IsotopeWaveletTransform<PeakType>::scoreThis_(const MSSpectrum<PeakType>& candidate,
01459 const UInt peak_cutoff, const DoubleReal seed_mz, const UInt c, const DoubleReal ampl_cutoff)
01460 {
01461 DoubleReal c_score = 0, c_val;
01462 typename MSSpectrum<PeakType>::const_iterator c_left_iter2, c_right_iter2;
01463 Int signal_size((Int)candidate.size());
01464
01465
01466
01467
01468 Int p_h_ind = 1, end = 4 * (peak_cutoff - 1) - 1;
01469
01470 std::vector<DoubleReal> positions(end);
01471 for (Int i = 0; i < end; ++i)
01472 {
01473 positions[i] = seed_mz - ((peak_cutoff - 1) * Constants::IW_NEUTRON_MASS - (i + 1) * Constants::IW_HALF_NEUTRON_MASS) / ((DoubleReal)c + 1);
01474 }
01475
01476 DoubleReal l_score = 0, mid_val = 0;
01477 Int start_index = distance(candidate.begin(), candidate.MZBegin(positions[0])) - 1;
01478 for (Int v = 1; v <= end; ++v, ++p_h_ind)
01479 {
01480 do
01481 {
01482 if (start_index < signal_size - 1)
01483 ++start_index;
01484 else
01485 break;
01486 }
01487 while (candidate[start_index].getMZ() < positions[v - 1]);
01488
01489 if (start_index <= 0 || start_index >= signal_size - 1)
01490 {
01491 continue;
01492 }
01493
01494 c_left_iter2 = candidate.begin() + start_index - 1;
01495 c_right_iter2 = c_left_iter2 + 1;
01496
01497 c_val = c_left_iter2->getIntensity() + (c_right_iter2->getIntensity() - c_left_iter2->getIntensity()) / (c_right_iter2->getMZ() - c_left_iter2->getMZ()) * (positions[v - 1] - c_left_iter2->getMZ());
01498
01499 if (v == (int)(ceil(end / 2.)))
01500 {
01501 l_score = c_score;
01502 mid_val = c_val;
01503 }
01504
01505 if (p_h_ind % 2 == 1)
01506 {
01507 c_score -= c_val;
01508 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01509 if (trunc(seed_mz) == 874)
01510 std::cout << -c_val << std::endl;
01511 #endif
01512 }
01513 else
01514 {
01515 c_score += c_val;
01516 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01517 if (trunc(seed_mz) == 874)
01518 std::cout << c_val << std::endl;
01519 #endif
01520 }
01521
01522
01523 start_index = distance(candidate.begin(), c_left_iter2);
01524 }
01525
01526 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01527 std::ofstream ofile_score("scores.dat", ios::app);
01528 std::ofstream ofile_check_score("check_scores.dat", ios::app);
01529 ofile_score.close();
01530 ofile_check_score.close();
01531 #endif
01532
01533 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01534 if (trunc(seed_mz) == 874)
01535 std::cout << "final_score: " << seed_mz << "\t" << c_score << "\t l_score: " << l_score << "\t" << c_score - l_score - mid_val << "\t" << c_score - mid_val << "\t" << ampl_cutoff << std::endl;
01536 #endif
01537
01538 if (c_score - mid_val <= 0)
01539 {
01540 return 0;
01541 }
01542
01543 if (c_score - mid_val <= ampl_cutoff)
01544 {
01545 return -1000;
01546 }
01547
01548 if (l_score <= 0 || c_score - l_score - mid_val <= 0)
01549 {
01550 return 0;
01551 }
01552
01553 return c_score;
01554 }
01555
01556 template <typename PeakType>
01557 DoubleReal IsotopeWaveletTransform<PeakType>::scoreThis_(const TransSpectrum& candidate,
01558 const UInt peak_cutoff, const DoubleReal seed_mz, const UInt c, const DoubleReal ampl_cutoff)
01559 {
01560 DoubleReal c_score = 0, c_val;
01561 typename MSSpectrum<PeakType>::const_iterator c_left_iter2, c_right_iter2;
01562 Int signal_size((Int)candidate.size());
01563
01564
01565 Int p_h_ind = 1, end = 4 * (peak_cutoff - 1) - 1;
01566
01567 std::vector<DoubleReal> positions(end);
01568 for (Int i = 0; i < end; ++i)
01569 {
01570 positions[i] = seed_mz - ((peak_cutoff - 1) * Constants::IW_NEUTRON_MASS - (i + 1) * Constants::IW_HALF_NEUTRON_MASS) / ((DoubleReal)c + 1);
01571 }
01572
01573 DoubleReal l_score = 0, mid_val = 0;
01574 Int start_index = distance(candidate.begin(), candidate.MZBegin(positions[0])) - 1;
01575 for (Int v = 1; v <= end; ++v, ++p_h_ind)
01576 {
01577 do
01578 {
01579 if (start_index < signal_size - 1)
01580 ++start_index;
01581 else
01582 break;
01583 }
01584 while (candidate.getMZ(start_index) < positions[v - 1]);
01585
01586 if (start_index <= 0 || start_index >= signal_size - 1)
01587 {
01588 continue;
01589 }
01590
01591 c_left_iter2 = candidate.begin() + start_index - 1;
01592 c_right_iter2 = c_left_iter2 + 1;
01593
01594 c_val = candidate.getTransIntensity(start_index - 1) + (candidate.getTransIntensity(start_index) - candidate.getTransIntensity(start_index - 1)) / (c_right_iter2->getMZ() - c_left_iter2->getMZ()) * (positions[v - 1] - c_left_iter2->getMZ());
01595 if (v == (int)(ceil(end / 2.)))
01596 {
01597 l_score = c_score;
01598 mid_val = c_val;
01599 }
01600
01601 if (p_h_ind % 2 == 1)
01602 {
01603 c_score -= c_val;
01604 }
01605 else
01606 {
01607 c_score += c_val;
01608 }
01609
01610 start_index = distance(candidate.begin(), c_left_iter2);
01611 }
01612
01613 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01614 std::ofstream ofile_score("scores.dat", ios::app);
01615 std::ofstream ofile_check_score("check_scores.dat", ios::app);
01616 ofile_score << c_check_point << "\t" << c_score << std::endl;
01617 ofile_score.close();
01618 ofile_check_score.close();
01619 #endif
01620
01621 if (l_score <= 0 || c_score - l_score - mid_val <= 0 || c_score - mid_val <= ampl_cutoff)
01622 {
01623 return 0;
01624 }
01625
01626 return c_score;
01627 }
01628
01629 template <typename PeakType>
01630 void IsotopeWaveletTransform<PeakType>::clusterSeeds_(const MSSpectrum<PeakType>& candidate,
01631 const MSSpectrum<PeakType>& ref, const UInt scan_index, const UInt c, const bool check_PPMs)
01632 {
01633 typename std::multimap<DoubleReal, Box>::iterator iter;
01634 typename Box::iterator box_iter;
01635 std::vector<BoxElement> final_box;
01636 DoubleReal c_mz, av_score = 0, av_mz = 0, av_intens = 0, av_abs_intens = 0, count = 0;
01637 DoubleReal virtual_av_mz = 0, virtual_av_intens = 0, virtual_av_abs_intens = 0, virtual_count = 0;
01638
01639 typename std::pair<DoubleReal, DoubleReal> c_extend;
01640 for (iter = tmp_boxes_->at(c).begin(); iter != tmp_boxes_->at(c).end(); ++iter)
01641 {
01642
01643 Box& c_box = iter->second;
01644 av_score = 0, av_mz = 0, av_intens = 0, av_abs_intens = 0, count = 0;
01645 virtual_av_mz = 0, virtual_av_intens = 0, virtual_av_abs_intens = 0, virtual_count = 0;
01646
01647
01648 for (box_iter = c_box.begin(); box_iter != c_box.end(); ++box_iter)
01649 {
01650 if (box_iter->second.score == 0)
01651 {
01652 if (count != 0)
01653 continue;
01654
01655 c_mz = box_iter->second.mz;
01656 virtual_av_intens += box_iter->second.intens;
01657 virtual_av_abs_intens += fabs(box_iter->second.intens);
01658 virtual_av_mz += c_mz * fabs(box_iter->second.intens);
01659 ++virtual_count;
01660 }
01661 else
01662 {
01663 c_mz = box_iter->second.mz;
01664 av_score += box_iter->second.score;
01665 av_intens += box_iter->second.intens;
01666 av_abs_intens += fabs(box_iter->second.intens);
01667 av_mz += c_mz * fabs(box_iter->second.intens);
01668 ++count;
01669 }
01670 }
01671
01672 if (count == 0)
01673 {
01674 av_intens = virtual_av_intens / virtual_count;
01675 av_score = 0;
01676 av_mz = virtual_av_mz / virtual_av_abs_intens;
01677 }
01678 else
01679 {
01680 av_intens /= count;
01681 av_score /= count;
01682 av_mz /= av_abs_intens;
01683 }
01684
01685 BoxElement c_box_element;
01686 c_box_element.mz = av_mz;
01687 c_box_element.c = c;
01688 c_box_element.score = av_score;
01689 c_box_element.intens = av_intens;
01690
01691 c_box_element.RT = c_box.begin()->second.RT;
01692 final_box.push_back(c_box_element);
01693 }
01694
01695 Size num_o_feature = final_box.size();
01696 if (num_o_feature == 0)
01697 {
01698 tmp_boxes_->at(c).clear();
01699 return;
01700 }
01701
01702
01703 std::vector<DoubleReal> bwd_diffs(num_o_feature, 0);
01704
01705 bwd_diffs[0] = 0;
01706 for (Size i = 1; i < num_o_feature; ++i)
01707 {
01708 bwd_diffs[i] = (final_box[i].intens - final_box[i - 1].intens) / (final_box[i].mz - final_box[i - 1].mz);
01709 }
01710
01711 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
01712 std::ofstream ofile_bwd("bwd_cpu.dat");
01713 for (Size i = 0; i < num_o_feature; ++i)
01714 {
01715 ofile_bwd << final_box[i].mz << "\t" << bwd_diffs[i] << std::endl;
01716 }
01717 ofile_bwd.close();
01718 #endif
01719
01720
01721 for (Size i = 0; i < num_o_feature - 1; ++i)
01722 {
01723 while (i < num_o_feature - 2)
01724 {
01725 if (final_box[i].score > 0 || final_box[i].score == -1000)
01726 break;
01727 ++i;
01728 }
01729
01730 if (bwd_diffs[i] > 0 && bwd_diffs[i + 1] < 0)
01731 {
01732 checkPositionForPlausibility_(candidate, ref, final_box[i].mz, final_box[i].c, scan_index, check_PPMs, final_box[i].intens, final_box[i].score);
01733 continue;
01734 }
01735 }
01736
01737 tmp_boxes_->at(c).clear();
01738 }
01739
01740 template <typename PeakType>
01741 DoubleReal IsotopeWaveletTransform<PeakType>::getAvIntens_(const MSSpectrum<PeakType>& scan)
01742 {
01743 DoubleReal av_intens = 0;
01744 for (UInt i = 0; i < scan.size(); ++i)
01745 {
01746 if (scan[i].getIntensity() >= 0)
01747 {
01748 av_intens += scan[i].getIntensity();
01749 }
01750 }
01751 return av_intens / (double)scan.size();
01752 }
01753
01754 template <typename PeakType>
01755 DoubleReal IsotopeWaveletTransform<PeakType>::getSdIntens_(const MSSpectrum<PeakType>& scan, const DoubleReal mean)
01756 {
01757 DoubleReal res = 0, intens;
01758 for (UInt i = 0; i < scan.size(); ++i)
01759 {
01760 if (scan[i].getIntensity() >= 0)
01761 {
01762 intens = scan[i].getIntensity();
01763 res += (intens - mean) * (intens - mean);
01764 }
01765 }
01766 return sqrt(res / (double)(scan.size() - 1));
01767 }
01768
01769 template <typename PeakType>
01770 DoubleReal IsotopeWaveletTransform<PeakType>::getAvMZSpacing_(const MSSpectrum<PeakType>& scan)
01771 {
01772 std::vector<DoubleReal> diffs(scan.size() - 1, 0);
01773 for (UInt i = 0; i < scan.size() - 1; ++i)
01774 {
01775 diffs[i] = scan[i + 1].getMZ() - scan[i].getMZ();
01776 }
01777
01778 sort(diffs.begin(), diffs.end());
01779 DoubleReal av_MZ_spacing = 0;
01780 for (UInt i = 0; i < diffs.size() / 2; ++i)
01781 {
01782 av_MZ_spacing += diffs[i];
01783 }
01784
01785 return av_MZ_spacing / (diffs.size() / 2);
01786 }
01787
01788 template <typename PeakType>
01789 DoubleReal IsotopeWaveletTransform<PeakType>::getAvIntens_(const TransSpectrum& scan)
01790 {
01791 DoubleReal av_intens = 0;
01792 for (UInt i = 0; i < scan.size(); ++i)
01793 {
01794 if (scan.getTransIntensity(i) >= 0)
01795 {
01796 av_intens += scan.getTransIntensity(i);
01797 }
01798 }
01799 return av_intens / (double)scan.size();
01800 }
01801
01802 template <typename PeakType>
01803 DoubleReal IsotopeWaveletTransform<PeakType>::getSdIntens_(const TransSpectrum& scan, const DoubleReal mean)
01804 {
01805 DoubleReal res = 0, intens;
01806 for (UInt i = 0; i < scan.size(); ++i)
01807 {
01808 if (scan.getTransIntensity(i) >= 0)
01809 {
01810 intens = scan.getTransIntensity(i);
01811 res += (intens - mean) * (intens - mean);
01812 }
01813 }
01814 return sqrt(res / (double)(scan.size() - 1));
01815 }
01816
01817 template <typename PeakType>
01818 void IsotopeWaveletTransform<PeakType>::push2Box_(const DoubleReal mz, const UInt scan, UInt c,
01819 const DoubleReal score, const DoubleReal intens, const DoubleReal rt, const UInt MZ_begin, const UInt MZ_end, DoubleReal ref_intens)
01820 {
01821 const DoubleReal dist_constraint(Constants::IW_HALF_NEUTRON_MASS / (DoubleReal)max_charge_);
01822
01823 typename std::multimap<DoubleReal, Box>::iterator upper_iter(open_boxes_.upper_bound(mz));
01824 typename std::multimap<DoubleReal, Box>::iterator lower_iter(open_boxes_.lower_bound(mz));
01825
01826 if (lower_iter != open_boxes_.end())
01827 {
01828
01829 if (mz != lower_iter->first && lower_iter != open_boxes_.begin())
01830 {
01831 --lower_iter;
01832 }
01833 }
01834
01835 typename std::multimap<DoubleReal, Box>::iterator insert_iter;
01836 bool create_new_box = true;
01837 if (lower_iter == open_boxes_.end())
01838 {
01839
01840
01841
01842 if (!open_boxes_.empty())
01843 {
01844 if (fabs((--lower_iter)->first - mz) < dist_constraint)
01845 {
01846 create_new_box = false;
01847 insert_iter = lower_iter;
01848 }
01849 }
01850 else
01851 {
01852 create_new_box = true;
01853 }
01854 }
01855 else
01856 {
01857 if (upper_iter == open_boxes_.end() && fabs(lower_iter->first - mz) < dist_constraint)
01858 {
01859 insert_iter = lower_iter;
01860 create_new_box = false;
01861 }
01862 else
01863 {
01864 create_new_box = true;
01865 }
01866 }
01867
01868
01869 if (upper_iter != open_boxes_.end() && lower_iter != open_boxes_.end())
01870 {
01871
01872
01873
01874 DoubleReal dist_lower = fabs(lower_iter->first - mz);
01875 DoubleReal dist_upper = fabs(upper_iter->first - mz);
01876 dist_lower = (dist_lower < dist_constraint) ? dist_lower : INT_MAX;
01877 dist_upper = (dist_upper < dist_constraint) ? dist_upper : INT_MAX;
01878
01879 if (dist_lower >= dist_constraint && dist_upper >= dist_constraint)
01880 {
01881 create_new_box = true;
01882 }
01883 else
01884 {
01885 insert_iter = (dist_lower < dist_upper) ? lower_iter : upper_iter;
01886 create_new_box = false;
01887 }
01888 }
01889
01890 BoxElement element;
01891 element.c = c; element.mz = mz; element.score = score; element.RT = rt; element.intens = intens; element.ref_intens = ref_intens;
01892 element.RT_index = scan; element.MZ_begin = MZ_begin; element.MZ_end = MZ_end;
01893
01894
01895 if (create_new_box == false)
01896 {
01897 std::pair<UInt, BoxElement> help2(scan, element);
01898 insert_iter->second.insert(help2);
01899
01900
01901 Box replacement(insert_iter->second);
01902
01903
01904
01905 DoubleReal c_mz = insert_iter->first * (insert_iter->second.size() - 1) + mz;
01906 c_mz /= ((DoubleReal) insert_iter->second.size());
01907
01908
01909 open_boxes_.erase(insert_iter);
01910 std::pair<DoubleReal, std::multimap<UInt, BoxElement> > help3(c_mz, replacement);
01911 open_boxes_.insert(help3);
01912 }
01913 else
01914 {
01915 std::pair<UInt, BoxElement> help2(scan, element);
01916 std::multimap<UInt, BoxElement> help3;
01917 help3.insert(help2);
01918 std::pair<DoubleReal, std::multimap<UInt, BoxElement> > help4(mz, help3);
01919 open_boxes_.insert(help4);
01920 }
01921 }
01922
01923 template <typename PeakType>
01924 void IsotopeWaveletTransform<PeakType>::push2TmpBox_(const DoubleReal mz, const UInt scan, UInt c,
01925 const DoubleReal score, const DoubleReal intens, const DoubleReal rt, const UInt MZ_begin, const UInt MZ_end)
01926 {
01927 const DoubleReal dist_constraint(Constants::IW_HALF_NEUTRON_MASS / (DoubleReal)max_charge_);
01928
01929 std::multimap<DoubleReal, Box>& tmp_box(tmp_boxes_->at(c));
01930 typename std::multimap<DoubleReal, Box>::iterator upper_iter(tmp_box.upper_bound(mz));
01931 typename std::multimap<DoubleReal, Box>::iterator lower_iter(tmp_box.lower_bound(mz));
01932
01933 if (lower_iter != tmp_box.end())
01934 {
01935
01936 if (mz != lower_iter->first && lower_iter != tmp_box.begin())
01937 {
01938 --lower_iter;
01939 }
01940 }
01941
01942 typename std::multimap<DoubleReal, Box>::iterator insert_iter;
01943 bool create_new_box = true;
01944 if (lower_iter == tmp_box.end())
01945 {
01946
01947
01948
01949 if (!tmp_box.empty())
01950 {
01951 if (fabs((--lower_iter)->first - mz) < dist_constraint)
01952 {
01953 create_new_box = false;
01954 insert_iter = lower_iter;
01955 }
01956 }
01957 else
01958 {
01959 create_new_box = true;
01960 }
01961 }
01962 else
01963 {
01964 if (upper_iter == tmp_box.end() && fabs(lower_iter->first - mz) < dist_constraint)
01965 {
01966 insert_iter = lower_iter;
01967 create_new_box = false;
01968 }
01969 else
01970 {
01971 create_new_box = true;
01972 }
01973 }
01974
01975
01976 if (upper_iter != tmp_box.end() && lower_iter != tmp_box.end())
01977 {
01978
01979 DoubleReal dist_lower = fabs(lower_iter->first - mz);
01980 DoubleReal dist_upper = fabs(upper_iter->first - mz);
01981 dist_lower = (dist_lower < dist_constraint) ? dist_lower : INT_MAX;
01982 dist_upper = (dist_upper < dist_constraint) ? dist_upper : INT_MAX;
01983
01984 if (dist_lower >= dist_constraint && dist_upper >= dist_constraint)
01985 {
01986 create_new_box = true;
01987 }
01988 else
01989 {
01990 insert_iter = (dist_lower < dist_upper) ? lower_iter : upper_iter;
01991 create_new_box = false;
01992 }
01993 }
01994
01995 BoxElement element;
01996 element.c = c; element.mz = mz; element.score = score; element.RT = rt; element.intens = intens; element.ref_intens = -1000;
01997 element.RT_index = scan; element.MZ_begin = MZ_begin; element.MZ_end = MZ_end;
01998
01999 if (create_new_box == false)
02000 {
02001 std::pair<UInt, BoxElement> help2(scan, element);
02002 insert_iter->second.insert(help2);
02003
02004
02005 Box replacement(insert_iter->second);
02006
02007
02008
02009 DoubleReal c_mz = insert_iter->first * (insert_iter->second.size() - 1) + mz;
02010 c_mz /= ((DoubleReal) insert_iter->second.size());
02011
02012
02013 tmp_box.erase(insert_iter);
02014 std::pair<DoubleReal, std::multimap<UInt, BoxElement> > help3(c_mz, replacement);
02015 tmp_box.insert(help3);
02016 }
02017 else
02018 {
02019 std::pair<UInt, BoxElement> help2(scan, element);
02020 std::multimap<UInt, BoxElement> help3;
02021 help3.insert(help2);
02022
02023 std::pair<DoubleReal, std::multimap<UInt, BoxElement> > help4(mz, help3);
02024 tmp_box.insert(help4);
02025 }
02026 }
02027
02028 template <typename PeakType>
02029 void IsotopeWaveletTransform<PeakType>::updateBoxStates(const MSExperiment<PeakType>& map, const Size scan_index, const UInt RT_interleave,
02030 const UInt RT_votes_cutoff, const Int front_bound, const Int end_bound)
02031 {
02032 typename std::multimap<DoubleReal, Box>::iterator iter, iter2;
02033
02034 if ((Int)scan_index == end_bound && end_bound != (Int)map.size() - 1)
02035 {
02036 for (iter = open_boxes_.begin(); iter != open_boxes_.end(); ++iter)
02037 {
02038 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02039 std::cout << "LOW THREAD insert in end_box " << iter->first << std::endl;
02040 typename Box::iterator dings;
02041 for (dings = iter->second.begin(); dings != iter->second.end(); ++dings)
02042 std::cout << map[dings->first].getRT() << "\t" << dings->second.c + 1 << std::endl;
02043 #endif
02044 end_boxes_.insert(*iter);
02045 }
02046 open_boxes_.clear();
02047 return;
02048 }
02049
02050 for (iter = open_boxes_.begin(); iter != open_boxes_.end(); )
02051 {
02052 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02053 if (front_bound > 0)
02054 {
02055 std::cout << "HIGH THREAD open box. " << iter->first << "\t current scan index " << scan_index << "\t" << ((iter->second.begin()))->first << "\t of last scan " << map.size() - 1 << "\t" << front_bound << std::endl;
02056 }
02057 #endif
02058
02059
02060 UInt lastScan = (--(iter->second.end()))->first;
02061 if (scan_index - lastScan > RT_interleave + 1 || scan_index == map.size() - 1)
02062 {
02063 if (iter->second.begin()->first - front_bound <= RT_interleave + 1 && front_bound > 0)
02064 {
02065 iter2 = iter;
02066 ++iter2;
02067 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02068 std::cout << "HIGH THREAD insert in front_box " << iter->first << std::endl;
02069 #endif
02070 front_boxes_.insert(*iter);
02071 open_boxes_.erase(iter);
02072 iter = iter2;
02073 continue;
02074 }
02075
02076 iter2 = iter;
02077 ++iter2;
02078
02079
02080
02081 if (iter->second.size() >= RT_votes_cutoff)
02082 {
02083
02084 iter = iter2;
02085 closed_boxes_.insert(*(--iter));
02086 }
02087 open_boxes_.erase(iter);
02088 iter = iter2;
02089 }
02090 else
02091 {
02092 ++iter;
02093 }
02094 }
02095 }
02096
02097 template <typename PeakType>
02098 void IsotopeWaveletTransform<PeakType>::extendBox_(const MSExperiment<PeakType>& map, const Box box)
02099 {
02100 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02101 std::cout << "**** CHECKING FOR BOX EXTENSIONS ****" << std::endl;
02102 #endif
02103
02104
02105 typename Box::const_iterator iter;
02106 std::vector<DoubleReal> elution_profile(box.size());
02107 UInt index = 0;
02108 for (iter = box.begin(); iter != box.end(); ++iter, ++index)
02109 {
02110 for (Size i = iter->second.MZ_begin; i != iter->second.MZ_end; ++i)
02111 {
02112 elution_profile[index] += map[iter->second.RT_index][i].getIntensity();
02113 }
02114 elution_profile[index] /= iter->second.MZ_end - iter->second.MZ_begin + 1.;
02115 }
02116
02117 DoubleReal max = 0;
02118 Int max_index = INT_MIN;
02119 for (Size i = 0; i < elution_profile.size(); ++i)
02120 {
02121 if (elution_profile[i] > max)
02122 {
02123 max_index = i;
02124 max = elution_profile[i];
02125 }
02126 }
02127
02128 Int max_extension = (Int)(elution_profile.size()) - 2 * max_index;
02129
02130 DoubleReal av_elution = 0;
02131 for (Size i = 0; i < elution_profile.size(); ++i)
02132 {
02133 av_elution += elution_profile[i];
02134 }
02135 av_elution /= (DoubleReal)elution_profile.size();
02136
02137 DoubleReal sd_elution = 0;
02138 for (Size i = 0; i < elution_profile.size(); ++i)
02139 {
02140 sd_elution += (av_elution - elution_profile[i]) * (av_elution - elution_profile[i]);
02141 }
02142 sd_elution /= (DoubleReal)(elution_profile.size() - 1);
02143 sd_elution = sqrt(sd_elution);
02144
02145
02146 DoubleReal av_mz = 0;
02147 for (iter = box.begin(); iter != box.end(); ++iter, ++index)
02148 {
02149 av_mz += iter->second.mz;
02150 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02151 std::cout << iter->second.RT << "\t" << iter->second.mz << "\t" << iter->second.c + 1 << std::endl;
02152 #endif
02153 }
02154 av_mz /= (DoubleReal)box.size();
02155
02156
02157
02158 if ((Int)(box.begin()->second.RT_index) - 1 < 0)
02159 {
02160 return;
02161 }
02162
02163 UInt pre_index = box.begin()->second.RT_index - 1;
02164 typename MSSpectrum<PeakType>::const_iterator c_iter = map[pre_index].MZBegin(av_mz);
02165 DoubleReal pre_elution = 0;
02166
02167 DoubleReal mz_start = map[pre_index + 1][box.begin()->second.MZ_begin].getMZ();
02168 DoubleReal mz_end = map[pre_index + 1][box.begin()->second.MZ_end].getMZ();
02169
02170 typename MSSpectrum<PeakType>::const_iterator mz_start_iter = map[pre_index].MZBegin(mz_start), mz_end_iter = map[pre_index].MZBegin(mz_end);
02171 for (typename MSSpectrum<PeakType>::const_iterator mz_iter = mz_start_iter; mz_iter != mz_end_iter; ++mz_iter)
02172 {
02173 pre_elution += mz_iter->getIntensity();
02174 }
02175
02176
02177
02178 if (pre_elution <= av_elution - 2 * sd_elution)
02179 {
02180 return;
02181 }
02182
02183 Int c_index = max_extension;
02184 Int first_index = box.begin()->second.RT_index;
02185 for (Int i = 1; i < max_extension; ++i)
02186 {
02187 c_index = first_index - i;
02188 if (c_index < 0)
02189 {
02190 break;
02191 }
02192
02193
02194 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02195 std::cout << box.begin()->second.RT << "\t" << av_mz << "\t" << box.begin()->second.c + 1 << "\t" << " extending the box " << std::endl;
02196 #endif
02197
02198 push2Box_(av_mz, c_index, box.begin()->second.c, box.begin()->second.score, c_iter->getIntensity(),
02199 map[c_index].getRT(), box.begin()->second.MZ_begin, box.begin()->second.MZ_end);
02200 }
02201 }
02202
02203 template <typename PeakType>
02204 void IsotopeWaveletTransform<PeakType>::clusterSeeds_(const TransSpectrum& candidates,
02205 const MSSpectrum<PeakType>& ref, const UInt scan_index, const UInt c, const bool check_PPMs)
02206 {
02207 typename std::multimap<DoubleReal, Box>::iterator iter;
02208 typename Box::iterator box_iter;
02209 std::vector<BoxElement> final_box;
02210 DoubleReal c_mz, av_score = 0, av_mz = 0, av_intens = 0, av_abs_intens = 0, count = 0;
02211 DoubleReal virtual_av_mz = 0, virtual_av_intens = 0, virtual_av_abs_intens = 0, virtual_count = 0;
02212
02213 typename std::pair<DoubleReal, DoubleReal> c_extend;
02214 for (iter = tmp_boxes_->at(c).begin(); iter != tmp_boxes_->at(c).end(); ++iter)
02215 {
02216 Box& c_box = iter->second;
02217 av_score = 0, av_mz = 0, av_intens = 0, av_abs_intens = 0, count = 0;
02218 virtual_av_mz = 0, virtual_av_intens = 0, virtual_av_abs_intens = 0, virtual_count = 0;
02219
02220 for (box_iter = c_box.begin(); box_iter != c_box.end(); ++box_iter)
02221 {
02222 if (box_iter->second.score == 0)
02223 {
02224 if (count != 0)
02225 continue;
02226
02227 c_mz = box_iter->second.mz;
02228 virtual_av_intens += box_iter->second.intens;
02229 virtual_av_abs_intens += fabs(box_iter->second.intens);
02230 virtual_av_mz += c_mz * fabs(box_iter->second.intens);
02231 ++virtual_count;
02232 }
02233 else
02234 {
02235 c_mz = box_iter->second.mz;
02236 av_score += box_iter->second.score;
02237 av_intens += box_iter->second.intens;
02238 av_abs_intens += fabs(box_iter->second.intens);
02239 av_mz += c_mz * fabs(box_iter->second.intens);
02240 ++count;
02241 }
02242 }
02243
02244 if (count == 0)
02245 {
02246 av_intens = virtual_av_intens / virtual_count;
02247 av_score = 0;
02248 av_mz = virtual_av_mz / virtual_av_abs_intens;
02249 }
02250 else
02251 {
02252 av_intens /= count;
02253 av_score /= count;
02254 av_mz /= av_abs_intens;
02255 }
02256
02257 BoxElement c_box_element;
02258 c_box_element.mz = av_mz;
02259 c_box_element.c = c;
02260 c_box_element.score = av_score;
02261 c_box_element.intens = av_intens;
02262
02263 c_box_element.RT = c_box.begin()->second.RT;
02264
02265 final_box.push_back(c_box_element);
02266 }
02267
02268 UInt num_o_feature = final_box.size();
02269 if (num_o_feature == 0)
02270 {
02271 tmp_boxes_->at(c).clear();
02272 return;
02273 }
02274
02275
02276 std::vector<DoubleReal> bwd_diffs(num_o_feature, 0);
02277
02278 bwd_diffs[0] = 0;
02279 for (UInt i = 1; i < num_o_feature; ++i)
02280 {
02281 bwd_diffs[i] = (final_box[i].intens - final_box[i - 1].intens) / (final_box[i].mz - final_box[i - 1].mz);
02282 }
02283
02284 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02285 std::ofstream ofile_bwd("bwd_gpu.dat");
02286 for (UInt i = 0; i < num_o_feature; ++i)
02287 {
02288 ofile_bwd << final_box[i].mz << "\t" << bwd_diffs[i] << std::endl;
02289 }
02290 ofile_bwd.close();
02291 #endif
02292
02293 for (UInt i = 0; i < num_o_feature - 1; ++i)
02294 {
02295 while (i < num_o_feature - 2)
02296 {
02297 if (final_box[i].score > 0 || final_box[i].score == -1000)
02298 break;
02299 ++i;
02300 }
02301
02302 if (bwd_diffs[i] > 0 && bwd_diffs[i + 1] < 0)
02303 {
02304 checkPositionForPlausibility_(candidates, ref, final_box[i].mz, final_box[i].c, scan_index, check_PPMs, final_box[i].intens, final_box[i].score);
02305 continue;
02306 }
02307 }
02308
02309 tmp_boxes_->at(c).clear();
02310 }
02311
02312 template <typename PeakType>
02313 FeatureMap<Feature> IsotopeWaveletTransform<PeakType>::mapSeeds2Features(const MSExperiment<PeakType>& map, const UInt RT_votes_cutoff)
02314 {
02315 FeatureMap<Feature> feature_map;
02316 typename std::multimap<DoubleReal, Box>::iterator iter;
02317 typename Box::iterator box_iter;
02318 UInt best_charge_index; DoubleReal best_charge_score, c_mz, c_RT; UInt c_charge;
02319 DoubleReal av_intens = 0, av_ref_intens = 0, av_score = 0, av_mz = 0, av_RT = 0, mz_cutoff, sum_of_ref_intenses_g;
02320 bool restart = false;
02321
02322 typename std::pair<DoubleReal, DoubleReal> c_extend;
02323 for (iter = closed_boxes_.begin(); iter != closed_boxes_.end(); ++iter)
02324 {
02325 sum_of_ref_intenses_g = 0;
02326 Box& c_box = iter->second;
02327 std::vector<DoubleReal> charge_votes(max_charge_, 0), charge_binary_votes(max_charge_, 0);
02328 restart = false;
02329
02330
02331
02332 for (box_iter = c_box.begin(); box_iter != c_box.end(); ++box_iter)
02333 {
02334 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02335 if (trunc(box_iter->second.mz) == 874)
02336 std::cout << box_iter->second.c << "\t" << box_iter->second.intens << "\t" << box_iter->second.score << std::endl;
02337 #endif
02338
02339 if (box_iter->second.score == -1000)
02340 {
02341 restart = true;
02342 break;
02343 }
02344
02345 charge_votes[box_iter->second.c] += box_iter->second.intens;
02346 ++charge_binary_votes[box_iter->second.c];
02347 }
02348
02349 if (restart)
02350 {
02351 continue;
02352 }
02353
02354
02355 best_charge_index = 0; best_charge_score = 0;
02356 for (UInt i = 0; i < max_charge_; ++i)
02357 {
02358 if (charge_votes[i] > best_charge_score)
02359 {
02360 best_charge_index = i;
02361 best_charge_score = charge_votes[i];
02362 }
02363 }
02364
02365
02366 if (charge_binary_votes[best_charge_index] < RT_votes_cutoff && RT_votes_cutoff <= map.size())
02367 {
02368 continue;
02369 }
02370
02371 c_charge = best_charge_index + 1;
02372
02373 av_intens = 0, av_ref_intens = 0, av_score = 0, av_mz = 0, av_RT = 0;
02374
02375 std::vector<DPosition<2> > point_set;
02376 DoubleReal sum_of_ref_intenses_l;
02377 for (box_iter = c_box.begin(); box_iter != c_box.end(); ++box_iter)
02378 {
02379 sum_of_ref_intenses_l = 0;
02380 c_mz = box_iter->second.mz;
02381 c_RT = box_iter->second.RT;
02382
02383 mz_cutoff = IsotopeWavelet::getMzPeakCutOffAtMonoPos(c_mz, c_charge);
02384
02385 point_set.push_back(DPosition<2>(c_RT, c_mz - Constants::IW_QUARTER_NEUTRON_MASS / (DoubleReal)c_charge));
02386
02387 point_set.push_back(DPosition<2>(c_RT, c_mz + mz_cutoff / (DoubleReal)c_charge));
02388
02389 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02390 std::cout << "Intenstype: " << intenstype_ << std::endl;
02391 #endif
02392 if (intenstype_ == "ref")
02393 {
02394
02395 const MSSpectrum<PeakType>& c_spec(map[box_iter->second.RT_index]);
02396
02397 for (unsigned int i = 0; i < mz_cutoff; ++i)
02398 {
02399 typename MSSpectrum<PeakType>::const_iterator h_iter = c_spec.MZBegin(c_mz + i * Constants::IW_NEUTRON_MASS / c_charge + Constants::IW_QUARTER_NEUTRON_MASS / (DoubleReal)c_charge), hc_iter = c_spec.MZBegin(c_mz + i * Constants::IW_NEUTRON_MASS / c_charge);
02400
02401 hc_iter = c_spec.MZBegin(c_mz + i * Constants::IW_NEUTRON_MASS / c_charge);
02402
02403 while (h_iter != c_spec.begin())
02404 {
02405
02406 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02407 if (trunc(c_mz) == 874)
02408 {
02409 std::cout << "cmz: " << c_mz + i * Constants::IW_NEUTRON_MASS / c_charge << "\t" << hc_iter->getMZ() << "\t" << hc_iter->getIntensity() << "\t" << h_iter->getMZ() << "\t" << h_iter->getIntensity() << std::endl;
02410 }
02411 #endif
02412
02413 --h_iter;
02414 if (h_iter->getIntensity() > hc_iter->getIntensity() || (h_iter->getIntensity() == hc_iter->getIntensity() && hc_iter->getIntensity() == 0))
02415 {
02416 hc_iter = h_iter;
02417 }
02418
02419 if (c_mz + i * Constants::IW_NEUTRON_MASS / c_charge - h_iter->getMZ() > Constants::IW_QUARTER_NEUTRON_MASS / (DoubleReal)c_charge)
02420 {
02421 break;
02422 }
02423 }
02424 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02425 if (trunc(c_mz) == 874)
02426 {
02427 std::cout << "c_mz: " << c_mz + i * Constants::IW_NEUTRON_MASS / c_charge << "\t" << hc_iter->getMZ() << "\t" << hc_iter->getIntensity() << "\t" << i * Constants::IW_NEUTRON_MASS / c_charge << "\t";
02428 }
02429 #endif
02430 sum_of_ref_intenses_l += hc_iter->getIntensity();
02431 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02432 if (trunc(c_mz) == 874)
02433 {
02434 std::cout << sum_of_ref_intenses_l << "********" << std::endl;
02435 }
02436 #endif
02437 }
02438 }
02439
02440 if (best_charge_index == box_iter->second.c)
02441 {
02442 av_score += box_iter->second.score;
02443 av_intens += box_iter->second.intens;
02444 av_ref_intens += box_iter->second.ref_intens;
02445 sum_of_ref_intenses_g += sum_of_ref_intenses_l;
02446 av_mz += c_mz * box_iter->second.intens;
02447 }
02448 av_RT += c_RT;
02449 }
02450
02451 av_mz /= av_intens;
02452 av_ref_intens /= (DoubleReal)charge_binary_votes[best_charge_index];
02453 av_score /= (DoubleReal)charge_binary_votes[best_charge_index];
02454 av_RT /= (DoubleReal)c_box.size();
02455
02456 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02457 if (trunc(av_mz) == 874)
02458 std::cout << av_mz << "\t" << best_charge_index << "\t" << best_charge_score << std::endl;
02459 #endif
02460
02461 Feature c_feature;
02462 ConvexHull2D c_conv_hull;
02463 c_conv_hull.addPoints(point_set);
02464 c_feature.setCharge(c_charge);
02465 c_feature.setConvexHulls(std::vector<ConvexHull2D>(1, c_conv_hull));
02466
02467
02468 if (intenstype_ == "corrected")
02469 {
02470 DoubleReal lambda = IsotopeWavelet::getLambdaL(av_mz * c_charge);
02471 av_intens /= exp(-2 * lambda) * boost::math::cyl_bessel_i(0, 2 * lambda);
02472 }
02473 if (intenstype_ == "ref")
02474 {
02475 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02476 if (trunc(c_mz) == 874)
02477 {
02478 std::cout << sum_of_ref_intenses_g << "####" << std::endl;
02479 }
02480 #endif
02481
02482 av_intens = sum_of_ref_intenses_g;
02483 }
02484
02485 c_feature.setMZ(av_mz);
02486 c_feature.setIntensity(av_intens);
02487 c_feature.setRT(av_RT);
02488 c_feature.setOverallQuality(av_score);
02489 feature_map.push_back(c_feature);
02490 }
02491
02492 return feature_map;
02493 }
02494
02495 template <typename PeakType>
02496 bool IsotopeWaveletTransform<PeakType>::checkPositionForPlausibility_(const MSSpectrum<PeakType>& candidate,
02497 const MSSpectrum<PeakType>& ref, const DoubleReal seed_mz, const UInt c, const UInt scan_index, const bool check_PPMs, const DoubleReal transintens, const DoubleReal prev_score)
02498 {
02499 typename MSSpectrum<PeakType>::const_iterator iter, ref_iter;
02500 UInt peak_cutoff;
02501 peak_cutoff = IsotopeWavelet::getNumPeakCutOff(seed_mz, c + 1);
02502
02503 iter = candidate.MZBegin(seed_mz);
02504
02505 if (iter == candidate.begin() || iter == candidate.end())
02506 {
02507 return false;
02508 }
02509
02510 std::pair<DoubleReal, DoubleReal> reals;
02511 ref_iter = ref.MZBegin(seed_mz);
02512
02513 DoubleReal real_mz, real_intens;
02514 if (check_PPMs)
02515 {
02516 reals = checkPPMTheoModel_(ref, iter->getMZ(), c);
02517 real_mz = reals.first, real_intens = reals.second;
02518
02519
02520 typename MSSpectrum<PeakType>::const_iterator h_iter = ref_iter, hc_iter = ref_iter;
02521 while (h_iter != ref.begin())
02522 {
02523 --h_iter;
02524 if (h_iter->getIntensity() > hc_iter->getIntensity() || (h_iter->getIntensity() == hc_iter->getIntensity() && hc_iter->getIntensity() == 0))
02525 {
02526 hc_iter = h_iter;
02527 }
02528 else
02529 {
02530 break;
02531 }
02532
02533 if (seed_mz - h_iter->getMZ() > Constants::IW_QUARTER_NEUTRON_MASS / (c + 1.))
02534 {
02535 return false;
02536 }
02537 }
02538 reals = checkPPMTheoModel_(ref, h_iter->getMZ(), c);
02539 real_mz = reals.first, real_intens = reals.second;
02540 if (real_mz <= 0 || real_intens <= 0)
02541 {
02542 return false;
02543 }
02544 real_mz = h_iter->getMZ();
02545 real_intens = h_iter->getIntensity();
02546
02547 }
02548 else
02549 {
02550 reals = std::pair<DoubleReal, DoubleReal>(seed_mz, ref_iter->getIntensity());
02551 real_mz = reals.first, real_intens = reals.second;
02552
02553 if (real_mz <= 0 || real_intens <= 0)
02554 {
02555 typename MSSpectrum<PeakType>::const_iterator h_iter = ref_iter, hc_iter = ref_iter;
02556 while (h_iter != ref.begin())
02557 {
02558 --h_iter;
02559 if (h_iter->getIntensity() > hc_iter->getIntensity() || (h_iter->getIntensity() == hc_iter->getIntensity() && hc_iter->getIntensity() == 0))
02560 {
02561 hc_iter = h_iter;
02562 }
02563 else
02564 {
02565 break;
02566 }
02567
02568 if (seed_mz - h_iter->getMZ() > Constants::IW_QUARTER_NEUTRON_MASS / (c + 1.))
02569 {
02570 return false;
02571 }
02572 }
02573 real_mz = h_iter->getMZ(), real_intens = h_iter->getIntensity();
02574 if (real_mz <= 0 || real_intens <= 0)
02575 {
02576 return false;
02577 }
02578 real_mz = h_iter->getMZ();
02579 real_intens = h_iter->getIntensity();
02580 }
02581 }
02582
02583 DoubleReal c_score = scoreThis_(candidate, peak_cutoff, real_mz, c, 0);
02584
02585 if (c_score <= 0)
02586 {
02587 return false;
02588 }
02589
02590 DoubleReal mz_cutoff = IsotopeWavelet::getMzPeakCutOffAtMonoPos(real_mz, c + 1);
02591 typename MSSpectrum<PeakType>::const_iterator real_l_MZ_iter = ref.MZBegin(real_mz - Constants::IW_QUARTER_NEUTRON_MASS / (c + 1.));
02592 typename MSSpectrum<PeakType>::const_iterator real_r_MZ_iter = ref.MZBegin(real_l_MZ_iter, real_mz + mz_cutoff / (c + 1.), ref.end());
02593 if (real_r_MZ_iter == ref.end())
02594 {
02595 --real_r_MZ_iter;
02596 }
02597
02598
02599 UInt real_mz_begin = distance(ref.begin(), real_l_MZ_iter);
02600 UInt real_mz_end = distance(ref.begin(), real_r_MZ_iter);
02601
02602 if (prev_score == -1000)
02603 {
02604 push2Box_(real_mz, scan_index, c, prev_score, transintens, ref.getRT(), real_mz_begin, real_mz_end, real_intens);
02605 }
02606 else
02607 {
02608 push2Box_(real_mz, scan_index, c, c_score, transintens, ref.getRT(), real_mz_begin, real_mz_end, real_intens);
02609 }
02610 return true;
02611 }
02612
02613 template <typename PeakType>
02614 bool IsotopeWaveletTransform<PeakType>::checkPositionForPlausibility_(const TransSpectrum& candidate,
02615 const MSSpectrum<PeakType>& ref, const DoubleReal seed_mz, const UInt c, const UInt scan_index, const bool check_PPMs, const DoubleReal transintens, const DoubleReal prev_score)
02616 {
02617 typename MSSpectrum<PeakType>::const_iterator iter, ref_iter;
02618 UInt peak_cutoff;
02619 peak_cutoff = IsotopeWavelet::getNumPeakCutOff(seed_mz, c + 1);
02620
02621 iter = candidate.MZBegin(seed_mz);
02622
02623 if (iter == candidate.begin() || iter == candidate.end())
02624 {
02625 return false;
02626 }
02627
02628 std::pair<DoubleReal, DoubleReal> reals;
02629 ref_iter = ref.MZBegin(seed_mz);
02630
02631 DoubleReal real_mz, real_intens;
02632 if (check_PPMs)
02633 {
02634 reals = checkPPMTheoModel_(ref, iter->getMZ(), c);
02635 real_mz = reals.first, real_intens = reals.second;
02636
02637
02638 typename MSSpectrum<PeakType>::const_iterator h_iter = ref_iter, hc_iter = ref_iter;
02639 while (h_iter != ref.begin())
02640 {
02641 --h_iter;
02642 if (h_iter->getIntensity() > hc_iter->getIntensity() || (h_iter->getIntensity() == hc_iter->getIntensity() && hc_iter->getIntensity() == 0))
02643 {
02644 hc_iter = h_iter;
02645 }
02646 else
02647 {
02648 break;
02649 }
02650
02651 if (seed_mz - h_iter->getMZ() > Constants::IW_QUARTER_NEUTRON_MASS / (c + 1.))
02652 {
02653 return false;
02654 }
02655 }
02656 ++h_iter;
02657 reals = checkPPMTheoModel_(ref, h_iter->getMZ(), c);
02658 real_mz = reals.first, real_intens = reals.second;
02659
02660 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02661 std::cout << "Plausibility check old_mz: " << iter->getMZ() << "\t" << real_mz << std::endl;
02662 #endif
02663
02664 if (real_mz <= 0 || real_intens <= 0)
02665 {
02666 return false;
02667 }
02668 real_mz = h_iter->getMZ();
02669 real_intens = h_iter->getIntensity();
02670
02671 }
02672 else
02673 {
02674 reals = std::pair<DoubleReal, DoubleReal>(seed_mz, ref_iter->getIntensity());
02675 real_mz = reals.first, real_intens = reals.second;
02676
02677 if (real_mz <= 0 || real_intens <= 0)
02678 {
02679 typename MSSpectrum<PeakType>::const_iterator h_iter = ref_iter, hc_iter = ref_iter;
02680 while (h_iter != ref.begin())
02681 {
02682 --h_iter;
02683 if (h_iter->getIntensity() > hc_iter->getIntensity() || (h_iter->getIntensity() == hc_iter->getIntensity() && hc_iter->getIntensity() == 0))
02684 {
02685 hc_iter = h_iter;
02686 }
02687 else
02688 {
02689 break;
02690 }
02691
02692 if (seed_mz - h_iter->getMZ() > Constants::IW_QUARTER_NEUTRON_MASS / (c + 1.))
02693 {
02694 return false;
02695 }
02696 }
02697 real_mz = h_iter->getMZ(), real_intens = h_iter->getIntensity();
02698 if (real_mz <= 0 || real_intens <= 0)
02699 {
02700 return false;
02701 }
02702 real_mz = h_iter->getMZ();
02703 real_intens = h_iter->getIntensity();
02704 }
02705 }
02706
02707 DoubleReal c_score = scoreThis_(candidate, peak_cutoff, real_mz, c, 0);
02708
02709 if (c_score <= 0)
02710 {
02711 return false;
02712 }
02713
02714 DoubleReal mz_cutoff = IsotopeWavelet::getMzPeakCutOffAtMonoPos(real_mz, c + 1);
02715 typename MSSpectrum<PeakType>::const_iterator real_l_MZ_iter = ref.MZBegin(real_mz - Constants::IW_QUARTER_NEUTRON_MASS / (c + 1.));
02716 typename MSSpectrum<PeakType>::const_iterator real_r_MZ_iter = ref.MZBegin(real_l_MZ_iter, real_mz + mz_cutoff / (c + 1.), ref.end());
02717 if (real_r_MZ_iter == ref.end())
02718 {
02719 --real_r_MZ_iter;
02720 }
02721
02722
02723 UInt real_mz_begin = distance(ref.begin(), real_l_MZ_iter);
02724 UInt real_mz_end = distance(ref.begin(), real_r_MZ_iter);
02725
02726 if (prev_score == -1000)
02727 {
02728 push2Box_(real_mz, scan_index, c, prev_score, transintens, ref.getRT(), real_mz_begin, real_mz_end, real_intens);
02729 }
02730 else
02731 {
02732 push2Box_(real_mz, scan_index, c, c_score, transintens, ref.getRT(), real_mz_begin, real_mz_end, real_intens);
02733 }
02734
02735 return true;
02736 }
02737
02738 template <typename PeakType>
02739 std::pair<DoubleReal, DoubleReal> IsotopeWaveletTransform<PeakType>::checkPPMTheoModel_(const MSSpectrum<PeakType>& ref, const DoubleReal c_mz, const UInt c)
02740 {
02741 DoubleReal mass = c_mz * (c + 1) - Constants::IW_PROTON_MASS * (c);
02742 DoubleReal ppms = getPPMs_(peptideMassRule_(mass), mass);
02743 if (ppms >= Constants::PEPTIDE_MASS_RULE_THEO_PPM_BOUND)
02744 {
02745 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02746 std::cout << ::std::setprecision(8) << std::fixed << c_mz << "\t =(" << "ISO_WAVE" << ")> " << "REJECT \t" << ppms << " (rule: " << peptideMassRule_(mass) << " got: " << mass << ")" << std::endl;
02747 #endif
02748 return std::pair<DoubleReal, DoubleReal>(-1, -1);
02749 }
02750
02751 #ifdef OPENMS_DEBUG_ISOTOPE_WAVELET
02752 std::cout << ::std::setprecision(8) << std::fixed << c_mz << "\t =(" << "ISO_WAVE" << ")> " << "ACCEPT \t" << ppms << " (rule: " << peptideMassRule_(mass) << " got: " << mass << ")" << std::endl;
02753 #endif
02754 return std::pair<DoubleReal, DoubleReal>(c_mz, ref.MZBegin(c_mz)->getIntensity());
02755 }
02756
02757 }
02758
02759 #endif