libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
filtermorpho.cpp
Go to the documentation of this file.
1/**
2 * \file pappsomspp/filers/filtermorpho.cpp
3 * \date 02/05/2019
4 * \author Olivier Langella
5 * \brief collection of morphological filters
6 */
7
8/*******************************************************************************
9 * Copyright (c) 2019 Olivier Langella <Olivier.Langella@u-psud.fr>.
10 *
11 * This file is part of the PAPPSOms++ library.
12 *
13 * PAPPSOms++ is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * PAPPSOms++ is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with PAPPSOms++. If not, see <http://www.gnu.org/licenses/>.
25 *
26 ******************************************************************************/
27
28#include "filtermorpho.h"
29#include "../../trace/trace.h"
30#include <QDebug>
33
34using namespace pappso;
35
37 : m_halfWindowSize(half_window_size)
38{
39}
41 const FilterMorphoWindowBase &other)
42 : m_halfWindowSize(other.m_halfWindowSize)
43{
44}
45std::size_t
50
58
59
60Trace &
62{
63
64 qDebug() << " " << m_halfWindowSize << " data_points.size()"
65 << data_points.size();
66 if(m_halfWindowSize == 0)
67 return data_points;
68 if(data_points.size() <= m_halfWindowSize)
69 return data_points;
70 Trace old_trace(data_points);
71 auto it = old_trace.begin();
72 auto itend = old_trace.end() - m_halfWindowSize - 1;
73 auto it_target = data_points.begin();
74
75
76 std::size_t loop_begin = 0;
77 while((it != itend) && (loop_begin < m_halfWindowSize))
78 {
79 // maxYDataPoint(it_begin, it + m_halfWindowSize + 1);
80 // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
81 // << it->x << " " << m_halfWindowSize;
82 // it_target->x = it->x;
83 it_target->y =
84 getWindowValue(old_trace.begin(), it + m_halfWindowSize + 1);
85 it++;
86 it_target++;
87 loop_begin++;
88 }
89 // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
90 while(it != itend)
91 {
92 // it_target->x = it->x;
93 // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
94 // << it->x;
95 it_target->y =
97 it++;
98 it_target++;
99 }
100 // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
101 while(it != old_trace.end())
102 {
103 // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
104 // << it->x;
105 // it_target->x = it->x;
106 it_target->y = getWindowValue(it - m_halfWindowSize, old_trace.end());
107 it++;
108 it_target++;
109 }
110 // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
111 // problem with move or swap : this lead to segmentation faults in some cases
112 // data_points = std::move(new_trace);
113 qDebug();
114 return data_points;
115}
116
117FilterMorphoSum::FilterMorphoSum(std::size_t half_window_size)
118 : FilterMorphoWindowBase(half_window_size)
119{
120}
122 : FilterMorphoWindowBase(other.m_halfWindowSize)
123{
124}
125
128{
130
131 return *this;
132}
133
134double
136 std::vector<DataPoint>::const_iterator begin,
137 std::vector<DataPoint>::const_iterator end) const
138{
139
140 qDebug();
141 return sumYTrace(begin, end, 0);
142}
143
144FilterMorphoMax::FilterMorphoMax(std::size_t half_window_size)
145 : FilterMorphoWindowBase(half_window_size)
146{
147}
149 : FilterMorphoWindowBase(other.m_halfWindowSize)
150{
151}
152
155{
157
158 return *this;
159}
160
161double
163 std::vector<DataPoint>::const_iterator begin,
164 std::vector<DataPoint>::const_iterator end) const
165{
166
167 // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
168 return maxYDataPoint(begin, end)->y;
169}
170
171std::size_t
176
177FilterMorphoMin::FilterMorphoMin(std::size_t half_window_size)
178 : FilterMorphoWindowBase(half_window_size)
179{
180}
182 : FilterMorphoWindowBase(other.m_halfWindowSize)
183{
184}
185
188{
190
191 return *this;
192}
193
194double
196 std::vector<DataPoint>::const_iterator begin,
197 std::vector<DataPoint>::const_iterator end) const
198{
199 return minYDataPoint(begin, end)->y;
200}
201
202std::size_t
207
208FilterMorphoMinMax::FilterMorphoMinMax(std::size_t half_window_size)
209 : m_filterMax(half_window_size), m_filterMin(half_window_size)
210{
211}
213 : m_filterMax(other.m_filterMax), m_filterMin(other.m_filterMin)
214{
215}
216
219{
220 m_filterMax = other.m_filterMax;
221 m_filterMin = other.m_filterMin;
222
223 return *this;
224}
225
226Trace &
228{
229 qDebug();
230 m_filterMax.filter(data_points);
231 m_filterMin.filter(data_points);
232 qDebug();
233 return data_points;
234}
235std::size_t
237{
238 return ((FilterMorphoMax)m_filterMax).getMaxHalfEdgeWindows();
239}
240
241
242FilterMorphoMaxMin::FilterMorphoMaxMin(std::size_t half_window_size)
243 : m_filterMin(half_window_size), m_filterMax(half_window_size)
244{
245}
247 : m_filterMin(other.m_filterMin), m_filterMax(other.m_filterMax)
248{
249}
250
253{
254 m_filterMin = other.m_filterMin;
255 m_filterMax = other.m_filterMax;
256
257 return *this;
258}
259
260Trace &
262{
263 qDebug();
264 m_filterMin.filter(data_points);
265 m_filterMax.filter(data_points);
266 qDebug();
267 return data_points;
268}
269std::size_t
271{
272 return ((FilterMorphoMax)m_filterMax).getMaxHalfEdgeWindows();
273}
274
276 : m_halfWindowSize(half_window_size)
277{
278}
279
281 : m_halfWindowSize(other.m_halfWindowSize)
282{
283}
284
286 const QString &strBuildParams)
287{
288 buildFilterFromString(strBuildParams);
289}
290
291void
293 const QString &strBuildParams)
294{
295 //"antiSpike|2"
296 if(strBuildParams.startsWith("antiSpike|"))
297 {
298 QStringList params = strBuildParams.split("|").back().split(";");
299
300 m_halfWindowSize = params.at(0).toUInt();
301 }
302 else
303 {
305 QString("building FilterMorphoAntiSpike from string %1 is not possible")
306 .arg(strBuildParams));
307 }
308}
309
310QString
312{
313 QString strCode = QString("antiSpike|%1").arg(m_halfWindowSize);
314
315 return strCode;
316}
317
318QString
320{
321 return "antiSpike";
322}
323
324
327{
329
330 return *this;
331}
332
333std::size_t
338Trace &
340{
341 // qDebug();
342 if(m_halfWindowSize == 0)
343 return data_points;
344 if(data_points.size() < m_halfWindowSize)
345 return data_points;
346 Trace old_trace(data_points);
347 auto it = old_trace.begin();
348 auto it_target = data_points.begin();
349 auto itw = old_trace.begin();
350
351 auto itend = old_trace.end() - m_halfWindowSize - 1;
352 // new_trace.reserve(data_points.size());
353
354 // qDebug();
355 while((it != old_trace.end()) &&
356 (std::distance(old_trace.begin(), it) < (int)m_halfWindowSize))
357 {
358 // no anti spike at the begining of the signal
359 it++;
360 it_target++;
361 }
362 // qDebug();
363 while((it != itend) && (it != old_trace.end()))
364 {
365 // qDebug();
366 auto itwend = it + m_halfWindowSize + 1;
367 itw = findDifferentYvalue(it - m_halfWindowSize, it + 1, 0);
368 if(itw == it)
369 {
370 // qDebug();
371 itw = findDifferentYvalue(it + 1, itwend, 0);
372 if(itw == itwend)
373 {
374 it_target->y = 0;
375 }
376 // qDebug();
377 }
378
379 // qDebug();
380 it++;
381 it_target++;
382 }
383
384 return data_points;
385}
386
387
388FilterMorphoMedian::FilterMorphoMedian(std::size_t half_window_size)
389 : FilterMorphoWindowBase(half_window_size)
390{
391}
393 : FilterMorphoWindowBase(other.m_halfWindowSize)
394{
395}
396
399{
401
402 return *this;
403}
404
405double
407 std::vector<DataPoint>::const_iterator begin,
408 std::vector<DataPoint>::const_iterator end) const
409{
410 return medianYTrace(begin, end);
411}
412
413
414FilterMorphoMean::FilterMorphoMean(std::size_t half_window_size)
415 : FilterMorphoWindowBase(half_window_size)
416{
417}
419 : FilterMorphoWindowBase(other.m_halfWindowSize)
420{
421}
422
425{
427
428 return *this;
429}
430
431std::size_t
436
437double
439 std::vector<DataPoint>::const_iterator begin,
440 std::vector<DataPoint>::const_iterator end) const
441{
442 return meanYTrace(begin, end);
443}
444
445
447 std::size_t median_half_window_size, std::size_t minmax_half_window_size)
448 : m_filterMorphoMedian(median_half_window_size),
449 m_filterMorphoMinMax(minmax_half_window_size)
450{
451}
452
454 const FilterMorphoBackground &other)
455 : m_filterMorphoMedian(other.m_filterMorphoMedian),
456 m_filterMorphoMinMax(other.m_filterMorphoMinMax)
457{
458}
459
468
469Trace &
471{
472 m_filterMorphoMedian.filter(data_points);
473 m_filterMorphoMinMax.filter(data_points);
474
475 // finally filter negative values
476 for(DataPoint &point : data_points)
477 {
478 if(point.y < 0)
479 {
480 point.y = 0;
481 }
482 }
483 return data_points;
484}
485const FilterMorphoMedian &
490const FilterMorphoMinMax &
excetion to use when an item type is not recognized
anti spike filter set to zero alone values inside the window
FilterMorphoAntiSpike & operator=(const FilterMorphoAntiSpike &other)
std::size_t getHalfWindowSize() const
void buildFilterFromString(const QString &strBuildParams) override
build this filter using a string
QString toString() const override
QString name() const override
FilterMorphoAntiSpike(std::size_t half_window_size)
Trace & filter(Trace &data_points) const override
compute background of a trace compute background noise on a trace
Trace & filter(Trace &data_points) const override
FilterMorphoBackground(std::size_t median_half_window_size, std::size_t minmax_half_window_size)
FilterMorphoMedian m_filterMorphoMedian
const FilterMorphoMedian & getFilterMorphoMedian() const
FilterMorphoBackground & operator=(const FilterMorphoBackground &other)
const FilterMorphoMinMax & getFilterMorphoMinMax() const
FilterMorphoMinMax m_filterMorphoMinMax
transform the trace with the maximum of the minimum equivalent of the erode filter for pictures
Trace & filter(Trace &data_points) const override
FilterMorphoMaxMin(std::size_t half_window_size)
FilterMorphoMax m_filterMax
std::size_t getMaxMinHalfEdgeWindows() const
FilterMorphoMaxMin & operator=(const FilterMorphoMaxMin &other)
FilterMorphoMin m_filterMin
transform the trace into its maximum over a window
double getWindowValue(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end) const override
std::size_t getMaxHalfEdgeWindows() const
FilterMorphoMax(std::size_t half_window_size)
FilterMorphoMax & operator=(const FilterMorphoMax &other)
mean filter apply mean of y values inside the window : this results in a kind of smoothing
FilterMorphoMean(std::size_t half_window_size)
FilterMorphoMean & operator=(const FilterMorphoMean &other)
double getWindowValue(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end) const override
std::size_t getMeanHalfEdgeWindows() const
median filter apply median of y values inside the window
FilterMorphoMedian & operator=(const FilterMorphoMedian &other)
double getWindowValue(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end) const override
FilterMorphoMedian(std::size_t half_window_size)
transform the trace with the minimum of the maximum equivalent of the dilate filter for pictures
FilterMorphoMax m_filterMax
FilterMorphoMin m_filterMin
FilterMorphoMinMax(std::size_t half_window_size)
std::size_t getMinMaxHalfEdgeWindows() const
Trace & filter(Trace &data_points) const override
FilterMorphoMinMax & operator=(const FilterMorphoMinMax &other)
transform the trace into its minimum over a window
std::size_t getMinHalfEdgeWindows() const
FilterMorphoMin(std::size_t half_window_size)
double getWindowValue(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end) const override
FilterMorphoMin & operator=(const FilterMorphoMin &other)
FilterMorphoSum & operator=(const FilterMorphoSum &other)
FilterMorphoSum(std::size_t half_window_size)
double getWindowValue(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end) const override
base class that apply a signal treatment based on a window
virtual Trace & filter(Trace &data_points) const override
virtual double getWindowValue(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end) const =0
FilterMorphoWindowBase(std::size_t half_window_size)
virtual std::size_t getHalfWindowSize() const
FilterMorphoWindowBase & operator=(const FilterMorphoWindowBase &other)
A simple container of DataPoint instances.
Definition trace.h:148
excetion to use when an item type is not recognized (file format, object type...)
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition aa.cpp:39
std::vector< DataPoint >::iterator findDifferentYvalue(std::vector< DataPoint >::iterator begin, std::vector< DataPoint >::iterator end, const double &y_value)
find the first element in which Y is different of value
Definition trace.cpp:127
std::vector< DataPoint >::const_iterator maxYDataPoint(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end)
Definition trace.cpp:180
double medianYTrace(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end)
calculate the median of y value of a trace
Definition trace.cpp:291
double meanYTrace(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end)
calculate the mean of y value of a trace
Definition trace.cpp:253
double sumYTrace(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end, double init)
calculate the sum of y value of a trace
Definition trace.cpp:244
std::vector< DataPoint >::const_iterator minYDataPoint(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end)
Definition trace.cpp:158