ParamGetDDBase.cc 7.6 KB
/*
 * ParamGetDDBase.cc
 *
 *  Created on: 15 oct. 2012
 *      Author: casimir
 */

#include "DDServerInterfaceConfig.hh"
#include "VirtualInstrumentManager.hh"
#include "VirtualInstrument.hh"
#include "VirtualInstrumentInterval.hh"
#include "Packet.hh"
#include "ParamGetDDBase.hh"

#include <stdlib.h>

#include "Parameter.hh"
#include "ParamData.hh"
#include "ParamMgr.hh"
#include "DataSetMgr.hh"
#include "DicError.hh"
#include "TimeUtil.hh"
#include "Helper.hh"


using namespace AMDA::DDServerInterface;
using namespace VI;

namespace AMDA {

	namespace DDServerInterface {
		class VirtualInstrumentInterval;
	} // DDServerInterface

	namespace Parameters {

		ParamGetDDBase::ParamGetDDBase(Parameter &parameter) :
				ParamGet_CRTP<ParamGetDDBase>(parameter), _parName(""), _viName(""), _pusher(NULL), _timeStamp(0) {
		}

		ParamGetDDBase::ParamGetDDBase(const ParamGetDDBase &pParamGetDDBase, Parameter &parameter) :
				ParamGet_CRTP<ParamGetDDBase>(pParamGetDDBase, parameter), _parName(pParamGetDDBase._parName), _viName(pParamGetDDBase._viName)
								, _pusher(pParamGetDDBase._pusher), _infoRequestList(pParamGetDDBase._infoRequestList), _timeStamp(pParamGetDDBase._timeStamp) {
		}

		ParamGetDDBase::~ParamGetDDBase() {
			/*---------- Close VI and return -----------------------*/
			delete _pusher;
		}

		TimeStamp ParamGetDDBase::init() {
			/// Create ParamData
			_vi = VirtualInstrumentManager::getInstance()->getVirtualInstrument(
					_viName);
			_pusher = _vi->getParamPusher(_parName);
			//Param info
			AMDA::Info::ParamInfoSPtr paramInfo = AMDA::Info::ParamMgr::getInstance()->getParamInfoFromId(_parameter.getInfoId(),true);
			if ((paramInfo != nullptr) && (isnan(_pusher->getFillValue())) && (!isnan(paramInfo->getFillValue())))
			{
				_pusher->setFillValue(paramInfo->getFillValue());
			}
			_paramData = ParamDataSPtr(_pusher->_paramData);
			_paramData->setMinSampling(_vi->getMinSampling());

			getDDInfo();
			// Get ParamFlow instance only if there is at least one TimeInterval to process
			// and if delta is not equal to 0.
			if (_timeIntervalList->size() != 0 && !(_timeIntervalList->size() == 1 && (_timeIntervalList->front()._stopTime - _timeIntervalList->front()._startTime) == 0) ) {
				_paramFlow = _vi->getParamFlow(_parName, _timeIntervalList);
			} else if (_timeIntervalList->size() == 0) {
				LOG4CXX_WARN(gLogger, "ParamGetDDBase::init => List of time interval is empty");
			} else {
				// Nothing to do
			}
			if (_timeStamp == 0 && _signatureTrigger != "") {
				// _signatureTrigger must be a name of xml parameter file
				_timeStamp = AMDA::Helpers::Helper::dateOfFile(
						_signatureTrigger.c_str());
			}

			return _timeStamp;
		}

		unsigned int ParamGetDDBase::write() {
			unsigned int result = 0;

			if (_paramFlow.get() == nullptr) {
				BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::ex_msg("Param flow not yet initialized for parameter '" + _parName));
			} else {
				// Nothing to do
			}

			PacketPtr lPacket = _paramFlow->get();
			if (lPacket) {
				if (lPacket->nodata) {
					LOG4CXX_DEBUG(gLogger, "ParamGetDDBase::write => no data packet");
					//Add NaN value at interval start and stop times
					_paramData->getTimeList().push_back(lPacket->startTime);
					_pusher->putNaN();
					_paramData->getTimeList().push_back(lPacket->stopTime);
					_pusher->putNaN();
					_paramData->getIndexInfo()._timeIntToProcessChanged = _paramFlow->isTimeIntToProcessChanged();
					_paramData->getIndexInfo()._nbDataToProcess = 2;
					result += 2;
					delete lPacket;
				}
				else {
					do {
						result += lPacket->data->VarNumber;
						_pusher->put(lPacket->data.get());
						updateTimeInParamData(lPacket->time.get());
						delete lPacket;
					} while( ( lPacket = _paramFlow->tryGet()));

					// Push up the information if all time interval was processed.
					_paramData->getIndexInfo()._timeIntToProcessChanged = _paramFlow->isTimeIntToProcessChanged();
				}
			}
			else {
				// Push up the information if all time interval was processed.
				_paramData->getIndexInfo()._timeIntToProcessChanged = _paramFlow->isTimeIntToProcessChanged();
			}



