62 #include <unsupported/Eigen/NonLinearOptimization> 
   64 #ifndef OPENMS_SYSTEM_STOPWATCH_H 
   67 #include <boost/math/special_functions/acosh.hpp> 
  111       tolerance_mz_ = tolerance_mz;
 
  112       param_.setValue(
"2d:tolerance_mz", tolerance_mz);
 
  120       max_peak_distance_ = max_peak_distance;
 
  121       param_.setValue(
"2d:max_peak_distance", max_peak_distance);
 
  129       max_iteration_ = max_iteration;
 
  130       param_.setValue(
"iterations", max_iteration);
 
  138       penalties_ = penalties;
 
  139       param_.setValue(
"penalties:position", penalties.
pos);
 
  140       param_.setValue(
"penalties:height", penalties.
height);
 
  141       param_.setValue(
"penalties:left_width", penalties.
lWidth);
 
  142       param_.setValue(
"penalties:right_width", penalties.
rWidth);
 
  161     template <
typename InputSpectrumIterator>
 
  162     void optimize(InputSpectrumIterator first,
 
  163                   InputSpectrumIterator last,
 
  164                   PeakMap& ms_exp, 
bool real2D = 
true);
 
  171       std::vector<std::pair<SignedSize, SignedSize> > 
signal2D;
 
  189       : m_inputs(dimensions), m_values(num_data_points), m_data(data) {}
 
  191       int operator()(
const Eigen::VectorXd &x, Eigen::VectorXd &fvec);
 
  193       int df(
const Eigen::VectorXd &x, Eigen::MatrixXd &J);
 
  233     std::vector<double>::iterator searchInScan_(std::vector<double>::iterator scan_begin,
 
  234                                                     std::vector<double>::iterator scan_end,
 
  238     template <
typename InputSpectrumIterator>
 
  239     void optimizeRegions_(InputSpectrumIterator& first,
 
  240                           InputSpectrumIterator& last,
 
  244     template <
typename InputSpectrumIterator>
 
  245     void optimizeRegionsScanwise_(InputSpectrumIterator& first,
 
  246                                   InputSpectrumIterator& last,
 
  251     template <
typename InputSpectrumIterator>
 
  252     void getRegionEndpoints_(
PeakMap& exp,
 
  253                              InputSpectrumIterator& first,
 
  254                              InputSpectrumIterator& last,
 
  260     void findMatchingPeaks_(std::multimap<double, IsotopeCluster>::iterator& it,
 
  266     void updateMembers_() 
override;
 
  270   template <
typename InputSpectrumIterator>
 
  275     if ((
UInt)distance(first, last) != ms_exp.
size())
 
  277       throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, 
"Error in Two2Optimization: Raw and peak map do not have the same number of spectra");
 
  285     for (
Size i = 0; i < ms_exp.
size(); ++i)
 
  288       if (ms_exp[i].getFloatDataArrays().
size() < 6)
 
  290         throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, 
"Error in Two2Optimization: Not enough meta data arrays present (1:area, 5:shape, 3:left width, 4:right width)");
 
  292       bool area = ms_exp[i].getFloatDataArrays()[1].getName() == 
"maximumIntensity";
 
  293       bool wleft = ms_exp[i].getFloatDataArrays()[3].getName() == 
"leftWidth";
 
  294       bool wright = ms_exp[i].getFloatDataArrays()[4].getName() == 
"rightWidth";
 
  295       bool shape = ms_exp[i].getFloatDataArrays()[5].getName() == 
"peakShape";
 
  297       if (!area || !wleft || !wright || !shape)
 
  299         throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, 
"Error in Two2Optimization: One or several meta data arrays missing (1:intensity, 5:shape, 3:left width, 4:right width)");
 
  312     std::vector<double> iso_last_scan;
 
  313     std::vector<double> iso_curr_scan;
 
  314     std::vector<std::multimap<double, IsotopeCluster>::iterator> clusters_last_scan;
 
  315     std::vector<std::multimap<double, IsotopeCluster>::iterator> clusters_curr_scan;
 
  316     std::multimap<double, IsotopeCluster>::iterator cluster_iter;
 
  317     double current_rt = ms_exp_it->getRT(), last_rt  = 0;
 
  323     UInt current_charge     = 0; 
 
  324     double mz_in_hash   = 0; 
 
  327     for (
UInt curr_scan = 0; ms_exp_it + curr_scan != ms_exp_it_end; ++curr_scan)
 
  329       Size nr_peaks_in_scan = (ms_exp_it + curr_scan)->size();
 
  330       if (nr_peaks_in_scan == 0)
 
  334       current_rt = (ms_exp_it + curr_scan)->getRT();
 
  338       iso_last_scan = iso_curr_scan;
 
  339       iso_curr_scan.clear();
 
  340       clusters_last_scan = clusters_curr_scan;
 
  341       clusters_curr_scan.clear();
 
  344       std::cout << 
"Next scan with rt: " << current_rt << std::endl;
 
  345       std::cout << 
"Next scan, rt = " << current_rt << 
" last_rt: " << last_rt << std::endl;
 
  346       std::cout << 
"---------------------------------------------------------------------------" << std::endl;
 
  356         for (
UInt curr_peak = 0; curr_peak < (ms_exp_it + curr_scan)->size() - 1; ++curr_peak)
 
  360           double curr_mz         = (peak_it + curr_peak)->getMZ();
 
  361           double dist2nextpeak = (peak_it + curr_peak + 1)->getMZ() - curr_mz;
 
  366             std::cout << 
"Isotopic pattern found ! " << std::endl;
 
  367             std::cout << 
"We are at: " << (peak_it + curr_peak)->getMZ()  << 
" " << curr_mz << std::endl;
 
  369             if (!iso_last_scan.empty()) 
 
  371               std::sort(iso_last_scan.begin(), iso_last_scan.end());
 
  373               std::vector<double>::iterator it =
 
  374                 searchInScan_(iso_last_scan.begin(), iso_last_scan.end(), curr_mz);
 
  376               double delta_mz = fabs(*it - curr_mz);
 
  378               if (delta_mz > tolerance_mz) 
 
  380                 mz_in_hash = curr_mz; 
 
  388                 new_cluster.
scans.push_back(curr_scan);
 
  389                 cluster_iter = 
iso_map_.insert(std::pair<double, IsotopeCluster>(mz_in_hash, new_cluster));
 
  397                 cluster_iter = clusters_last_scan[distance(iso_last_scan.begin(), it)];
 
  400                 if (
find(cluster_iter->second.scans.begin(), cluster_iter->second.scans.end(), curr_scan)
 
  401                     == cluster_iter->second.scans.end())
 
  403                   cluster_iter->second.scans.push_back(curr_scan);
 
  420               mz_in_hash = curr_mz; 
 
  425               new_cluster.
scans.push_back(curr_scan);
 
  426               cluster_iter = 
iso_map_.insert(std::pair<double, IsotopeCluster>(mz_in_hash, new_cluster));
 
  436             cluster_iter->second.peaks.insert(std::pair<UInt, UInt>(curr_scan, curr_peak));
 
  438             iso_curr_scan.push_back(mz_in_hash);
 
  439             clusters_curr_scan.push_back(cluster_iter);
 
  442             cluster_iter->second.peaks.insert(std::pair<UInt, UInt>(curr_scan, curr_peak));
 
  443             iso_curr_scan.push_back((peak_it + curr_peak)->getMZ());
 
  444             clusters_curr_scan.push_back(cluster_iter);
 
  447             if ((curr_peak + 1) >= nr_peaks_in_scan)
 
  449             dist2nextpeak = (peak_it + curr_peak + 1)->getMZ() -  (peak_it + curr_peak)->getMZ();
 
  454                   &&  curr_peak < (nr_peaks_in_scan - 1))
 
  456               cluster_iter->second.peaks.insert(std::pair<UInt, UInt>(curr_scan, curr_peak + 1)); 
 
  457               iso_curr_scan.push_back((peak_it + curr_peak + 1)->getMZ());
 
  458               clusters_curr_scan.push_back(cluster_iter);
 
  461               if (curr_peak >= nr_peaks_in_scan - 1)
 
  463               dist2nextpeak = (peak_it + curr_peak + 1)->getMZ() -  (peak_it + curr_peak)->getMZ(); 
 
  473             if (!iso_last_scan.empty()) 
 
  475               std::sort(iso_last_scan.begin(), iso_last_scan.end());
 
  477               std::vector<double>::iterator it =
 
  478                 searchInScan_(iso_last_scan.begin(), iso_last_scan.end(), curr_mz);
 
  480               double delta_mz = fabs(*it - curr_mz);
 
  482               if (delta_mz > tolerance_mz) 
 
  484                 mz_in_hash = curr_mz; 
 
  492                 new_cluster.
scans.push_back(curr_scan);
 
  493                 cluster_iter = 
iso_map_.insert(std::pair<double, IsotopeCluster>(mz_in_hash, new_cluster));
 
  501                 cluster_iter = clusters_last_scan[distance(iso_last_scan.begin(), it)];
 
  504                 if (
find(cluster_iter->second.scans.begin(), cluster_iter->second.scans.end(), curr_scan)
 
  505                     == cluster_iter->second.scans.end())
 
  507                   cluster_iter->second.scans.push_back(curr_scan);
 
  524               mz_in_hash = curr_mz; 
 
  529               new_cluster.
scans.push_back(curr_scan);
 
  530               cluster_iter = 
iso_map_.insert(std::pair<double, IsotopeCluster>(mz_in_hash, new_cluster));
 
  540             cluster_iter->second.peaks.insert(std::pair<UInt, UInt>(curr_scan, curr_peak));
 
  542             iso_curr_scan.push_back(mz_in_hash);
 
  543             clusters_curr_scan.push_back(cluster_iter);
 
  551       last_rt = current_rt;
 
  555     std::cout << 
iso_map_.size() << 
" isotopic clusters were found ! " << std::endl;
 
  567   template <
typename InputSpectrumIterator>
 
  569                                           InputSpectrumIterator& last,
 
  574     for (std::multimap<double, IsotopeCluster>::iterator it = 
iso_map_.begin();
 
  579       std::cout << 
"element: " << counter << std::endl;
 
  580       std::cout << 
"mz: " << it->first << std::endl << 
"rts: ";
 
  582       std::cout << std::endl << 
"peaks: ";
 
  583       IsotopeCluster::IndexSet::const_iterator iter = it->second.peaks.begin();
 
  584       for (; iter != it->second.peaks.end(); ++iter)
 
  585         std::cout << ms_exp[iter->first].getRT() << 
" " << (ms_exp[iter->first][iter->second]).getMZ() << std::endl;
 
  588       std::cout << std::endl << std::endl;
 
  614       Eigen::VectorXd x_init (nr_parameters);
 
  617       std::map<Int, std::vector<PeakIndex> >::iterator m_peaks_it = twoD_data.
matching_peaks.begin();
 
  618       Int peak_counter = 0;
 
  619       Int diff_peak_counter = 0;
 
  621       for (; m_peaks_it != twoD_data.
matching_peaks.end(); ++m_peaks_it)
 
  623         double av_mz = 0, av_lw = 0, av_rw = 0, avr_height = 0, height;
 
  624         std::vector<PeakIndex>::iterator iter_iter = (m_peaks_it)->second.begin();
 
  625         for (; iter_iter != m_peaks_it->second.end(); ++iter_iter)
 
  627           height = ms_exp[(iter_iter)->spectrum].getFloatDataArrays()[1][(iter_iter)->peak]; 
 
  628           avr_height += height;
 
  629           av_mz += (iter_iter)->getPeak(ms_exp).getMZ() * height;
 
  630           av_lw += ms_exp[(iter_iter)->spectrum].getFloatDataArrays()[3][(iter_iter)->peak] * height; 
 
  631           av_rw +=    ms_exp[(iter_iter)->spectrum].getFloatDataArrays()[4][(iter_iter)->peak] * height; 
 
  632           x_init(peak_counter) = height;
 
  635         x_init(twoD_data.
total_nr_peaks + 3 * diff_peak_counter) = av_mz / avr_height;
 
  636         x_init(twoD_data.
total_nr_peaks + 3 * diff_peak_counter + 1) = av_lw / avr_height;
 
  637         x_init(twoD_data.
total_nr_peaks + 3 * diff_peak_counter + 2) = av_rw / avr_height;
 
  642       std::cout << 
"----------------------------\n\nstart_value: " << std::endl;
 
  643       for (
Size k = 0; 
k < start_value->size; ++
k)
 
  645           std::cout << x_init(
k) << std::endl;
 
  648       Int num_positions = 0;
 
  651         num_positions += (twoD_data.
signal2D[i + 1].second - twoD_data.
signal2D[i].second + 1);
 
  653         std::cout << twoD_data.
signal2D[i + 1].second << 
" - " << twoD_data.
signal2D[i].second << 
" +1 " << std::endl;
 
  658       std::cout << 
"num_positions : " << num_positions << std::endl;
 
  661       TwoDOptFunctor functor (nr_parameters, std::max(num_positions + 1, (
Int)(nr_parameters)), &twoD_data);
 
  662       Eigen::LevenbergMarquardt<TwoDOptFunctor> lmSolver (functor);
 
  663       Eigen::LevenbergMarquardtSpace::Status status = lmSolver.minimize(x_init);
 
  668       if (status <= Eigen::LevenbergMarquardtSpace::ImproperInputParameters)
 
  670           throw Exception::UnableToFit(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, 
"UnableToFit-TwoDOptimization:", 
"Could not fit the data: Error " + 
String(status));
 
  674       std::map<Int, std::vector<PeakIndex> >::iterator itv
 
  679         for (
Size j = 0; j < itv->second.size(); ++j)
 
  683           std::cout << 
"pos: " << itv->second[j].getPeak(ms_exp).getMZ() << 
"\nint: " << itv->second[j].getSpectrum(ms_exp).getFloatDataArrays()[1][itv->second[j].peak] 
 
  684                     << 
"\nlw: " << itv->second[j].getSpectrum(ms_exp).getFloatDataArrays()[3][itv->second[j].peak]
 
  685                     << 
"\nrw: " << itv->second[j].getSpectrum(ms_exp).getFloatDataArrays()[4][itv->second[j].peak] << 
"\n";
 
  689           ms_exp[itv->second[j].spectrum][itv->second[j].peak].setMZ(mz);
 
  690           double height = x_init(peak_idx);
 
  691           ms_exp[itv->second[j].spectrum].getFloatDataArrays()[1][itv->second[j].peak] = height;
 
  693           ms_exp[itv->second[j].spectrum].getFloatDataArrays()[3][itv->second[j].peak] = left_width;
 
  694           double right_width = x_init(twoD_data.
total_nr_peaks + 3 * i + 2);
 
  696           ms_exp[itv->second[j].spectrum].getFloatDataArrays()[4][itv->second[j].peak] = right_width;
 
  700             double x_left_endpoint = mz - 1 / left_width* sqrt(height / 1 - 1);
 
  701             double x_right_endpoint = mz + 1 / right_width* sqrt(height / 1 - 1);
 
  702             double area_left = -height / left_width* atan(left_width * (x_left_endpoint - mz));
 
  703             double area_right = -height / right_width* atan(right_width * (mz - x_right_endpoint));
 
  704             ms_exp[itv->second[j].spectrum][itv->second[j].peak].setIntensity(area_left + area_right);
 
  708             double x_left_endpoint = mz - 1 / left_width* boost::math::acosh(sqrt(height / 0.001));
 
  709             double x_right_endpoint = mz + 1 / right_width* boost::math::acosh(sqrt(height / 0.001));
 
  710             double area_left = -height / left_width * (sinh(left_width * (mz - x_left_endpoint)) / cosh(left_width * (mz - x_left_endpoint)));
 
  711             double area_right = -height / right_width * (sinh(right_width * (mz - x_right_endpoint)) / cosh(right_width * (mz - x_right_endpoint)));
 
  712             ms_exp[itv->second[j].spectrum][itv->second[j].peak].setIntensity(area_left + area_right);
 
  717           std::cout << 
"pos: " << itv->second[j].getPeak(ms_exp).getMZ() << 
"\nint: " << itv->second[j].getSpectrum(ms_exp).getFloatDataArrays()[1][itv->second[j].peak] 
 
  718                     << 
"\nlw: " << itv->second[j].getSpectrum(ms_exp).getFloatDataArrays()[3][itv->second[j].peak]
 
  719                     << 
"\nrw: " << itv->second[j].getSpectrum(ms_exp).getFloatDataArrays()[4][itv->second[j].peak] << 
"\n";
 
  733   template <
typename InputSpectrumIterator>
 
  735                                                   InputSpectrumIterator& last,
 
  748     if (dv.isEmpty() || dv.toString() == 
"")
 
  751       penalties.
pos = (
float)dv;
 
  754     if (dv.isEmpty() || dv.toString() == 
"")
 
  757       penalties.
lWidth = (
float)dv;
 
  760     if (dv.isEmpty() || dv.toString() == 
"")
 
  763       penalties.
rWidth = (
float)dv;
 
  765     std::cout << penalties.
pos << 
" " 
  766               << penalties.
rWidth << 
" " 
  767               << penalties.
lWidth << std::endl;
 
  780     if (dv.isEmpty() || dv.toString() == 
"")
 
  783       max_iteration = (
UInt)dv;
 
  785     std::vector<PeakShape> peak_shapes;
 
  789     for (std::multimap<double, IsotopeCluster>::iterator it = 
iso_map_.begin();
 
  795       std::cerr << 
"element: " << counter << std::endl;
 
  796       std::cerr << 
"mz: " << it->first << std::endl << 
"rts: ";
 
  797       for (
Size i = 0; i < it->second.scans.size(); ++i)
 
  798         std::cerr << it->second.scans[i] << 
"\n";
 
  799       std::cerr << std::endl << 
"peaks: ";
 
  800       IsotopeCluster::IndexSet::const_iterator iter = it->second.peaks.begin();
 
  801       for (; iter != it->second.peaks.end(); ++iter)
 
  802         std::cerr << ms_exp[iter->first].getRT() << 
" " << (ms_exp[iter->first][iter->second]).getMZ() << std::endl;
 
  804       std::cerr << std::endl << std::endl;
 
  825         data.
signal.reserve(size);
 
  829           data.
positions.push_back(ms_it->getMZ());
 
  830           data.
signal.push_back(ms_it->getIntensity());
 
  836         pair.first =  d.
iso_map_iter->second.peaks.begin()->first + idx;
 
  838         IsotopeCluster::IndexSet::const_iterator set_iter = lower_bound(d.
iso_map_iter->second.peaks.begin(),
 
  845         IsotopeCluster::IndexSet::const_iterator set_iter2 = lower_bound(d.
iso_map_iter->second.peaks.begin(),
 
  849         while (set_iter != set_iter2)
 
  851           const Size peak_index = set_iter->second;
 
  852           const MSSpectrum& spec = ms_exp[set_iter->first];
 
  854                           spec[peak_index].getMZ(),
 
  857                           spec[peak_index].getIntensity(), 
 
  859           peak_shapes.push_back(shape);
 
  869         std::cout << 
"vorher\n";
 
  871         for (
Size p = 0; p < peak_shapes.size(); ++p)
 
  873           std::cout << peak_shapes[p].mz_position << 
"\t" << peak_shapes[p].height
 
  874                     << 
"\t" << peak_shapes[p].left_width << 
"\t" << peak_shapes[p].right_width  << std::endl;
 
  879         std::cout << 
"nachher\n";
 
  880         for (
Size p = 0; p < peak_shapes.size(); ++p)
 
  882           std::cout << peak_shapes[p].mz_position << 
"\t" << peak_shapes[p].height
 
  883                     << 
"\t" << peak_shapes[p].left_width << 
"\t" << peak_shapes[p].right_width  << std::endl;
 
  887         pair.first =  d.
iso_map_iter->second.peaks.begin()->first + idx;
 
  889         set_iter = lower_bound(d.
iso_map_iter->second.peaks.begin(),
 
  893         while (p < peak_shapes.size())
 
  896           spec[set_iter->second].setMZ(peak_shapes[p].mz_position);
 
  908             spec[set_iter->second].setIntensity(area_left + area_right); 
 
  917             spec[set_iter->second].setIntensity(area_left + area_right); 
 
  930   template <
typename InputSpectrumIterator>
 
  932                                              InputSpectrumIterator& first,
 
  933                                              InputSpectrumIterator& last,
 
  939     typedef typename InputSpectrumIterator::value_type InputExperimentType;
 
  940     typedef typename InputExperimentType::value_type InputPeakType;
 
  941     typedef std::multimap<double, IsotopeCluster> 
MapType;
 
  943     double rt, first_peak_mz, last_peak_mz;
 
  949     for (
Size i = 0; i < iso_map_idx; ++i)
 
  953     std::cout << 
"rt begin: " << exp[iso_map_iter->second.scans[0]].getRT()
 
  954               << 
"\trt end: " << exp[iso_map_iter->second.scans[iso_map_iter->second.scans.size() - 1]].getRT()
 
  955               << 
" \t" << iso_map_iter->second.scans.
size() << 
" scans" 
  960     for (
Size i = 0; i < iso_map_iter->second.scans.size(); ++i)
 
  965       rt = exp[iso_map_iter->second.scans[i]].getRT();
 
  971       std::cout << exp_it->getRT() << 
" vs " << iter->getRT() << std::endl;
 
  975       pair.first =  iso_map_iter->second.peaks.begin()->first + i;
 
  977       IsotopeCluster::IndexSet::const_iterator set_iter = lower_bound(iso_map_iter->second.peaks.begin(),
 
  978                                                                       iso_map_iter->second.peaks.end(),
 
  982       first_peak_mz = (exp_it->begin() + set_iter->second)->getMZ() - 1;
 
  986       IsotopeCluster::IndexSet::const_iterator set_iter2 = lower_bound(iso_map_iter->second.peaks.begin(),
 
  987                                                                        iso_map_iter->second.peaks.end(),
 
  990       if (i == iso_map_iter->second.scans.size() - 1)
 
  992         set_iter2 = iso_map_iter->second.peaks.end();
 
  995       else if (set_iter2 != iso_map_iter->second.peaks.begin())
 
  998       last_peak_mz = (exp_it->begin() + set_iter2->second)->getMZ() + 1;
 
 1001       peak.setPosition(first_peak_mz);
 
 1003         = lower_bound(iter->begin(), iter->end(), peak, 
typename InputPeakType::PositionLess());
 
 1004       if (raw_data_iter != iter->begin())
 
 1008       double intensity = raw_data_iter->getIntensity();
 
 1010       while (raw_data_iter != iter->begin() && (raw_data_iter - 1)->getIntensity() < intensity &&
 
 1011              (raw_data_iter - 1)->getIntensity() > noise_level)
 
 1014         intensity = raw_data_iter->getIntensity();
 
 1018       left.first = distance(first, iter);
 
 1019       left.second = raw_data_iter - iter->begin();
 
 1021       std::cout << 
"left: " << iter->getRT() << 
"\t" << raw_data_iter->getMZ() << std::endl;
 
 1024       peak.setPosition(last_peak_mz + 1);
 
 1026         = upper_bound(iter->begin(), iter->end(), peak, 
typename InputPeakType::PositionLess());
 
 1027       if (raw_data_iter == iter->end())
 
 1029       intensity = raw_data_iter->getIntensity();
 
 1031       while (raw_data_iter + 1 != iter->end() && (raw_data_iter + 1)->getIntensity() < intensity)
 
 1034         intensity = raw_data_iter->getIntensity();
 
 1035         if ((raw_data_iter + 1 != iter->end()) && (raw_data_iter + 1)->getIntensity() > noise_level)
 
 1038       right.first = left.first;
 
 1039       right.second = raw_data_iter - iter->begin();
 
 1041       std::cout << 
"right: " << iter->getRT() << 
"\t" << raw_data_iter->getMZ() << std::endl;
 
 1049     std::cout << first_peak_mz << 
"\t" << last_peak_mz << std::endl;