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;