void GaussTraceFitter::fit(FeatureFinderAlgorithmPickedHelperStructs::MassTraces& traces) { LOG_DEBUG << "Traces length: " << traces.size() << "\n"; setInitialParameters_(traces); Eigen::VectorXd x_init(NUM_PARAMS_); x_init(0) = height_; x_init(1) = x0_; x_init(2) = sigma_; TraceFitter::ModelData data; data.traces_ptr = &traces; data.weighted = this->weighted_; GaussTraceFunctor functor(NUM_PARAMS_, &data); TraceFitter::optimize_(x_init, functor); }
void EGHTraceFitter::setInitialParameters_(FeatureFinderAlgorithmPickedHelperStructs::MassTraces& traces) { LOG_DEBUG << "EGHTraceFitter->setInitialParameters(...)" << std::endl; LOG_DEBUG << "Number of traces: " << traces.size() << std::endl; // aggregate data; some peaks (where intensity is zero) can be missing! // mapping: RT -> total intensity over all mass traces std::list<std::pair<double, double> > total_intensities; traces.computeIntensityProfile(total_intensities); // compute moving average for smoothing: const Size N = total_intensities.size(); const Size LEN = 2; // window size: 2 * LEN + 1 std::vector<double> totals(N + 2 * LEN); // pad with zeros at ends Int index = LEN; // LOG_DEBUG << "Summed intensities:\n"; for (std::list<std::pair<double, double> >::iterator it = total_intensities.begin(); it != total_intensities.end(); ++it) { totals[index++] = it->second; // LOG_DEBUG << it->second << std::endl; } std::vector<double> smoothed(N); Size max_index = 0; // index of max. smoothed intensity // LOG_DEBUG << "Smoothed intensities:\n"; double sum = std::accumulate(&totals[LEN], &totals[2 * LEN], 0.0); for (Size i = 0; i < N; ++i) { sum += totals[i + 2 * LEN]; smoothed[i] = sum / (2 * LEN + 1); sum -= totals[i]; if (smoothed[i] > smoothed[max_index]) max_index = i; // LOG_DEBUG << smoothed[i] << std::endl; } LOG_DEBUG << "Maximum at index " << max_index << std::endl; height_ = smoothed[max_index] - traces.baseline; LOG_DEBUG << "height: " << height_ << std::endl; std::list<std::pair<double, double> >::iterator it = total_intensities.begin(); std::advance(it, max_index); apex_rt_ = it->first; LOG_DEBUG << "apex_rt: " << apex_rt_ << std::endl; region_rt_span_ = (total_intensities.rbegin()->first - total_intensities.begin()->first); LOG_DEBUG << "region_rt_span: " << region_rt_span_ << std::endl; // find RT values where intensity is at half-maximum: index = static_cast<Int>(max_index); while ((index > 0) && (smoothed[index] > height_ * 0.5)) --index; double left_height = smoothed[index]; it = total_intensities.begin(); std::advance(it, index); double left_rt = it->first; LOG_DEBUG << "Left half-maximum at index " << index << ", RT " << left_rt << std::endl; index = static_cast<Int>(max_index); while ((index < Int(N - 1)) && (smoothed[index] > height_ * 0.5)) ++index; double right_height = smoothed[index]; it = total_intensities.end(); std::advance(it, index - Int(N)); double right_rt = it->first; LOG_DEBUG << "Right half-maximum at index " << index << ", RT " << right_rt << std::endl; double A = apex_rt_ - left_rt; double B = right_rt - apex_rt_; //LOG_DEBUG << "A: " << A << std::endl; //LOG_DEBUG << "B: " << B << std::endl; // compute estimates for tau / sigma based on A and B: double alpha = (left_height + right_height) * 0.5 / height_; // ~0.5 double log_alpha = log(alpha); tau_ = -1 / log_alpha * (B - A); //EGH function fails when tau==0 if (tau_ == 0) tau_ = std::numeric_limits<double>::epsilon(); LOG_DEBUG << "tau: " << tau_ << std::endl; sigma_ = sqrt(-0.5 / log_alpha * B * A); LOG_DEBUG << "sigma: " << sigma_ << std::endl; }
void GaussTraceFitter::setInitialParameters_(FeatureFinderAlgorithmPickedHelperStructs::MassTraces& traces) { LOG_DEBUG << "GaussTraceFitter->setInitialParameters(...)" << std::endl; LOG_DEBUG << "Number of traces: " << traces.size() << std::endl; // aggregate data; some peaks (where intensity is zero) can be missing! // mapping: RT -> total intensity over all mass traces std::list<std::pair<double, double> > total_intensities; traces.computeIntensityProfile(total_intensities); const Size N = total_intensities.size(); const Size LEN = 2; // window size: 2 * LEN + 1 std::vector<double> totals(N + 2 * LEN); // pad with zeros at ends Int index = LEN; // LOG_DEBUG << "Summed intensities:\n"; for (std::list<std::pair<double, double> >::iterator it = total_intensities.begin(); it != total_intensities.end(); ++it) { totals[index++] = it->second; // LOG_DEBUG << it->second << std::endl; } std::vector<double> smoothed(N); Size max_index = 0; // index of max. smoothed intensity if (N <= LEN + 1) // not enough distinct x values for smoothing { // throw Exception::UnableToFit(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "UnableToFit-MovingAverage", "Too few time points for smoothing with window size " + String(2 * LEN + 1)); for (Size i = 0; i < N; ++i) { smoothed[i] = totals[i + LEN]; if (smoothed[i] > smoothed[max_index]) max_index = i; } } else // compute moving average for smoothing { // LOG_DEBUG << "Smoothed intensities:\n"; double sum = std::accumulate(&totals[LEN], &totals[2 * LEN], 0.0); for (Size i = 0; i < N; ++i) { sum += totals[i + 2 * LEN]; smoothed[i] = sum / (2 * LEN + 1); sum -= totals[i]; if (smoothed[i] > smoothed[max_index]) max_index = i; // LOG_DEBUG << smoothed[i] << std::endl; } } LOG_DEBUG << "Maximum at index " << max_index << std::endl; height_ = smoothed[max_index] - traces.baseline; LOG_DEBUG << "height: " << height_ << std::endl; std::list<std::pair<double, double> >::iterator it = total_intensities.begin(); std::advance(it, max_index); x0_ = it->first; LOG_DEBUG << "x0: " << x0_ << std::endl; region_rt_span_ = (total_intensities.rbegin()->first - total_intensities.begin()->first); LOG_DEBUG << "region_rt_span: " << region_rt_span_ << std::endl; // find RT values where intensity is at half-maximum: index = static_cast<Int>(max_index); while ((index > 0) && (smoothed[index] > height_ * 0.5)) --index; double left_height = smoothed[index]; it = total_intensities.begin(); std::advance(it, index); double left_rt = it->first; LOG_DEBUG << "Left half-maximum at index " << index << ", RT " << left_rt << std::endl; index = static_cast<Int>(max_index); while ((index < Int(N - 1)) && (smoothed[index] > height_ * 0.5)) ++index; double right_height = smoothed[index]; it = total_intensities.end(); std::advance(it, index - Int(N)); double right_rt = it->first; LOG_DEBUG << "Right half-maximum at index " << index << ", RT " << right_rt << std::endl; double delta_x = right_rt - left_rt; double alpha = (left_height + right_height) * 0.5 / height_; // ~0.5 if (alpha >= 1) sigma_ = 1.0; // degenerate case, all values are the same else sigma_ = delta_x * 0.5 / sqrt(-2.0 * log(alpha)); LOG_DEBUG << "sigma: " << sigma_ << std::endl; }