CountStatistic.hh 13.5 KB

/* 
 * File:   CountStatistic.hh
 * Author: AKKA
 *
 * Created on December 20, 2019, 1:44 PM
 */

#ifndef COUNTSTATISTIC_HH
#define COUNTSTATISTIC_HH

#include "ParamData.hh"
#include "DataTypeMath.hh"
#include "VisitorOfParamData.hh"
#include "StatisticData.hh"
#include "StatisticOperation.hh"
#include "StatisticProcess.hh"
#include <math.h>
#include "TimeInterval.hh"

namespace AMDA {
    namespace Statistic {
        namespace Count {

            using namespace AMDA::Parameters;

            typedef enum {
                FT_COUNT,
                FT_COUNT_NOT_NAN
            } COUNT_FUNC_TYPE;

            template <typename TParamData, typename TResultData>
            class CountStatisticOperation : public StatisticOperation<TResultData> {
            public:
                typedef typename TParamData::ElementType ElementType;

                CountStatisticOperation(StatisticProcess& process,
                        TimeIntervalListSPtr pTimeIntervalList, TParamData &param,  COUNT_FUNC_TYPE funcType) :
                StatisticOperation<TResultData>(process),
                _paramInput(param), _timeIntervalList(pTimeIntervalList),
                _currentTimeInterval(_timeIntervalList->begin()),
                _funcType(funcType), _dimDef("unknown") {
                    resetData(StatisticOperation<TResultData>::_resultData);
                }

                virtual ~CountStatisticOperation(void) {
                }

                virtual void compute(ParamDataIndexInfo &pParamDataIndexInfo) {
                    for (unsigned int index = pParamDataIndexInfo._startIndex;
                            index < pParamDataIndexInfo._startIndex
                            + pParamDataIndexInfo._nbDataToProcess;
                            index++) {
                        _val = _paramInput.get(index);
                        switch (_funcType) {
                            case FT_COUNT:
                                count(_val);
                                break;
                            case FT_COUNT_NOT_NAN:
                                count(_val, "NotNan");
                                break;
                        }
                    }
                }

                virtual void finalizeCompute(void) {
                    if (_funcType == FT_COUNT || _funcType == FT_COUNT_NOT_NAN) {
                        finalizeCountResult(StatisticOperation<TResultData>::_resultData);
                    }
                }

                virtual std::string getResultDimDefinition(bool /* forCoverage */) {
                    return _dimDef.str();
                }

                virtual void reset() {
                    StatisticOperation<TResultData>::reset();
                    resetData(StatisticOperation<TResultData>::_resultData);
                }
            private:

                template<typename Type>
                void resetData(Type &a) {
                    a._result << NotANumber();
                    a._nbDataProcessed = 0;
                }

                template<typename Type>
                void resetData(std::vector<Type> &a) {
                    a.clear();
                }

                template<typename Type>
                void count(Type &a, std::string mode = " ") {
                    _dimDef.str("1");
                    if (mode == "NotNan" && isNAN(a))
                        return;
                    ++StatisticOperation<TResultData>::_resultData._nbDataProcessed;
                }

                template<typename Type>
                void count(std::vector<Type> &a, std::string mode = " ") {
                    if (StatisticOperation<TResultData>::_resultData.empty()) {
                        _dimDef.str("");
                        _dimDef << a.size();
                        for (unsigned int i = 0; i < a.size(); ++i) {
                            StatisticDataScalar<int> data;
                            resetData(data);
                            if (!isNAN(a[i]) || mode == " ")
                                ++data._nbDataProcessed;
                            StatisticOperation<TResultData>::_resultData.push_back(data);
                        }
                        return;
                    }
                    for (unsigned int i = 0; i < StatisticOperation<TResultData>::_resultData.size(); ++i) {
                        if (isNAN(a[i]) && mode == "NotNan")
                            continue;
                        ++StatisticOperation<TResultData>::_resultData[i]._nbDataProcessed;
                    }
                }

                template<typename Type>
                void finalizeCountResult(Type &a) {
                    if (!isNAN(a._nbDataProcessed))
                        a._result = a._nbDataProcessed;
                }

                template<typename Type>
                void finalizeCountResult(std::vector<Type> &a) {
                    for (int i = 0; i < a.size(); i++)
                        finalizeCountResult(a[i]);
                }

                /**
                 * @brief real ParamData Input
                 */
                TParamData& _paramInput;

                TimeIntervalListSPtr _timeIntervalList;

                TimeIntervalList::iterator _currentTimeInterval;

                ElementType _val;

                 COUNT_FUNC_TYPE _funcType;

                std::stringstream _dimDef;

            }; //Class Count

            class CreateCountStatistic : public VisitorOfParamData {
            public:

                CreateCountStatistic(StatisticProcess& pProcess,
                        TimeIntervalListSPtr pTimeIntervalList,
                        ParamData &paramData, COUNT_FUNC_TYPE type) :
                _process(pProcess), _timeIntervalList(pTimeIntervalList),
                _paramData(paramData), _operation(NULL), _type(type) {
                    _paramData.accept(*this);
                }

