00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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
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
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
00159 for (UInt i = 0; i < n; ++i)
00160 {
00161 MSSpectrum< OutputPeakType > spectrum;
00162 InputSpectrumIterator input_it = first+i;
00163
00164
00165 filter(*input_it,spectrum);
00166 setProgress(i);
00167
00168
00169 static_cast<SpectrumSettings&>(spectrum) = *input_it;
00170 spectrum.setType(SpectrumSettings::RAWDATA);
00171
00172
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
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
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
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
00250 while ((help != first) && ((help-1)->getMZ() > start_pos))
00251 {
00252
00253 DoubleReal distance_in_gaussian = fabs(x->getMZ() - help->getMZ());
00254 UInt left_position = (UInt)floor(distance_in_gaussian / spacing_);
00255
00256
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
00273 int right_position = left_position+1;
00274 DoubleReal d = fabs((left_position*spacing_)-distance_in_gaussian) / spacing_;
00275
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
00290 distance_in_gaussian = fabs(x->getMZ() - (help-1)->getMZ());
00291 left_position = (UInt)floor(distance_in_gaussian / spacing_);
00292
00293
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
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
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
00345 DoubleReal distance_in_gaussian = fabs(x->getMZ() - help->getMZ());
00346 int left_position = (UInt)floor(distance_in_gaussian / spacing_);
00347
00348
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
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
00379 distance_in_gaussian = fabs(x->getMZ() - (help+1)->getMZ());
00380 left_position = (UInt)floor(distance_in_gaussian / spacing_);
00381
00382
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
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 }
00434 #endif