37 #include <OpenMS/config.h>  
   98       double apex_pos = 0.0;
 
  133       double width_at_5 = 0.0;
 
  137       double width_at_10 = 0.0;
 
  141       double width_at_50 = 0.0;
 
  145       double start_position_at_5 = 0.0;
 
  149       double start_position_at_10 = 0.0;
 
  153       double start_position_at_50 = 0.0;
 
  157       double end_position_at_5 = 0.0;
 
  161       double end_position_at_10 = 0.0;
 
  165       double end_position_at_50 = 0.0;
 
  169       double total_width = 0.0;
 
  183       double tailing_factor = 0.0;
 
  193       double asymmetry_factor = 0.0;
 
  198       double slope_of_baseline = 0.0;
 
  203       double baseline_delta_2_height = 0.0;
 
  207       Int points_across_baseline = 0;
 
  211       Int points_across_half_height = 0;
 
  220     static constexpr 
const char* INTEGRATION_TYPE_INTENSITYSUM = 
"intensity_sum";
 
  224     static constexpr 
const char* INTEGRATION_TYPE_TRAPEZOID = 
"trapezoid";
 
  226     static constexpr 
const char* INTEGRATION_TYPE_SIMPSON = 
"simpson";
 
  228     static constexpr 
const char* BASELINE_TYPE_BASETOBASE = 
"base_to_base";
 
  230     static constexpr 
const char* BASELINE_TYPE_VERTICALDIVISION = 
"vertical_division";
 
  232     static constexpr 
const char* BASELINE_TYPE_VERTICALDIVISION_MIN = 
"vertical_division_min";
 
  234     static constexpr 
const char* BASELINE_TYPE_VERTICALDIVISION_MAX = 
"vertical_division_max";
 
  256       const MSChromatogram& chromatogram, 
const double left, 
const double right
 
  300       const MSSpectrum& spectrum, 
const double left, 
const double right
 
  350       const MSChromatogram& chromatogram, 
const double left, 
const double right,
 
  351       const double peak_apex_pos
 
  380       const double peak_apex_pos
 
  408       const MSSpectrum& spectrum, 
const double left, 
const double right,
 
  409       const double peak_apex_pos
 
  438       const double peak_apex_pos
 
  461       const MSChromatogram& chromatogram, 
const double left, 
const double right,
 
  462       const double peak_height, 
const double peak_apex_pos
 
  486       const double peak_height, 
const double peak_apex_pos
 
  509       const MSSpectrum& spectrum, 
const double left, 
const double right,
 
  510       const double peak_height, 
const double peak_apex_pos
 
  534       const double peak_height, 
const double peak_apex_pos
 
  537     void getDefaultParameters(
Param& params);
 
  540     void updateMembers_();
 
  542     template <
typename PeakContainerT>
 
  545       OPENMS_PRECONDITION(left <= right, 
"Left peak boundary must be smaller than right boundary!") 
 
  546       PeakContainerT emg_pc;
 
  547       const PeakContainerT& p = EMGPreProcess_(pc, emg_pc, left, right);
 
  549       std::function<
double(
const double, 
const double)>
 
  550       compute_peak_area_trapezoid = [&p](
const double left, 
const double right)
 
  552         double peak_area { 0.0 };
 
  553         for (
typename PeakContainerT::ConstIterator it = p.PosBegin(left); it != p.PosEnd(right) - 1; ++it)
 
  555           peak_area += ((it + 1)->getPos() - it->getPos()) * ((it->getIntensity() + (it + 1)->getIntensity()) / 2.0);
 
  560       std::function<
double(
const double, 
const double)>
 
  561       compute_peak_area_intensity_sum = [&p](
const double left, 
const double right)
 
  564         double peak_area { 0.0 };
 
  565         for (
typename PeakContainerT::ConstIterator it = p.PosBegin(left); it != p.PosEnd(right); ++it)
 
  567           peak_area += it->getIntensity();
 
  574       UInt n_points = std::distance(p.PosBegin(left), p.PosEnd(right));
 
  575       for (
auto it = p.PosBegin(left); it != p.PosEnd(right); ++it) 
 
  578         if (pa.
height < it->getIntensity())
 
  580           pa.
height = it->getIntensity();
 
  585       if (integration_type_ == INTEGRATION_TYPE_TRAPEZOID)
 
  589           pa.
area = compute_peak_area_trapezoid(left, right);
 
  592       else if (integration_type_ == INTEGRATION_TYPE_SIMPSON)
 
  597             "number of points is 2, falling back to `trapezoid`." << std::endl;
 
  598           pa.
