DoubleReal IsobaricChannelExtractor::computePrecursorPurity_(const MSExperiment<Peak1D>::ConstIterator& ms2_spec, const MSExperiment<Peak1D>::ConstIterator& precursor) const
  {
    // we cannot analyze precursors without a charge
    if (ms2_spec->getPrecursors()[0].getCharge() == 0)
      return 1.0;

    // compute boundaries
    const MSExperiment<>::SpectrumType::ConstIterator isolation_lower_mz = precursor->MZBegin(ms2_spec->getPrecursors()[0].getMZ() - ms2_spec->getPrecursors()[0].getIsolationWindowLowerOffset());
    const MSExperiment<>::SpectrumType::ConstIterator isolation_upper_mz = precursor->MZEnd(ms2_spec->getPrecursors()[0].getMZ() + ms2_spec->getPrecursors()[0].getIsolationWindowUpperOffset());

    Peak1D::IntensityType total_intensity = 0;

    // get total intensity
    for (MSExperiment<>::SpectrumType::ConstIterator isolation_it = isolation_lower_mz;
         isolation_it != isolation_upper_mz;
         ++isolation_it)
    {
      total_intensity += isolation_it->getIntensity();
    }

    // now get the intensity of the precursor .. we assume everything in the distance of 1/c to belong to the precursor
    // for c == charge of precursor

    // precursor mz
    Size precursor_peak_idx = precursor->findNearest(ms2_spec->getPrecursors()[0].getMZ());
    Peak1D precursor_peak = (*precursor)[precursor_peak_idx];
    Peak1D::IntensityType precursor_intensity = precursor_peak.getIntensity();

    // compute the
    double charge_dist = Constants::NEUTRON_MASS_U / (double) ms2_spec->getPrecursors()[0].getCharge();

    // search left of precursor for isotopic peaks
    precursor_intensity += sumPotentialIsotopePeaks_(precursor, isolation_lower_mz->getMZ(), isolation_upper_mz->getMZ(), precursor_peak.getMZ(), -1 * charge_dist);
    // search right of precursor for isotopic peaks
    precursor_intensity += sumPotentialIsotopePeaks_(precursor, isolation_lower_mz->getMZ(), isolation_upper_mz->getMZ(), precursor_peak.getMZ(), charge_dist);

    return precursor_intensity / total_intensity;
  }