Pusher.hh 7.55 KB
/*
 * Pusher.hh
 *
 *  Created on: Nov 25, 2014
 *      Author: AKKA
 */

#ifndef PUSHER_H_
#define PUSHER_H_

#include <vector>
#include "ParamData.hh"


#include "LocalParamData.hh"

namespace AMDA {
namespace LocalFileInterface {

/**
 * @class PusherBase
 * @details This class is the operation responsible to transform raw data from local file into a ParamData
 * of the corresponding type ( scalar or vector of short or int or float or double or ... type).
 */
struct PusherBase {
public:
	/*
	 * @brief Constructor
	 */
	PusherBase (int dim1=1, int dim2=1) : _paramData(NULL), _dim1(dim1), _dim2(dim2), _fillValue(NAN)
	{
	}

	/*
	 * @brief Destructor
	 */
	virtual ~PusherBase()
	{
	}

	/*
	 * @brief Set the fill value definition
	 * All fill values will be replaced by NAN
	 */
	void setFillValue(double pFillValue)
	{
		_fillValue = pFillValue;
	}

	/*
	 * @brief Get the ParamData
	 */
	AMDA::Parameters::ParamData* getParamData(void)
	{
		return _paramData;
	}

	/*
	 * @brief Virtual method to put a packet in the ParamData
	 */
	virtual int put(LocalParamDataPacket *packet) = 0;

	virtual void putNaN() = 0;

protected:
	/*
	 * @brief Pointer to the paramData
	 */
	AMDA::Parameters::ParamData* _paramData;

	/*
	 * @brief For Vector and Tab2D dimension
	 */
	int _dim1;

	/*
	 * @brief For Tab2D dimension
	 */
	int _dim2;

	/*
	 * @brief Fill value definition
	 */
	double _fillValue;
};



template <LocalParamType type>
struct MapType { typedef void Type; };

template <> struct MapType<LocalParamType::TYPE_SHORT>  { typedef short Type; };
template <> struct MapType<LocalParamType::TYPE_INT>  { typedef int Type; };
template <> struct MapType<LocalParamType::TYPE_FLOAT>  { typedef float Type; };
template <> struct MapType<LocalParamType::TYPE_DOUBLE> { typedef double Type; };


template<LocalParamType type,LocalContainerType container = CONTAINER_VECTOR>
class Pusher;

/**
 * @brief Pusher implementation for the Tab2D.
 */
template<LocalParamType type>
class Pusher<type,CONTAINER_MATRIX> : public PusherBase
{
public:
	/*
	 * @brief Define some usefull types
	 */
	typedef typename MapType<type>::Type BaseElemenType;
	typedef AMDA::Parameters::Tab2DData<BaseElemenType> ElemenType;
	typedef AMDA::Parameters::ParamDataSpec<ElemenType> SpecParamData;

	SpecParamData* _specParamData;

	/*
	 * @brief Constructor
	 */
	Pusher(int dim1, int dim2) : PusherBase(dim1,dim2)
	{
		_paramData = _specParamData = createParamData();
	}

	/*
	 * @brief Put packet in a "vector" ParamData
	 */
	virtual int put(LocalParamDataPacket *packet)
	{
		//ParamData is created, add data

		_specParamData->getDataList().resize(packet->getNbData());

		BaseElemenType fillEl = _fillValue;

		for (int index = 0; index < packet->getNbData(); ++index)
		{
			//get time
			double time = packet->getTime(index);
			//this element will be deleted by the Container designed by "_specParamData->getDataList()"
			ElemenType elem = ElemenType(packet->getDim1Size(),packet->getDim2Size());
			for (int dim1Index = 0;  dim1Index < packet->getDim1Size(); ++dim1Index)
			{
				for (int dim2Index = 0;  dim2Index < packet->getDim2Size(); ++dim2Index)
				{
					BaseElemenType baseElem;
					//get data element
					if (packet->getDataValue(&baseElem,index,dim1Index,dim2Index))
					{
						if (!isnan(_fillValue))
							if (baseElem == fillEl)
								baseElem = (BaseElemenType)NAN;
					}
					else
						baseElem = (BaseElemenType)NAN;
					elem[dim1Index][dim2Index] = baseElem;
				}
			}

			//push time and element in the ParamData
			_specParamData->getDataList().push_back(elem);
			_specParamData->getTimeList().push_back(time);
		}

		//return nb of processed records
		return packet->getNbData();
	}

