/* * ParameterData.cc * * Created on: 10 déc. 2013 * Author: CS */ #include "ParameterData.hh" #include "PlotLogger.hh" #include #include #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() && ((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 */