/* * Pusher.h * * Created on: Dec 10, 2012 * Author: f.casimir */ #ifndef PUSHER_H_ #define PUSHER_H_ #include #include "ParamData.hh" #include "DD.hh" namespace AMDA { namespace Parameters { namespace Base { /** * @class Pusher * @details This class is the operation responsible to transform raw data from DDServer into a ParamData * of the corresponding type ( scalar or vector or Tab2D of short or int or float or double or ... type). */ struct Pusher { Pusher (int dim1=1,int dim2=1) : _dim1(dim1), _dim2(dim2), _paramData(NULL), _fillValue(NAN) {} virtual ~Pusher() {} virtual void put(DD_data_t *data) = 0; virtual void putNaN() = 0; void setFillValue(double pFillValue) { _fillValue = pFillValue; } double getFillValue() { return _fillValue; } int _dim1; /*!< Used for vector and Tab2D */ int _dim2; /*!< Used for Tab2D */ ParamData* _paramData; /*!< return ParamData to a Process*/ protected: float _fillValue; /*!< When this value is different of NAN, into the raw data, it is replaced by NAN into ParamData. */ }; } //#define DD_SHORT 4 //#define DD_INT 1 //#define DD_FLOAT 2 //#define DD_DOUBLE 3 //#define DD_CHAR 0 typedef enum { CT_UNKNOWN, CT_SCALAR, CT_TAB1D, CT_TAB2D } ContainerType; template struct MapType { typedef void Type; }; template <> struct MapType<4> { typedef short Type; }; template <> struct MapType<1> { typedef int Type; }; template <> struct MapType<2> { typedef float Type; }; template <> struct MapType<3> { typedef double Type; }; template <> struct MapType<0> { typedef char Type; }; template class Pusher; /** * @brief Pusher implementation for the CT_TAB2D. */ template class Pusher : public Base::Pusher { public: typedef typename MapType::Type BaseElemenType; typedef Tab2DData ElemenType; typedef ParamDataSpec SpecParamData; SpecParamData* _specParamData; Pusher(int dim1, int dim2) : Base::Pusher(dim1,dim2) { _paramData = _specParamData = createParamData(); } void put(DD_data_t *data) { BaseElemenType **lData = reinterpret_cast(data->Variables); //ParamData is created, add data _specParamData->getDataList().resize(data->VarNumber); for (int index = 0; index < data->VarNumber; index++) { ElemenType elem = ElemenType(data->Dimensions[0],data->Dimensions[1]); for (int dim1Index= 0; dim1Index < data->Dimensions[0]; ++dim1Index) { for (int dim2Index= 0; dim2Index < data->Dimensions[1]; ++dim2Index) { BaseElemenType baseElem = lData[index][dim1Index*data->Dimensions[1]+dim2Index]; if (!isnan(_fillValue)) { if(baseElem == _fillValue) baseElem = (BaseElemenType)NAN; } elem[dim1Index][dim2Index] = baseElem; } } _specParamData->getDataList().push_back(elem); } } void putNaN() { _specParamData->getDataList().resize(1); ElemenType nanElem = ElemenType(_dim1,_dim2); for(int i = 0; i < _dim1; ++i) { for(int j = 0; j < _dim2; ++j) { nanElem[i][j] = ((BaseElemenType)NAN); } } _specParamData->getDataList().push_back(nanElem); } SpecParamData* createParamData() { return new ParamDataSpec< Tab2DData::Type> >(_dim1,_dim2); } }; /** * @brief Pusher implementation for the CT_TAB1D. */ template class Pusher : public Base::Pusher { public: typedef typename MapType::Type BaseElemenType; typedef std::vector ElemenType; typedef ParamDataSpec SpecParamData; SpecParamData* _specParamData; Pusher(int dim) : Base::Pusher(dim) { _paramData = _specParamData = createParamData(); } void put(DD_data_t *data) { BaseElemenType **lData = reinterpret_cast(data->Variables); //ParamData is created, add data _specParamData->getDataList().resize(data->VarNumber); for (int index = 0; index < data->VarNumber; index++) { ElemenType elem = ElemenType(lData[index],lData[index]+_dim1); if(!isnan(_fillValue)) { for(auto it = elem.begin(); it != elem.end(); ++it) { if(*it == _fillValue) { *it = (BaseElemenType)NAN; } } } _specParamData->getDataList().push_back(elem); } } void putNaN() { _specParamData->getDataList().resize(1); ElemenType nanElem = ElemenType(); for(int i = 0; i < _dim1; ++i) { nanElem.push_back((BaseElemenType)NAN); } _specParamData->getDataList().push_back(nanElem); } SpecParamData* createParamData() { return new ParamDataSpec< std::vector::Type> >(_dim1); } }; /** * @brief Pusher implementation for the scalar. */ template class Pusher : public Base::Pusher { public: typedef typename MapType::Type BaseElemenType; typedef BaseElemenType ElemenType; typedef ParamDataSpec SpecParamData; SpecParamData* _specParamData; /** * @brief Constructor * @details Create the real ParamData. */ Pusher() : Base::Pusher() { _paramData = _specParamData = createParamData(); } void put(DD_data_t *data) { BaseElemenType **lData = reinterpret_cast(data->Variables); //ParamData is created, add data _specParamData->getDataList().resize(data->VarNumber); if(!isnan(_fillValue)) { for (int index = 0; index < data->VarNumber; index++) { if(*lData[index] != _fillValue) { _specParamData->getDataList().push_back(*lData[index]); } else { _specParamData->getDataList().push_back((BaseElemenType)NAN); } } } else { for (int index = 0; index < data->VarNumber; index++) { _specParamData->getDataList().push_back(*lData[index]); } } } void putNaN() { _specParamData->getDataList().resize(1); _specParamData->getDataList().push_back((BaseElemenType)NAN); } SpecParamData* createParamData() { return new SpecParamData(); } }; } /* namespace Parameters */ } /* namespace AMDA */ #endif /* PUSHER_H_ */