			// if time interval changed store index which delimit the end of the time interval.
			if (_paramData->getIndexInfo()._timeIntToProcessChanged || (!_paramData->getIndexInfo()._timeIntToProcessChanged && result == 0)) {
				unsigned int lEndTimeIntIndex = _paramData->getIndexInfo()._nbDataToProcess;
				_paramData->getIndexInfo()._endTimeIntIndexList.push_back(lEndTimeIntIndex);
			}
			else {
				// Nothing to do.
			}

			return result;
		}

		void ParamGetDDBase::updateTimeInParamData(DD_data_t* data) {
			LOG4CXX_DEBUG(gLogger, "updateTimeInParamData data->VarNumber = " << data->VarNumber);
			//ParamData is created, add data
			//The capacity must be == at Data
			for (int index = 0; index < data->VarNumber; index++) {
				double t = DD_Time2Double((char *) data->Variables[index]);
				_paramData->getTimeList().push_back(t);
			}
		}

		void ParamGetDDBase::getDDInfo() {
			for (InfoRequestList::iterator lIt = _infoRequestList.begin();
					lIt != _infoRequestList.end(); ++lIt) {
				auto lInfoName = *lIt;
				if (_parameter.getInfoList().find(lInfoName)
						== _parameter.getInfoList().end()) {
					LOG4CXX_INFO( gLogger,
							"ParamGetDDBase:getInfoDD( " << lInfoName << "')");
					const InfoList& lList = _vi->getDDInfo(lIt->c_str());
					for (auto lIt : lList) {
						_parameter.setInfoValues(lIt.first.c_str(), lIt.second);
					}
				}
			}
		}

		/*
		 * @brief Get min sampling
		 */
		double ParamGetDDBase::getMinSampling()
		{
			_vi = VirtualInstrumentManager::getInstance()->getVirtualInstrument(
				_viName);
			return _vi->getMinSampling();
		}

		/**
		 * @brief update parameter info in relation to the ParamGet
		 */
		void ParamGetDDBase::updateInfo(Parameter & parameter)
		{
			LOG4CXX_DEBUG(gLogger, "ParamGetDDBase::updateInfo - " << parameter.getId());
			if (parameter.getInfoId().empty())
				parameter.setInfoId(parameter.getId());

			//Param info
			AMDA::Info::ParamInfoSPtr paramInfo = AMDA::Info::ParamMgr::getInstance()->getParamInfoFromId(parameter.getInfoId(),true);

			if (paramInfo == nullptr)
				return;

			//fill value automatically replace by nan
			paramInfo->setFillValue(NAN);

			//Add parameter info id as parameter name if no exist
			if (paramInfo->getName().empty())
				paramInfo->setName(parameter.getInfoId());

			//Add parameter info id as parameter short name if no exist
			if (paramInfo->getShortName().empty())
				paramInfo->setShortName(parameter.getInfoId());

			std::string datasetId = paramInfo->getDatasetId();
			if (datasetId.empty())
				//get vi ID as dataset id if no dataset info defined
				datasetId = _vi->getViName();

			//link dataset info to param info
			paramInfo->setDatasetId(datasetId);

			//Dataset info
			AMDA::Info::DataSetInfoSPtr datasetInfo = AMDA::Info::DataSetMgr::getInstance()->getDataSetInfoFromId(datasetId,true);

			if (datasetInfo == nullptr)
				return;

			//Add dataset id as dataset name if no exist
			if (datasetInfo->getName().empty())
				datasetInfo->setName(_vi->getViName());

			//Set sampling values
			datasetInfo->setMinSampling((int)_vi->getMinSampling());
			datasetInfo->setMaxSampling((int)_vi->getMaxSampling());

			//Set global start time
			std::stringstream isoTime;
			TimeUtil::formatTimeDateInIso(_vi->getGlobalStartTime(), isoTime);
			datasetInfo->setGlobalStart(isoTime.str());

			//Set global stop time
			isoTime.str("");
			TimeUtil::formatTimeDateInIso(_vi->getGlobalStopTime(), isoTime);
			datasetInfo->setGlobalStop(isoTime.str());

			//Set source
			datasetInfo->setSource("CDPP/DDServer");
		}

	} /* namespace Parameters */
} /* namespace AMDA */