58 template <
typename IteratorT>
60 public std::iterator<std::forward_iterator_tag, typename IteratorT::value_type::IntensityType>
63 typedef typename IteratorT::value_type::IntensityType
value_type;
64 typedef typename IteratorT::value_type::IntensityType &
reference;
65 typedef typename IteratorT::value_type::IntensityType *
pointer;
75 return base->getIntensity();
78 template <
typename IndexT>
81 return base[index].getIntensity();
97 IteratorT tmp = *
this;
117 template <
typename IteratorT>
170 struct_size_in_datapoints_(0)
173 defaults_.setValue(
"struc_elem_length", 3.0,
"Length of the structuring element. This should be wider than the expected peak width.");
174 defaults_.setValue(
"struc_elem_unit",
"Thomson",
"The unit of the 'struct_elem_length'.");
175 defaults_.setValidStrings(
"struc_elem_unit", ListUtils::create<String>(
"Thomson,DataPoints"));
177 defaults_.setValue(
"method",
"tophat",
"Method to use, the default is 'tophat'. Do not change this unless you know what you are doing. The other methods may be useful for tuning the parameters, see the class documentation of MorpthologicalFilter.");
178 defaults_.setValidStrings(
"method", ListUtils::create<String>(
"identity,erosion,dilation,opening,closing,gradient,tophat,bothat,erosion_simple,dilation_simple"));
199 template <
typename InputIterator,
typename OutputIterator>
200 void filterRange(InputIterator input_begin, InputIterator input_end, OutputIterator output_begin)
203 static std::vector<typename InputIterator::value_type> buffer;
204 const UInt size = input_end - input_begin;
207 if (struct_size_in_datapoints_ == 0)
209 struct_size_in_datapoints_ = (
UInt)(
double)param_.getValue(
"struc_elem_length");
213 String method = param_.getValue(
"method");
214 if (method ==
"identity")
216 std::copy(input_begin, input_end, output_begin);
218 else if (method ==
"erosion")
220 applyErosion_(struct_size_in_datapoints_, input_begin, input_end, output_begin);
222 else if (method ==
"dilation")
224 applyDilation_(struct_size_in_datapoints_, input_begin, input_end, output_begin);
226 else if (method ==
"opening")
228 if (buffer.size() < size) buffer.resize(size);
229 applyErosion_(struct_size_in_datapoints_, input_begin, input_end, buffer.begin());
230 applyDilation_(struct_size_in_datapoints_, buffer.begin(), buffer.begin() + size, output_begin);
232 else if (method ==
"closing")
234 if (buffer.size() < size) buffer.resize(size);
235 applyDilation_(struct_size_in_datapoints_, input_begin, input_end, buffer.begin());
236 applyErosion_(struct_size_in_datapoints_, buffer.begin(), buffer.begin() + size, output_begin);
238 else if (method ==
"gradient")
240 if (buffer.size() < size) buffer.resize(size);
241 applyErosion_(struct_size_in_datapoints_, input_begin, input_end, buffer.begin());
242 applyDilation_(struct_size_in_datapoints_, input_begin, input_end, output_begin);
243 for (
UInt i = 0; i < size; ++i) output_begin[i] -= buffer[i];
245 else if (method ==
"tophat")
247 if (buffer.size() < size) buffer.resize(size);
248 applyErosion_(struct_size_in_datapoints_, input_begin, input_end, buffer.begin());
249 applyDilation_(struct_size_in_datapoints_, buffer.begin(), buffer.begin() + size, output_begin);
250 for (
UInt i = 0; i < size; ++i) output_begin[i] = input_begin[i] - output_begin[i];
252 else if (method ==
"bothat")
254 if (buffer.size() < size) buffer.resize(size);
255 applyDilation_(struct_size_in_datapoints_, input_begin, input_end, buffer.begin());
256 applyErosion_(struct_size_in_datapoints_, buffer.begin(), buffer.begin() + size, output_begin);
257 for (
UInt i = 0; i < size; ++i) output_begin[i] = input_begin[i] - output_begin[i];
259 else if (method ==
"erosion_simple")
261 applyErosionSimple_(struct_size_in_datapoints_, input_begin, input_end, output_begin);
263 else if (method ==
"dilation_simple")
265 applyDilationSimple_(struct_size_in_datapoints_, input_begin, input_end, output_begin);
268 struct_size_in_datapoints_ = 0;
291 if (spectrum.size() <= 1) {
return; }
294 if ((
String)(param_.getValue(
"struc_elem_unit")) ==
"Thomson")
296 const double struc_elem_length = (
double)param_.getValue(
"struc_elem_length");
297 const double mz_diff = spectrum.back().getMZ() - spectrum.begin()->getMZ();
298 struct_size_in_datapoints_ = (
UInt)(ceil(struc_elem_length*(
double)(spectrum.size() - 1)/mz_diff));
302 struct_size_in_datapoints_ = (
UInt)(
double)param_.getValue(
"struc_elem_length");
305 if (!
Math::isOdd(struct_size_in_datapoints_)) ++struct_size_in_datapoints_;
308 std::vector<Peak1D::IntensityType> output(spectrum.size());
315 for (
Size i = 0; i < spectrum.size(); ++i)
317 spectrum[i].setIntensity(output[i]);
329 startProgress(0, exp.
size(),
"filtering baseline");
330 for (
UInt i = 0; i < exp.
size(); ++i)
347 template <
typename InputIterator,
typename OutputIterator>
348 void applyErosion_(
Int struc_size, InputIterator input, InputIterator input_end, OutputIterator output)
350 typedef typename InputIterator::value_type ValueType;
351 const Int size = input_end - input;
352 const Int struc_size_half = struc_size / 2;
354 static std::vector<ValueType> buffer;
355 if (
Int(buffer.size()) < struc_size) buffer.resize(struc_size);
364 if (size <= struc_size || size <= 5)
366 applyErosionSimple_(struc_size, input, input_end, output);
372 for (++ii; ii < struc_size_half; ++ii)
if (current > input[ii]) current = input[ii];
373 for (; ii < std::min(
Int(struc_size), size); ++ii, ++oi)
375 if (current > input[ii]) current = input[ii];
376 output[oi] = current;
381 for (anchor = struc_size;
382 anchor <= size - struc_size;
389 for (i = 1; i < struc_size; ++i, ++ii)
391 if (current > input[ii]) current = input[ii];
395 oi = ii + struc_size_half;
397 for (i = 1; i < struc_size; ++i, --ii, --oi)
399 if (current > input[ii]) current = input[ii];
400 output[oi] = std::min(buffer[struc_size - i], current);
402 if (current > input[ii]) current = input[ii];
403 output[oi] = current;
411 for (--ii; ii >= size - struc_size_half; --ii)
if (current > input[ii]) current = input[ii];
412 for (; ii >= std::max(size -
Int(struc_size), 0); --ii, --oi)
414 if (current > input[ii]) current = input[ii];
415 output[oi] = current;
417 anchor = size - struc_size;
421 for (i = 1; i < struc_size; ++i, ++ii)
423 if (current > input[ii]) current = input[ii];
427 oi = ii + struc_size_half;
429 for (i = 1; (ii >= 0) && (i < struc_size); ++i, --ii, --oi)
431 if (current > input[ii]) current = input[ii];
432 output[oi] = std::min(buffer[struc_size - i], current);
436 if (current > input[ii]) current = input[ii];
437 output[oi] = current;
447 template <
typename InputIterator,
typename OutputIterator>
448 void applyDilation_(
Int struc_size, InputIterator input, InputIterator input_end, OutputIterator output)
450 typedef typename InputIterator::value_type ValueType;
451 const Int size = input_end - input;
452 const Int struc_size_half = struc_size / 2;
454 static std::vector<ValueType> buffer;
455 if (
Int(buffer.size()) < struc_size) buffer.resize(struc_size);
464 if (size <= struc_size || size <= 5)
466 applyDilationSimple_(struc_size, input, input_end, output);
472 for (++ii; ii < struc_size_half; ++ii)
if (current < input[ii]) current = input[ii];
473 for (; ii < std::min(
Int(struc_size), size); ++ii, ++oi)
475 if (current < input[ii]) current = input[ii];
476 output[oi] = current;
481 for (anchor = struc_size;
482 anchor <= size - struc_size;
489 for (i = 1; i < struc_size; ++i, ++ii)
491 if (current < input[ii]) current = input[ii];
495 oi = ii + struc_size_half;
497 for (i = 1; i < struc_size; ++i, --ii, --oi)
499 if (current < input[ii]) current = input[ii];
500 output[oi] = std::max(buffer[struc_size - i], current);
502 if (current < input[ii]) current = input[ii];
503 output[oi] = current;
511 for (--ii; ii >= size - struc_size_half; --ii)
if (current < input[ii]) current = input[ii];
512 for (; ii >= std::max(size -
Int(struc_size), 0); --ii, --oi)
514 if (current < input[ii]) current = input[ii];
515 output[oi] = current;
517 anchor = size - struc_size;
521 for (i = 1; i < struc_size; ++i, ++ii)
523 if (current < input[ii]) current = input[ii];
527 oi = ii + struc_size_half;
529 for (i = 1; (ii >= 0) && (i < struc_size); ++i, --ii, --oi)
531 if (current < input[ii]) current = input[ii];
532 output[oi] = std::max(buffer[struc_size - i], current);
536 if (current < input[ii]) current = input[ii];
537 output[oi] = current;
544 template <
typename InputIterator,
typename OutputIterator>
545 void applyErosionSimple_(
Int struc_size, InputIterator input_begin, InputIterator input_end, OutputIterator output_begin)
547 typedef typename InputIterator::value_type ValueType;
548 const int size = input_end - input_begin;
549 const Int struc_size_half = struc_size / 2;
550 for (
Int index = 0; index < size; ++index)
552 Int start = std::max(0, index - struc_size_half);
553 Int stop = std::min(size - 1, index + struc_size_half);
554 ValueType value = input_begin[start];
555 for (
Int i = start + 1; i <= stop; ++i)
if (value > input_begin[i]) value = input_begin[i];
556 output_begin[index] = value;
562 template <
typename InputIterator,
typename OutputIterator>
565 typedef typename InputIterator::value_type ValueType;
566 const int size = input_end - input_begin;
567 const Int struc_size_half = struc_size / 2;
568 for (
Int index = 0; index < size; ++index)
570 Int start = std::max(0, index - struc_size_half);
571 Int stop = std::min(size - 1, index + struc_size_half);
572 ValueType value = input_begin[start];
573 for (
Int i = start + 1; i <= stop; ++i)
if (value < input_begin[i]) value = input_begin[i];
574 output_begin[index] = value;