Home  · Classes  · Annotated Classes  · Modules  · Members  · Namespaces  · Related Pages

GaussFilter.h (Maintainer: Eva Lange)

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // --------------------------------------------------------------------------
00005 //                   OpenMS Mass Spectrometry Framework
00006 // --------------------------------------------------------------------------
00007 //  Copyright (C) 2003-2008 -- Oliver Kohlbacher, Knut Reinert
00008 //
00009 //  This library is free software; you can redistribute it and/or
00010 //  modify it under the terms of the GNU Lesser General Public
00011 //  License as published by the Free Software Foundation; either
00012 //  version 2.1 of the License, or (at your option) any later version.
00013 //
00014 //  This library is distributed in the hope that it will be useful,
00015 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 //  Lesser General Public License for more details.
00018 //
00019 //  You should have received a copy of the GNU Lesser General Public
00020 //  License along with this library; if not, write to the Free Software
00021 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 // --------------------------------------------------------------------------
00024 // $Maintainer: Eva Lange  $
00025 // --------------------------------------------------------------------------
00026 
00027 #ifndef OPENMS_FILTERING_SMOOTHING_GAUSSFILTER_H
00028 #define OPENMS_FILTERING_SMOOTHING_GAUSSFILTER_H
00029 
00030 #include <OpenMS/FILTERING/SMOOTHING/SmoothFilter.h>
00031 #include <OpenMS/DATASTRUCTURES/DefaultParamHandler.h>
00032 
00033 
00034 #include <math.h>
00035 
00036 namespace OpenMS
00037 {
00059 //#define DEBUG_FILTERING
00060 
00061   class GaussFilter : public SmoothFilter, public DefaultParamHandler
00062   {
00063     public:
00064       using SmoothFilter::coeffs_;
00065 
00067       inline GaussFilter()
00068       : SmoothFilter(),
00069         DefaultParamHandler("GaussFilter"),
00070         sigma_(0.1),
00071         spacing_(0.01)
00072       {
00073         //Parameter settings
00074         defaults_.setValue("gaussian_width",0.2,"Use a gaussian filter kernel which has approximately the same width as your mass peaks.\n"
00075                                                 "This width corresponds to 8 times sigma of the gaussian.");
00076         defaultsToParam_();
00077       }
00078 
00080       virtual ~GaussFilter()
00081       {
00082       }
00083 
00096       template <typename InputPeakIterator, typename OutputPeakContainer  >
00097       void filter(InputPeakIterator first, InputPeakIterator last, OutputPeakContainer& smoothed_data_container)
00098       {
00099         smoothed_data_container.resize(distance(first,last));
00100 
00101 #ifdef DEBUG_FILTERING
00102         std::cout << "KernelWidth: " << 8*sigma_ << std::endl;
00103         std::cout << "Spacing: " << spacing_ << std::endl;
00104 #endif
00105 
00106         InputPeakIterator help = first;
00107         typename OutputPeakContainer::iterator out_it = smoothed_data_container.begin();
00108         while (help != last)
00109         {
00110           out_it->setPosition(help->getMZ());
00111           out_it->setIntensity(integrate_(help,first,last));
00112           ++out_it;
00113           ++help;
00114         }
00115       }
00116 
00117 
00130       template <typename InputPeakContainer, typename OutputPeakContainer >
00131       void filter(const InputPeakContainer& input_peak_container, OutputPeakContainer& smoothed_data_container)
00132       {
00133         // copy the spectrum settings
00134         static_cast<SpectrumSettings&>(smoothed_data_container) = input_peak_container;
00135         
00136         filter(input_peak_container.begin(), input_peak_container.end(), smoothed_data_container);
00137       }
00138 
00139 
00151       template <typename InputSpectrumIterator, typename OutputPeakType >
00152       void filterExperiment(InputSpectrumIterator first, InputSpectrumIterator last, MSExperiment<OutputPeakType>& ms_exp_filtered)
00153       {
00154         UInt n = distance(first,last);
00155         ms_exp_filtered.reserve(n);
00156         startProgress(0,n,"smoothing data");
00157         
00158         // pick peaks on each scan
00159         for (UInt i = 0; i < n; ++i)
00160         {
00161           MSSpectrum< OutputPeakType > spectrum;
00162           InputSpectrumIterator input_it = first+i;
00163           
00164           // filter scan i
00165           filter(*input_it,spectrum);
00166           setProgress(i);
00167           
00168           // copy the spectrum settings
00169           static_cast<SpectrumSettings&>(spectrum) = *input_it;
00170           spectrum.setType(SpectrumSettings::RAWDATA);
00171 
00172           // copy the spectrum information
00173           spectrum.getPrecursorPeak() = input_it->getPrecursorPeak();
00174           spectrum.setRT(input_it->getRT());
00175           spectrum.setMSLevel(input_it->getMSLevel());
00176           spectrum.getName() = input_it->getName();
00177 
00178           ms_exp_filtered.push_back(spectrum);
00179         }
00180         endProgress();
00181       }
00182 
00192       template <typename InputPeakType, typename OutputPeakType >
00193       void filterExperiment(const MSExperiment< InputPeakType >& ms_exp_raw, MSExperiment<OutputPeakType>& ms_exp_filtered)
00194       {
00195         // copy the experimental settings
00196         static_cast<ExperimentalSettings&>(ms_exp_filtered) = ms_exp_raw;
00197 
00198         filterExperiment(ms_exp_raw.begin(), ms_exp_raw.end(), ms_exp_filtered);
00199       }
00200 
00201     protected:
00203       DoubleReal sigma_;
00205       DoubleReal spacing_;
00206       
00207       // Docu in base class
00208       virtual void updateMembers_() 
00209       {
00210         sigma_ = (DoubleReal)param_.getValue("gaussian_width") / 8.;
00211         int number_of_points_right = (int)(ceil(4*sigma_ / spacing_))+1;
00212         coeffs_.resize(number_of_points_right);
00213         coeffs_[0] = 1.0/(sigma_ * sqrt(2.0 * M_PI));
00214     
00215         for (int i=1; i < number_of_points_right; i++)
00216         {
00217           coeffs_[i] = 1.0/(sigma_ * sqrt(2.0 * M_PI)) * exp(-((i*spacing_)*(i*spacing_)) / (2 * sigma_ * sigma_));
00218         }
00219 #ifdef DEBUG_FILTERING
00220         std::cout << "Coeffs: " << std::endl;
00221         for (int i=0; i < number_of_points_right; i++)
00222         {
00223             std::cout << i*spacing_ << ' ' << coeffs_[i] << std::endl;
00224         }
00225 #endif
00226       }
00227 
00229       template < typename InputPeakIterator >
00230       DoubleReal integrate_(InputPeakIterator x, InputPeakIterator first, InputPeakIterator last)
00231       {
00232         DoubleReal v = 0.;
00233         // norm the gaussian kernel area to one
00234         DoubleReal norm = 0.;
00235         int middle = coeffs_.size();
00236 
00237         DoubleReal start_pos = ((x->getMZ()-(middle*spacing_)) > first->getMZ()) ? (x->getMZ()-(middle*spacing_))
00238                            : first->getMZ();
00239         DoubleReal end_pos = ((x->getMZ()+(middle*spacing_)) < (last-1)->getMZ()) ? (x->getMZ()+(middle*spacing_))
00240                          : (last-1)->getMZ();
00241 
00242 
00243         InputPeakIterator help = x;
00244 #ifdef DEBUG_FILTERING
00245 
00246         std::cout << "integrate from middle to start_pos "<< help->getMZ() << " until " << start_pos << std::endl;
00247 #endif
00248 
00249         //integrate from middle to start_pos
00250         while ((help != first) && ((help-1)->getMZ() > start_pos))
00251         {
00252           // search for the corresponding datapoint of help in the gaussian (take the left most adjacent point)
00253           DoubleReal distance_in_gaussian = fabs(x->getMZ() - help->getMZ());
00254           UInt left_position = (UInt)floor(distance_in_gaussian / spacing_);
00255 
00256           // search for the true left adjacent data point (because of rounding errors)
00257           for (int j=0; ((j<3) &&  (distance(first,help-j) >= 0)); ++j)
00258           {
00259             if (((left_position-j)*spacing_ <= distance_in_gaussian) && ((left_position-j+1)*spacing_ >= distance_in_gaussian))
00260             {
00261               left_position -= j;
00262               break;
00263             }
00264 
00265             if (((left_position+j)*spacing_ < distance_in_gaussian) && ((left_position+j+1)*spacing_ < distance_in_gaussian))
00266             {
00267               left_position +=j;
00268               break;
00269             }
00270           }
00271 
00272           // interpolate between the left and right data points in the gaussian to get the true value at position distance_in_gaussian
00273           int right_position = left_position+1;
00274           DoubleReal d = fabs((left_position*spacing_)-distance_in_gaussian) / spacing_;
00275           // check if the right data point in the gaussian exists
00276           DoubleReal coeffs_right = (right_position < middle) ? (1-d)*coeffs_[left_position]+d*coeffs_[right_position]
00277                                 : coeffs_[left_position];
00278 #ifdef DEBUG_FILTERING
00279 
00280           std::cout << "distance_in_gaussian " << distance_in_gaussian << std::endl;
00281           std::cout << " right_position " << right_position << std::endl;
00282           std::cout << " left_position " << left_position << std::endl;
00283           std::cout << "coeffs_ at left_position "  <<  coeffs_[left_position] << std::endl;
00284           std::cout << "coeffs_ at right_position "  <<  coeffs_[right_position] << std::endl;
00285           std::cout << "interpolated value left " << coeffs_right << std::endl;
00286 #endif
00287 
00288 
00289           // search for the corresponding datapoint for (help-1) in the gaussian (take the left most adjacent point)
00290           distance_in_gaussian = fabs(x->getMZ() - (help-1)->getMZ());
00291           left_position = (UInt)floor(distance_in_gaussian / spacing_);
00292 
00293           // search for the true left adjacent data point (because of rounding errors)
00294           for (int j=0; ((j<3) && (distance(first,help-j) >= 0)); ++j)
00295           {
00296             if (((left_position-j)*spacing_ <= distance_in_gaussian) && ((left_position-j+1)*spacing_ >= distance_in_gaussian))
00297             {
00298               left_position -= j;
00299               break;
00300             }
00301 
00302             if (((left_position+j)*spacing_ < distance_in_gaussian) && ((left_position+j+1)*spacing_ < distance_in_gaussian))
00303             {
00304               left_position +=j;
00305               break;
00306             }
00307           }
00308 
00309           // start the interpolation for the true value in the gaussian
00310           right_position = left_position+1;
00311           d = fabs((left_position*spacing_)-distance_in_gaussian) / spacing_;
00312           DoubleReal coeffs_left= (right_position < middle) ? (1-d)*coeffs_[left_position]+d*coeffs_[right_position]
00313                               : coeffs_[left_position];
00314 #ifdef DEBUG_FILTERING
00315 
00316           std::cout << " help-1 " << (help-1)->getMZ() << " distance_in_gaussian " << distance_in_gaussian << std::endl;
00317           std::cout << " right_position " << right_position << std::endl;
00318           std::cout << " left_position " << left_position << std::endl;
00319           std::cout << "coeffs_ at left_position " <<  coeffs_[left_position]<<std::endl;
00320           std::cout << "coeffs_ at right_position " <<   coeffs_[right_position]<<std::endl;
00321           std::cout << "interpolated value right " << coeffs_left << std::endl;
00322 
00323           std::cout << " intensity " << fabs((help-1)->getMZ()-help->getMZ()) / 2. << " * " << (help-1)->getIntensity() << " * " << coeffs_left <<" + " << (help)->getIntensity()<< "* " << coeffs_right
00324           << std::endl;
00325 #endif
00326 
00327 
00328           norm += fabs((help-1)->getMZ()-help->getMZ()) / 2. * (coeffs_left + coeffs_right);
00329 
00330           v+= fabs((help-1)->getMZ()-help->getMZ()) / 2. * ((help-1)->getIntensity()*coeffs_left + help->getIntensity()*coeffs_right);
00331           --help;
00332         }
00333 
00334 
00335         //integrate from middle to end_pos
00336         help = x;
00337 #ifdef DEBUG_FILTERING
00338 
00339         std::cout << "integrate from middle to endpos "<< (help)->getMZ() << " until " << end_pos << std::endl;
00340 #endif
00341 
00342         while ((help != (last-1)) && ((help+1)->getMZ() < end_pos))
00343         {
00344           // search for the corresponding datapoint for help in the gaussian (take the left most adjacent point)
00345           DoubleReal distance_in_gaussian = fabs(x->getMZ() - help->getMZ());
00346           int left_position = (UInt)floor(distance_in_gaussian / spacing_);
00347 
00348           // search for the true left adjacent data point (because of rounding errors)
00349           for (int j=0; ((j<3) && (distance(help+j,last-1) >= 0)); ++j)
00350           {
00351             if (((left_position-j)*spacing_ <= distance_in_gaussian) && ((left_position-j+1)*spacing_ >= distance_in_gaussian))
00352             {
00353               left_position -= j;
00354               break;
00355             }
00356 
00357             if (((left_position+j)*spacing_ < distance_in_gaussian) && ((left_position+j+1)*spacing_ < distance_in_gaussian))
00358             {
00359               left_position +=j;
00360               break;
00361             }
00362           }
00363           // start the interpolation for the true value in the gaussian
00364           int right_position = left_position+1;
00365           DoubleReal d = fabs((left_position*spacing_)-distance_in_gaussian) / spacing_;
00366           DoubleReal coeffs_left= (right_position < middle) ? (1-d)*coeffs_[left_position]+d*coeffs_[right_position]
00367                               : coeffs_[left_position];
00368 
00369 #ifdef DEBUG_FILTERING
00370 
00371           std::cout << " help " << (help)->getMZ() << " distance_in_gaussian " << distance_in_gaussian << std::endl;
00372           std::cout << " left_position " << left_position << std::endl;
00373           std::cout << "coeffs_ at right_position " <<  coeffs_[left_position]<<std::endl;
00374           std::cout << "coeffs_ at left_position " <<  coeffs_[right_position]<<std::endl;
00375           std::cout << "interpolated value left " << coeffs_left << std::endl;
00376 #endif
00377 
00378           // search for the corresponding datapoint for (help+1) in the gaussian (take the left most adjacent point)
00379           distance_in_gaussian = fabs(x->getMZ() - (help+1)->getMZ());
00380           left_position = (UInt)floor(distance_in_gaussian / spacing_);
00381 
00382           // search for the true left adjacent data point (because of rounding errors)
00383           for (int j=0; ((j<3) && (distance(help+j,last-1) >= 0)); ++j)
00384           {
00385             if (((left_position-j)*spacing_ <= distance_in_gaussian) && ((left_position-j+1)*spacing_ >= distance_in_gaussian))
00386             {
00387               left_position -= j;
00388               break;
00389             }
00390 
00391             if (((left_position+j)*spacing_ < distance_in_gaussian) && ((left_position+j+1)*spacing_ < distance_in_gaussian))
00392             {
00393               left_position +=j;
00394               break;
00395             }
00396           }
00397 
00398           // start the interpolation for the true value in the gaussian
00399           right_position = left_position+1;
00400           d = fabs((left_position*spacing_)-distance_in_gaussian) / spacing_;
00401           DoubleReal coeffs_right = (right_position < middle) ? (1-d)*coeffs_[left_position]+d*coeffs_[right_position]
00402                                 : coeffs_[left_position];
00403 #ifdef DEBUG_FILTERING
00404 
00405           std::cout << " (help + 1) " << (help+1)->getMZ() << " distance_in_gaussian " << distance_in_gaussian << std::endl;
00406           std::cout << " left_position " << left_position << std::endl;
00407           std::cout << "coeffs_ at right_position " <<   coeffs_[left_position]<<std::endl;
00408           std::cout << "coeffs_ at left_position " <<  coeffs_[right_position]<<std::endl;
00409           std::cout << "interpolated value right " << coeffs_right << std::endl;
00410 
00411           std::cout << " intensity " <<  fabs(help->getMZ() - (help+1)->getMZ()) / 2.
00412           << " * " << help->getIntensity() << " * " << coeffs_left <<" + " << (help+1)->getIntensity()
00413           << "* " << coeffs_right
00414           << std::endl;
00415 #endif
00416           norm += fabs(help->getMZ() - (help+1)->getMZ()) / 2. * (coeffs_left + coeffs_right);
00417 
00418           v+= fabs(help->getMZ() - (help+1)->getMZ()) / 2. * (help->getIntensity()*coeffs_left + (help+1)->getIntensity()*coeffs_right);
00419           ++help;
00420         }
00421 
00422         if (v > 0)
00423         {
00424           return v / norm;
00425         }
00426         else
00427         {
00428           return 0;
00429         }
00430       }
00431   };
00432 
00433 } // namespace OpenMS
00434 #endif

Generated Tue Apr 1 15:36:34 2008 -- using doxygen 1.5.4 OpenMS / TOPP 1.1