/* * AbstractFunc.hh * * Created on: Jun 21, 2018 * Author: benjamin */ #ifndef ABSTRACTFUNC_HH_ #define ABSTRACTFUNC_HH_ #include "Parameter.hh" #include "ParamData.hh" #include "DataTypeMath.hh" #include "Operation.hh" #include namespace AMDA { namespace Parameters { namespace StatisticFunctions { /** * @class AbstractFunc * @brief * @details This class implement the interface Operation. */ class AbstractFuncBase : public Operation { public: AbstractFuncBase(Process& pProcess, TimeIntervalListSPtr pTimeIntervalList, double windowtime) : Operation(pProcess), _timeIntervalList(pTimeIntervalList), _currentTimeInterval(pTimeIntervalList->begin()), _windowtime(windowtime), _needInit(true) { } virtual ~AbstractFuncBase() { } double getWindowTime() { return _windowtime; } bool inWindow(double time) { return (time >= _minWindow && time <= _maxWindow); } double getIntStartTime() { return _currentTimeInterval->_startTime; } double getIntStopTime() { return _currentTimeInterval->_stopTime; } bool inInt(double time) { return (time >= _currentTimeInterval->_startTime && time <= _currentTimeInterval->_stopTime); } double getTarget() { return _target; } bool needInit() { return _needInit; } void setNeedInit(bool needInit) { _needInit = needInit; } bool setTarget(double time) { if (!inInt(time)) { return false; } _target = time; _minWindow = _target - _windowtime / 2.; if (_minWindow < _currentTimeInterval->_startTime) { _minWindow = _currentTimeInterval->_startTime; } _maxWindow = _target + _windowtime / 2.; if (_maxWindow > _currentTimeInterval->_stopTime) { _maxWindow = _currentTimeInterval->_stopTime; } return true; } /** * @overload Operation::reset(double pStartTime, double pTimeInt) * @brief reset static data to process another TimeInterval */ virtual void reset() { Operation::reset(); if (_currentTimeInterval == _timeIntervalList->end()) { return; } ++_currentTimeInterval; _needInit = true; resetFunc(); } virtual bool nextTarget() = 0; virtual bool needToChangeTarget(double crtTime) = 0; virtual double getSampling() = 0; virtual void init() = 0; virtual void resetFunc() = 0; private: TimeIntervalListSPtr _timeIntervalList; TimeIntervalList::iterator _currentTimeInterval; double _windowtime; double _minWindow; double _maxWindow; double _target; bool _needInit; }; template class AbstractFunc : public AbstractFuncBase { public: /** * @brief Constructor. * @details Create the ParamData type of the input ParamData. */ AbstractFunc(Process& pProcess, TimeIntervalListSPtr pTimeIntervalList, ParamDataSpec& paramInput, double windowtime) : AbstractFuncBase(pProcess, pTimeIntervalList, windowtime), _paramInput(paramInput), _paramOutput(new ParamDataSpec) { _paramDataOutput=_paramOutput; } virtual ~AbstractFunc() { } virtual void pushData(double time, InputElemType& elem) = 0; virtual OutputElemType compute() = 0; /** * @overload Operation::write(ParamDataIndexInfo &pParamDataIndexInfo) */ void write(ParamDataIndexInfo &pParamDataIndexInfo) { if ((pParamDataIndexInfo._nbDataToProcess > 0)) { if (pParamDataIndexInfo._startIndex == 0) { _nanVal = _paramInput.get(0); _nanVal << NotANumber(); } for (unsigned int _index = pParamDataIndexInfo._startIndex ; _index < pParamDataIndexInfo._startIndex + pParamDataIndexInfo._nbDataToProcess; ++_index) { double crtTime = _paramInput.getTime(_index); InputElemType crtVal = _paramInput.get(_index); if (needToChangeTarget(crtTime)) { _paramOutput->pushTime(getTarget()); _paramOutput->push(compute()); pushData(crtTime, crtVal); nextTarget(); bool skip = false; while (!skip && needToChangeTarget(crtTime)) { _paramOutput->pushTime(getTarget()); _paramOutput->push(compute()); skip = nextTarget(); } } else { pushData(crtTime, crtVal); if (needInit()) { init(); } } } } if (pParamDataIndexInfo._timeIntToProcessChanged || pParamDataIndexInfo._noMoreTimeInt) { if (!needInit()) { do { if (inInt(getTarget())) { _paramOutput->pushTime(getTarget()); _paramOutput->push(compute()); } } while (nextTarget()); } } } double getInputParamSampling() { return _paramInput.getMinSampling(); } private: ParamDataSpec& _paramInput; ParamDataSpec* _paramOutput; protected: OutputElemType _nanVal; }; template class Abstract2ParamsFunc : public AbstractFuncBase { public: /** * @brief Constructor. * @details Create the ParamData type of the input ParamData. */ Abstract2ParamsFunc(Process& pProcess, TimeIntervalListSPtr pTimeIntervalList, ParamDataSpec& param1Input, ParamDataSpec& param2Input, double windowtime) : AbstractFuncBase(pProcess, pTimeIntervalList, windowtime), _param1Input(param1Input), _param2Input(param2Input), _paramOutput(new ParamDataSpec) { _paramDataOutput=_paramOutput; } virtual ~Abstract2ParamsFunc() { } virtual void pushData(double time, InputElemType& elem1, InputElemType& elem2) = 0; virtual OutputElemType compute() = 0; /** * @overload Operation::write(ParamDataIndexInfo &pParamDataIndexInfo) */ void write(ParamDataIndexInfo &pParamDataIndexInfo) { if ((pParamDataIndexInfo._nbDataToProcess > 0)) { for (unsigned int _index = pParamDataIndexInfo._startIndex ; _index < pParamDataIndexInfo._startIndex + pParamDataIndexInfo._nbDataToProcess; ++_index) { double crtTime = _param1Input.getTime(_index); InputElemType crtVal1 = _param1Input.get(_index); InputElemType crtVal2 = _param2Input.get(_index); if (needToChangeTarget(crtTime)) { _paramOutput->pushTime(getTarget()); _paramOutput->push(compute()); pushData(crtTime, crtVal1, crtVal2); nextTarget(); bool skip = false; while (!skip && needToChangeTarget(crtTime)) { _paramOutput->pushTime(getTarget()); _paramOutput->push(compute()); skip = nextTarget(); } } else { pushData(crtTime, crtVal1, crtVal2); if (needInit()) { init(); } } } } if (pParamDataIndexInfo._timeIntToProcessChanged || pParamDataIndexInfo._noMoreTimeInt) { if (!needInit()) { do { if (inInt(getTarget())) { _paramOutput->pushTime(getTarget()); _paramOutput->push(compute()); } } while (nextTarget()); } } } double getInputParamSampling() { return _param1Input.getMinSampling(); } public: ParamDataSpec& _param1Input; ParamDataSpec& _param2Input; ParamDataSpec* _paramOutput; }; template class ClassicAbstractFunc : public AbstractFunc { public: ClassicAbstractFunc(Process& pProcess, TimeIntervalListSPtr pTimeIntervalList, ParamDataSpec& paramInput, double windowtime) : AbstractFunc(pProcess, pTimeIntervalList, paramInput, windowtime) { } virtual ~ClassicAbstractFunc() { } virtual void init() { AbstractFunc::setTarget(AbstractFunc::getIntStartTime()); AbstractFunc::setNeedInit(false); } virtual bool nextTarget() { double target = AbstractFunc::getTarget() + AbstractFunc::getWindowTime(); bool res = AbstractFunc::setTarget(target); while (!_mem.empty() && !AbstractFunc::inWindow(_mem.front().first)) { _mem.pop_front(); } return res; } virtual bool needToChangeTarget(double crtTime) { return !AbstractFunc::needInit() && !AbstractFunc::inWindow(crtTime); } virtual double getSampling() { return AbstractFunc::getWindowTime(); } virtual void pushData(double time, InputElemType& elem) { _mem.push_back(std::make_pair(time, elem)); } virtual void resetFunc() { _mem.clear(); } protected: std::list > _mem; }; template class SmAbstractFunc : public AbstractFunc { public: SmAbstractFunc(Process& pProcess, TimeIntervalListSPtr pTimeIntervalList, ParamDataSpec& paramInput, double windowtime) : AbstractFunc(pProcess, pTimeIntervalList, paramInput, windowtime) { } virtual ~SmAbstractFunc() { } virtual void init() { if (!_targets.empty()) { AbstractFunc::setTarget(_targets.front()); AbstractFunc::setNeedInit(false); _targets.pop_front(); } } virtual bool nextTarget() { if (!_targets.empty()) { bool res = AbstractFunc::setTarget(_targets.front()); _targets.pop_front(); while (!_mem.empty() && !AbstractFunc::inWindow(_mem.front().first)) { _mem.pop_front(); } return res; } return false; } virtual bool needToChangeTarget(double crtTime) { return !AbstractFunc::needInit() && !AbstractFunc::inWindow(crtTime) && !_targets.empty() ; } virtual double getSampling() { return AbstractFunc::getInputParamSampling(); } virtual void pushData(double time, InputElemType& elem) { _mem.push_back(std::make_pair(time, elem)); _targets.push_back(time); } virtual void resetFunc() { _mem.clear(); _targets.clear(); } protected: std::list _targets; std::list > _mem; }; template class Sm2ParamsAbstractFunc : public Abstract2ParamsFunc { public: Sm2ParamsAbstractFunc(Process& pProcess, TimeIntervalListSPtr pTimeIntervalList, ParamDataSpec& param1Input, ParamDataSpec& param2Input, double windowtime) : Abstract2ParamsFunc(pProcess, pTimeIntervalList, param1Input, param2Input, windowtime) { } virtual ~Sm2ParamsAbstractFunc() { } virtual void init() { if (!_targets.empty()) { Abstract2ParamsFunc::setTarget(_targets.front()); Abstract2ParamsFunc::setNeedInit(false); _targets.pop_front(); } } virtual bool nextTarget() { if (!_targets.empty()) { bool res = Abstract2ParamsFunc::setTarget(_targets.front()); _targets.pop_front(); while (!_mem.empty() && !Abstract2ParamsFunc::inWindow(_mem.front().first)) { _mem.pop_front(); } return res; } return false; } virtual bool needToChangeTarget(double crtTime) { return !Abstract2ParamsFunc::needInit() && !Abstract2ParamsFunc::inWindow(crtTime) && !_targets.empty() ; } virtual double getSampling() { return Abstract2ParamsFunc::getInputParamSampling(); } virtual void pushData(double time, InputElemType& elem1, InputElemType& elem2) { _mem.push_back(std::make_pair(time, std::make_pair(elem1,elem2))); _targets.push_back(time); } virtual void resetFunc() { _mem.clear(); _targets.clear(); } protected: std::list _targets; std::list > > _mem; }; } /* namespace StatisticFunctions */ } /* namespace Parameters */ } /* namespace AMDA */ #endif /* ABSTRACTFUNC_HH_ */