/*////////////////////////////////////////////////////////////////////////////// // CMT Cosmic Muon Tomography project ////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova All rights reserved Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > ------------------------------------------------------------------ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. //////////////////////////////////////////////////////////////////////////////*/ #ifndef U_DATABINNING_H #define U_DATABINNING_H #include "Core/Vector.h" #include "Dense.h" namespace uLib { // TODO: USE BOOST ACCUMULATORS // template class Accumulator_Mean { typedef std::pair Tmean; public: Accumulator_Mean() { m_Means.push_back( Tmean(0,0) ); } void operator()(const T data) { T tmp = 0; // for(typename std::vector::iterator it = m_Means.begin(); it < m_Means.back(); ++it) // tmp += it->first/it->second; for(int i=0; i::iterator it = m_Means.begin(); it < m_Means.end(); ++it) { // mean += it->first/it->second; } for(int i=0; i m_Means; }; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // accumulator Trim // template < typename T, int subsample_size=200 > class Accumulator_ABTrim { public: Accumulator_ABTrim() : m_Avg(0), m_InternalCount(0), m_SizeA(0), m_SizeB(0), m_IdA(0), m_IdB(0) {} Accumulator_ABTrim(const Accumulator_ABTrim &c) { # pragma omp critical { m_Avg = c.m_Avg; m_InternalCount = c.m_InternalCount; m_SizeA = c.m_SizeA; m_SizeB = c.m_SizeB; m_IdA = c.m_IdA; m_IdB = c.m_IdB; memcpy (m_Av, c.m_Av, sizeof (m_Av)); } } void operator += (T value) { if(m_InternalCount > subsample_size) { // array complete and counter over subsample // if( m_SizeA > 0 && value < m_ValA ) { ;// m_Avg += m_ValA; } else if (m_SizeB > 0 && value > m_ValB) { ;// m_Avg += m_ValB; } else { m_Avg += value; m_InternalCount++; } } else if(m_InternalCount >=0) { // array complete if(m_SizeA > 0 && value < m_ValA) { m_Avg += m_ValA; m_Av[m_IdA] = value; for (unsigned int i=0; i < m_SizeA; i++) if(m_Av[i] > m_Av[m_IdA]) { m_IdA = i; m_ValA = m_Av[i]; } } else if(m_SizeB > 0 && value > m_ValB) { m_Avg += m_ValB; m_Av[m_IdB] = value; for (unsigned int i=m_SizeA; i < m_SizeA+m_SizeB; i++) if(m_Av[i] < m_Av[m_IdB]) { m_IdB = i; m_ValB = m_Av[i]; } } else { m_Avg += value; } m_InternalCount++; } else { // m_InternalCount < 0 // array is not fullfilled m_Av[m_SizeA+m_SizeB+m_InternalCount] = value; m_InternalCount++; if(m_InternalCount == 0) { std::sort(m_Av,m_Av+m_SizeA+m_SizeB); if(m_SizeA > 0) { m_IdA = m_SizeA-1; m_ValA = m_Av[m_IdA]; } if(m_SizeB > 0) { m_IdB = m_SizeA; m_ValB = m_Av[m_SizeA]; } } } } T operator()() { if(m_InternalCount <= 0) { std::sort(m_Av, m_Av+m_SizeA+m_SizeB+m_InternalCount); return m_Av[ (m_SizeA+m_SizeB+m_InternalCount) / 2]; // median value // } else { // return (m_Avg + m_ValA * m_SizeA + m_ValB * m_SizeB) / // (m_InternalCount + m_SizeA + m_SizeB); return (m_Avg) / m_InternalCount; } } void SetABTrim(int a, int b) { if(a+b > subsample_size/2) { m_SizeA = a/(a+b) * subsample_size/2; m_SizeB = b/(a+b) * subsample_size/2; } else { m_SizeA = a; m_SizeB = b; } m_Avg = 0; m_InternalCount = -m_SizeA-m_SizeB; } private: T m_Av[subsample_size/2]; T m_Avg, m_ValA, m_ValB; int m_IdA, m_IdB, m_InternalCount; int m_SizeA, m_SizeB; }; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Clip Accumulator // template < typename T, int subsample_size=200 > class Accumulator_ABClip { public: Accumulator_ABClip() : m_Avg(0), m_InternalCount(0), m_SizeA(0), m_SizeB(0), m_IdA(0), m_IdB(0) {} Accumulator_ABClip(const Accumulator_ABClip &c) { # pragma omp critical { m_Avg = c.m_Avg; m_InternalCount = c.m_InternalCount; m_SizeA = c.m_SizeA; m_SizeB = c.m_SizeB; m_IdA = c.m_IdA; m_IdB = c.m_IdB; memcpy (m_Av, c.m_Av, sizeof (m_Av)); } } void operator += (T value) { if(m_InternalCount > subsample_size) { // array complete and counter over subsample // if( m_SizeA > 0 && value < m_ValA ) { m_Avg += m_ValA; } else if (m_SizeB > 0 && value > m_ValB) { m_Avg += m_ValB; } else { m_Avg += value; } m_InternalCount++; } else if(m_InternalCount >=0) { // array complete if(m_SizeA > 0 && value < m_ValA) { m_Avg += m_ValA; m_Av[m_IdA] = value; for (unsigned int i=0; i < m_SizeA; i++) if(m_Av[i] > m_Av[m_IdA]) { m_IdA = i; m_ValA = m_Av[i]; } } else if(m_SizeB > 0 && value > m_ValB) { m_Avg += m_ValB; m_Av[m_IdB] = value; for (unsigned int i=m_SizeA; i < m_SizeA+m_SizeB; i++) if(m_Av[i] < m_Av[m_IdB]) { m_IdB = i; m_ValB = m_Av[i]; } } else { m_Avg += value; } m_InternalCount++; } else { // m_InternalCount < 0 // array is not fullfilled m_Av[m_SizeA+m_SizeB+m_InternalCount] = value; m_InternalCount++; if(m_InternalCount == 0) { std::sort(m_Av,m_Av+m_SizeA+m_SizeB); if(m_SizeA > 0) { m_IdA = m_SizeA-1; m_ValA = m_Av[m_IdA]; } if(m_SizeB > 0) { m_IdB = m_SizeA; m_ValB = m_Av[m_SizeA]; } } } } T operator()() { if(m_InternalCount <= 0) { std::sort(m_Av, m_Av+m_SizeA+m_SizeB+m_InternalCount); return m_Av[ (m_SizeA+m_SizeB+m_InternalCount) / 2]; // median value // } else { return (m_Avg + m_ValA * m_SizeA + m_ValB * m_SizeB) / (m_InternalCount + m_SizeA + m_SizeB); } } void SetABTrim(int a, int b) { if(a+b > subsample_size/2) { m_SizeA = a/(a+b) * subsample_size/2; m_SizeB = b/(a+b) * subsample_size/2; } else { m_SizeA = a; m_SizeB = b; } m_Avg = 0; m_InternalCount = -m_SizeA-m_SizeB; } private: T m_Av[subsample_size/2]; T m_Avg, m_ValA, m_ValB; int m_IdA, m_IdB, m_InternalCount; int m_SizeA, m_SizeB; }; } // uLib #endif // U_DATABINNING_H