                StatisticOperationBase* getStatisticOperation(void) {
                    return _operation;
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataScalaireShort *)
                 */
                virtual void visit(ParamDataScalaireShort *) {
                    _operation = new CountStatisticOperation<ParamDataScalaireShort, StatisticDataScalar<int>>(_process,
                            _timeIntervalList, dynamic_cast<ParamDataScalaireShort &> (_paramData), _type);
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataScalaireFloat *)
                 */
                virtual void visit(ParamDataScalaireFloat *) {
                    _operation = new CountStatisticOperation<ParamDataScalaireFloat, StatisticDataScalar<int>>(_process,
                            _timeIntervalList, dynamic_cast<ParamDataScalaireFloat &> (_paramData), _type);
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataScalaireDouble *)
                 */
                virtual void visit(ParamDataScalaireDouble *) {
                    _operation = new CountStatisticOperation<ParamDataScalaireDouble, StatisticDataScalar<int>>(_process,
                            _timeIntervalList, dynamic_cast<ParamDataScalaireDouble &> (_paramData), _type);
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataScalaireLongDouble *)
                 */
                virtual void visit(ParamDataScalaireLongDouble *) {
                    _operation = new CountStatisticOperation<ParamDataScalaireLongDouble, StatisticDataScalar<int>>(_process,
                            _timeIntervalList, dynamic_cast<ParamDataScalaireLongDouble &> (_paramData), _type);
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataScalaireInt *)
                 */
                virtual void visit(ParamDataScalaireInt *) {
                    _operation = new CountStatisticOperation<ParamDataScalaireInt, StatisticDataScalar<int>>(_process,
                            _timeIntervalList, dynamic_cast<ParamDataScalaireInt &> (_paramData), _type);
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataLogicalData *)
                 */
                virtual void visit(ParamDataLogicalData *) {
                    BOOST_THROW_EXCEPTION(
                            AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN)
                            << AMDA::ex_msg(
                            "CreateStatistic operation not supported"));
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataTab1DShort *)
                 */
                virtual void visit(ParamDataTab1DShort *) {
                    _operation = new CountStatisticOperation<ParamDataTab1DShort, StatisticDataVector<int>>(_process,
                            _timeIntervalList, dynamic_cast<ParamDataTab1DShort &> (_paramData), _type);
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataTab1DFloat *)
                 */
                virtual void visit(ParamDataTab1DFloat *) {
                    _operation = new CountStatisticOperation<ParamDataTab1DFloat, StatisticDataVector<int>>(_process,
                            _timeIntervalList, dynamic_cast<ParamDataTab1DFloat &> (_paramData), _type);
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataTab1DDouble *)
                 */
                virtual void visit(ParamDataTab1DDouble *) {
                    _operation = new CountStatisticOperation<ParamDataTab1DDouble, StatisticDataVector<int>>(_process,
                            _timeIntervalList, dynamic_cast<ParamDataTab1DDouble &> (_paramData), _type);
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataTab1DLongDouble *)
                 */
                virtual void visit(ParamDataTab1DLongDouble *) {
                    _operation = new CountStatisticOperation<ParamDataTab1DLongDouble, StatisticDataVector<int>>(_process,
                            _timeIntervalList, dynamic_cast<ParamDataTab1DLongDouble &> (_paramData), _type);
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataTab1DInt *)
                 */
                virtual void visit(ParamDataTab1DInt *) {
                    _operation = new CountStatisticOperation<ParamDataTab1DInt, StatisticDataVector<int>>(_process,
                            _timeIntervalList, dynamic_cast<ParamDataTab1DInt &> (_paramData), _type);
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataTab1DLogicalData *)
                 */
                virtual void visit(ParamDataTab1DLogicalData *) {
                    BOOST_THROW_EXCEPTION(
                            AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN)
                            << AMDA::ex_msg(
                            "CreateStatistic operation not supported"));
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataTab2DShort *)
                 */
                virtual void visit(ParamDataTab2DShort *) {
                    BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("ParamDataTab2DShort data not supported"));
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataTab2DFloat *)
                 */
                virtual void visit(ParamDataTab2DFloat *) {
                    BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("ParamDataTab2DFloat data not supported"));
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataTab2DDouble *)
                 */
                virtual void visit(ParamDataTab2DDouble *) {
                    BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("ParamDataTab2DDouble data not supported"));
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataTab2DLongDouble *)
                 */
                virtual void visit(ParamDataTab2DLongDouble *) {
                    BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("ParamDataTab2DLongDouble data not supported"));
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataTab2DInt *)
                 */
                virtual void visit(ParamDataTab2DInt *) {
                    BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("ParamDataTab2DInt data not supported"));
                }

                /**
                 * @overload VisitorOfParamData::visit(ParamDataTab2DLogicalData *)
                 */
                virtual void visit(ParamDataTab2DLogicalData *) {
                    BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("ParamDataTab2DLogicalData data not supported"));
                }

            private:
                StatisticProcess& _process;

                TimeIntervalListSPtr& _timeIntervalList;

                ParamData &_paramData;

                StatisticOperationBase *_operation;

                COUNT_FUNC_TYPE _type;


            };

        }//Count
    }//STATISTIC
} //AMDA



#endif /* COUNTSTATISTIC_HH */