Boxcar.hh 3.53 KB
/*
 * Boxcar.hh
 *
 *  Created on: Dec 3, 2012
 *      Author: f.casimir
 */

#ifndef Boxcar_HH_
#define Boxcar_HH_

#include "Parameter.hh"
#include "ParamData.hh"
#include "DataTypeMath.hh"
#include "Operation.hh"

namespace AMDA {
namespace Parameters {

/**
 * @class Boxcar
 * @brief It is responsible to shift data of any ParamData type.
 * @details This class implement the interface Operation.
 */
template<class TParamData>
class Boxcar : public Operation {
public:
	/**
	 * @brief Constructor.
	 * @details Create the ParamData type of the input ParamData.
	 */
  Boxcar(Process& pProcess, TParamData& paramInput, TimeIntervalListSPtr pTimeIntervalList, double second)
	: Operation(pProcess),
	  _paramInput(paramInput),
	  _paramOutput(new TParamData()),
	  _timeIntervalList(pTimeIntervalList),
	  _currentTimeInterval(_timeIntervalList->begin()),
	  _second(second),
	  _nb(0),
	  _lastTime(0.0){
	  _sum << elemNull;
	  _paramDataOutput=_paramOutput;
  }

	/**
	 * @overload Operation::write(ParamDataIndexInfo &pParamDataIndexInfo)
	 */
  void  write(ParamDataIndexInfo &pParamDataIndexInfo) {
   //first call
    if((_lastTime == 0.0) && (pParamDataIndexInfo._nbDataToProcess > 0)) {
    	_lastTime = _paramInput.getTime(pParamDataIndexInfo._startIndex);
    	//To create a _sum with the good dimention
    	_sum =  _paramInput.getDataList()[pParamDataIndexInfo._startIndex];
    	_sum << elemNull;
    }
    for (unsigned int index = pParamDataIndexInfo._startIndex;
		index< pParamDataIndexInfo._startIndex + pParamDataIndexInfo._nbDataToProcess; index++) {
    	if(_paramInput.getTime(index) - _lastTime >= _second) {
        	pushData();
          	_lastTime = _paramInput.getTime(index);
    	}
    	_nb++;
    	_sum =_sum + _paramInput.getDataList()[index];
    	_timeMemory.push_back(_paramInput.getTime(index));
    }
    if (pParamDataIndexInfo._timeIntToProcessChanged || pParamDataIndexInfo._noMoreTimeInt) {
    	pushData();
    }
  }

  /**
   * @overload Operation::reset(double pStartTime, double pTimeInt)
   * @brief reset static data to process another TimeInterval
   */
  virtual  void  reset() {
	  Operation::reset();
	  _nb = 0;
	  _lastTime = 0.0;
	  _sum << elemNull;
	  _timeMemory.clear();
	  if (_currentTimeInterval != _timeIntervalList->end())
		++_currentTimeInterval;
  }

private:

  /**
   * @brief write time and data in _paramOutput
   */
  inline void pushData() {

		typename TParamData::ElementType lMean = _sum / _nb;
		for(unsigned indexLocal = 0; indexLocal < _nb; ++indexLocal) {
			double crtTime = _timeMemory[indexLocal];
			if ((crtTime >= (*_currentTimeInterval)._startTime) && (crtTime <= (*_currentTimeInterval)._stopTime)) {
				_paramOutput->pushTime(crtTime);
				_paramOutput->getDataList().push_back(lMean);
			}

		}
  	_sum << elemNull ;
  	_nb = 0;
  	_timeMemory.clear();
  }
	/**
	 * @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 laps time to shift data.
   */
  double _second;

  /**
   * @brief sum of data to compute mean = _sum / _nb.
   */
  typename TParamData::ElementType _sum;

  /**
   * @brief number of data to compute mean = _sum / _nb.
   */
  unsigned int _nb;

  /**
   * @brief time memory.
   */
  std::vector <double > _timeMemory;

  /**
   * @brief last start time of mean compute .
   */
  double _lastTime;
};

} /* namespace Parameters */
} /* namespace AMDA */
#endif /* Boxcar_HH_ */