/////////////////////////////////////////////////////////////////////////////
// merge the target to the search feature
  void MS1FeatureMerger::mergeFeatures(SHFeature * target, SHFeature * toMerge)
  {

    double TOT_AREA = target->get_peak_area() + toMerge->get_peak_area();
    // merge the m/z:
    target->set_MZ(
      (target->get_peak_area() * target->get_MZ() + toMerge->get_peak_area() * toMerge->get_MZ()) / TOT_AREA);
    // merge S/N:
    target->setSignalToNoise(
      (target->getSignalToNoise() * target->get_peak_area() + toMerge->getSignalToNoise() * toMerge->get_peak_area())
      / TOT_AREA);
    // merge score:
    target->set_peak_score(
      (target->get_peak_score() * target->get_peak_area() + toMerge->get_peak_score() * toMerge->get_peak_area())
      / TOT_AREA);

    // merge first the elution profiles:
    FeatureLCProfile * targetLC = target->getLCelutionProfile();
    FeatureLCProfile * mergeLC = toMerge->getLCelutionProfile();

    // add points of the toMerge to the target:
    map<int, MS1Signal>::iterator LC = mergeLC->getLCelutionSignalsStart();
    while (LC != mergeLC->getLCelutionSignalsEnd())
    {
      targetLC->addMS1elutionSignal(&(LC->second));
      ++LC;
    }

    // possible extra info:
    if (target->getFeatureExtraInformation().empty())
    {
      target->setFeatureExtraInformation(toMerge->getFeatureExtraInformation());
    }

    // compute new parameters
    computeNewMS1FeatureParameters(target);

    // copy MS/MS information:
    if (toMerge->get_MS2_info(-3.0))
    {
      target->add_MS2_info(toMerge->get_MS2_SCAN_MAP());
    }

  }
//////////////////////////////////////////////////////////////////
// Compute a varietiy of parameters for the LC elution peak
  void MS1FeatureMerger::computeNewMS1FeatureParameters(SHFeature * in)
  {

    FeatureLCProfile * lcProfile = in->getLCelutionProfile();

    // define the apex treshold:
    double maxIntens = -1;
    map<int, MS1Signal>::iterator LC = lcProfile->getLCelutionSignalsStart();
    while (LC != lcProfile->getLCelutionSignalsEnd())
    {
      if (maxIntens < (*LC).second.intensity)
      {
        maxIntens = (*LC).second.intensity;
      }
      ++LC;
    }

    // get the MS peak above noise to copmute:
    double THRESHOLD = maxIntens / in->getSignalToNoise();
    vector<MS1Signal *> computeMap;
    LC = lcProfile->getLCelutionSignalsStart();

    in->set_scan_start((*LC).second.scan);
    in->set_retention_time_START((*LC).second.TR);

    while (LC != lcProfile->getLCelutionSignalsEnd())
    {
      if ((*LC).second.intensity >= THRESHOLD)
      {
        computeMap.push_back(&(LC->second));
      }
      ++LC;
    }
    --LC;
    in->set_scan_end((*LC).second.scan);
    in->set_retention_time_END((*LC).second.TR);

    if (!computeMap.empty())
    {

      vector<MS1Signal *>::iterator P = computeMap.begin();

      double TOT_AREA = 0;
      double start_TR = 0;
      double start_int = 0;
      double apexScan = 0;
      double apexTr = 0;
      double end_TR = 0;
      double end_int = 0;

      start_TR = (*P)->TR;
      start_int = (*P)->intensity;
      ++P;
      // go through all peaks in the LC elution profile:
      while (P != computeMap.end())
      {

        if ((*P)->intensity >= THRESHOLD)
        {

          end_TR = (*P)->TR;
          end_int = (*P)->intensity;

          // compute an area between local start / end ms peak:
          double area = computeDeltaArea(start_TR, start_int - THRESHOLD, end_TR, end_int - THRESHOLD);
          TOT_AREA += area;
          apexScan += (double) ((*P)->scan) * area;
          apexTr += start_TR * area;

          // next scan:
          start_TR = end_TR;
          start_int = end_int;
        }

        ++P;
      }

      // if contained only one peak!
      if (computeMap.size() == 1)
      {
        in->set_peak_area((float) start_int);
        in->set_retention_time(in->get_retention_time_START());
        in->set_scan_number(in->get_scan_start());
      }
      else
      {
        in->set_peak_area((float) TOT_AREA);
        apexScan /= TOT_AREA;
        in->set_scan_number((int) apexScan);
        apexTr /= TOT_AREA;
        in->set_retention_time(apexTr);
      }

      // set the apex ms peak:
      LC = lcProfile->getLCelutionSignalMap()->lower_bound(in->get_scan_number());
      in->set_apex_peak_intensity((*LC).second.intensity);
    }
    else
    {
      // no good peak above threshold, so reset all the features parameters to remove the feature
      in->set_peak_area(0);
      in->set_scan_number(0);
      in->set_retention_time(0);

    }

  }