diff --git a/src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMTransitionGroupPicker.h b/src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMTransitionGroupPicker.h index b743a7746c5..3413cab6a65 100644 --- a/src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMTransitionGroupPicker.h +++ b/src/openms/include/OpenMS/ANALYSIS/OPENSWATH/MRMTransitionGroupPicker.h @@ -46,6 +46,7 @@ #include #include +#include // Cross-correlation #include @@ -115,45 +116,57 @@ namespace OpenMS OPENMS_PRECONDITION(transition_group.isInternallyConsistent(), "Consistent state required") OPENMS_PRECONDITION(transition_group.chromatogramIdsMatch(), "Chromatogram native IDs need to match keys in transition group") - std::vector picked_chroms; - std::vector smoothed_chroms; + std::vector picked_chroms; + std::vector smoothed_chroms; - // Pick fragment ion chromatograms - for (Size k = 0; k < transition_group.getChromatograms().size(); k++) + picked_chroms.resize(transition_group.getChromatograms().size()); + smoothed_chroms.resize(transition_group.getChromatograms().size()); + + // Pick precursor chromatograms + if (use_precursors_) { - MSChromatogram& chromatogram = transition_group.getChromatograms()[k]; - String native_id = chromatogram.getNativeID(); - - // only pick detecting transitions (skip all others) - if (transition_group.getTransitions().size() > 0 && - transition_group.hasTransition(native_id) && - !transition_group.getTransition(native_id).isDetectingTransition() ) + #pragma omp parallel num_threads(transition_group.getPrecursorChromatograms().size()) { - continue; - } - - MSChromatogram picked_chrom, smoothed_chrom; - smoothed_chrom.setNativeID(native_id); - picker_.pickChromatogram(chromatogram, picked_chrom, smoothed_chrom); - picked_chrom.sortByIntensity(); - picked_chroms.push_back(std::move(picked_chrom)); - smoothed_chroms.push_back(std::move(smoothed_chrom)); - } + PeakPickerMRM picker_temp(picker_); + #pragma omp for + for (Size k = 0; k < transition_group.getPrecursorChromatograms().size(); k++) + { + SpectrumT& picked_chrom = picked_chroms[k]; + SpectrumT& smoothed_chrom = smoothed_chroms[k]; + SpectrumT& chromatogram = transition_group.getPrecursorChromatograms()[k]; - // Pick precursor chromatograms - if (use_precursors_) + picker_temp.pickChromatogram(chromatogram, picked_chrom, smoothed_chrom); + picked_chrom.sortByIntensity(); + } + } + } + else { - for (Size k = 0; k < transition_group.getPrecursorChromatograms().size(); k++) + #pragma omp parallel num_threads(transition_group.getChromatograms().size()) { - SpectrumT picked_chrom, smoothed_chrom; - SpectrumT& chromatogram = transition_group.getPrecursorChromatograms()[k]; + PeakPickerMRM picker_temp(picker_); + #pragma omp for + for (Size k = 0; k < transition_group.getChromatograms().size(); k++) // Pick fragment ion chromatograms + { + MSChromatogram& chromatogram = transition_group.getChromatograms()[k]; + String native_id = chromatogram.getNativeID(); - picker_.pickChromatogram(chromatogram, picked_chrom, smoothed_chrom); - picked_chrom.sortByIntensity(); - picked_chroms.push_back(picked_chrom); - smoothed_chroms.push_back(smoothed_chrom); + // only pick detecting transitions (skip all others) + if (transition_group.getTransitions().size() > 0 && + transition_group.hasTransition(native_id) && + !transition_group.getTransition(native_id).isDetectingTransition() ) + { + continue; + } + + MSChromatogram& picked_chrom = picked_chroms[k]; + MSChromatogram& smoothed_chrom = smoothed_chroms[k]; + smoothed_chrom.setNativeID(native_id); + picker_temp.pickChromatogram(chromatogram, picked_chrom, smoothed_chrom); + picked_chrom.sortByIntensity(); + } } - } + } // Find features (peak groups) in this group of transitions. // While there are still peaks left, one will be picked and used to create diff --git a/src/openms/include/OpenMS/FILTERING/SMOOTHING/GaussFilterAlgorithm.h b/src/openms/include/OpenMS/FILTERING/SMOOTHING/GaussFilterAlgorithm.h index 93facd7d645..a58ea7b7326 100644 --- a/src/openms/include/OpenMS/FILTERING/SMOOTHING/GaussFilterAlgorithm.h +++ b/src/openms/include/OpenMS/FILTERING/SMOOTHING/GaussFilterAlgorithm.h @@ -37,8 +37,11 @@ #include #include #include +#include #include #include +#include // Reihenfolge TODO +#include namespace OpenMS { @@ -126,7 +129,7 @@ namespace OpenMS /** @brief Smoothes an two data arrays containing data. - Convolutes the filter and the profile data and writes the results into the output iterators mz_out and int_out. + Convolutes the filter and the profile data and writes the results into the output iterators mz_out and int_out. */ template bool filter( @@ -137,56 +140,150 @@ namespace OpenMS IterT int_out) { bool found_signal = false; - - ConstIterT mz_it = mz_in_start; + ConstIterT int_it = int_in_start; - for (; mz_it != mz_in_end; mz_it++, int_it++) - { - // if ppm tolerance is used, calculate a reasonable width value for this m/z + ConstIterT mz_it = mz_in_start; + // if ppm tolerance is used, calculate a reasonable width value for this m/z if (use_ppm_tolerance_) - { - initialize((*mz_it) * ppm_tolerance_ * 10e-6, spacing_, ppm_tolerance_, use_ppm_tolerance_ ); + { + for (; mz_it != mz_in_end; mz_it++, int_it++) + { + initialize((*mz_it) * ppm_tolerance_ * 10e-6, spacing_, ppm_tolerance_, use_ppm_tolerance_ ); + + double new_int = integrate_(mz_it, int_it, mz_in_start, mz_in_end); + + // store new intensity and m/z into output iterator + *mz_out = *mz_it; + *int_out = new_int; + ++mz_out; + ++int_out; + + if (new_int != 0) found_signal = true; + } } + else + { + evergreen::Tensor gaussian_data({coeffs_.size()}); - double new_int = integrate_(mz_it, int_it, mz_in_start, mz_in_end); - - // store new intensity and m/z into output iterator - *mz_out = *mz_it; - *int_out = new_int; - ++mz_out; - ++int_out; + // normalize the gaussian coefficients to scale the intensities correctly + double sum = std::accumulate(coeffs_.begin(), coeffs_.end(), 0.0); + if (sum != 1.0) + { + for (long unsigned i = 0; i < coeffs_.size(); i++) + { + gaussian_data[i] = coeffs_[i] / sum; + } + } + else + { + for (long unsigned i = 0; i < coeffs_.size(); i++) + { + gaussian_data[i] = coeffs_[i]; + } + } + + // saving the spacing_ nearest mz values in the same bin (binning) + std::vector bin_numbers = {}; + evergreen::Tensor bins({(double(*(mz_in_end - 1) - *mz_in_start) / spacing_) + 1.0}); + binning(bins, bin_numbers, mz_in_start, mz_in_end, int_it); + + //Fast Fourier Transformation from evergreen + evergreen::Tensor out_fft = evergreen::fft_convolve(bins, gaussian_data); + + mz_it = mz_in_start; + int_it = int_in_start; - if (fabs(new_int) > 0) found_signal = true; + out_fft = debinning(out_fft, bin_numbers, mz_in_start, mz_in_end, int_it); + + mz_it = mz_in_start; + int_it = int_in_start; + + //cutting off the access data that was calculated by convolve + for (int i = ((out_fft.flat_size() - bins.flat_size())/ 2); mz_it != mz_in_end; mz_it++, int_it++, i++) + { + *mz_out = *mz_it; + *int_out = out_fft[i]; + ++mz_out; + ++int_out; + + if (out_fft[i] != 0) found_signal = true; + } } return found_signal; } + void initialize(double gaussian_width, double spacing, double ppm_tolerance, bool use_ppm_tolerance); -protected: + template + void binning(DataPackage& bins, BinPosPackage& bin_numbers, ConstIterT mz_it, ConstIterT mz_end, ConstIterT int_it) const + { + double start = *mz_it; + unsigned j = 0; + for (unsigned i = 0; mz_it != mz_end; j++) + { + if (*mz_it < (start + (i + 1) * spacing_)) + { + bins[i] += *int_it; + int_it++; + mz_it++; + bin_numbers.push_back(1); - ///Coefficients - std::vector coeffs_; - /// The standard derivation \f$ \sigma \f$. - double sigma_; - /// The spacing of the pre-tabulated kernel coefficients - double spacing_; + continue; + } - // tolerance in ppm - bool use_ppm_tolerance_; - double ppm_tolerance_; + i++; + bin_numbers.push_back(0); + } + } + + + template + DataPackage debinning(DataPackage& out_fft, BinPosPackage& bin_numbers, ConstIterT mz_it, ConstIterT mz_end, ConstIterT int_it) const + { + unsigned start_bin = 0; + unsigned end_bin = 0; + for (unsigned i = 0; i < out_fft.flat_size() - 1; i++) + { + // search for bin with original data + if (bin_numbers[i] != 0) + { + end_bin = i; + } + else + { + end_bin++; + continue; + } + + // adding the values in the [start_bin, end_bin] interval (while considering the distance to the start_bin and end_bin peaks) + unsigned j = start_bin + 1; + while (j != end_bin) + { + out_fft[end_bin] += out_fft[j] * ((1.0 - double(end_bin - j)) / double(end_bin - start_bin)); + out_fft[start_bin] += out_fft[j] * ((1.0 - double(j - start_bin)) / double(end_bin - start_bin)); + + out_fft[j] = 0.0; + j++; + } + start_bin = end_bin; + } + return out_fft; + } + +protected: /// Computes the convolution of the raw data at position x and the gaussian kernel template - double integrate_(InputPeakIterator x /* mz */, InputPeakIterator y /* int */, InputPeakIterator first, InputPeakIterator last) + double integrate_(InputPeakIterator x /* mz */, InputPeakIterator y /* int */, InputPeakIterator first, InputPeakIterator last) const { double v = 0.; // norm the gaussian kernel area to one double norm = 0.; Size middle = coeffs_.size(); - double start_pos = (( (*x) - (middle * spacing_)) > (*first)) ? ((*x) - (middle * spacing_)) : (*first); - double end_pos = (( (*x) + (middle * spacing_)) < (*(last - 1))) ? ((*x) + (middle * spacing_)) : (*(last - 1)); + double start_pos = (((*x) - (middle * spacing_)) > (*first)) ? ((*x) - (middle * spacing_)) : (*first); + double end_pos = (((*x) + (middle * spacing_)) < (*(last - 1))) ? ((*x) + (middle * spacing_)) : (*(last - 1)); InputPeakIterator help_x = x; InputPeakIterator help_y = y; @@ -203,7 +300,7 @@ namespace OpenMS Size left_position = (Size)floor(distance_in_gaussian / spacing_); // search for the true left adjacent data point (because of rounding errors) - for (int j = 0; ((j < 3) && (distance(first, help_x - j) >= 0)); ++j) + for (UInt j = 0; ((j < 3) && (distance(first, help_x - j) >= 0)); ++j) { if (((left_position - j) * spacing_ <= distance_in_gaussian) && ((left_position - j + 1) * spacing_ >= distance_in_gaussian)) { @@ -234,7 +331,6 @@ namespace OpenMS std::cout << "interpolated value left " << coeffs_right << std::endl; #endif - // search for the corresponding datapoint for (help-1) in the gaussian (take the left most adjacent point) distance_in_gaussian = fabs((*x) - (*(help_x - 1))); left_position = (Size)floor(distance_in_gaussian / spacing_); @@ -273,7 +369,6 @@ namespace OpenMS << std::endl; #endif - norm += fabs((*(help_x - 1)) - (*help_x)) / 2. * (coeffs_left + coeffs_right); v += fabs((*(help_x - 1)) - (*help_x)) / 2. * (*(help_y - 1) * coeffs_left + (*help_y) * coeffs_right); @@ -364,6 +459,7 @@ namespace OpenMS << "* " << coeffs_right << std::endl; #endif + norm += fabs((*help_x) - (*(help_x + 1)) ) / 2. * (coeffs_left + coeffs_right); v += fabs((*help_x) - (*(help_x + 1)) ) / 2. * ((*help_y) * coeffs_left + (*(help_y + 1)) * coeffs_right); @@ -381,6 +477,17 @@ namespace OpenMS } } + /// Coefficients + std::vector coeffs_; // Gaussian numbers for FFT + /// The standard derivation \f$ \sigma \f$. + double sigma_; + /// The spacing of the pre-tabulated kernel coefficients + double spacing_; + + // tolerance in ppm + bool use_ppm_tolerance_; + double ppm_tolerance_; + }; } // namespace OpenMS diff --git a/src/openms/include/OpenMS/FILTERING/SMOOTHING/SavitzkyGolayFilter.h b/src/openms/include/OpenMS/FILTERING/SMOOTHING/SavitzkyGolayFilter.h index 3cb4ba62571..18a292b8f88 100644 --- a/src/openms/include/OpenMS/FILTERING/SMOOTHING/SavitzkyGolayFilter.h +++ b/src/openms/include/OpenMS/FILTERING/SMOOTHING/SavitzkyGolayFilter.h @@ -112,7 +112,7 @@ namespace OpenMS // low level template to filters spectra and chromatograms // raw data and meta data needs to be copied to the output container before calling this function template - void filter(InputIt first, InputIt last, OutputIt d_first) + void filter(InputIt first, InputIt last, OutputIt d_first) const { size_t n = std::distance(first, last); @@ -198,7 +198,7 @@ namespace OpenMS /** @brief Removed the noise from an MSChromatogram */ - void filter(MSChromatogram & chromatogram) + void filter(MSChromatogram & chromatogram) const { // copy the data AND META DATA to the output container MSChromatogram output = chromatogram; diff --git a/src/openms/source/ANALYSIS/OPENSWATH/PeakPickerMRM.cpp b/src/openms/source/ANALYSIS/OPENSWATH/PeakPickerMRM.cpp index 5bf62415f76..bbad886df0f 100644 --- a/src/openms/source/ANALYSIS/OPENSWATH/PeakPickerMRM.cpp +++ b/src/openms/source/ANALYSIS/OPENSWATH/PeakPickerMRM.cpp @@ -125,6 +125,8 @@ namespace OpenMS gauss_.filter(smoothed_chrom); } + // läuft top + // Find initial seeds (peak picking) pp_.pick(smoothed_chrom, picked_chrom); OPENMS_LOG_DEBUG << "Picked " << picked_chrom.size() << " chromatographic peaks." << std::endl; @@ -165,9 +167,9 @@ namespace OpenMS picked_chrom.getFloatDataArrays()[IDX_RIGHTBORDER].reserve(picked_chrom.size()); for (Size i = 0; i < picked_chrom.size(); i++) { - picked_chrom.getFloatDataArrays()[IDX_ABUNDANCE].push_back(integrated_intensities_[i]); - picked_chrom.getFloatDataArrays()[IDX_LEFTBORDER].push_back((float)chromatogram[left_width_[i]].getRT()); - picked_chrom.getFloatDataArrays()[IDX_RIGHTBORDER].push_back((float)chromatogram[right_width_[i]].getRT()); + picked_chrom.getFloatDataArrays()[IDX_ABUNDANCE][i] = integrated_intensities_[i]; + picked_chrom.getFloatDataArrays()[IDX_LEFTBORDER][i] = (float)chromatogram[left_width_[i]].getRT(); + picked_chrom.getFloatDataArrays()[IDX_RIGHTBORDER][i] = (float)chromatogram[right_width_[i]].getRT(); } } diff --git a/src/openms/source/FILTERING/SMOOTHING/GaussFilter.cpp b/src/openms/source/FILTERING/SMOOTHING/GaussFilter.cpp index e8b45f774ce..ae4a7e7f6be 100644 --- a/src/openms/source/FILTERING/SMOOTHING/GaussFilter.cpp +++ b/src/openms/source/FILTERING/SMOOTHING/GaussFilter.cpp @@ -68,7 +68,7 @@ namespace OpenMS write_log_messages_ = param_.getValue("write_log_messages").toBool(); } - void GaussFilter::filter(MSSpectrum & spectrum) + void GaussFilter::filter(MSSpectrum & spectrum) { // make sure the right data type is set spectrum.setType(SpectrumSettings::PROFILE); @@ -115,7 +115,7 @@ namespace OpenMS } } - void GaussFilter::filter(MSChromatogram & chromatogram) + void GaussFilter::filter(MSChromatogram & chromatogram) { if (param_.getValue("use_ppm_tolerance").toBool()) { diff --git a/src/openms/source/FILTERING/SMOOTHING/GaussFilterAlgorithm.cpp b/src/openms/source/FILTERING/SMOOTHING/GaussFilterAlgorithm.cpp index 9f35a10f914..d7bdc3c72c1 100644 --- a/src/openms/source/FILTERING/SMOOTHING/GaussFilterAlgorithm.cpp +++ b/src/openms/source/FILTERING/SMOOTHING/GaussFilterAlgorithm.cpp @@ -33,6 +33,7 @@ // -------------------------------------------------------------------------- #include +#include namespace OpenMS { @@ -61,8 +62,9 @@ namespace OpenMS for (Size i = 1; i < number_of_points_right; i++) { - coeffs_[i] = 1.0 / (sigma_ * sqrt(2.0 * Constants::PI)) * exp(-((i * spacing_) * (i * spacing_)) / (2 * sigma_ * sigma_)); + coeffs_[i] = (1.0 / (sigma_ * sqrt(2.0 * Constants::PI))) * exp(-((i * spacing_) * (i * spacing_)) / (2 * sigma_ * sigma_)); } + #ifdef DEBUG_FILTERING std::cout << "Coeffs: " << std::endl; for (Size i = 0; i < number_of_points_right; i++) @@ -70,7 +72,13 @@ namespace OpenMS std::cout << i * spacing_ << ' ' << coeffs_[i] << std::endl; } #endif - + if(!use_ppm_tolerance) + { + std::vector temp = coeffs_; + std::reverse(coeffs_.begin(), coeffs_.end()); + coeffs_.insert(coeffs_.end(), temp.begin(), temp.end()); + // member? + } } } diff --git a/src/openms/source/TRANSFORMATIONS/FEATUREFINDER/FeatureFinderAlgorithmMetaboIdent.cpp b/src/openms/source/TRANSFORMATIONS/FEATUREFINDER/FeatureFinderAlgorithmMetaboIdent.cpp index 9e4cfa66160..999896e0f45 100644 --- a/src/openms/source/TRANSFORMATIONS/FEATUREFINDER/FeatureFinderAlgorithmMetaboIdent.cpp +++ b/src/openms/source/TRANSFORMATIONS/FEATUREFINDER/FeatureFinderAlgorithmMetaboIdent.cpp @@ -315,7 +315,10 @@ namespace OpenMS double best_MZ = cluster_representative.getMZ(); double overlap_MZ = overlap.getMZ(); - // are the features the same? (@TODO: use "Math::approximatelyEqual"?) + // are the features the same? (@TODO: use "OpenMS::Math::approximatelyEqual(overlap_MZ, best_MZ, tol?)"?) + //"OpenMS::Math::approximatelyEqual(overlap_RT, best_RT, tol?)" + // if (OpenMS::Math::approximatelyEqual(overlap_MZ, best_MZ, tol?) && OpenMS::Math::approximatelyEqual(overlap_RT, best_RT, tol?)) + // tol = |best_MZ - observed_MZ| oder |theoretical_MZ - observed_MZ| if ((overlap_MZ == best_MZ) && (overlap_RT == best_RT)) { // update annotations: @@ -388,7 +391,7 @@ namespace OpenMS /// Add a target (from the input file) to the assay library void FeatureFinderAlgorithmMetaboIdent::addTargetToLibrary_(const String& name, const String& formula, double mass, const vector& charges, - const vector& rts, + const vector& rts, // retention times vector rt_ranges, const vector& iso_distrib) { @@ -405,6 +408,14 @@ namespace OpenMS return; } // @TODO: detect entries with same RT and m/z ("collisions") + /* + if () + { + OPENMS_LOG_ERROR << "Error: Collision. Already found an entry with the same RT and m/z '" + << name << "' - skipping this target." << endl; + return; + } + */ TargetedExperiment::Compound target; target.setMetaValue("name", name); target.molecular_formula = formula; @@ -424,9 +435,11 @@ namespace OpenMS { if (formula.empty()) { - OPENMS_LOG_ERROR << "Error: No sum formula given for target '" << name + /* + OPENMS_LOG_ERROR << "Warning: No sum formula given for target '" << name << "'; cannot calculate isotope distribution" << " - using estimation method for peptides." << endl; + */ iso_dist = iso_gen_.estimateFromPeptideWeight(mass); } else @@ -513,6 +526,7 @@ namespace OpenMS { // go through different isotopes: Size counter = 0; + //vector mass = iso_dist.MassAbundance(); for (const Peak1D& iso : iso_dist) { ReactionMonitoringTransition transition; @@ -524,6 +538,7 @@ namespace OpenMS // @TODO: use accurate masses from the isotope distribution here? transition.setProductMZ(mz + abs(Constants::C13C12_MASSDIFF_U * float(counter) / charge)); + //(mass * charge)? where counter? transition.setLibraryIntensity(iso.getIntensity()); // transition.setMetaValue("annotation", annotation); // ??? transition.setCompoundRef(target_id); diff --git a/src/openms/source/TRANSFORMATIONS/RAW2PEAK/PeakPickerHiRes.cpp b/src/openms/source/TRANSFORMATIONS/RAW2PEAK/PeakPickerHiRes.cpp index c8a91ab25bb..adef836a259 100644 --- a/src/openms/source/TRANSFORMATIONS/RAW2PEAK/PeakPickerHiRes.cpp +++ b/src/openms/source/TRANSFORMATIONS/RAW2PEAK/PeakPickerHiRes.cpp @@ -216,7 +216,7 @@ namespace OpenMS // special case: if a peak core is surrounded by more intense // satellite peaks (indicates oscillation rather than // real peaks) -> remove - + std::cout << "peak core searching..." << std::endl; double act_snt_l2 = 0.0, act_snt_r2 = 0.0; if (signal_to_noise_ > 0.0) @@ -298,7 +298,6 @@ namespace OpenMS left_boundary = i - k; ++k; } - // to the right k = 2; diff --git a/src/openms/thirdparty/evergreen/src/Convolution/fft_convolve.hpp b/src/openms/thirdparty/evergreen/src/Convolution/fft_convolve.hpp index 4ae0fe4a068..2ee4da7b0a8 100644 --- a/src/openms/thirdparty/evergreen/src/Convolution/fft_convolve.hpp +++ b/src/openms/thirdparty/evergreen/src/Convolution/fft_convolve.hpp @@ -76,7 +76,6 @@ inline Tensor fft_convolve_already_padded_rvalue(Tensor && lhs_p Tensor lhs_padded = Tensor::create_reinterpreted(std::move(lhs_padded_doubles)); Tensor rhs_padded = Tensor::create_reinterpreted(std::move(rhs_padded_doubles)); - apply_real_fft_packed(lhs_padded); apply_real_fft_packed(rhs_padded); @@ -90,7 +89,6 @@ inline Tensor fft_convolve_already_padded_rvalue(Tensor && lhs_p // Unpack: Tensor result = Tensor::create_reinterpreted(std::move(lhs_padded)); - result.shrink(result_shape); return result; } diff --git a/src/openms/thirdparty/evergreen/src/Tensor/Tensor.hpp b/src/openms/thirdparty/evergreen/src/Tensor/Tensor.hpp index 54e28d8aecd..38107cc3ecb 100644 --- a/src/openms/thirdparty/evergreen/src/Tensor/Tensor.hpp +++ b/src/openms/thirdparty/evergreen/src/Tensor/Tensor.hpp @@ -213,7 +213,7 @@ class Tensor : public WritableTensorLike { const Vector & data_shape() const { return _data_shape; } - const Vector & view_shape() const { + const Vector & view_shape() const { return data_shape(); } unsigned long flat_size() const { diff --git a/src/topp/NoiseFilterGaussian.cpp b/src/topp/NoiseFilterGaussian.cpp index debe74cf57c..4606e6a6c2d 100644 --- a/src/topp/NoiseFilterGaussian.cpp +++ b/src/topp/NoiseFilterGaussian.cpp @@ -116,11 +116,13 @@ class TOPPNoiseFilterGaussian : void processSpectrum_(MapType::SpectrumType& s) override { + std::cout << "spectrum filter" << std::endl; gf_.filter(s); } void processChromatogram_(MapType::ChromatogramType& c) override { + std::cout << "chromatogram filter" << std::endl; gf_.filter(c); }