area = compute_peak_area_trapezoid(left, right);
 
  600         else if (n_points > 2)
 
  604             pa.
area = simpson_(p.PosBegin(left), p.PosEnd(right));
 
  608             double areas[4] = {-1.0, -1.0, -1.0, -1.0};
 
  609             areas[0] = simpson_(p.PosBegin(left), p.PosEnd(right) - 1);   
 
  610             areas[1] = simpson_(p.PosBegin(left) + 1, p.PosEnd(right));   
 
  611             if (p.begin() <= p.PosBegin(left) - 1)
 
  613               areas[2] = simpson_(p.PosBegin(left) - 1, p.PosEnd(right)); 
 
  615             if (p.PosEnd(right) < p.end())
 
  617               areas[3] = simpson_(p.PosBegin(left), p.PosEnd(right) + 1); 
 
  620             for (
const auto& area : areas)
 
  632       else if (integration_type_ == INTEGRATION_TYPE_INTENSITYSUM)
 
  634         pa.
area = compute_peak_area_intensity_sum(left, right);
 
  638         throw Exception::InvalidParameter(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, 
"Please set a valid value for the parameter \"integration_type\".");
 
  646     template <
typename PeakContainerT>
 
  648       const PeakContainerT& pc, 
double left, 
double right,
 
  649       const double peak_apex_pos
 
  652       PeakContainerT emg_pc;
 
  653       const PeakContainerT& p = EMGPreProcess_(pc, emg_pc, left, right);
 
  655       const double int_l = p.PosBegin(left)->getIntensity();
 
  656       const double int_r = (p.PosEnd(right) - 1)->getIntensity();
 
  657       const double delta_int = int_r - int_l;
 
  658       const double delta_pos = (p.PosEnd(right) - 1)->getPos() - p.PosBegin(left)->getPos();
 
  659       const double min_int_pos = int_r <= int_l ? (p.PosEnd(right) - 1)->getPos() : p.PosBegin(left)->getPos();
 
  660       const double delta_int_apex = std::fabs(delta_int) * std::fabs(min_int_pos - peak_apex_pos) / delta_pos;
 
  663       if (baseline_type_ == BASELINE_TYPE_BASETOBASE)
 
  665         height = std::min(int_r, int_l) + delta_int_apex;
 
  666         if (integration_type_ == INTEGRATION_TYPE_TRAPEZOID || integration_type_ == INTEGRATION_TYPE_SIMPSON)
 
  670           area = delta_pos * (std::min(int_r, int_l) + 0.5 * std::fabs(delta_int));
 
  672         else if (integration_type_ == INTEGRATION_TYPE_INTENSITYSUM)
 
  679           double pos_sum = 0.0; 
 
  680           for (
auto it = p.PosBegin(left); it != p.PosEnd(right); ++it) 
 
  682             pos_sum += it->getPos();
 
  684           UInt n_points = std::distance(p.PosBegin(left), p.PosEnd(right));
 
  689           const double rectangle_area = n_points * int_l;
 
  690           const double slope = delta_int / delta_pos;
 
  691           const double triangle_area = (pos_sum - n_points * p.PosBegin(left)->getPos()) * slope;
 
  692           area = triangle_area + rectangle_area;
 
  695       else if (baseline_type_ == BASELINE_TYPE_VERTICALDIVISION || baseline_type_ == BASELINE_TYPE_VERTICALDIVISION_MIN)
 
  697         height = std::min(int_r, int_l);
 
  698         if (integration_type_ == INTEGRATION_TYPE_TRAPEZOID || integration_type_ == INTEGRATION_TYPE_SIMPSON)
 
  700           area = delta_pos * std::min(int_r, int_l);
 
  702         else if (integration_type_ == INTEGRATION_TYPE_INTENSITYSUM)
 
  704           area = std::min(int_r, int_l) * std::distance(p.PosBegin(left), p.PosEnd(right));;
 
  707       else if (baseline_type_ == BASELINE_TYPE_VERTICALDIVISION_MAX)
 
  709         height = std::max(int_r, int_l);
 
  710         if (integration_type_ == INTEGRATION_TYPE_TRAPEZOID || integration_type_ == INTEGRATION_TYPE_SIMPSON)
 
  712           area = delta_pos * std::max(int_r, int_l);
 
  714         else if (integration_type_ == INTEGRATION_TYPE_INTENSITYSUM)
 
  716           area = std::max(int_r, int_l) * std::distance(p.PosBegin(left), p.PosEnd(right));
 
  721         throw Exception::InvalidParameter(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, 
"Please set a valid value for the parameter \"baseline_type\".");
 
  743     template <
