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_BASELINE_MORPHFILTER_H
00028 #define OPENMS_FILTERING_BASELINE_MORPHFILTER_H
00029
00030 #include <OpenMS/DATASTRUCTURES/DefaultParamHandler.h>
00031 #include <OpenMS/CONCEPT/ProgressLogger.h>
00032
00033 #include <iostream>
00034
00035 namespace OpenMS
00036 {
00053 class MorphFilter
00054 : public DefaultParamHandler,
00055 public ProgressLogger
00056 {
00057 public:
00059 inline MorphFilter()
00060 : DefaultParamHandler("MorphFilter"),
00061 struc_size_(3)
00062 {
00063 defaults_.setValue("struc_elem_length",3.0,"Length of the structuring element. Should be wider than the expected peak width.");
00064
00065 defaultsToParam_();
00066 }
00067
00069 virtual ~MorphFilter()
00070 {
00071 }
00072
00081 template < typename InputPeakIterator, typename OutputPeakContainer >
00082 void dilatation(InputPeakIterator first, InputPeakIterator last, OutputPeakContainer& result, int l)
00083 {
00084
00085 result.resize(distance(first,last));
00086
00087 int middle = l/2;
00088 int i,k,m,n;
00089 int length = distance(first,last);
00090
00091 DoubleReal *g = new DoubleReal[l];
00092 DoubleReal *h = new DoubleReal[l];
00093 k=length-(length%l)-1;
00094
00095 calcGDilatation_<InputPeakIterator>(first,last,l,g,true);
00096 calcHDilatation_<InputPeakIterator>(first,first+l-1,l,h,true);
00097
00098 typename OutputPeakContainer::iterator it = result.begin();
00099 for (i = 0; i < middle; ++i)
00100 {
00101 it->setIntensity(g[i+middle]);
00102 it->setPosition(first->getPosition());
00103 ++first;
00104 ++it;
00105 }
00106
00107 m = l-1;
00108 n = 0;
00109 for (i = middle; i<(length-middle); ++i)
00110 {
00111 if ((i%l)==(middle+1))
00112 {
00113 if (i==k)
00114 {
00115 calcGDilatation_<InputPeakIterator>((first+middle),last,l,g,false);
00116 }
00117 else
00118 {
00119 calcGDilatation_<InputPeakIterator>((first+middle),last,l,g,true);
00120 }
00121 m=0;
00122 }
00123 if ((i%l)==middle && (i>middle))
00124 {
00125 if (i>k)
00126 {
00127 calcHDilatation_<InputPeakIterator>(first,last,l,h,false);
00128 }
00129 else
00130 {
00131 calcHDilatation_<InputPeakIterator>((first-middle),(first+middle),l,h,true);
00132 }
00133 n=0;
00134 }
00135
00136 it->setIntensity(std::max(g[m],h[n]));
00137 it->getPosition() = first->getPosition();
00138 ++it;
00139 ++first;
00140 ++m;
00141 ++n;
00142 }
00143
00144 DoubleReal last_int = (first-1)->getIntensity();
00145 for (i=0; i<middle; ++i)
00146 {
00147 it->setIntensity(last_int);
00148 it->getPosition() = first->getPosition();
00149 ++it;
00150 ++first;
00151 }
00152
00153 delete [] g;
00154 delete [] h;
00155 }
00156
00157
00158
00167 template < typename InputPeakIterator, typename OutputPeakContainer >
00168 void erosion(InputPeakIterator first, InputPeakIterator last, OutputPeakContainer& result, int l)
00169 {
00170
00171 result.resize(distance(first,last));
00172
00173 int middle=l/2;
00174 int i,k,m,n;
00175 int length=distance(first,last);
00176
00177 DoubleReal *g = new DoubleReal[l];
00178 DoubleReal *h = new DoubleReal[l];
00179 k=length-(length%l)-1;
00180
00181 calcGErosion_<InputPeakIterator>(first,last,l,g,true);
00182 calcHErosion_<InputPeakIterator>(first+l-1,l,h,true);
00183
00184 typename OutputPeakContainer::iterator it = result.begin();
00185 for (i=0; i<middle; ++i)
00186 {
00187 it->setIntensity(0);
00188 it->getPosition() = first->getPosition();
00189 ++it;
00190 ++first;
00191 }
00192
00193 m = l-1;
00194 n = 0;
00195 for (i=middle; i<(length-middle); ++i)
00196 {
00197 if ((i%l)==(middle+1))
00198 {
00199 if (i==k)
00200 {
00201 calcGErosion_<InputPeakIterator>((first+middle),last,l,g,false);
00202 }
00203 else
00204 {
00205 calcGErosion_<InputPeakIterator>((first+middle),last,l,g,true);
00206 }
00207 m=0;
00208 }
00209 if ((i%l)==middle && (i>middle) )
00210 {
00211 if (i>k)
00212 {
00213 calcHErosion_<InputPeakIterator>((first+middle),l,h,false);
00214 }
00215 else
00216 {
00217 calcHErosion_<InputPeakIterator>((first+middle),l,h,true);
00218 }
00219 n=0;
00220 }
00221
00222 it->setIntensity(std::min(g[m],h[n]));
00223 it->setPosition(first->getPosition());
00224 ++it;
00225 ++first;
00226 ++m;
00227 ++n;
00228 }
00229
00230 for (i=0; i<middle; ++i)
00231 {
00232 it->setIntensity(0);
00233 it->getPosition() = first->getPosition();
00234 ++it;
00235 ++first;
00236 }
00237
00238 delete [] g;
00239 delete [] h;
00240 }
00241
00242
00243
00244
00245 protected:
00247 DoubleReal struc_size_;
00248
00249
00250 virtual void updateMembers_()
00251 {
00252 struc_size_ = (DoubleReal)param_.getValue("struc_elem_length");
00253 }
00254
00256 template < typename InputPeakIterator, typename OutputPeakContainer >
00257 inline void minusIntensities_(InputPeakIterator first, InputPeakIterator last, OutputPeakContainer& result)
00258 {
00259 typename OutputPeakContainer::iterator it = result.begin();
00260 while (first != last)
00261 {
00262 it->setIntensity(first->getIntensity() - it->getIntensity());
00263 ++first;
00264 ++it;
00265 }
00266 }
00267
00269 template < typename InputPeakIterator >
00270 void calcGErosion_(InputPeakIterator first, InputPeakIterator last, int l, DoubleReal* g, bool b)
00271 {
00272 int i,j;
00273
00274 if (b)
00275 {
00276 for (j=0; j<l; ++j)
00277 {
00278 if (first < last)
00279 {
00280 if (j==0)
00281 {
00282 g[j]=first->getIntensity();
00283 }
00284 else
00285 {
00286 g[j]=std::min((DoubleReal)(first->getIntensity()),g[j-1]);
00287 }
00288 ++first;
00289 }
00290 else
00291 {
00292 break;
00293 }
00294 }
00295 }
00296 else
00297 {
00298 j=0;
00299 while (first!=last)
00300 {
00301 if (j==0)
00302 {
00303 g[j]=first->getIntensity();
00304 }
00305 else
00306 {
00307 g[j]=std::min((DoubleReal)(first->getIntensity()),g[j-1]);
00308 }
00309 ++first;
00310 ++j;
00311 }
00312
00313 for (i=j; i<l; ++i)
00314 {
00315 g[i]=0;
00316 }
00317 }
00318 }
00319
00320
00321 template < typename InputPeakIterator >
00322 void calcHErosion_(InputPeakIterator first, int l, DoubleReal* h, bool b)
00323 {
00324 int j;
00325 if (b)
00326 {
00327 for (j=l-1; j>=0; --j)
00328 {
00329 if (j==(l-1))
00330 {
00331 h[j]=first->getIntensity();
00332 }
00333 else
00334 {
00335 h[j]=std::min((DoubleReal)(first->getIntensity()),h[j+1]);
00336 }
00337 --first;
00338 }
00339 }
00340 else
00341 {
00342 for (j=0;j<l;++j)
00343 {
00344 h[j]=0;
00345 }
00346 }
00347 }
00348
00349
00351 template < typename InputPeakIterator >
00352 void calcGDilatation_(InputPeakIterator first, InputPeakIterator last, int l, DoubleReal* g, bool b)
00353 {
00354 int i,j;
00355
00356 if (b)
00357 {
00358 for (j=0; j<l; ++j)
00359 {
00360 if (first < last)
00361 {
00362 if (j==0)
00363 {
00364 g[j]=first->getIntensity();
00365 }
00366 else
00367 {
00368 g[j]=std::max((DoubleReal)(first->getIntensity()),g[j-1]);
00369 }
00370 ++first;
00371 }
00372 else
00373 {
00374 break;
00375 }
00376 }
00377 }
00378 else
00379 {
00380 j=0;
00381 while (first!=last)
00382 {
00383 if (j==0)
00384 {
00385 g[j]=first->getIntensity();
00386 }
00387 else
00388 {
00389 g[j]=std::max((DoubleReal)(first->getIntensity()),g[j-1]);
00390 }
00391 ++first;
00392 ++j;
00393 }
00394 for (i=j; i<l; ++i)
00395 {
00396 g[i]=g[j-1];
00397 }
00398 }
00399 }
00400
00401
00402 template < typename InputPeakIterator >
00403 void calcHDilatation_(InputPeakIterator first, InputPeakIterator last, int l, DoubleReal* h, bool b)
00404 {
00405 int j;
00406
00407 if (b)
00408 {
00409 for (j=l-1; j>=0; --j)
00410 {
00411 if (j==(l-1))
00412 {
00413 h[j]=last->getIntensity();
00414 }
00415 else
00416 {
00417 h[j]=std::max((DoubleReal)(last->getIntensity()),h[j+1]);
00418 }
00419 --last;
00420 }
00421 }
00422 else
00423 {
00424 j=(last-first)-1;
00425 h[j]=(--last)->getIntensity();
00426 while (last!=first)
00427 {
00428 --j;
00429 h[j]=std::max((DoubleReal)(first->getIntensity()),h[j+1]);;
00430 --last;
00431 }
00432 }
00433 }
00434
00435 };
00436
00437 }
00438
00439 #endif