Scheduled service maintenance on November 22


On Friday, November 22, 2024, between 06:00 CET and 18:00 CET, GIN services will undergo planned maintenance. Extended service interruptions should be expected. We will try to keep downtimes to a minimum, but recommend that users avoid critical tasks, large data uploads, or DOI requests during this time.

We apologize for any inconvenience.

CommonAverager.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #ifndef COMMONAVERAGER_H_E6A1FBFD
  2. #define COMMONAVERAGER_H_E6A1FBFD
  3. #include <iostream>
  4. #include <numeric>
  5. #include <type_traits>
  6. #include "CereConnBaseTypes.h"
  7. #include "CereConnHelpers.h"
  8. namespace cc
  9. {
  10. template<typename T, typename V = std::vector<T>>
  11. class CommonAverager
  12. {
  13. public:
  14. using ContinuousDataSampleT = T; //!< data type of samples
  15. using ContinuousDataSampleVT = V; //!< type of item that will be stored in RingBufferT
  16. explicit CommonAverager (const ChannelNumList_t &car_ch_map);
  17. explicit CommonAverager (ChannelNumList_t &&car_ch_map);
  18. virtual ~CommonAverager () {}
  19. void operator()(V &v);
  20. private:
  21. // this picks a type for calculation: a larger integer type for integer, or just the same for everything else (floating point)
  22. using TempT = typename std::conditional<std::is_integral<T>::value, smallest_larger_integral_t<typename std::conditional<std::is_integral<T>::value, T, int>::type>, T>::type;
  23. // clamp subtraction for unsigned integer sample types T. Necessary to prevent underflow if sample value is less than average
  24. template <typename Q = T>
  25. typename std::enable_if<std::is_integral<Q>::value && std::is_unsigned<Q>::value, Q>::type minus(Q x, Q y)
  26. {
  27. Q res = x - y;
  28. res &= -(res <= x);
  29. return res;
  30. }
  31. // standard subtraction for all other sample types T
  32. template <typename Q = T>
  33. typename std::enable_if<std::is_floating_point<Q>::value || std::is_signed<Q>::value, Q>::type minus(Q x, Q y)
  34. {
  35. return x - y;
  36. }
  37. ChannelNumList_t m_car_channel_map;
  38. #ifdef CC_TESTING_DEBUG
  39. FRIEND_TEST(CommonAverager, Constructor1);
  40. FRIEND_TEST(CommonAverager, Constructor2);
  41. #endif
  42. };
  43. template<typename T, typename V>
  44. CommonAverager<T, V>::CommonAverager(const ChannelNumList_t &car_ch_map)
  45. : m_car_channel_map(car_ch_map)
  46. {
  47. }
  48. template<typename T, typename V>
  49. CommonAverager<T, V>::CommonAverager(ChannelNumList_t &&car_ch_map)
  50. : m_car_channel_map(std::move(car_ch_map))
  51. {
  52. }
  53. template<typename T, typename V>
  54. void CommonAverager<T, V>::operator()(V &v)
  55. {
  56. if (m_car_channel_map.size() == 0)
  57. {
  58. return;
  59. }
  60. TempT sum = std::accumulate(m_car_channel_map.cbegin(), m_car_channel_map.cend(),
  61. static_cast<TempT>(0),
  62. [&v](TempT n, ChannelNumCont_t i){
  63. return n + static_cast<TempT>(v[i]);
  64. });
  65. T avg = sum / static_cast<TempT>(m_car_channel_map.size());
  66. for (auto &w:v)
  67. {
  68. w = minus<>(w, avg);
  69. }
  70. }
  71. } /* cc */
  72. #endif /* end of include guard: COMMONAVERAGER_H_E6A1FBFD */