Go to the documentation of this file.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
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef OPENMS_FILTERING_SMOOTHING_GAUSSFILTER_H
00036 #define OPENMS_FILTERING_SMOOTHING_GAUSSFILTER_H
00037
00038 #include <OpenMS/DATASTRUCTURES/DefaultParamHandler.h>
00039 #include <OpenMS/CONCEPT/ProgressLogger.h>
00040 #include <OpenMS/CONCEPT/Constants.h>
00041 #include <OpenMS/KERNEL/MSExperiment.h>
00042
00043 #include <cmath>
00044
00045 namespace OpenMS
00046 {
00070
00071
00072 class OPENMS_DLLAPI GaussFilter :
00073 public ProgressLogger,
00074 public DefaultParamHandler
00075 {
00076 public:
00078 GaussFilter();
00079
00081 virtual ~GaussFilter();
00082
00090 template <typename PeakType>
00091 void filter(MSSpectrum<PeakType> & spectrum)
00092 {
00093
00094 spectrum.setType(SpectrumSettings::RAWDATA);
00095
00096 std::vector<DoubleReal> output(spectrum.size());
00097
00098 bool use_ppm_tolerance(param_.getValue("use_ppm_tolerance").toBool());
00099 DoubleReal ppm_tolerance((DoubleReal)param_.getValue("ppm_tolerance"));
00100
00101 bool found_signal = false;
00102 for (Size p = 0; p < spectrum.size(); ++p)
00103 {
00104
00105 if (use_ppm_tolerance)
00106 {
00107 param_.setValue("gaussian_width", spectrum[p].getMZ() * ppm_tolerance * 10e-6);
00108 updateMembers_();
00109 }
00110
00111 DoubleReal new_int = integrate_(spectrum.begin() + p, spectrum.begin(), spectrum.end());
00112 output[p] = std::max(new_int, 0.0);
00113 if (fabs(new_int) > 0) found_signal = true;
00114 }
00115
00116
00117
00118 if (!found_signal && spectrum.size() >= 3)
00119 {
00120 String error_message = "Found no signal. The gaussian width is probably smaller than the spacing in your profile data. Try to use a bigger width.";
00121 if (spectrum.getRT() > 0.0)
00122 {
00123 error_message += String(" The error occured in the spectrum with retention time ") + spectrum.getRT() + ".\n";
00124 }
00125 std::cerr << error_message;
00126 }
00127 else
00128 {
00129
00130 for (Size p = 0; p < spectrum.size(); ++p)
00131 {
00132 spectrum[p].setIntensity(output[p]);
00133 }
00134 }
00135 }
00136
00142 template <typename PeakType>
00143 void filterExperiment(MSExperiment<PeakType> & map)
00144 {
00145 startProgress(0, map.size(), "smoothing data");
00146 for (Size i = 0; i < map.size(); ++i)
00147 {
00148 filter(map[i]);
00149 setProgress(i);
00150 }
00151 endProgress();
00152 }
00153
00154 protected:
00155
00157 std::vector<DoubleReal> coeffs_;
00159 DoubleReal sigma_;
00161 DoubleReal spacing_;
00162
00163
00164 virtual void updateMembers_();
00165
00167 template <typename InputPeakIterator>
00168 DoubleReal integrate_(InputPeakIterator x, InputPeakIterator first, InputPeakIterator last)
00169 {
00170 DoubleReal v = 0.;
00171
00172 DoubleReal norm = 0.;
00173 Size middle = coeffs_.size();
00174
00175 DoubleReal start_pos = ((x->getMZ() - (middle * spacing_)) > first->getMZ()) ? (x->getMZ() - (middle * spacing_))
00176 : first->getMZ();
00177 DoubleReal end_pos = ((x->getMZ() + (middle * spacing_)) < (last - 1)->getMZ()) ? (x->getMZ() + (middle * spacing_))
00178 : (last - 1)->getMZ();
00179
00180
00181 InputPeakIterator help = x;
00182 #ifdef DEBUG_FILTERING
00183
00184 std::cout << "integrate from middle to start_pos " << help->getMZ() << " until " << start_pos << std::endl;
00185 #endif
00186
00187
00188 while ((help != first) && ((help - 1)->getMZ() > start_pos))
00189 {
00190
00191 DoubleReal distance_in_gaussian = fabs(x->getMZ() - help->getMZ());
00192 Size left_position = (Size)floor(distance_in_gaussian / spacing_);
00193
00194
00195 for (int j = 0; ((j < 3) && (distance(first, help - j) >= 0)); ++j)
00196 {
00197 if (((left_position - j) * spacing_ <= distance_in_gaussian) && ((left_position - j + 1) * spacing_ >= distance_in_gaussian))
00198 {
00199 left_position -= j;
00200 break;
00201 }
00202
00203 if (((left_position + j) * spacing_ < distance_in_gaussian) && ((left_position + j + 1) * spacing_ < distance_in_gaussian))
00204 {
00205 left_position += j;
00206 break;
00207 }
00208 }
00209
00210
00211 Size right_position = left_position + 1;
00212 DoubleReal d = fabs((left_position * spacing_) - distance_in_gaussian) / spacing_;
00213
00214 DoubleReal coeffs_right = (right_position < middle) ? (1 - d) * coeffs_[left_position] + d * coeffs_[right_position]
00215 : coeffs_[left_position];
00216 #ifdef DEBUG_FILTERING
00217
00218 std::cout << "distance_in_gaussian " << distance_in_gaussian << std::endl;
00219 std::cout << " right_position " << right_position << std::endl;
00220 std::cout << " left_position " << left_position << std::endl;
00221 std::cout << "coeffs_ at left_position " << coeffs_[left_position] << std::endl;
00222 std::cout << "coeffs_ at right_position " << coeffs_[right_position] << std::endl;
00223 std::cout << "interpolated value left " << coeffs_right << std::endl;
00224 #endif
00225
00226
00227
00228 distance_in_gaussian = fabs(x->getMZ() - (help - 1)->getMZ());
00229 left_position = (Size)floor(distance_in_gaussian / spacing_);
00230
00231
00232 for (UInt j = 0; ((j < 3) && (distance(first, help - j) >= 0)); ++j)
00233 {
00234 if (((left_position - j) * spacing_ <= distance_in_gaussian) && ((left_position - j + 1) * spacing_ >= distance_in_gaussian))
00235 {
00236 left_position -= j;
00237 break;
00238 }
00239
00240 if (((left_position + j) * spacing_ < distance_in_gaussian) && ((left_position + j + 1) * spacing_ < distance_in_gaussian))
00241 {
00242 left_position += j;
00243 break;
00244 }
00245 }
00246
00247
00248 right_position = left_position + 1;
00249 d = fabs((left_position * spacing_) - distance_in_gaussian) / spacing_;
00250 DoubleReal coeffs_left = (right_position < middle) ? (1 - d) * coeffs_[left_position] + d * coeffs_[right_position]
00251 : coeffs_[left_position];
00252 #ifdef DEBUG_FILTERING
00253
00254 std::cout << " help-1 " << (help - 1)->getMZ() << " distance_in_gaussian " << distance_in_gaussian << std::endl;
00255 std::cout << " right_position " << right_position << std::endl;
00256 std::cout << " left_position " << left_position << std::endl;
00257 std::cout << "coeffs_ at left_position " << coeffs_[left_position] << std::endl;
00258 std::cout << "coeffs_ at right_position " << coeffs_[right_position] << std::endl;
00259 std::cout << "interpolated value right " << coeffs_left << std::endl;
00260
00261 std::cout << " intensity " << fabs((help - 1)->getMZ() - help->getMZ()) / 2. << " * " << (help - 1)->getIntensity() << " * " << coeffs_left << " + " << (help)->getIntensity() << "* " << coeffs_right
00262 << std::endl;
00263 #endif
00264
00265
00266 norm += fabs((help - 1)->getMZ() - help->getMZ()) / 2. * (coeffs_left + coeffs_right);
00267
00268 v += fabs((help - 1)->getMZ() - help->getMZ()) / 2. * ((help - 1)->getIntensity() * coeffs_left + help->getIntensity() * coeffs_right);
00269 --help;
00270 }
00271
00272
00273
00274 help = x;
00275 #ifdef DEBUG_FILTERING
00276
00277 std::cout << "integrate from middle to endpos " << (help)->getMZ() << " until " << end_pos << std::endl;
00278 #endif
00279
00280 while ((help != (last - 1)) && ((help + 1)->getMZ() < end_pos))
00281 {
00282
00283 DoubleReal distance_in_gaussian = fabs(x->getMZ() - help->getMZ());
00284 int left_position = (UInt)floor(distance_in_gaussian / spacing_);
00285
00286
00287 for (int j = 0; ((j < 3) && (distance(help + j, last - 1) >= 0)); ++j)
00288 {
00289 if (((left_position - j) * spacing_ <= distance_in_gaussian) && ((left_position - j + 1) * spacing_ >= distance_in_gaussian))
00290 {
00291 left_position -= j;
00292 break;
00293 }
00294
00295 if (((left_position + j) * spacing_ < distance_in_gaussian) && ((left_position + j + 1) * spacing_ < distance_in_gaussian))
00296 {
00297 left_position += j;
00298 break;
00299 }
00300 }
00301
00302 Size right_position = left_position + 1;
00303 DoubleReal d = fabs((left_position * spacing_) - distance_in_gaussian) / spacing_;
00304 DoubleReal coeffs_left = (right_position < middle) ? (1 - d) * coeffs_[left_position] + d * coeffs_[right_position]
00305 : coeffs_[left_position];
00306
00307 #ifdef DEBUG_FILTERING
00308
00309 std::cout << " help " << (help)->getMZ() << " distance_in_gaussian " << distance_in_gaussian << std::endl;
00310 std::cout << " left_position " << left_position << std::endl;
00311 std::cout << "coeffs_ at right_position " << coeffs_[left_position] << std::endl;
00312 std::cout << "coeffs_ at left_position " << coeffs_[right_position] << std::endl;
00313 std::cout << "interpolated value left " << coeffs_left << std::endl;
00314 #endif
00315
00316
00317 distance_in_gaussian = fabs(x->getMZ() - (help + 1)->getMZ());
00318 left_position = (UInt)floor(distance_in_gaussian / spacing_);
00319
00320
00321 for (int j = 0; ((j < 3) && (distance(help + j, last - 1) >= 0)); ++j)
00322 {
00323 if (((left_position - j) * spacing_ <= distance_in_gaussian) && ((left_position - j + 1) * spacing_ >= distance_in_gaussian))
00324 {
00325 left_position -= j;
00326 break;
00327 }
00328
00329 if (((left_position + j) * spacing_ < distance_in_gaussian) && ((left_position + j + 1) * spacing_ < distance_in_gaussian))
00330 {
00331 left_position += j;
00332 break;
00333 }
00334 }
00335
00336
00337 right_position = left_position + 1;
00338 d = fabs((left_position * spacing_) - distance_in_gaussian) / spacing_;
00339 DoubleReal coeffs_right = (right_position < middle) ? (1 - d) * coeffs_[left_position] + d * coeffs_[right_position]
00340 : coeffs_[left_position];
00341 #ifdef DEBUG_FILTERING
00342
00343 std::cout << " (help + 1) " << (help + 1)->getMZ() << " distance_in_gaussian " << distance_in_gaussian << std::endl;
00344 std::cout << " left_position " << left_position << std::endl;
00345 std::cout << "coeffs_ at right_position " << coeffs_[left_position] << std::endl;
00346 std::cout << "coeffs_ at left_position " << coeffs_[right_position] << std::endl;
00347 std::cout << "interpolated value right " << coeffs_right << std::endl;
00348
00349 std::cout << " intensity " << fabs(help->getMZ() - (help + 1)->getMZ()) / 2.
00350 << " * " << help->getIntensity() << " * " << coeffs_left << " + " << (help + 1)->getIntensity()
00351 << "* " << coeffs_right
00352 << std::endl;
00353 #endif
00354 norm += fabs(help->getMZ() - (help + 1)->getMZ()) / 2. * (coeffs_left + coeffs_right);
00355
00356 v += fabs(help->getMZ() - (help + 1)->getMZ()) / 2. * (help->getIntensity() * coeffs_left + (help + 1)->getIntensity() * coeffs_right);
00357 ++help;
00358 }
00359
00360 if (v > 0)
00361 {
00362 return v / norm;
00363 }
00364 else
00365 {
00366 return 0;
00367 }
00368 }
00369
00370 };
00371
00372 }
00373 #endif