	virtual 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);
	}

	/*
	 * @brief ParamData creation
	 */
	SpecParamData* createParamData()
	{
		return new AMDA::Parameters::ParamDataSpec<AMDA::Parameters::Tab2DData<typename MapType<type>::Type> >(_dim1,_dim2);
	}
};

/**
 * @brief Pusher implementation for the vector.
 */
template<LocalParamType type>
class Pusher<type,CONTAINER_VECTOR> : public PusherBase
{
public:
	/*
	 * @brief Define some usefull types
	 */
	typedef typename MapType<type>::Type BaseElemenType;
	typedef std::vector<BaseElemenType> ElemenType;
	typedef AMDA::Parameters::ParamDataSpec<ElemenType> SpecParamData;

	SpecParamData* _specParamData;

	/*
	 * @brief Constructor
	 */
	Pusher(int dim) : PusherBase(dim)
	{
		_paramData = _specParamData = createParamData();
	}

	/*
	 * @brief Put packet in a "vector" ParamData
	 */
	virtual int put(LocalParamDataPacket *packet)
	{
		//ParamData is created, add data
		_specParamData->getDataList().resize(packet->getNbData());

		BaseElemenType fillEl = _fillValue;

		for (int index = 0; index < packet->getNbData(); ++index)
		{
			//get time
			double time = packet->getTime(index);

			ElemenType elem;
			for (int dimIndex = 0;  dimIndex < packet->getDim1Size(); ++dimIndex)
			{
				BaseElemenType baseElem;
				//get data element
				if (packet->getDataValue(&baseElem,index,dimIndex))
				{
					if (!isnan(_fillValue))
						if (baseElem == fillEl)
							baseElem = (BaseElemenType)NAN;
				}
				else
					baseElem = (BaseElemenType)NAN;
				//push data base element
				elem.push_back(baseElem);
			}

			//push time and element in the ParamData
			_specParamData->getDataList().push_back(elem);
			_specParamData->getTimeList().push_back(time);
		}

		//return nb of processed records
		return packet->getNbData();
	}

	virtual void putNaN() {
		_specParamData->getDataList().resize(1);
		ElemenType nanElem = ElemenType();
		nanElem.resize(_dim1);
		nanElem << NotANumber();
		_specParamData->getDataList().push_back(nanElem);
	}

	/*
	 * @brief ParamData creation
	 */
	SpecParamData* createParamData()
	{
		return new AMDA::Parameters::ParamDataSpec< std::vector<typename MapType<type>::Type> >(_dim1);
	}
};

/**
 * @brief Pusher implementation for the scalar.
 */
template<LocalParamType type>
class Pusher<type,CONTAINER_SCALAR> : public PusherBase {
public:
	/*
	 * @brief Define some usefull types
	 */
	typedef typename MapType<type>::Type BaseElemenType;
	typedef BaseElemenType ElemenType;
	typedef AMDA::Parameters::ParamDataSpec<ElemenType> SpecParamData;

	SpecParamData* _specParamData;

	/*
	 * @brief Constructor
	 */
	Pusher() : PusherBase()
	{
		_paramData = _specParamData = createParamData();
	}

	/*
	 * @brief Put packet in a "scalar" ParamData
	 */
	virtual int put(LocalParamDataPacket *packet)
	{
		//ParamData is created, add data
		_specParamData->getDataList().resize(packet->getNbData());

		BaseElemenType fillEl = _fillValue;

		for (int index = 0; index < packet->getNbData(); ++index)
		{
			//get time
			double time = packet->getTime(index);

			BaseElemenType baseElem;
			//get element
			if (packet->getDataValue(&baseElem,index))
			{
				if (!isnan(_fillValue))
				{
					if (baseElem == fillEl)
						baseElem = (BaseElemenType)NAN;
				}
			}
			else
				baseElem = (BaseElemenType)NAN;

			//push time and element in the ParamData
			_specParamData->getDataList().push_back(baseElem);
			_specParamData->getTimeList().push_back(time);
		}

		return packet->getNbData();
	}

	virtual void putNaN() {
		_specParamData->getDataList().resize(1);
		_specParamData->getDataList().push_back((BaseElemenType)NAN);
	}

	SpecParamData* createParamData() {
		return new SpecParamData();
	}
};

} /* namespace LocalFileInterface */
} /* namespace AMDA */
#endif /* PUSHER_H_ */