ProcessSamplingUnderRefParam.cc 6.3 KB
/**
 * ProcessSamplingUnderTimeList.cc
 *
 *  Created on: Jul 25, 2014
 *      Author: AKKA IS
 */
#include <stdlib.h>
#include <string>

#include "ProcessSamplingUnderRefParam.hh"
#include "Parameter.hh"
#include "ParameterManager.hh"
#include "ParameterCreatorFromExpression.hh"
#include "Resampling.hh"
#include "ParamMgr.hh"

using namespace std;
using namespace boost;
using namespace log4cxx;

namespace AMDA {
namespace Parameters {

ProcessSamplingUnderRefParam::ProcessSamplingUnderRefParam(Parameter &parameter) :
		SingleParamProcess_CRTP(parameter), _paramRefInput(NULL) {
}

ProcessSamplingUnderRefParam::ProcessSamplingUnderRefParam(const ProcessSamplingUnderRefParam& pProcess, Parameter &parameter)
: SingleParamProcess_CRTP(pProcess,parameter), _paramRefInput(pProcess._paramRefInput) {
}

ProcessSamplingUnderRefParam::~ProcessSamplingUnderRefParam() {
	if (_refParameterSPtr != nullptr)
	{
		_refParameterSPtr->closeConnection(this);
	}
}


void ProcessSamplingUnderRefParam::establishConnection() {
	if ((_refParameterSPtr != nullptr) && (_refParameterSPtr != _parameterInput)) {
		_refParameterSPtr->openConnection(this);
	}

	SingleParamProcess_CRTP::establishConnection();

	if ((_refParameterSPtr == nullptr) && (_attributList.size() == 1) ) {
		_refParameterSPtr =  _parameterInput->getParameterManager().getParameter(_attributList[0]);
		if ((_refParameterSPtr != nullptr) && (_refParameterSPtr != _parameterInput)) {
			_refParameterSPtr->openConnection(this);
		}
	}
}

TimeStamp ProcessSamplingUnderRefParam::init() {
	/// Init input parameter
	TimeStamp timeStamp = _parameterInput->init( this, _timeIntervalList);
	/// Calibration information copy
	Parameter::InfoList lInfoList = _parameterInput->getInfoList();
	_parameter.getInfoList().insert(lInfoList.begin(), lInfoList.end());
	_paramInput = _parameterInput->getParamData(this).get();

	// check reference parameter
	if (_refParameterSPtr == nullptr) {
		BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_PROCESS_ERR) << AMDA::ex_msg(std::string("ProcessSamplingUnderRefParam : cannot retrieve reference parameter ")));
	}

	timeStamp = std::max(timeStamp, _refParameterSPtr->init( this, _timeIntervalList));

	_paramRefInput = _refParameterSPtr->getParamData(this).get();

	double computedGapSize = _refParameterSPtr->getParameterManager().getComputedGapSize(_parameterInput->getGapThreshold(), _paramInput->getMinSampling());
	//_parameter.setGapThreshold(computedGapSize/_paramRefInput->getMinSampling());

	// ProcessSamplingClassic _operation creation
	Resampling::CreateResampling lCreateResampling(*this, _timeIntervalList,
			*_paramInput, *_paramRefInput, computedGapSize, _parameterInput->getDataWriterTemplate()->useNearestValue(), _refParameterSPtr == _parameterInput);
	_operation = lCreateResampling.getResampling();

	static_cast<Resampling::ResamplingAbstract*>(_operation)->init();

	/// Get result ParamData
	_paramData = ParamDataSPtr(_operation->getParamOutput());

	_paramData->setMinSampling(static_cast<Resampling::ResamplingAbstract*>(_operation)->getSampling());
	_parameter.setGapThreshold(_refParameterSPtr->getGapThreshold());

	return timeStamp;
}

unsigned int ProcessSamplingUnderRefParam::write()
{
	int ret = 0;
	unsigned int nbDataBeforeCallProcess = _paramData->getDataNumber();

	ParamDataIndexInfo lParamDataIndexInfo;
	if (_refParameterSPtr != _parameterInput) {
		if (static_cast<Resampling::ResamplingAbstract*>(_operation)->isNewInt()) {
			_paramRefInput = _refParameterSPtr->getParamData(this).get();
			ParamDataIndexInfo lRefParamDataIndexInfo;
			do {
				lRefParamDataIndexInfo = _refParameterSPtr->getAsync(this).get();
				for (unsigned int index = lRefParamDataIndexInfo._startIndex; index < lRefParamDataIndexInfo._startIndex + lRefParamDataIndexInfo._nbDataToProcess; index++) {
					static_cast<Resampling::ResamplingAbstract*>(_operation)->pushTime(_paramRefInput->getTime(index));
				}
			} while (!lRefParamDataIndexInfo._timeIntToProcessChanged && !lRefParamDataIndexInfo._noMoreTimeInt);
		}
	}

	lParamDataIndexInfo = _parameterInput->getAsync(this).get();

	_operation->write(lParamDataIndexInfo);
	ret = _paramData->getDataNumber() - nbDataBeforeCallProcess;

	bool updateDims = (nbDataBeforeCallProcess == 0) && (ret > 0);
	if (updateDims)
		_paramData->updateDims();

	// Reset operation to prepare static data for the next TimeInterval.
	if (lParamDataIndexInfo._timeIntToProcessChanged) {
		_paramData->getIndexInfo()._endTimeIntIndexList.push_back(_paramData->getDataNumber());
		_operation->reset();
	}
	// There is no more time interval to process
	else if (lParamDataIndexInfo._noMoreTimeInt) {
		_paramData->getIndexInfo()._endTimeIntIndexList.push_back(_paramData->getDataNumber());
	} else {
		// Nothing to do.
	}

	// Pull up information on which time interval changed.
	_paramData->getIndexInfo()._timeIntToProcessChanged = lParamDataIndexInfo._timeIntToProcessChanged;
	_paramData->getIndexInfo()._noMoreTimeInt = lParamDataIndexInfo._noMoreTimeInt;

	return ret;
}

/*
 * @brief Get min sampling
 */
double ProcessSamplingUnderRefParam::getMinSampling()
{
	if (_refParameterSPtr == nullptr)
		return 0;
	if (_refParameterSPtr->getDataWriterTemplate() == nullptr)
		return 0;
	return _refParameterSPtr->getDataWriterTemplate()->getMinSampling();
}

/**
 * @overload SingleParamProcess_CRTP::updateInfo update parameter info in relation to the sampling process
 */
void ProcessSamplingUnderRefParam::updateInfo(Parameter & parameter)
{
	LOG4CXX_DEBUG(_logger, "ProcessSamplingUnderRefParam::updateInfo - " << parameter.getId());

	SingleParamProcess::updateInfo(parameter);

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

	if (paramInfo == nullptr)
		return;

	std::string processInfo = "Resampling of '";
	processInfo += _parameterInput->getId();
	processInfo += "' under times list of '";
	processInfo += _refParameterSPtr->getId();
	processInfo += "'";

	if (_parameterInput->getDataWriterTemplate()->useNearestValue())
			processInfo += ". Use nearest value.";

	paramInfo->setProcessInfo(processInfo);
}

double ProcessSamplingUnderRefParam::getGapThreshold() {
	double gapSize = _parameterInput->getGapThreshold() * _parameterInput->getDataWriterTemplate()->getMinSampling();
	
	return gapSize / this->getMinSampling();
}

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