typename PeakContainerConstIteratorT>
 
  744     double simpson_(PeakContainerConstIteratorT it_begin, PeakContainerConstIteratorT it_end)
 const 
  746       double integral = 0.0;
 
  747       for (
auto it = it_begin + 1; it < it_end - 1; it = it + 2) 
 
  749         const double h = it->getPos() - (it - 1)->getPos();
 
  750         const double k = (it + 1)->getPos() - it->getPos();
 
  751         const double y_h = (it - 1)->getIntensity();
 
  752         const double y_0 = it->getIntensity();
 
  753         const double y_k = (it + 1)->getIntensity();
 
  754         integral += (1.0 / 6.0) * (
h + 
k) * ((2.0 - 
k / 
h) * y_h + (pow(
h + 
k, 2) / (
h * 
k)) * y_0 + (2.0 - 
h / 
k) * y_k);
 
  760     template <
typename PeakContainerT>
 
  762       const PeakContainerT& pc, 
double left, 
double right,
 
  763       const double peak_height, 
const double peak_apex_pos
 
  768       if (pc.empty()) 
return psm; 
 
  771       if (!(left <= peak_apex_pos && peak_apex_pos <= right)) 
throw Exception::InvalidRange(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION);
 
  773       PeakContainerT emg_pc;
 
  774       const PeakContainerT& p = EMGPreProcess_(pc, emg_pc, left, right);
 
  776       typename PeakContainerT::ConstIterator it_PosBegin_l = p.PosBegin(left);
 
  777       typename PeakContainerT::ConstIterator it_PosEnd_apex = p.PosBegin(peak_apex_pos); 
 
  778       typename PeakContainerT::ConstIterator it_PosEnd_r = p.PosEnd(right); 
 
  779       for (
auto it = it_PosBegin_l; it != it_PosEnd_r; ++it) 
 
  783         if (it->getIntensity() >= 0.5 * peak_height)
 
  789       psm.
start_position_at_5 = findPosAtPeakHeightPercent_(it_PosBegin_l, it_PosEnd_apex, p.end(), peak_height, 0.05, 
true);
 
  790       psm.
start_position_at_10 = findPosAtPeakHeightPercent_(it_PosBegin_l, it_PosEnd_apex, p.end(), peak_height, 0.1, 
true);
 
  791       psm.
start_position_at_50 = findPosAtPeakHeightPercent_(it_PosBegin_l, it_PosEnd_apex, p.end(), peak_height, 0.5, 
true);
 
  792       psm.
end_position_at_5 = findPosAtPeakHeightPercent_(it_PosEnd_apex, it_PosEnd_r, p.end(), peak_height, 0.05, 
false);
 
  793       psm.
end_position_at_10 = findPosAtPeakHeightPercent_(it_PosEnd_apex, it_PosEnd_r, p.end(), peak_height, 0.1, 
false);
 
  794       psm.
end_position_at_50 = findPosAtPeakHeightPercent_(it_PosEnd_apex, it_PosEnd_r, p.end(), peak_height, 0.5, 
false);
 
  799       psm.
total_width = (p.PosEnd(right) - 1)->getPos() - p.PosBegin(left)->getPos();
 
  800       psm.
slope_of_baseline = (p.PosEnd(right) - 1)->getIntensity() - p.PosBegin(left)->getIntensity();
 
  831     template <
typename PeakContainerConstIteratorT>
 
  833       PeakContainerConstIteratorT it_left,  
 
  834       PeakContainerConstIteratorT it_right, 
 
  835       PeakContainerConstIteratorT it_end,   
 
  836       const double peak_height,
 
  837       const double percent,
 
  838       const bool is_left_half)
 const 
  844       if (it_left == it_right) 
return it_left->getPos();
 
  846       const double percent_intensity = peak_height * percent;
 
  847       PeakContainerConstIteratorT closest;
 
  852           PeakContainerConstIteratorT it = it_left;
 
  853           it < it_right && it->getIntensity() <= percent_intensity;
 
  859         closest = it_right - 1; 
 
  861           PeakContainerConstIteratorT it = it_right - 1;
 
  862           it >= it_left && it->getIntensity() <= percent_intensity;
 
  866       return closest->getPos();
 
  879     String integration_type_ = INTEGRATION_TYPE_INTENSITYSUM;
 
  884     String baseline_type_ = BASELINE_TYPE_BASETOBASE;
 
  905     template <
typename PeakContainerT>
 
  907       const PeakContainerT& pc,
 
  908       PeakContainerT& emg_pc,
 
  916         left = emg_pc.front().getPos();
 
  917         right = emg_pc.back().getPos();