ParameterData.cc 4.85 KB
/*
 * ParameterData.cc
 *
 *  Created on: 10 déc. 2013
 *      Author: CS
 */

#include "ParameterData.hh"
#include "PlotLogger.hh"
#include <cmath>
#include <iostream>
#include "TimeUtil.hh"

namespace plot {

ParameterData::ParameterData() :
		_minTime(nan("")), _maxTime(nan("")), _dim1Size(-1), _dim2Size(-1), _paramGapSize(0.) {
}

ParameterData::~ParameterData() {
}

void ParameterData::preAllocate(int nbData)
{
	_dates.reserve(nbData);

	int maxValueIndex = 0;
	for (auto index : _indexes)
	{
		int valueIndex = componentToValuesIndex(index);
		if (valueIndex > maxValueIndex)
			maxValueIndex = valueIndex;
	}
	_values.resize(maxValueIndex+1);

	for (auto index : _indexes)
	{
		int valueIndex = componentToValuesIndex(index);
		_values[valueIndex].preAllocate(nbData);
	}
}

/**
 * @brief Add a new time record to parameter
 */
void ParameterData::addTime(double time, double sampling, bool &gapDetected) {
	if (!_dates.empty() && (abs(time - _dates.back()) > _paramGapSize)) {
		//gap detected => push a NaN value in data list
		if (_dates.back() + sampling > time)
			_dates.push_back((time - _dates.back()) / 2.);
		else
			_dates.push_back(_dates.back() + sampling);
		gapDetected = true;
	}
	else {
		gapDetected = false;
	}
	_dates.push_back(time);

	// calculate min end max time for auto scale
	if (isnan(_minTime)) {
		_minTime = time;
	}
	else {
		_minTime = std::min(time, _minTime);
	}

	if (isnan(_maxTime)) {
		_maxTime = time;
	}
	else {
		_maxTime = std::max(time, _maxTime);
	}
}

/**
 * @brief Add a component value
 */
void ParameterData::addValue(double value, AMDA::Common::ParameterIndexComponent& index, bool gapDetected) {
	int valueIndex = componentToValuesIndex(index);
	if (valueIndex >= (int)_values.size())
	{
		_values.resize(valueIndex+1);
	}

	if (gapDetected)
		_values[valueIndex].addValue(NAN);

	// add relative value
	_values[valueIndex].addValue(value);
}

/**
 * Gets the index of the given time (or just after) in time array,
 * returns -1 if not found
 */
int ParameterData::indexOf(double time_){
	// get index of first time after given time_
	if(isnan(time_)){
		return 0;
	}
	int i = 0;
	for(auto time : _dates){
		if(time >= time_){
			return i;
		}
		++i;
	}
	return -1;
}

/**
 * @brief Computes an interpolated value at a given time
 */
double ParameterData::getInterpolatedValue (double atTime, AMDA::Common::ParameterIndexComponent index , double& prevTime, double& nextTime) {

	// get index of first time after given time_
	if(isnan(atTime)){
		return nan("");
	}
	prevTime = 0;
	nextTime = 0;
	int firstSuperiorIndex = 0;
	for(auto time : _dates){
		// No interpolation required
		if (time == atTime){
			prevTime = _dates [firstSuperiorIndex-1];
			nextTime = _dates [firstSuperiorIndex+1];
			return getValues (index, firstSuperiorIndex) [0];
		}
		// Interpolation required
		if (time >= atTime){
			if (firstSuperiorIndex == 0) {
				prevTime = _dates [firstSuperiorIndex];
				nextTime = _dates [firstSuperiorIndex+1];
				return nan("");
			}
			else {
				double v1 = getValues (index, firstSuperiorIndex-1) [0];
				double v2 = getValues (index, firstSuperiorIndex) [0];
				double d1 = _dates [firstSuperiorIndex-1];
				double d2 = _dates [firstSuperiorIndex];
				
				prevTime = d1;
				nextTime = _dates [firstSuperiorIndex+1];
				// Return a linear interpolation of the value for the index
				return (v1 + (v2-v1) * (atTime-d1)/(d2-d1));
			}
		}
		++firstSuperiorIndex;
	}
	return nan("");
}


/**
 * Dump properties, for TU
 */
void ParameterData::dump(std::ostream& out_, std::string& prefix_) {
	for(auto index : _indexes){
		out_ << prefix_ << "index " << index.getDim1Index() << "x" << index.getDim2Index() << " => " << _values[componentToValuesIndex(index)].getNumberOfData()
				<< " data" << std::endl;
	}
	for (size_t i = 0; i < _dates.size(); ++i) {
		out_ << prefix_;
		AMDA::TimeUtil::formatTimeDateInIso(_dates[i], out_);
		if(!_indexes.empty()){
			for(auto index : _indexes){
				out_ << prefix_ << getValues(index)[i] << " ";
			}
		}
		else {
			out_ << prefix_ << getValues()[i] << " ";
		}
		out_<< std::endl;
	}
}

 // ------------------ COMPONENTPARAMTERDATA ------------------------ //

ComponentParameterData::ComponentParameterData() :
		_min(nan("")), _minStrictPos(nan("")), _max(nan("")), _noData(true) {
}

ComponentParameterData::~ComponentParameterData() {

}

void ComponentParameterData::preAllocate(int nbData)
{
	_values.reserve(nbData);
}

/**
 * @brief Adds a value and updates min and max values.
 */
void ComponentParameterData::addValue(double value) {
	_values.push_back(value);

	if (!isnan(value))
	{
		_noData = false;
		if (isnan(_min))
			_min = value;
		else
			_min = std::min(_min, value);

		if (isnan(_max))
			_max = value;
		else
			_max = std::max(_max, value);

		if (value > 0)
		{

			if (isnan(_minStrictPos))
				_minStrictPos = value;
			else
				_minStrictPos = std::min(_minStrictPos, value);
		}
	}
}

} /* namespace plot */