/* * SumIntoTableRange.hh * * Created on: Oct 6, 2016 * Author: AKKA IS */ #ifndef SUMINTOTABLERANGE_HH_ #define SUMINTOTABLERANGE_HH_ #include "Parameter.hh" #include "ParamData.hh" #include "DataTypeMath.hh" #include "Operation.hh" namespace AMDA { namespace Parameters { namespace SumIntoTableRange { namespace Base { class TableDataTransform { public: virtual ~TableDataTransform() {} virtual std::vector transformData(unsigned int /*index*/) = 0; }; } template class TableDataTransform : public Base::TableDataTransform { public: /** * @brief Constructor */ TableDataTransform(ParamInput& pParamInput) : _paramInput(pParamInput) {} private: /** * @brief paramData Input */ ParamInput& _paramInput; }; template class TableDataTransform >> : public Base::TableDataTransform { public: typedef ParamDataSpec > ParamInput; /** * @brief Constructor */ TableDataTransform(ParamInput& pParamInput) : _paramInput(pParamInput) {} /** * @overload Base::TableDataTransform::transformData(unsigned int index) */ std::vector transformData(unsigned int index) { const std::vector& lData = _paramInput.getDataList()[index]; std::vector transData; for (typename std::vector::const_iterator it = lData.begin(); it != lData.end(); ++it) { transData.push_back((double)*it); } return transData; } private: ParamInput& _paramInput; }; class TableParamDataVisitor : public VisitorOfParamData { public: /** * @brief Constructor. */ TableParamDataVisitor(ParamData& pInputParamData) : _dataTransform(NULL) { pInputParamData.accept(*this); } /** * @overload VisitorOfParamData::visit(ParamDataScalaireShort *) */ void visit(ParamDataScalaireShort *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("TableParamDataPusher operation not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataScalaireFloat *) */ void visit(ParamDataScalaireFloat *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("TableParamDataPusher operation not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataScalaireDouble *) */ void visit(ParamDataScalaireDouble *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("TableParamDataPusher operation not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataScalaireLongDouble *) */ void visit(ParamDataScalaireLongDouble *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("TableParamDataPusher operation not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataScalaireInt *) */ void visit(ParamDataScalaireInt *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("TableParamDataPusher operation not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataLogicalData *) */ void visit(ParamDataLogicalData *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("TableParamDataPusher operation not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DShort *) */ void visit(ParamDataTab1DShort *pInputParamData) { _dataTransform = new TableDataTransform(*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DFloat *) */ void visit(ParamDataTab1DFloat *pInputParamData) { _dataTransform = new TableDataTransform(*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DDouble *) */ void visit(ParamDataTab1DDouble *pInputParamData) { _dataTransform = new TableDataTransform(*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DLongDouble *) */ void visit(ParamDataTab1DLongDouble *pInputParamData) { _dataTransform = new TableDataTransform(*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DInt *) */ void visit(ParamDataTab1DInt *pInputParamData) { _dataTransform = new TableDataTransform(*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DLogicalData *) */ void visit(ParamDataTab1DLogicalData *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("TableParamDataPusher operation not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DShort *) */ void visit(ParamDataTab2DShort *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("TableParamDataPusher operation not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DFloat *) */ void visit(ParamDataTab2DFloat *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("TableParamDataPusher operation not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DDouble *) */ void visit(ParamDataTab2DDouble *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("TableParamDataPusher operation not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DLongDouble *) */ void visit(ParamDataTab2DLongDouble *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("TableParamDataPusher operation not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DInt *) */ void visit(ParamDataTab2DInt *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("TableParamDataPusher operation not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DLogicalData *) */ void visit(ParamDataTab2DLogicalData *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("TableParamDataPusher operation not supported")); } /** * @brief get the Deriv parameterized operation. */ std::vector transformData(unsigned int index) { return _dataTransform->transformData(index); } private: Base::TableDataTransform* _dataTransform; }; class SumIntoTableRangeTool { public: SumIntoTableRangeTool(Process& pProcess, AMDA::Info::ParamTable* tablePtr, double minRange, double maxRange) : _process(pProcess), _tablePtr(tablePtr), _minRange(minRange), _maxRange(maxRange) { } virtual ~SumIntoTableRangeTool() { for (std::map::iterator it = _tableParamDataVisitor.begin(); it != _tableParamDataVisitor.end(); ++it) delete it->second; _tableParamDataVisitor.clear(); } std::list getIndexesList(double time, unsigned int size) { std::list indexes; if (!_tablePtr->isVariable(&_process.getParameterManager())) { AMDA::Info::t_TableBound crtBound; for (unsigned int i = 0; i < size; ++i) { crtBound = _tablePtr->getBound(&_process.getParameterManager(), i); if (crtBound.min >= _minRange && crtBound.max <= _maxRange) indexes.push_back(i); } } else { std::map> paramsTableData; for (std::map::iterator it = _tablePtr->getTableParams(&_process.getParameterManager()).begin(); it != _tablePtr->getTableParams(&_process.getParameterManager()).end(); ++it) { ParameterSPtr crtParam = _process.getParameterManager().getParameter(it->second); ParamData* ltableParamInput = crtParam->getParamData(&_process).get(); //Retrieve related index for this "table" parameter unsigned int crtTimeTableParamIndex = 0; for (unsigned int tableParamindex = ltableParamInput->getIndexInfo()._startIndex ; tableParamindex < ltableParamInput->getDataNumber(); ++tableParamindex) { if (time < ltableParamInput->getTime(tableParamindex)) break; crtTimeTableParamIndex = tableParamindex; } if (_tableParamDataVisitor.find(it->first) == _tableParamDataVisitor.end()) { _tableParamDataVisitor[it->first] = new TableParamDataVisitor(*ltableParamInput); } paramsTableData[it->first] = _tableParamDataVisitor[it->first]->transformData(crtTimeTableParamIndex); AMDA::Info::t_TableBound crtBound; for (unsigned int i = 0; i < size; ++i) { crtBound = _tablePtr->getBound(&_process.getParameterManager(), i, ¶msTableData); if ((crtBound.min >= _minRange) && (crtBound.max <= _maxRange)) { indexes.push_back(i); } } } } return indexes; } private: Process &_process; AMDA::Info::ParamTable* _tablePtr; double _minRange; double _maxRange; std::map _tableParamDataVisitor; }; /** * @class SumIntoTableRange1D * @brief It is responsible to compute the sum of 1D parameter data into a table range. * @details This class implement the interface Operation. */ template class SumIntoTableRange1D : public Operation { public: /** * @brief Constructor. * @details Create the ParamData type of the input ParamData. */ SumIntoTableRange1D(Process& pProcess, ParamDataSpec >& paramInput, double minRange, double maxRange, AMDA::Info::ParamTable* tablePtr) : Operation(pProcess), _paramInput(paramInput), _paramOutput(new ParamDataSpec()), _tableTool(pProcess, tablePtr, minRange, maxRange) { _paramDataOutput=_paramOutput; } virtual ~SumIntoTableRange1D() { } /** * @overload Operation::write(ParamDataIndexInfo &pParamDataIndexInfo) */ void write(ParamDataIndexInfo &pParamDataIndexInfo) { for (unsigned int _index = pParamDataIndexInfo._startIndex ; _index < pParamDataIndexInfo._startIndex + pParamDataIndexInfo._nbDataToProcess; ++_index) { double crtTime = _paramInput.getTime(_index); std::vector inputElt = _paramInput.get(_index); std::list indexes = _tableTool.getIndexesList(crtTime, inputElt.size()); DataType output = 0; for (std::list::iterator it = indexes.begin(); it != indexes.end(); ++it) { if (isNAN(inputElt[*it])) continue; output += inputElt[*it]; } _paramOutput->pushTime(crtTime); _paramOutput->getDataList().push_back(output); } } private: /**< * @brief It is the channel of data derived */ ParamDataSpec > &_paramInput; /**< * @brief It is the channel of the data derived */ ParamDataSpec *_paramOutput; SumIntoTableRangeTool _tableTool; }; /** * @class SumIntoTableRange2DOneRange * @brief It is responsible to compute the sum of 2D parameter data into one table range. * @details This class implement the interface Operation. */ template class SumIntoTableRange2DOneRange : public Operation { public: /** * @brief Constructor. * @details Create the ParamData type of the input ParamData when only one range is defined for one dimension (the output data is a vector). */ SumIntoTableRange2DOneRange(Process& pProcess, ParamDataSpec >& paramInput, double minRange, double maxRange, AMDA::Info::ParamTable* tablePtr, int tableRelatedDim) : Operation(pProcess), _paramInput(paramInput), _paramOutput(new ParamDataSpec>()), _tableTool(new SumIntoTableRangeTool(pProcess, tablePtr, minRange, maxRange)), _tableRelatedDim(tableRelatedDim) { _paramDataOutput = _paramOutput; } virtual ~SumIntoTableRange2DOneRange() { if (_tableTool != NULL) delete _tableTool; } /** * @overload Operation::write(ParamDataIndexInfo &pParamDataIndexInfo) */ void write(ParamDataIndexInfo &pParamDataIndexInfo) { for (unsigned int _index = pParamDataIndexInfo._startIndex ; _index < pParamDataIndexInfo._startIndex + pParamDataIndexInfo._nbDataToProcess; ++_index) { double crtTime = _paramInput.getTime(_index); Tab2DData inputElt = _paramInput.get(_index); std::vector outputElt; if (_tableRelatedDim == 0) { std::list indexesTable = _tableTool->getIndexesList(crtTime, inputElt.getDim1Size()); outputElt.resize(inputElt.getDim2Size(), 0); for (std::list::iterator it1 = indexesTable.begin(); it1 != indexesTable.end(); ++it1) { for (int i = 0; i < inputElt.getDim2Size(); ++i) { if (isNAN(inputElt[*it1][i])) continue; outputElt[i] += inputElt[*it1][i]; } } } else { std::list indexesTable = _tableTool->getIndexesList(crtTime, inputElt.getDim2Size()); outputElt.resize(inputElt.getDim1Size(), 0); for (std::list::iterator it1 = indexesTable.begin(); it1 != indexesTable.end(); ++it1) { for (int i = 0; i < inputElt.getDim1Size(); ++i) { if (isNAN(inputElt[i][*it1])) continue; outputElt[i] += inputElt[i][*it1]; } } } _paramOutput->pushTime(crtTime); _paramOutput->getDataList().push_back(outputElt); } } private: /**< * @brief It is the channel of data derived */ ParamDataSpec > &_paramInput; ParamDataSpec *_paramOutputScalar; ParamDataSpec> *_paramOutput; SumIntoTableRangeTool* _tableTool; int _tableRelatedDim; }; /** * @class SumIntoTableRange2DTwoRanges * @brief It is responsible to compute the sum of 2D parameter data into two tables ranges. * @details This class implement the interface Operation. */ template class SumIntoTableRange2DTwoRanges : public Operation { public: /** * @brief Constructor. * @details Create the ParamData type of the input ParamData when a range is defined for each dimensions (the output data is a scalar). */ SumIntoTableRange2DTwoRanges(Process& pProcess, ParamDataSpec >& paramInput, double minRange1, double maxRange1, AMDA::Info::ParamTable* table1Ptr, int table1RelatedDim, double minRange2, double maxRange2, AMDA::Info::ParamTable* table2Ptr) : Operation(pProcess), _paramInput(paramInput), _paramOutput(new ParamDataSpec()), _table1Tool(new SumIntoTableRangeTool(pProcess, table1Ptr, minRange1, maxRange1)), _table2Tool(new SumIntoTableRangeTool(pProcess, table2Ptr, minRange2, maxRange2)), _table1RelatedDim(table1RelatedDim) { _paramDataOutput = _paramOutput; } virtual ~SumIntoTableRange2DTwoRanges() { if (_table1Tool != NULL) delete _table1Tool; if (_table2Tool != NULL) delete _table2Tool; } /** * @overload Operation::write(ParamDataIndexInfo &pParamDataIndexInfo) */ void write(ParamDataIndexInfo &pParamDataIndexInfo) { for (unsigned int _index = pParamDataIndexInfo._startIndex ; _index < pParamDataIndexInfo._startIndex + pParamDataIndexInfo._nbDataToProcess; ++_index) { double crtTime = _paramInput.getTime(_index); Tab2DData inputElt = _paramInput.get(_index); std::list indexesTable1 = _table1Tool->getIndexesList(crtTime, inputElt.getDim1Size()); std::list indexesTable2 = _table2Tool->getIndexesList(crtTime, inputElt.getDim2Size()); DataType outputElt = 0; for (std::list::iterator it1 = indexesTable1.begin(); it1 != indexesTable1.end(); ++it1) { for (std::list::iterator it2 = indexesTable2.begin(); it2 != indexesTable2.end(); ++it2) { if (_table1RelatedDim == 0) { if (isNAN(inputElt[*it1][*it2])) continue; outputElt += inputElt[*it1][*it2]; } else { if (isNAN(inputElt[*it2][*it1])) continue; outputElt += inputElt[*it2][*it1]; } } } _paramOutput->pushTime(crtTime); _paramOutput->getDataList().push_back(outputElt); } } private: /**< * @brief It is the channel of data derived */ ParamDataSpec > &_paramInput; ParamDataSpec *_paramOutput; SumIntoTableRangeTool* _table1Tool; SumIntoTableRangeTool* _table2Tool; int _table1RelatedDim; }; } /* namespace SumIntoTableRange */ } /* namespace Parameters */ } /* namespace AMDA */ #endif /* SUMINTOTABLERANGE_HH_ */