/* * SlidingAverage.hh * * Created on: Dec 3, 2012 * Author: f.casimir */ #ifndef SlidingAverage_HH_ #define SlidingAverage_HH_ #include #include #include "Parameter.hh" #include "ParamData.hh" #include "DataTypeMath.hh" #include "Operation.hh" namespace AMDA { namespace Parameters { /** * @class SlidingAverage * @brief It is responsible to shift data of any ParamData type. * @details This class implement the interface Operation. */ template class SlidingAverage : public Operation { typedef typename TParamData::ElementType ElemType; public: /** * @brief Constructor. * @details Create the ParamData type of the input ParamData. */ SlidingAverage(Process& pProcess, TParamData& paramInput, TimeIntervalListSPtr pTimeIntervalList, double window) : Operation(pProcess), _paramInput(paramInput), _paramOutput(new TParamData()), _timeIntervalList(pTimeIntervalList), _currentTimeInterval(_timeIntervalList->begin()), _window(window), _nanVal() { _paramDataOutput=_paramOutput; } /** * @overload Operation::write(ParamDataIndexInfo &pParamDataIndexInfo) */ void write(ParamDataIndexInfo &pParamDataIndexInfo) { if ((pParamDataIndexInfo._nbDataToProcess > 0)) { if (pParamDataIndexInfo._startIndex == 0) { //init nan value (to init dimensions) _nanVal = _paramInput.get(pParamDataIndexInfo._startIndex); _nanVal << NotANumber(); } } for (unsigned int index = pParamDataIndexInfo._startIndex; index < pParamDataIndexInfo._startIndex + pParamDataIndexInfo._nbDataToProcess; index++) { while (!_memTime.empty() && (_paramInput.getTime(index) > _memTime.front() + _window / 2)) { double crtTime = _memTime.front(); if ((crtTime >= (*_currentTimeInterval)._startTime) && (crtTime <= (*_currentTimeInterval)._stopTime)) { _paramOutput->pushTime(crtTime); _paramOutput->getDataList().push_back(computeAverage(crtTime)); } _memTime.pop_front(); } //Cleanup unnecessary data while (!_memTime.empty() && !_mem.empty() && (_mem.front().first < _memTime.front() - _window / 2)) { _mem.pop_front(); } _memTime.push_back(_paramInput.getTime(index)); _mem.push_back(std::make_pair(_paramInput.getTime(index), _paramInput.getDataList()[index])); } if (pParamDataIndexInfo._timeIntToProcessChanged || pParamDataIndexInfo._noMoreTimeInt) { while (!_memTime.empty()) { double crtTime = _memTime.front(); if ((crtTime >= (*_currentTimeInterval)._startTime) && (crtTime <= (*_currentTimeInterval)._stopTime)) { _paramOutput->pushTime(crtTime); _paramOutput->getDataList().push_back(computeAverage(crtTime)); } _memTime.pop_front(); } } } ElemType computeAverage(double crtTime) { ElemType mean = _nanVal; std::list averageDataList; for (typename std::list>::iterator it = _mem.begin(); it != _mem.end(); ++it) { if (it->first >= crtTime - _window / 2. && it->first <= crtTime + _window / 2.) { averageDataList.push_back(it->second); } } if (!averageDataList.empty()) { mean = average(averageDataList, _paramInput.getDim1(), _paramInput.getDim2()); } return mean; } /** * @overload Operation::reset(double pStartTime, double pTimeInt) * @brief reset static data to process another TimeInterval */ virtual void reset() { Operation::reset(); _memTime.clear(); _mem.clear(); if (_currentTimeInterval != _timeIntervalList->end()) ++_currentTimeInterval; } private: /** * @brief It is the channel of data to shift. */ TParamData &_paramInput; /** * @brief It is the channel of the data shifted. */ TParamData *_paramOutput; TimeIntervalListSPtr _timeIntervalList; TimeIntervalList::iterator _currentTimeInterval; /** * @brief window size for sliding average. */ double _window; ElemType _nanVal; /** * @brief keep some data in memory. */ std::list> _mem; /** * @brief list of times over which sliding average must be computed */ std::list _memTime; }; } /* namespace Parameters */ } /* namespace AMDA */ #endif /* SlidingAverage_HH_ */