ParameterData.cc 4.6 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) {
}

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 Adds a value by time to parameter
 */
void ParameterData::addValue(double time, double value,
		double sampling, double gapSize, bool &gapDetected, AMDA::Common::ParameterIndexComponent& index) {
	int valueIndex = componentToValuesIndex(index);
	if (valueIndex >= (int)_values.size())
	{
		_values.resize(valueIndex+1);
	}
	// add time if not already in
	if (_dates.empty() || _dates.back() != time) {

		if (!_dates.empty() && ((time - _dates.back()) > gapSize))
		{
			//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);
			_values[valueIndex].addValue(NAN);
			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);
		}
	}
	else 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) {

	// get index of first time after given time_
	if(isnan(atTime)){
		return nan("");
	}

	int firstSuperiorIndex = 0;
	for(auto time : _dates){
		// No interpolation required
		if (time == atTime){
			return getValues (index, firstSuperiorIndex) [0];
		}
		// Interpolation required
		if (time >= atTime){
			if (firstSuperiorIndex == 0) {
				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];
				// 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("")) {
}

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(_min) && !isnan(value)) {
		_min = value;
	} else if (!isnan(_min) && !isnan(value)) {
		_min = std::min(_min, value);
	}

	if (isnan(_max) && !isnan(value)) {
		_max = value;
	} else if (!isnan(value) && !isnan(_max)) {
		_max = std::max(_max, value);
	}

	if (isnan(_minStrictPos) && !isnan(value) && (value > 0))
		_minStrictPos = std::min(_min, value);
}

} /* namespace plot */