std::vector<PeakSpectrum> AScore::peakPickingPerWindowsInSpectrum_(PeakSpectrum &real_spectrum) const { vector<PeakSpectrum> windows_top10; double spect_lower_bound = floor(real_spectrum.front().getMZ() / 100) * 100; double spect_upper_bound = ceil(real_spectrum.back().getMZ() / 100) * 100; Size number_of_windows = static_cast<Size>(ceil((spect_upper_bound - spect_lower_bound) / 100)); windows_top10.resize(number_of_windows); PeakSpectrum::Iterator it_current_peak = real_spectrum.begin(); Size window_upper_bound(spect_lower_bound + 100); for (Size current_window = 0; current_window < number_of_windows; ++current_window) { PeakSpectrum real_window; while (((*it_current_peak).getMZ() <= window_upper_bound) && (it_current_peak < real_spectrum.end())) { real_window.push_back(*it_current_peak); ++it_current_peak; } real_window.sortByIntensity(true); for (Size i = 0; (i < 10) & (i < real_window.size()); ++i) { windows_top10[current_window].push_back(real_window[i]); } window_upper_bound += 100; } return windows_top10; }
double XQuestScores::logOccupancyProb(const PeakSpectrum& theoretical_spec, const Size matched_size, double fragment_mass_tolerance, bool fragment_mass_tolerance_unit_ppm) { using boost::math::binomial; Size theo_size = theoretical_spec.size(); if (matched_size < 1 || theo_size < 1) { return 0; } double range; double used_tolerance; if (fragment_mass_tolerance_unit_ppm) { range = std::log(theoretical_spec.back().getMZ()) - std::log(theoretical_spec[0].getMZ()); used_tolerance = fragment_mass_tolerance / 1e6; } else { range = theoretical_spec.back().getMZ() - theoretical_spec[0].getMZ(); used_tolerance = fragment_mass_tolerance; } // A priori probability of a random match given info about the theoretical spectrum double a_priori_p = 0; a_priori_p = 1 - pow(1 - 2 * used_tolerance / range, static_cast<double>(theo_size)); double log_occu_prob = 0; binomial flip(theo_size, a_priori_p); // min double number to avoid 0 values, causing scores with the value "inf" log_occu_prob = -log(1 - cdf(flip, matched_size) + std::numeric_limits<double>::min()); // score lower than 0 does not make sense, but can happen, if cfd = 0, then -log( 1 + <double>::min() ) < 0 if (log_occu_prob >= 0.0) { return log_occu_prob; } else // underflow warning? { return 0; } }