ParamGetDDBase.cc 9.99 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(""), _maxDim1Size(-1), _maxDim2Size(-1), _maxDim3Size(-1), _dim3Num(-1), _dim3CutIndex(-1), _minSumIndex(-1), _maxSumIndex(-1), _pusher(NULL), _timeStamp(0) {
		}

		ParamGetDDBase::ParamGetDDBase(const ParamGetDDBase &pParamGetDDBase, Parameter &parameter) :
				ParamGet_CRTP<ParamGetDDBase>(pParamGetDDBase, parameter), _parName(pParamGetDDBase._parName), _viName(pParamGetDDBase._viName)
								, _maxDim1Size(pParamGetDDBase._maxDim1Size), _maxDim2Size(pParamGetDDBase._maxDim2Size), _maxDim3Size(pParamGetDDBase._maxDim3Size)
								, _dim3Num(pParamGetDDBase._dim3Num), _dim3CutIndex(pParamGetDDBase._dim3CutIndex)
                                                                                                                                                                , _minSumIndex(pParamGetDDBase._minSumIndex), _maxSumIndex(pParamGetDDBase._maxSumIndex)
								, _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, _maxDim1Size, _maxDim2Size, _maxDim3Size, _dim3Num, _dim3CutIndex, _minSumIndex, _maxSumIndex, _parameter.getTimeRestriction());
			//Param info
			AMDA::Info::ParamInfoSPtr paramInfo = AMDA::Info::ParamMgr::getInstance()->getParamInfoFromId(_parameter.getInfoId(),true);
			if ((paramInfo != nullptr) && (!isnan(paramInfo->getOriginalFillValue())))
			{
				_pusher->setFillValue(paramInfo->getOriginalFillValue());
			}
			_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());
			}
                        
                        setGlobalStart(_vi->getGlobalStartTime());
                        setGlobalStop(_vi->getGlobalStopTime());

			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()._noMoreTimeInt = _paramFlow->isNoMoreTimeInt();
					_paramData->getIndexInfo()._nbDataToProcess = 2;
					result += 2;
					delete lPacket;
				}
				else {
					do {
						result += lPacket->data->VarNumber;
						LOG4CXX_DEBUG(gLogger, "put data " << lPacket->data->VarNumber);
						_pusher->put(lPacket->data.get(), lPacket->time.get());
						delete lPacket;
					} while( ( lPacket = _paramFlow->tryGet()));

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



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

			return result;
		}

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

 										                                                            // adding tableParams into linked params 
                                                            std::map<int, boost::shared_ptr<AMDA::Info::ParamTable>> tables =paramInfo->getTables();

                                                            if(! tables.empty()){
                                                                 for(auto table : tables){
                                                                     if (table.second != nullptr){
                                                                            if(table.second->isVariable(&parameter.getParameterManager())){
                                                                            std::map<std::string, std::string> tableParams = table.second->getTableParams(&parameter.getParameterManager());
                                                                            if(! tableParams.empty())
                                                                                for(auto tableParam : tableParams){
                                                                                    paramInfo->addLinkedParamId(tableParam.second);
                                                                                }
                                                                     
                                                                           }
                                                                     }
                                                               }
                                                            }
                        
			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 */