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_RAW2PEAK_TWODOPTIMIZATION_H
00036 #define OPENMS_TRANSFORMATIONS_RAW2PEAK_TWODOPTIMIZATION_H
00037
00038
00039 #undef DEBUG_2D
00040
00041 #ifdef DEBUG_2D
00042 #include <iostream>
00043 #include <fstream>
00044 #endif
00045
00046 #include <vector>
00047 #include <utility>
00048 #include <cmath>
00049 #include <set>
00050
00051 #include <OpenMS/TRANSFORMATIONS/RAW2PEAK/PeakShape.h>
00052 #include <OpenMS/TRANSFORMATIONS/RAW2PEAK/OptimizePeakDeconvolution.h>
00053 #include <OpenMS/KERNEL/MSExperiment.h>
00054 #include <OpenMS/KERNEL/MSSpectrum.h>
00055 #include <OpenMS/KERNEL/PeakIndex.h>
00056 #include <OpenMS/CONCEPT/Exception.h>
00057 #include <OpenMS/DATASTRUCTURES/IsotopeCluster.h>
00058 #include <OpenMS/DATASTRUCTURES/DefaultParamHandler.h>
00059
00060 #ifndef OPENMS_SYSTEM_STOPWATCH_H
00061 #endif
00062
00063 #include <boost/math/special_functions/acosh.hpp>
00064 #include <gsl/gsl_vector.h>
00065 #include <gsl/gsl_multifit_nlin.h>
00066 #include <gsl/gsl_blas.h>
00067 #include <OpenMS/TRANSFORMATIONS/RAW2PEAK/OptimizePick.h>
00068 #include <OpenMS/TRANSFORMATIONS/RAW2PEAK/PeakShape.h>
00069
00070 namespace OpenMS
00071 {
00086 class OPENMS_DLLAPI TwoDOptimization :
00087 public DefaultParamHandler
00088 {
00089 public:
00090
00092 TwoDOptimization();
00093
00095 TwoDOptimization(const TwoDOptimization& opt);
00096
00098 virtual ~TwoDOptimization(){}
00099
00101 TwoDOptimization& operator=(const TwoDOptimization& opt);
00102
00103
00105 inline DoubleReal getMZTolerance() const {return tolerance_mz_; }
00107 inline void setMZTolerance(DoubleReal tolerance_mz)
00108 {
00109 tolerance_mz_ = tolerance_mz;
00110 param_.setValue("2d:tolerance_mz", tolerance_mz);
00111 }
00112
00114 inline DoubleReal getMaxPeakDistance() const {return max_peak_distance_; }
00116 inline void setMaxPeakDistance(DoubleReal max_peak_distance)
00117 {
00118 max_peak_distance_ = max_peak_distance;
00119 param_.setValue("2d:max_peak_distance", max_peak_distance);
00120 }
00121
00123 inline DoubleReal getMaxAbsError() const {return eps_abs_; }
00125 inline void setMaxAbsError(DoubleReal eps_abs)
00126 {
00127 eps_abs_ = eps_abs;
00128 param_.setValue("delta_abs_error", eps_abs);
00129 }
00130
00132 inline DoubleReal getMaxRelError() const {return eps_rel_; }
00134 inline void setMaxRelError(DoubleReal eps_rel)
00135 {
00136 eps_rel_ = eps_rel;
00137 param_.setValue("delta_rel_error", eps_rel);
00138 }
00139
00141 inline UInt getMaxIterations() const {return max_iteration_; }
00143 inline void setMaxIterations(UInt max_iteration)
00144 {
00145 max_iteration_ = max_iteration;
00146 param_.setValue("iterations", max_iteration);
00147 }
00148
00150 inline const OptimizationFunctions::PenaltyFactorsIntensity& getPenalties() const {return penalties_; }
00152 inline void setPenalties(OptimizationFunctions::PenaltyFactorsIntensity& penalties)
00153 {
00154 penalties_ = penalties;
00155 param_.setValue("penalties:position", penalties.pos);
00156 param_.setValue("penalties:height", penalties.height);
00157 param_.setValue("penalties:left_width", penalties.lWidth);
00158 param_.setValue("penalties:right_width", penalties.rWidth);
00159 }
00160
00177 template <typename InputSpectrumIterator, typename OutputPeakType>
00178 void optimize(InputSpectrumIterator first,
00179 InputSpectrumIterator last,
00180 MSExperiment<OutputPeakType>& ms_exp, bool real2D = true);
00181
00182
00183 protected:
00185 struct Data
00186 {
00187 std::vector<std::pair<SignedSize, SignedSize> > signal2D;
00188 std::multimap<DoubleReal, IsotopeCluster>::iterator iso_map_iter;
00189 Size total_nr_peaks;
00190 std::map<Int, std::vector<PeakIndex> > matching_peaks;
00191 MSExperiment<> picked_peaks;
00192 MSExperiment<Peak1D>::ConstIterator raw_data_first;
00193 OptimizationFunctions::PenaltyFactorsIntensity penalties;
00194 std::vector<DoubleReal> positions;
00195 std::vector<DoubleReal> signal;
00196 };
00197
00199 std::multimap<DoubleReal, IsotopeCluster> iso_map_;
00200
00202 std::multimap<DoubleReal, IsotopeCluster>::const_iterator curr_region_;
00203
00205 DoubleReal max_peak_distance_;
00206
00208 DoubleReal tolerance_mz_;
00209
00211
00212 std::map<Int, std::vector<PeakIndex> > matching_peaks_;
00213
00214
00216 DoubleReal eps_abs_;
00217
00219 DoubleReal eps_rel_;
00220
00222 UInt max_iteration_;
00223
00225 bool real_2D_;
00226
00227
00229 OptimizationFunctions::PenaltyFactorsIntensity penalties_;
00230
00231
00236
00237 static Int residual2D_(const gsl_vector* x, void* params, gsl_vector* f);
00239 static Int jacobian2D_(const gsl_vector* x, void* params, gsl_matrix* J);
00241 static Int evaluate2D_(const gsl_vector* x, void* params, gsl_vector* f, gsl_matrix* J);
00242
00243
00248 std::vector<DoubleReal>::iterator searchInScan_(std::vector<DoubleReal>::iterator scan_begin,
00249 std::vector<DoubleReal>::iterator scan_end,
00250 DoubleReal current_mz);
00251
00253 template <typename InputSpectrumIterator, typename OutputPeakType>
00254 void optimizeRegions_(InputSpectrumIterator& first,
00255 InputSpectrumIterator& last,
00256 MSExperiment<OutputPeakType>& ms_exp);
00257
00259 template <typename InputSpectrumIterator, typename OutputPeakType>
00260 void optimizeRegionsScanwise_(InputSpectrumIterator& first,
00261 InputSpectrumIterator& last,
00262 MSExperiment<OutputPeakType>& ms_exp);
00263
00264
00266 template <typename InputSpectrumIterator, typename OutputPeakType>
00267 void getRegionEndpoints_(MSExperiment<OutputPeakType>& exp,
00268 InputSpectrumIterator& first,
00269 InputSpectrumIterator& last,
00270 Size iso_map_idx,
00271 DoubleReal noise_level,
00272 TwoDOptimization::Data& d);
00273
00275 void findMatchingPeaks_(std::multimap<DoubleReal, IsotopeCluster>::iterator& it,
00276 MSExperiment<>& ms_exp);
00277
00279
00281 void updateMembers_();
00282 };
00283
00284
00285 template <typename InputSpectrumIterator, typename OutputPeakType>
00286 void TwoDOptimization::optimize(InputSpectrumIterator first, InputSpectrumIterator last, MSExperiment<OutputPeakType>& ms_exp, bool real2D)
00287 {
00288
00289
00290 if ((UInt)distance(first, last) != ms_exp.size())
00291 {
00292 throw Exception::IllegalArgument(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Error in Two2Optimization: Raw and peak map do not have the same number of spectra");
00293 }
00294
00295 if (ms_exp.empty())
00296 {
00297 return;
00298 }
00299
00300 for (Size i = 0; i < ms_exp.size(); ++i)
00301 {
00302
00303 if (ms_exp[i].getFloatDataArrays().size() < 6)
00304 {
00305 throw Exception::IllegalArgument(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Error in Two2Optimization: Not enough meta data arrays present (1:area, 5:shape, 3:left width, 4:right width)");
00306 }
00307 bool area = ms_exp[i].getFloatDataArrays()[1].getName() == "maximumIntensity";
00308 bool wleft = ms_exp[i].getFloatDataArrays()[3].getName() == "leftWidth";
00309 bool wright = ms_exp[i].getFloatDataArrays()[4].getName() == "rightWidth";
00310 bool shape = ms_exp[i].getFloatDataArrays()[5].getName() == "peakShape";
00311
00312 if (!area || !wleft || !wright || !shape)
00313 {
00314 throw Exception::IllegalArgument(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Error in Two2Optimization: One or several meta data arrays missing (1:intensity, 5:shape, 3:left width, 4:right width)");
00315 }
00316 }
00317 real_2D_ = real2D;
00318 typedef typename InputSpectrumIterator::value_type InputSpectrumType;
00319 typedef typename InputSpectrumType::value_type PeakType;
00320 typedef MSSpectrum<PeakType> SpectrumType;
00321
00322 typename MSExperiment<OutputPeakType>::Iterator ms_exp_it = ms_exp.begin();
00323 typename MSExperiment<OutputPeakType>::Iterator ms_exp_it_end = ms_exp.end();
00324 if (ms_exp.empty())
00325 {
00326 std::cout << "empty experiment" << std::endl;
00327 return;
00328 }
00329
00330 std::vector<DoubleReal> iso_last_scan;
00331 std::vector<DoubleReal> iso_curr_scan;
00332 std::vector<std::multimap<DoubleReal, IsotopeCluster>::iterator> clusters_last_scan;
00333 std::vector<std::multimap<DoubleReal, IsotopeCluster>::iterator> clusters_curr_scan;
00334 std::multimap<DoubleReal, IsotopeCluster>::iterator cluster_iter;
00335 DoubleReal current_rt = ms_exp_it->getRT(), last_rt = 0;
00336
00337
00338 max_peak_distance_ = param_.getValue("2d:max_peak_distance");
00339 DoubleReal tolerance_mz = param_.getValue("2d:tolerance_mz");
00340
00341 UInt current_charge = 0;
00342 DoubleReal mz_in_hash = 0;
00343
00344
00345 for (UInt curr_scan = 0; ms_exp_it + curr_scan != ms_exp_it_end; ++curr_scan)
00346 {
00347 Size nr_peaks_in_scan = (ms_exp_it + curr_scan)->size();
00348 if (nr_peaks_in_scan == 0)
00349 continue;
00350
00351
00352 current_rt = (ms_exp_it + curr_scan)->getRT();
00353 typename MSExperiment<OutputPeakType>::SpectrumType::Iterator peak_it = (ms_exp_it + curr_scan)->begin();
00354
00355
00356 iso_last_scan = iso_curr_scan;
00357 iso_curr_scan.clear();
00358 clusters_last_scan = clusters_curr_scan;
00359 clusters_curr_scan.clear();
00360
00361 #ifdef DEBUG_2D
00362 std::cout << "Next scan with rt: " << current_rt << std::endl;
00363 std::cout << "Next scan, rt = " << current_rt << " last_rt: " << last_rt << std::endl;
00364 std::cout << "---------------------------------------------------------------------------" << std::endl;
00365 #endif
00366 MSSpectrum<PeakType> s;
00367 s.setRT(current_rt);
00368
00369 if (last_rt == 0 ||
00370 ((lower_bound(first, last, s, typename SpectrumType::RTLess()) - 1)->getRT() == last_rt))
00371 {
00372
00373
00374 for (UInt curr_peak = 0; curr_peak < (ms_exp_it + curr_scan)->size() - 1; ++curr_peak)
00375 {
00376
00377
00378 DoubleReal curr_mz = (peak_it + curr_peak)->getMZ();
00379 DoubleReal dist2nextpeak = (peak_it + curr_peak + 1)->getMZ() - curr_mz;
00380
00381 if (dist2nextpeak <= max_peak_distance_)
00382 {
00383 #ifdef DEBUG_2D
00384 std::cout << "Isotopic pattern found ! " << std::endl;
00385 std::cout << "We are at: " << (peak_it + curr_peak)->getMZ() << " " << curr_mz << std::endl;
00386 #endif
00387 if (!iso_last_scan.empty())
00388 {
00389 std::sort(iso_last_scan.begin(), iso_last_scan.end());
00390
00391 std::vector<DoubleReal>::iterator it =
00392 searchInScan_(iso_last_scan.begin(), iso_last_scan.end(), curr_mz);
00393
00394 DoubleReal delta_mz = fabs(*it - curr_mz);
00395
00396 if (delta_mz > tolerance_mz)
00397 {
00398 mz_in_hash = curr_mz;
00399
00400
00401
00402
00403
00404 IsotopeCluster new_cluster;
00405 new_cluster.peaks.charge = current_charge;
00406 new_cluster.scans.push_back(curr_scan);
00407 cluster_iter = iso_map_.insert(std::pair<DoubleReal, IsotopeCluster>(mz_in_hash, new_cluster));
00408
00409 }
00410 else
00411 {
00412
00413
00414
00415 cluster_iter = clusters_last_scan[distance(iso_last_scan.begin(), it)];
00416
00417
00418 if (find(cluster_iter->second.scans.begin(), cluster_iter->second.scans.end(), curr_scan)
00419 == cluster_iter->second.scans.end())
00420 {
00421 cluster_iter->second.scans.push_back(curr_scan);
00422 }
00423
00424
00425
00426
00427
00428 }
00429
00430 }
00431 else
00432 {
00433
00434
00435
00436
00437
00438 mz_in_hash = curr_mz;
00439
00440
00441 IsotopeCluster new_cluster;
00442 new_cluster.peaks.charge = current_charge;
00443 new_cluster.scans.push_back(curr_scan);
00444 cluster_iter = iso_map_.insert(std::pair<DoubleReal, IsotopeCluster>(mz_in_hash, new_cluster));
00445
00446 }
00447
00448
00449
00450
00451
00452
00453
00454 cluster_iter->second.peaks.insert(std::pair<UInt, UInt>(curr_scan, curr_peak));
00455
00456 iso_curr_scan.push_back(mz_in_hash);
00457 clusters_curr_scan.push_back(cluster_iter);
00458 ++curr_peak;
00459
00460 cluster_iter->second.peaks.insert(std::pair<UInt, UInt>(curr_scan, curr_peak));
00461 iso_curr_scan.push_back((peak_it + curr_peak)->getMZ());
00462 clusters_curr_scan.push_back(cluster_iter);
00463
00464
00465 if ((curr_peak + 1) >= nr_peaks_in_scan)
00466 break;
00467 dist2nextpeak = (peak_it + curr_peak + 1)->getMZ() - (peak_it + curr_peak)->getMZ();
00468
00469
00470
00471 while (dist2nextpeak <= max_peak_distance_
00472 && curr_peak < (nr_peaks_in_scan - 1))
00473 {
00474 cluster_iter->second.peaks.insert(std::pair<UInt, UInt>(curr_scan, curr_peak + 1));
00475 iso_curr_scan.push_back((peak_it + curr_peak + 1)->getMZ());
00476 clusters_curr_scan.push_back(cluster_iter);
00477
00478 ++curr_peak;
00479 if (curr_peak >= nr_peaks_in_scan - 1)
00480 break;
00481 dist2nextpeak = (peak_it + curr_peak + 1)->getMZ() - (peak_it + curr_peak)->getMZ();
00482
00483
00484 }
00485
00486
00487
00488 }
00489 else
00490 {
00491 if (!iso_last_scan.empty())
00492 {
00493 std::sort(iso_last_scan.begin(), iso_last_scan.end());
00494
00495 std::vector<DoubleReal>::iterator it =
00496 searchInScan_(iso_last_scan.begin(), iso_last_scan.end(), curr_mz);
00497
00498 DoubleReal delta_mz = fabs(*it - curr_mz);
00499
00500 if (delta_mz > tolerance_mz)
00501 {
00502 mz_in_hash = curr_mz;
00503
00504
00505
00506
00507
00508 IsotopeCluster new_cluster;
00509 new_cluster.peaks.charge = current_charge;
00510 new_cluster.scans.push_back(curr_scan);
00511 cluster_iter = iso_map_.insert(std::pair<DoubleReal, IsotopeCluster>(mz_in_hash, new_cluster));
00512
00513 }
00514 else
00515 {
00516
00517
00518
00519 cluster_iter = clusters_last_scan[distance(iso_last_scan.begin(), it)];
00520
00521
00522 if (find(cluster_iter->second.scans.begin(), cluster_iter->second.scans.end(), curr_scan)
00523 == cluster_iter->second.scans.end())
00524 {
00525 cluster_iter->second.scans.push_back(curr_scan);
00526 }
00527
00528
00529
00530
00531
00532 }
00533
00534 }
00535 else
00536 {
00537
00538
00539
00540
00541
00542 mz_in_hash = curr_mz;
00543
00544
00545 IsotopeCluster new_cluster;
00546 new_cluster.peaks.charge = current_charge;
00547 new_cluster.scans.push_back(curr_scan);
00548 cluster_iter = iso_map_.insert(std::pair<DoubleReal, IsotopeCluster>(mz_in_hash, new_cluster));
00549
00550 }
00551
00552
00553
00554
00555
00556
00557
00558 cluster_iter->second.peaks.insert(std::pair<UInt, UInt>(curr_scan, curr_peak));
00559
00560 iso_curr_scan.push_back(mz_in_hash);
00561 clusters_curr_scan.push_back(cluster_iter);
00562
00563
00564 }
00565
00566 current_charge = 0;
00567 }
00568 }
00569 last_rt = current_rt;
00570 }
00571 curr_region_ = iso_map_.begin();
00572 #ifdef DEBUG_2D
00573 std::cout << iso_map_.size() << " isotopic clusters were found ! " << std::endl;
00574 #endif
00575
00576 if (real_2D_)
00577 optimizeRegions_(first, last, ms_exp);
00578 else
00579 optimizeRegionsScanwise_(first, last, ms_exp);
00580
00581 }
00582
00583 template <typename InputSpectrumIterator, typename OutputPeakType>
00584 void TwoDOptimization::optimizeRegions_(InputSpectrumIterator& first,
00585 InputSpectrumIterator& last,
00586 MSExperiment<OutputPeakType>& ms_exp)
00587 {
00588 Int counter = 0;
00589
00590 for (std::multimap<DoubleReal, IsotopeCluster>::iterator it = iso_map_.begin();
00591 it != iso_map_.end();
00592 ++it)
00593 {
00594 #ifdef DEBUG_2D
00595 std::cout << "element: " << counter << std::endl;
00596 std::cout << "mz: " << it->first << std::endl << "rts: ";
00597
00598 std::cout << std::endl << "peaks: ";
00599 IsotopeCluster::IndexSet::const_iterator iter = it->second.peaks.begin();
00600 for (; iter != it->second.peaks.end(); ++iter)
00601 std::cout << ms_exp[iter->first].getRT() << " " << (ms_exp[iter->first][iter->second]).getMZ() << std::endl;
00602
00603
00604 std::cout << std::endl << std::endl;
00605
00606 #endif
00607
00608
00609
00610 matching_peaks_.clear();
00611 findMatchingPeaks_(it, ms_exp);
00612 TwoDOptimization::Data d;
00613 d.penalties = penalties_;
00614 d.matching_peaks = matching_peaks_;
00615
00616 getRegionEndpoints_(ms_exp, first, last, counter, 400, d);
00617
00618
00619 d.iso_map_iter = it;
00620
00621 d.picked_peaks = ms_exp;
00622 d.raw_data_first = first;
00623
00624 Size nr_diff_peaks = matching_peaks_.size();
00625 d.total_nr_peaks = it->second.peaks.size();
00626
00627 Size nr_parameters = nr_diff_peaks * 3 + d.total_nr_peaks;
00628
00629 gsl_vector* start_value = gsl_vector_alloc(nr_parameters);
00630 gsl_vector_set_zero(start_value);
00631
00632
00633 std::map<Int, std::vector<PeakIndex> >::iterator m_peaks_it = d.matching_peaks.begin();
00634 DoubleReal av_mz = 0, av_lw = 0, av_rw = 0, avr_height = 0, height;
00635 Int peak_counter = 0;
00636 Int diff_peak_counter = 0;
00637
00638 for (; m_peaks_it != d.matching_peaks.end(); ++m_peaks_it)
00639 {
00640 av_mz = 0, av_lw = 0, av_rw = 0, avr_height = 0;
00641 std::vector<PeakIndex>::iterator iter_iter = (m_peaks_it)->second.begin();
00642 for (; iter_iter != m_peaks_it->second.end(); ++iter_iter)
00643 {
00644 height = ms_exp[(iter_iter)->spectrum].getFloatDataArrays()[1][(iter_iter)->peak];
00645 avr_height += height;
00646 av_mz += (iter_iter)->getPeak(ms_exp).getMZ() * height;
00647 av_lw += ms_exp[(iter_iter)->spectrum].getFloatDataArrays()[3][(iter_iter)->peak] * height;
00648 av_rw += ms_exp[(iter_iter)->spectrum].getFloatDataArrays()[4][(iter_iter)->peak] * height;
00649 gsl_vector_set(start_value, peak_counter, height);
00650 ++peak_counter;
00651 }
00652 gsl_vector_set(start_value, d.total_nr_peaks + 3 * diff_peak_counter, av_mz / avr_height);
00653 gsl_vector_set(start_value, d.total_nr_peaks + 3 * diff_peak_counter + 1, av_lw / avr_height);
00654 gsl_vector_set(start_value, d.total_nr_peaks + 3 * diff_peak_counter + 2, av_rw / avr_height);
00655 ++diff_peak_counter;
00656 }
00657
00658 #ifdef DEBUG_2D
00659 std::cout << "----------------------------\n\nstart_value: " << std::endl;
00660 for (Size k = 0; k < start_value->size; ++k)
00661 {
00662 std::cout << gsl_vector_get(start_value, k) << std::endl;
00663 }
00664 #endif
00665 Int num_positions = 0;
00666 for (Size i = 0; i < d.signal2D.size(); i += 2)
00667 {
00668 num_positions += (d.signal2D[i + 1].second - d.signal2D[i].second + 1);
00669 #ifdef DEBUG_2D
00670 std::cout << d.signal2D[i + 1].second << " - " << d.signal2D[i].second << " +1 " << std::endl;
00671 #endif
00672
00673 }
00674 #ifdef DEBUG_2D
00675 std::cout << "num_positions : " << num_positions << std::endl;
00676 #endif
00677
00678
00679 gsl_multifit_function_fdf fit_function;
00680 fit_function.f = (Int (*)(const gsl_vector* x, void* params, gsl_vector* f)) & OpenMS::TwoDOptimization::residual2D_;
00681 fit_function.df = (Int (*)(const gsl_vector* x, void* params, gsl_matrix* J)) & OpenMS::TwoDOptimization::jacobian2D_;
00682 fit_function.fdf = (Int (*)(const gsl_vector* x, void* params, gsl_vector* f, gsl_matrix* J)) & OpenMS::TwoDOptimization::evaluate2D_;
00683
00684 fit_function.n = std::max(num_positions + 1, (Int)(nr_parameters));
00685 fit_function.p = nr_parameters;
00686 fit_function.params = &d;
00687 #ifdef DEBUG_2D
00688 std::cout << "fit_function.n " << fit_function.n
00689 << "\tfit_function.p " << fit_function.p << std::endl;
00690 #endif
00691 const gsl_multifit_fdfsolver_type* type = gsl_multifit_fdfsolver_lmsder;
00692
00693 gsl_multifit_fdfsolver* fit = gsl_multifit_fdfsolver_alloc(type,
00694 std::max(num_positions + 1, (Int)(nr_parameters)),
00695 nr_parameters);
00696
00697 gsl_multifit_fdfsolver_set(fit, &fit_function, start_value);
00698
00699
00700
00701
00702 #ifdef DEBUG_2D
00703 std::cout << "Before optimization: ||f|| = " << gsl_blas_dnrm2(fit->f) << std::endl;
00704 #endif
00705
00706 UInt iteration = 0;
00707 Int status;
00708
00709 do
00710 {
00711 iteration++;
00712 status = gsl_multifit_fdfsolver_iterate(fit);
00713 #ifdef DEBUG_2D
00714 std::cout << "Iteration " << iteration << "; Status " << gsl_strerror(status) << "; " << std::endl;
00715 std::cout << "||f|| = " << gsl_blas_dnrm2(fit->f) << std::endl;
00716 std::cout << "Number of parms: " << nr_parameters << std::endl;
00717 std::cout << "Delta: " << gsl_blas_dnrm2(fit->dx) << std::endl;
00718 #endif
00719
00720 status = gsl_multifit_test_delta(fit->dx, fit->x, eps_abs_, eps_rel_);
00721 if (status != GSL_CONTINUE)
00722 break;
00723
00724 }
00725 while (status == GSL_CONTINUE && iteration < max_iteration_);
00726
00727 #ifdef DEBUG_2D
00728 std::cout << "Finished! No. of iterations" << iteration << std::endl;
00729 std::cout << "Delta: " << gsl_blas_dnrm2(fit->dx) << std::endl;
00730 DoubleReal chi = gsl_blas_dnrm2(fit->f);
00731 std::cout << "After optimization: || f || = " << gsl_blas_dnrm2(fit->f) << std::endl;
00732 std::cout << "chisq/dof = " << pow(chi, 2.0) / (num_positions - nr_parameters);
00733
00734
00735 std::cout << "----------------------------------------------\n\nnachher" << std::endl;
00736 for (Size k = 0; k < fit->x->size; ++k)
00737 {
00738 std::cout << gsl_vector_get(fit->x, k) << std::endl;
00739 }
00740 #endif
00741 Int peak_idx = 0;
00742 std::map<Int, std::vector<PeakIndex> >::iterator itv
00743 = d.matching_peaks.begin();
00744 for (; itv != d.matching_peaks.end(); ++itv)
00745 {
00746 Int i = distance(d.matching_peaks.begin(), itv);
00747 for (Size j = 0; j < itv->second.size(); ++j)
00748 {
00749
00750 #ifdef DEBUG_2D
00751 std::cout << "pos: " << itv->second[j].getPeak(ms_exp).getMZ() << "\nint: " << itv->second[j].getSpectrum(ms_exp).getFloatDataArrays()[1][itv->second[j].peak]
00752 << "\nlw: " << itv->second[j].getSpectrum(ms_exp).getFloatDataArrays()[3][itv->second[j].peak]
00753 << "\nrw: " << itv->second[j].getSpectrum(ms_exp).getFloatDataArrays()[4][itv->second[j].peak] << "\n";
00754
00755 #endif
00756 DoubleReal mz = gsl_vector_get(fit->x, d.total_nr_peaks + 3 * i);
00757 ms_exp[itv->second[j].spectrum][itv->second[j].peak].setMZ(mz);
00758 DoubleReal height = (gsl_vector_get(fit->x, peak_idx));
00759 ms_exp[itv->second[j].spectrum].getFloatDataArrays()[1][itv->second[j].peak] = height;
00760 DoubleReal left_width = gsl_vector_get(fit->x, d.total_nr_peaks + 3 * i + 1);
00761 ms_exp[itv->second[j].spectrum].getFloatDataArrays()[3][itv->second[j].peak] = left_width;
00762 DoubleReal right_width = gsl_vector_get(fit->x, d.total_nr_peaks + 3 * i + 2);
00763 ms_exp[itv->second[j].spectrum].getFloatDataArrays()[4][itv->second[j].peak] = right_width;
00764
00765 if ((PeakShape::Type)(Int)ms_exp[itv->second[j].spectrum].getFloatDataArrays()[5][itv->second[j].peak] == PeakShape::LORENTZ_PEAK)
00766 {
00767 DoubleReal x_left_endpoint = mz - 1 / left_width* sqrt(height / 1 - 1);
00768 DoubleReal x_rigth_endpoint = mz + 1 / right_width* sqrt(height / 1 - 1);
00769 DoubleReal area_left = -height / left_width* atan(left_width * (x_left_endpoint - mz));
00770 DoubleReal area_right = -height / right_width* atan(right_width * (mz - x_rigth_endpoint));
00771 ms_exp[itv->second[j].spectrum][itv->second[j].peak].setIntensity(area_left + area_right);
00772 }
00773 else
00774 {
00775 DoubleReal x_left_endpoint = mz - 1 / left_width* boost::math::acosh(sqrt(height / 0.001));
00776 DoubleReal x_rigth_endpoint = mz + 1 / right_width* boost::math::acosh(sqrt(height / 0.001));
00777 DoubleReal area_left = -height / left_width * (sinh(left_width * (mz - x_left_endpoint)) / cosh(left_width * (mz - x_left_endpoint)));
00778 DoubleReal area_right = -height / right_width * (sinh(right_width * (mz - x_rigth_endpoint)) / cosh(right_width * (mz - x_rigth_endpoint)));
00779 ms_exp[itv->second[j].spectrum][itv->second[j].peak].setIntensity(area_left + area_right);
00780 }
00781
00782
00783 #ifdef DEBUG_2D
00784 std::cout << "pos: " << itv->second[j].getPeak(ms_exp).getMZ() << "\nint: " << itv->second[j].getSpectrum(ms_exp).getFloatDataArrays()[1][itv->second[j].peak]
00785 << "\nlw: " << itv->second[j].getSpectrum(ms_exp).getFloatDataArrays()[3][itv->second[j].peak]
00786 << "\nrw: " << itv->second[j].getSpectrum(ms_exp).getFloatDataArrays()[4][itv->second[j].peak] << "\n";
00787
00788
00789
00790
00791
00792 #endif
00793
00794 ++peak_idx;
00795
00796
00797 }
00798 }
00799
00800 gsl_multifit_fdfsolver_free(fit);
00801 gsl_vector_free(start_value);
00802 ++counter;
00803 }
00804
00805 }
00806
00807 template <typename InputSpectrumIterator, typename OutputPeakType>
00808 void TwoDOptimization::optimizeRegionsScanwise_(InputSpectrumIterator& first,
00809 InputSpectrumIterator& last,
00810 MSExperiment<OutputPeakType>& ms_exp)
00811 {
00812 Int counter = 0;
00813 TwoDOptimization::Data d;
00814 d.picked_peaks = ms_exp;
00815 d.raw_data_first = first;
00816
00817
00818 struct OpenMS::OptimizationFunctions::PenaltyFactors penalties;
00819
00820
00821 DataValue dv = param_.getValue("penalties:position");
00822 if (dv.isEmpty() || dv.toString() == "")
00823 penalties.pos = 0.;
00824 else
00825 penalties.pos = (float)dv;
00826
00827 dv = param_.getValue("penalties:left_width");
00828 if (dv.isEmpty() || dv.toString() == "")
00829 penalties.lWidth = 1.;
00830 else
00831 penalties.lWidth = (float)dv;
00832
00833 dv = param_.getValue("penalties:right_width");
00834 if (dv.isEmpty() || dv.toString() == "")
00835 penalties.rWidth = 1.;
00836 else
00837 penalties.rWidth = (float)dv;
00838 #ifdef DEBUG_2D
00839 std::cout << penalties.pos << " "
00840 << penalties.rWidth << " "
00841 << penalties.lWidth << std::endl;
00842 #endif
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852 UInt max_iteration;
00853 dv = param_.getValue("iterations");
00854 if (dv.isEmpty() || dv.toString() == "")
00855 max_iteration = 15;
00856 else
00857 max_iteration = (UInt)dv;
00858
00859 DoubleReal eps_abs;
00860 dv = param_.getValue("delta_abs_error");
00861 if (dv.isEmpty() || dv.toString() == "")
00862 eps_abs = 1e-04f;
00863 else
00864 eps_abs = (DoubleReal)dv;
00865
00866 DoubleReal eps_rel;
00867 dv = param_.getValue("delta_rel_error");
00868 if (dv.isEmpty() || dv.toString() == "")
00869 eps_rel = 1e-04f;
00870 else
00871 eps_rel = (DoubleReal)dv;
00872
00873 std::vector<PeakShape> peak_shapes;
00874
00875
00876
00877 for (std::multimap<DoubleReal, IsotopeCluster>::iterator it = iso_map_.begin();
00878 it != iso_map_.end();
00879 ++it)
00880 {
00881 d.iso_map_iter = it;
00882 #ifdef DEBUG_2D
00883 std::cerr << "element: " << counter << std::endl;
00884 std::cerr << "mz: " << it->first << std::endl << "rts: ";
00885 for (Size i = 0; i < it->second.scans.size(); ++i)
00886 std::cerr << it->second.scans[i] << "\n";
00887 std::cerr << std::endl << "peaks: ";
00888 IsotopeCluster::IndexSet::const_iterator iter = it->second.peaks.begin();
00889 for (; iter != it->second.peaks.end(); ++iter)
00890 std::cerr << ms_exp[iter->first].getRT() << " " << (ms_exp[iter->first][iter->second]).getMZ() << std::endl;
00891
00892 std::cerr << std::endl << std::endl;
00893
00894 #endif
00895
00896
00897
00898
00899 getRegionEndpoints_(ms_exp, first, last, counter, 400, d);
00900 OptimizePick::Data data;
00901
00902
00903 Size idx = 0;
00904 for (Size i = 0; i < d.signal2D.size() / 2; ++i)
00905 {
00906 data.positions.clear();
00907 data.signal.clear();
00908
00909 MSExperiment<Peak1D>::SpectrumType::const_iterator ms_it =
00910 (d.raw_data_first + d.signal2D[2 * i].first)->begin() + d.signal2D[2 * i].second;
00911 Int size = distance(ms_it, (d.raw_data_first + d.signal2D[2 * i].first)->begin() + d.signal2D[2 * i + 1].second);
00912 data.positions.reserve(size);
00913 data.signal.reserve(size);
00914
00915 while (ms_it != (d.raw_data_first + d.signal2D[2 * i].first)->begin() + d.signal2D[2 * i + 1].second)
00916 {
00917 data.positions.push_back(ms_it->getMZ());
00918 data.signal.push_back(ms_it->getIntensity());
00919 ++ms_it;
00920 }
00921
00922
00923 IsotopeCluster::IndexPair pair;
00924 pair.first = d.iso_map_iter->second.peaks.begin()->first + idx;
00925
00926 IsotopeCluster::IndexSet::const_iterator set_iter = lower_bound(d.iso_map_iter->second.peaks.begin(),
00927 d.iso_map_iter->second.peaks.end(),
00928 pair, PairComparatorFirstElement<IsotopeCluster::IndexPair>());
00929
00930
00931
00932 ++pair.first;
00933 IsotopeCluster::IndexSet::const_iterator set_iter2 = lower_bound(d.iso_map_iter->second.peaks.begin(),
00934 d.iso_map_iter->second.peaks.end(),
00935 pair, PairComparatorFirstElement<IsotopeCluster::IndexPair>());
00936
00937 while (set_iter != set_iter2)
00938 {
00939 const Size peak_index = set_iter->second;
00940 const MSSpectrum<>& spec = ms_exp[set_iter->first];
00941 PeakShape shape(spec.getFloatDataArrays()[1][peak_index],
00942 spec[peak_index].getMZ(),
00943 spec.getFloatDataArrays()[3][peak_index],
00944 spec.getFloatDataArrays()[4][peak_index],
00945 spec[peak_index].getIntensity(),
00946 std::vector<Peak1D>::iterator(),
00947 std::vector<Peak1D>::iterator(),
00948 PeakShape::Type(Int(spec.getFloatDataArrays()[5][peak_index])));
00949 peak_shapes.push_back(shape);
00950 ++set_iter;
00951 }
00952 #ifdef DEBUG_2D
00953 std::cout << "rt "
00954 << (d.raw_data_first + d.signal2D[2 * i].first)->getRT()
00955 << "\n";
00956 #endif
00957 OptimizePick opt(penalties, max_iteration, eps_abs, eps_rel);
00958 #ifdef DEBUG_2D
00959 std::cout << "vorher\n";
00960
00961 for (Size p = 0; p < peak_shapes.size(); ++p)
00962 {
00963 std::cout << peak_shapes[p].mz_position << "\t" << peak_shapes[p].height
00964 << "\t" << peak_shapes[p].left_width << "\t" << peak_shapes[p].right_width << std::endl;
00965 }
00966 #endif
00967 opt.optimize(peak_shapes, data);
00968 #ifdef DEBUG_2D
00969 std::cout << "nachher\n";
00970 for (Size p = 0; p < peak_shapes.size(); ++p)
00971 {
00972 std::cout << peak_shapes[p].mz_position << "\t" << peak_shapes[p].height
00973 << "\t" << peak_shapes[p].left_width << "\t" << peak_shapes[p].right_width << std::endl;
00974 }
00975 #endif
00976 std::sort(peak_shapes.begin(), peak_shapes.end(), PeakShape::PositionLess());
00977 pair.first = d.iso_map_iter->second.peaks.begin()->first + idx;
00978
00979 set_iter = lower_bound(d.iso_map_iter->second.peaks.begin(),
00980 d.iso_map_iter->second.peaks.end(),
00981 pair, PairComparatorFirstElement<IsotopeCluster::IndexPair>());
00982 Size p = 0;
00983 while (p < peak_shapes.size())
00984 {
00985 MSSpectrum<>& spec = ms_exp[set_iter->first];
00986 spec[set_iter->second].setMZ(peak_shapes[p].mz_position);
00987 spec.getFloatDataArrays()[3][set_iter->second] = peak_shapes[p].left_width;
00988 spec.getFloatDataArrays()[4][set_iter->second] = peak_shapes[p].right_width;
00989 spec.getFloatDataArrays()[1][set_iter->second] = peak_shapes[p].height;
00990
00991 if (peak_shapes[p].type == PeakShape::LORENTZ_PEAK)
00992 {
00993 PeakShape& ps = peak_shapes[p];
00994 double x_left_endpoint = ps.mz_position - 1 / ps.left_width* sqrt(ps.height / 1 - 1);
00995 double x_rigth_endpoint = ps.mz_position + 1 / ps.right_width* sqrt(ps.height / 1 - 1);
00996 double area_left = -ps.height / ps.left_width* atan(ps.left_width * (x_left_endpoint - ps.mz_position));
00997 double area_right = -ps.height / ps.right_width* atan(ps.right_width * (ps.mz_position - x_rigth_endpoint));
00998 spec[set_iter->second].setIntensity(area_left + area_right);
00999 }
01000 else
01001 {
01002 PeakShape& ps = peak_shapes[p];
01003 double x_left_endpoint = ps.mz_position - 1 / ps.left_width* boost::math::acosh(sqrt(ps.height / 0.001));
01004 double x_rigth_endpoint = ps.mz_position + 1 / ps.right_width* boost::math::acosh(sqrt(ps.height / 0.001));
01005 double area_left = ps.height / ps.left_width * (sinh(ps.left_width * (ps.mz_position - x_left_endpoint)) / cosh(ps.left_width * (ps.mz_position - x_left_endpoint)));
01006 double area_right = -ps.height / ps.right_width * (sinh(ps.right_width * (ps.mz_position - x_rigth_endpoint)) / cosh(ps.right_width * (ps.mz_position - x_rigth_endpoint)));
01007 spec[set_iter->second].setIntensity(area_left + area_right);
01008 }
01009 ++set_iter;
01010 ++p;
01011 }
01012 ++idx;
01013 peak_shapes.clear();
01014 }
01015
01016 ++counter;
01017 }
01018 }
01019
01020 template <typename InputSpectrumIterator, typename OutputPeakType>
01021 void TwoDOptimization::getRegionEndpoints_(MSExperiment<OutputPeakType>& exp,
01022 InputSpectrumIterator& first,
01023 InputSpectrumIterator& last,
01024 Size iso_map_idx,
01025 DoubleReal noise_level,
01026 TwoDOptimization::Data& d)
01027 {
01028 d.signal2D.clear();
01029 typedef typename InputSpectrumIterator::value_type InputExperimentType;
01030 typedef typename InputExperimentType::value_type InputPeakType;
01031 typedef std::multimap<DoubleReal, IsotopeCluster> MapType;
01032
01033 DoubleReal rt, first_peak_mz, last_peak_mz;
01034
01035
01036 typename MSExperiment<InputPeakType>::SpectrumType spec;
01037 InputPeakType peak;
01038
01039 MapType::iterator iso_map_iter = iso_map_.begin();
01040 for (Size i = 0; i < iso_map_idx; ++i)
01041 ++iso_map_iter;
01042
01043 #ifdef DEBUG2D
01044 std::cout << "rt begin: " << exp[iso_map_iter->second.scans[0]].getRT()
01045 << "\trt end: " << exp[iso_map_iter->second.scans[iso_map_iter->second.scans.size() - 1]].getRT()
01046 << " \t" << iso_map_iter->second.scans.size() << " scans"
01047 << std::endl;
01048 #endif
01049
01050
01051 for (Size i = 0; i < iso_map_iter->second.scans.size(); ++i)
01052 {
01053 typename MSExperiment<OutputPeakType>::iterator exp_it;
01054
01055
01056 rt = exp[iso_map_iter->second.scans[i]].getRT();
01057 spec.setRT(rt);
01058 InputSpectrumIterator iter = lower_bound(first, last, spec, typename MSSpectrum<InputPeakType>::RTLess());
01059
01060 exp_it = exp.RTBegin(rt);
01061 #ifdef DEBUG2D
01062 std::cout << exp_it->getRT() << " vs " << iter->getRT() << std::endl;
01063 #endif
01064
01065 IsotopeCluster::IndexPair pair;
01066 pair.first = iso_map_iter->second.peaks.begin()->first + i;
01067
01068 IsotopeCluster::IndexSet::const_iterator set_iter = lower_bound(iso_map_iter->second.peaks.begin(),
01069 iso_map_iter->second.peaks.end(),
01070 pair, PairComparatorFirstElement<IsotopeCluster::IndexPair>());
01071
01072
01073 first_peak_mz = (exp_it->begin() + set_iter->second)->getMZ() - 1;
01074
01075
01076 ++pair.first;
01077 IsotopeCluster::IndexSet::const_iterator set_iter2 = lower_bound(iso_map_iter->second.peaks.begin(),
01078 iso_map_iter->second.peaks.end(),
01079 pair, PairComparatorFirstElement<IsotopeCluster::IndexPair>());
01080
01081 if (i == iso_map_iter->second.scans.size() - 1)
01082 {
01083 set_iter2 = iso_map_iter->second.peaks.end();
01084 --set_iter2;
01085 }
01086 else if (set_iter2 != iso_map_iter->second.peaks.begin())
01087 --set_iter2;
01088
01089 last_peak_mz = (exp_it->begin() + set_iter2->second)->getMZ() + 1;
01090
01091
01092 peak.setPosition(first_peak_mz);
01093 typename MSExperiment<InputPeakType>::SpectrumType::const_iterator raw_data_iter
01094 = lower_bound(iter->begin(), iter->end(), peak, typename InputPeakType::PositionLess());
01095 if (raw_data_iter != iter->begin())
01096 {
01097 --raw_data_iter;
01098 }
01099 DoubleReal intensity = raw_data_iter->getIntensity();
01100
01101 while (raw_data_iter != iter->begin() && (raw_data_iter - 1)->getIntensity() < intensity &&
01102 (raw_data_iter - 1)->getIntensity() > noise_level)
01103 {
01104 --raw_data_iter;
01105 intensity = raw_data_iter->getIntensity();
01106 }
01107 ++raw_data_iter;
01108 IsotopeCluster::IndexPair left, right;
01109 left.first = distance(first, iter);
01110 left.second = raw_data_iter - iter->begin();
01111 #ifdef DEBUG2D
01112 std::cout << "left: " << iter->getRT() << "\t" << raw_data_iter->getMZ() << std::endl;
01113 #endif
01114
01115 peak.setPosition(last_peak_mz + 1);
01116 raw_data_iter
01117 = upper_bound(iter->begin(), iter->end(), peak, typename InputPeakType::PositionLess());
01118 if (raw_data_iter == iter->end())
01119 --raw_data_iter;
01120 intensity = raw_data_iter->getIntensity();
01121
01122 while (raw_data_iter + 1 != iter->end() && (raw_data_iter + 1)->getIntensity() < intensity)
01123 {
01124 ++raw_data_iter;
01125 intensity = raw_data_iter->getIntensity();
01126 if ((raw_data_iter + 1 != iter->end()) && (raw_data_iter + 1)->getIntensity() > noise_level)
01127 break;
01128 }
01129 right.first = left.first;
01130 right.second = raw_data_iter - iter->begin();
01131 #ifdef DEBUG2D
01132 std::cout << "right: " << iter->getRT() << "\t" << raw_data_iter->getMZ() << std::endl;
01133 #endif
01134
01135 d.signal2D.push_back(left);
01136 d.signal2D.push_back(right);
01137 }
01138 #ifdef DEBUG2D
01139
01140 std::cout << first_peak_mz << "\t" << last_peak_mz << std::endl;
01141 #endif
01142 }
01143
01144 }
01145
01146 #endif //OPENMS_TRANSFORMATIONS_RAW2PEAK_TWODOPTIMIZATION_H