From 3cf118118221e740de4f2e3907900973ec700c34 Mon Sep 17 00:00:00 2001 From: Menouar AZIB Date: Fri, 25 Nov 2022 14:00:48 +0100 Subject: [PATCH] FFT Validated and I add Test fucntions --- src/ParamOutputImpl/Plot/InstantPlot/PlotFunction.cc | 412 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------------------------------------------------- src/ParamOutputImpl/Plot/InstantPlot/PlotFunction.hh | 9 ++++++--- src/ParamOutputImpl/Plot/InstantPlot/PlotFunctionNode.cc | 4 ++-- src/ParamOutputImpl/Plot/PanelPlotOutput.cc | 2 ++ src/ParamOutputImpl/Plot/PanelPlotOutput.hh | 1120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/Parameters/fonctions/fourier/DiscreteFourierTransform.cc | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------- src/Parameters/fonctions/fourier/DiscreteFourierTransform.hh | 25 +++++++++++++++++++++++++ 7 files changed, 1074 insertions(+), 678 deletions(-) diff --git a/src/ParamOutputImpl/Plot/InstantPlot/PlotFunction.cc b/src/ParamOutputImpl/Plot/InstantPlot/PlotFunction.cc index 15cb7ec..7369a62 100644 --- a/src/ParamOutputImpl/Plot/InstantPlot/PlotFunction.cc +++ b/src/ParamOutputImpl/Plot/InstantPlot/PlotFunction.cc @@ -14,6 +14,7 @@ #include "fonctions/fourier/DiscreteFourierTransform.cc" #include "fonctions/fourier/DiscreteFourierTransform.hh" #include +#include #include #include @@ -45,14 +46,162 @@ namespace plot } } + void PlotFunction::createParameters(std::list &usedParametersId_) + { + PanelPlotOutput::createParameters(usedParametersId_); + } + + void PlotFunction::writeContext(ContextFileWriter &writer, AMDA::Parameters::TimeIntervalList::iterator currentTimeInterval) + { + writer.startElement("panel"); + _panel->writeContext(_pls, writer); + + writer.startElement("parameters"); + + for (ParameterAxesList::iterator it = _parameterAxesList.begin(); + it != _parameterAxesList.end(); ++it) + { + AMDA::Parameters::ParameterSPtr originalParam = + _parameterManager.getParameter(it->_originalParamId); + + // Retrieve ParamInfo Manager + ParamMgr *piMgr = ParamMgr::getInstance(); + ParamInfoSPtr paramInfo = piMgr->getParamInfoFromId(it->_originalParamId); + + double resol = originalParam->getDataWriterTemplate()->getMinSampling(); + std::string resolstr = std::to_string(resol); + + writer.startElement("parameter"); + writer.addAttribute("id", paramInfo->getName().c_str()); + writer.addAttribute("name", paramInfo->getName().c_str()); + writer.addAttribute("shortname", paramInfo->getShortName().c_str()); + writer.addAttribute("MinSampling", resolstr.c_str()); + writer.addAttribute("unit", paramInfo->getUnits().c_str()); + + std::ostringstream legends; + + for (auto lSeries : it->getYSeriePropertiesList()) + { + writer.startElement("serie"); + writer.addAttribute("id", std::to_string(lSeries.getId()).c_str()); + + std::ostringstream labels; + for (auto lIndex : lSeries.getIndexList(_pParameterValues)) + { + std::string label = PanelPlotOutput::getSerieParamsLegendString(lSeries, lIndex, it->_originalParamId); + labels << label << ";"; + } + + writer.addAttribute("serie_label", labels.str().c_str()); + writer.addAttribute("dimSize", "-1"); + + std::ostringstream values; + + plot::ParameterData &data = (*_pParameterValues)[lSeries.getParamId()]; + for (int index_time = 0; index_time < data.getSize(); index_time++) + { + double time = data.getTimes()[index_time]; + values << std::fixed << time; + + for (auto lIndex : lSeries.getIndexList(_pParameterValues)) + { + double value = data.getValues(lIndex)[index_time]; + values << ";" << std::fixed << value; + } + values << "|"; + } + writer.addAttribute("data", values.str().c_str()); + writer.endElement(); + } + + if (it->getSpectroProperties() != nullptr) + { + plot::ParameterData &data = (*_pParameterValues)[it->getSpectroProperties()->getParamId()]; + SpectroProperties *pSpectro = it->getSpectroProperties().get(); + int dimSize = -1; + if (pSpectro->getRelatedDim() == 0) + dimSize = data.getDim1Size(); + else + dimSize = data.getDim2Size(); + + std::ostringstream values; + for (int index_time = 0; index_time < data.getSize(); index_time++) + { + double time = data.getTimes()[index_time]; + values << std::fixed << time; + double valueTemp = 0.0; + for (int j = 0; j < dimSize; j++) + { + double value; + if (pSpectro->getRelatedDim() == 0) + value = data.getValues(AMDA::Common::ParameterIndexComponent(j, -1), 0)[index_time]; + else + value = data.getValues(AMDA::Common::ParameterIndexComponent(-1, j), 0)[index_time]; + valueTemp += value; + } + values << ";" << std::fixed << valueTemp << "|"; + LOG4CXX_DEBUG(gLogger, time << std::fixed << " COUCOU " << valueTemp); + } + + writer.startElement("serie"); + writer.addAttribute("id", "1"); + writer.addAttribute("serie_label", ";"); + writer.addAttribute("dimSize", std::to_string(dimSize).c_str()); + writer.addAttribute("data", values.str().c_str()); + writer.endElement(); + } + writer.endElement(); + } + writer.endElement(); + writer.endElement(); + } + + void PlotFunction::applyFunction() + { + std::string paramId = ""; + bool isSpectro = false; + SeriesProperties lSeries; + for (auto parameter : _parameterAxesList) + { + paramId = parameter._originalParamId; + for (auto lSeries : parameter.getYSeriePropertiesList()) + { + for (auto lIndex : lSeries.getIndexList(_pParameterValues)) + { + std::string id = std::to_string(lSeries.getId()) + "_" + lSeries.getParamId() + "_" + std::to_string(lIndex.getDim1Index()); + plot::ParameterData &data = (*_pParameterValues)[lSeries.getParamId()]; + PlotFunction::compute(lIndex, data, &lSeries, nullptr, parameter._originalParamId); + } + } + } + + for (auto parameter : _parameterAxesList) + { + paramId = parameter._originalParamId; + if (parameter.getSpectroProperties() != nullptr) + { + isSpectro = true; + ParameterData &data = (*_pParameterValues)[parameter.getSpectroProperties()->getParamId()]; + SpectroProperties *pSpectro = parameter.getSpectroProperties().get(); + PlotFunction::compute(AMDA::Common::ParameterIndexComponent(-1, -1), data, nullptr, pSpectro, parameter._originalParamId); + } + } + + PlotFunction::createXAxis(); + PlotFunction::createYAxis(paramId, isSpectro); + } + void PlotFunction::drawSeries(double startDate, double stopDate, int intervalIndex, std::string pParamId, SeriesProperties &pSerie, AMDA::Common::ParameterIndexComponent pParamIndex, ParameterAxes ¶m, bool moreThanOneSerieForAxis) { std::string id = std::to_string(pSerie.getId()) + "_" + pSerie.getParamId() + "_" + std::to_string(pParamIndex.getDim1Index()); + LOG4CXX_DEBUG(gLogger, " id Serie " << id); std::vector xValues = xValuesMap[id]; std::vector yValues = yValuesMap[id]; + std::string ss = PanelPlotOutput::getSerieParamsLegendString(pSerie, pParamIndex, pParamId); + LOG4CXX_DEBUG(gLogger, " HHHHH" << ss); double *coloredComputedValues = NULL; int nbValues = yValues.size(); @@ -83,28 +232,46 @@ namespace plot nbValues, xValuesTemp, yValuesTemp, coloredComputedValues); } - void PlotFunction::configureSeriesAxis() + void PlotFunction::drawInstantPlot() { - //_panel->_leftMargin = 10; - //_panel->_rightMargin = 5; - //_panel->_bottomMargin = 4; - - SeriesProperties lSeries; for (auto parameter : _parameterAxesList) { - for (auto lSeries : parameter.getYSeriePropertiesList()) + if (parameter.getSpectroProperties() != nullptr) { - for (auto lIndex : lSeries.getIndexList(_pParameterValues)) - { - std::string id = std::to_string(lSeries.getId()) + "_" + lSeries.getParamId() + "_" + std::to_string(lIndex.getDim1Index()); - plot::ParameterData data = (*_pParameterValues)[lSeries.getParamId()]; - PlotFunction::compute(lIndex, data, id, lSeries.getParamId()); - } + std::string pramId = parameter.getSpectroProperties()->getParamId(); + std::vector xValues = xValuesMap[pramId]; + std::vector yValues = yValuesMap[pramId]; + plot::SeriesProperties *pSerie = new plot::SeriesProperties(); + + double *coloredComputedValues = NULL; + int nbValues = yValues.size(); + + double *yValuesTemp = &yValues[0]; + double *xValuesTemp = &xValues[0]; + + pSerie->setXAxisId(X_AXIS_ID); + pSerie->setYAxisId(Y_AXIS_ID); + + PanelPlotOutput::drawSeries(0, 0, 0, "", + *pSerie, AMDA::Common::ParameterIndexComponent(-1, -1), parameter, false); + + Color lineColor = getSerieLineColor(*pSerie, false); + Color symbolColor = getSerieSymbolColor(*pSerie, lineColor); + + drawSymbols( + pSerie->getSymbolProperties().getType(), + pSerie->getSymbolProperties().getSize(), 1., + symbolColor, + nbValues, xValuesTemp, yValuesTemp, coloredComputedValues); + + drawLines( + pSerie->getLineProperties().getType(), + pSerie->getLineProperties().getStyle(), + pSerie->getLineProperties().getWidth(), + lineColor, + nbValues, xValuesTemp, yValuesTemp, coloredComputedValues); } } - - PlotFunction::createXAxis(); - PlotFunction::createYAxis(); } void PlotFunction::createXAxis() @@ -112,6 +279,8 @@ namespace plot double minValue = 0; double maxValue = 0; PlotFunction::getMinMax(xValuesMap, &minValue, &maxValue); + LOG4CXX_DEBUG(gLogger, " min X " << minValue); + LOG4CXX_DEBUG(gLogger, " man X " << maxValue); // Create X axis boost::shared_ptr lXAxis(new TimeAxis()); lXAxis.get()->_timeFormat = "%H:%M"; @@ -132,18 +301,22 @@ namespace plot _panel->addAxis(X_AXIS_ID, lXAxis); } - void PlotFunction::createYAxis() + void PlotFunction::createYAxis(std::string paramId, bool isSpectro) { std::string y_label = ""; if (function == PlotFunction::Function::AVG) - y_label = "AVG"; - else - y_label = "Amplitude"; + y_label = ""; + else if (function == PlotFunction::Function::SUM) + y_label = ""; + else if (function == PlotFunction::Function::FFT) + y_label = "DSP"; double minValue = 0; double maxValue = 0; PlotFunction::getMinMax(yValuesMap, &minValue, &maxValue); + LOG4CXX_DEBUG(gLogger, " min Y " << minValue); + LOG4CXX_DEBUG(gLogger, " man Y " << maxValue); // Create X axis boost::shared_ptr lYAxis(new Axis(false)); plot::Range range_x = Range(minValue - abs(minValue) * 0.10, maxValue + abs(maxValue) * 0.1); @@ -159,6 +332,16 @@ namespace plot lYAxis.get()->_showTickMark = true; lYAxis.get()->_used = true; // add X Axis to panel + if (isSpectro) + { + AxisLegendManager::setAxisLegendForSpectro(this, lYAxis, paramId); + } + else + { + AxisLegendManager::AxisParamsComponents axisParamsComponents; + axisParamsComponents[paramId].push_back(ParameterIndexComponentColor(1, -1, lYAxis->_color)); + AxisLegendManager::setAxisLegendForSeries(this, lYAxis, axisParamsComponents); + } _panel->addAxis(Y_AXIS_ID, lYAxis); } @@ -181,12 +364,24 @@ namespace plot *maxToFill = maxValue; } - void PlotFunction::compute(AMDA::Common::ParameterIndexComponent pParamIndex, plot::ParameterData data, std::string id, std::string param_id) + void PlotFunction::compute(AMDA::Common::ParameterIndexComponent pParamIndex, plot::ParameterData &data, SeriesProperties *pSerie, SpectroProperties *pSpectro, std::string paramOriginID) { double samplingValue = 60.0; int nb_points = data.getSize(); + std::string param_id, id; - auto it = find(paramsNbPoints.begin(), paramsNbPoints.end(), param_id); + if (pSerie == nullptr) + { + param_id = pSpectro->getParamId(); + id = param_id; + } + else + { + param_id = pSerie->getParamId(); + id = std::to_string(pSerie->getId()) + "_" + param_id + "_" + std::to_string(pParamIndex.getDim1Index()); + } + + auto it = find(paramsNbPoints.begin(), paramsNbPoints.end(), paramOriginID); // If parameter was found if (it != paramsNbPoints.end()) { @@ -196,57 +391,129 @@ namespace plot } else { - std::stringstream lError; + /*std::stringstream lError; lError << "PlotFunction::compute" - << ": param with id " << param_id << " is not found in param_nb_points xml node."; + << ": param with id " << paramOriginID << " is not found in param_nb_points xml node."; LOG4CXX_DEBUG(gLogger, lError.str()); - BOOST_THROW_EXCEPTION(PanelPlotOutputException() << AMDA::errno_code(AMDA_ERROR_PLOTFUNCTION_PARAM_NOT_FOUND) << AMDA::ex_msg(lError.str())); + BOOST_THROW_EXCEPTION(PanelPlotOutputException() << AMDA::errno_code(AMDA_ERROR_PLOTFUNCTION_PARAM_NOT_FOUND) << AMDA::ex_msg(lError.str()));*/ } - double *values = data.getValues(pParamIndex, 0); + std::vector xValues; + std::vector yValues; - double *timeValues = &data.getTimes()[0]; + int dimSize = -1; + if (pSpectro != nullptr) + if (pSpectro->getRelatedDim() == 0) + dimSize = data.getDim1Size(); + else + dimSize = data.getDim2Size(); - std::vector signal; - for (int i = 0; i < data.getSize(); i++) - signal.push_back(values[i]); + for (int index_time = 0; index_time < data.getSize(); index_time++) + { + double time = data.getTimes()[index_time]; + xValues.push_back(time); - std::vector xValues; - std::vector yValues; + double valueTemp = 0.0; + for (int j = 0; j < dimSize; j++) + { + double value; + if (pSpectro->getRelatedDim() == 0) + value = data.getValues(AMDA::Common::ParameterIndexComponent(j, -1), 0)[index_time]; + else + value = data.getValues(AMDA::Common::ParameterIndexComponent(-1, j), 0)[index_time]; + valueTemp += value; + } - if (function == PlotFunction::Function::AVG) + LOG4CXX_DEBUG(gLogger, time << std::fixed << " " << valueTemp); + if (dimSize < 0) + valueTemp = data.getValues(pParamIndex, 0)[index_time]; + + yValues.push_back(valueTemp); + } + + if (function == PlotFunction::Function::SUM) { - double sum = std::accumulate(signal.begin(), signal.end(), 0); - for (int i = 0; i < data.getSize(); i++) + if (dimSize < 0) { - yValues.push_back(sum / data.getSize()); - xValues.push_back(timeValues[i]); + double sum = std::accumulate(yValues.begin(), yValues.end(), 0); + yValues.assign(yValues.size(), sum); } } - else + else if (function == PlotFunction::Function::AVG) + { + int size = dimSize; + if (dimSize < 0) + { + double sum = std::accumulate(yValues.begin(), yValues.end(), 0); + yValues.assign(yValues.size(), sum); + size = data.getSize(); + } + + transform(yValues.begin(), yValues.end(), yValues.begin(), [size](double &c) + { return c / size; }); + } + else if (function == PlotFunction::Function::FFT) { - DiscreteFourierTransform DFT(std::min(nb_points, data.getSize()), signal, 1 / samplingValue); - DFT.compute(); + DiscreteFourierTransform DFT(std::min(nb_points, data.getSize()), yValues, 1.0 / samplingValue); + // DFT.compute(); + + std::vector vect; + vect.push_back(1); + vect.push_back(2); + vect.push_back(1); + vect.push_back(-1); + vect.push_back(1.5); + + std::vector> vectOUT = DFT.fft(vect); + for (int u = 0; u < vectOUT.size(); u++) + { + LOG4CXX_DEBUG(gLogger, "Real part: " << real(vectOUT[u]) << " Imaginary part: " << imag(vectOUT[u]) << " " << abs(vectOUT[u])); + } - yValues = DFT.getAmplitudes(); + vectOUT = DFT.dft(vect); + for (int u = 0; u < vectOUT.size(); u++) + { + LOG4CXX_DEBUG(gLogger, "Real part: " << real(vectOUT[u]) << " Imaginary part: " << imag(vectOUT[u]) << " " << abs(vectOUT[u])); + } + + std::vector x_ = DFT.createTestPoints(600, 1.0 / 800); + std::vector y_ = DFT.createTestFunction(x_); + std::vector> ph = DFT.dft(y_); + LOG4CXX_DEBUG(gLogger, "size of x_ : " << x_.size() << " size of y " << y_.size() << " size of phasors " << ph.size()); + DFT.setPhasors(ph); + for (int u = 0; u < ph.size(); u++) + { + std::complex mycomplex = ph[u]; + } + std::vector dsp = DFT.computeDSP(ph); + for (int u = 0; u < dsp.size(); u++) + { + LOG4CXX_DEBUG(gLogger, " DSP " << dsp[u]); + } + + yValues = dsp; + // dsp; // DFT.getAmplitudes(); if (abscisse.getType() == Abscisse::Abscisse_Type::FREQUENCY) - xValues = DFT.getFrequences(); + { + xValues = DFT.getFreq(ph, 1.0 / 800); // DFT.getFrequences(); + for (int u = 0; u < xValues.size(); u++) + { + LOG4CXX_DEBUG(gLogger, " indice " << u << " freq " << xValues[u]); + } + } else xValues = DFT.getPeriodes(); + // xValues = x_; } if (ordonneeScale == Axis::Scale::LOGARITHMIC) - { std::for_each(yValues.begin(), yValues.end(), [&](double &i) { return log10(i); }); - } if (abscisseScale == Axis::Scale::LOGARITHMIC) - { std::for_each(xValues.begin(), xValues.end(), [&](double &i) { return log10(i); }); - } PlotFunction::xValuesMap[id] = xValues; PlotFunction::yValuesMap[id] = yValues; @@ -302,7 +569,7 @@ namespace plot void PlotFunction::preparePlotArea(double startTime, double stopTime, int intervalIndex) { - PlotFunction::configureSeriesAxis(); + PlotFunction::applyFunction(); if (abscisse.getType() == Abscisse::TIME) { @@ -310,32 +577,9 @@ namespace plot getTimeAxisDecorator()->configure(this, dynamic_cast(xAxis.get()), startTime, stopTime, _pParameterValues); _pls->timefmt(getTimeAxisDecorator()->getPlFormat().c_str()); } - PanelPlotOutput::preparePlotArea(startTime, stopTime, intervalIndex); - } - - void PlotFunction::createParameters(std::list &usedParametersId_) - { - - for (ParameterAxesList::iterator it = _parameterAxesList.begin(); - it != _parameterAxesList.end(); ++it) - { - AMDA::Parameters::ParameterSPtr originalParam = - _parameterManager.getParameter(it->_originalParamId); + PanelPlotOutput::configureParamsLegend(startTime, stopTime, intervalIndex); - // For each series - std::vector::iterator ity; - for (ity = it->getYSeriePropertiesList().begin(); ity != it->getYSeriePropertiesList().end(); - ++ity) - { - // Add parameter to parameters list - if (std::find(usedParametersId_.begin(), usedParametersId_.end(), - originalParam->getId()) == usedParametersId_.end()) - usedParametersId_.push_back(originalParam->getId()); - - // link this paramter to the serie - ity->setParamId(originalParam->getId()); - } - } + PanelPlotOutput::preparePlotArea(startTime, stopTime, intervalIndex); } /** @@ -349,23 +593,6 @@ namespace plot _panel->draw(_pls); fillBackground(_pls); - bool noData = true; - - if (_parameterAxesList.empty()) - { - noData = false; // Do not draw No Data if the panel is empty - _panel->drawEmptyPanel(_pls); - } - - // Set pointer to ParameterData list - if (_pParameterValues == NULL) - { - std::stringstream lError; - lError << "PanelPlotOutput::draw - Pointer to parameterValues is not set"; - BOOST_THROW_EXCEPTION( - PanelPlotOutputException() << AMDA::ex_msg(lError.str())); - } - // Compute nb series to draw by y axis std::map nbSeriesByYAxisMap = getNbSeriesByYAxis(); SeriesProperties lSeries; @@ -386,10 +613,6 @@ namespace plot drawSeries(startTime, stopTime, intervalIndex, parameter._originalParamId, lSeries, lIndex, parameter, moreThanOneSerieForYAxis); ParameterData &data = (*_pParameterValues)[lSeries.getParamId()]; - if (noData) - { - noData = data.noData(lIndex); - } } } } @@ -400,6 +623,7 @@ namespace plot PlotFunction::drawStartDate(_timeFormat, startTime, stopTime); } - return noData; + PlotFunction::drawInstantPlot(); + return true; } } diff --git a/src/ParamOutputImpl/Plot/InstantPlot/PlotFunction.hh b/src/ParamOutputImpl/Plot/InstantPlot/PlotFunction.hh index 54e4932..8190075 100644 --- a/src/ParamOutputImpl/Plot/InstantPlot/PlotFunction.hh +++ b/src/ParamOutputImpl/Plot/InstantPlot/PlotFunction.hh @@ -148,8 +148,11 @@ namespace plot virtual bool draw(double startTime, double stopTime, int intervalIndex, bool isFirstInterval, bool isLastInterval); + virtual void writeContext(ContextFileWriter &writer, AMDA::Parameters::TimeIntervalList::iterator currentTimeInterval); + private: - void configureSeriesAxis(); + void drawInstantPlot(); + void applyFunction(); void configureAxisLegend(); /** * @brief Afficher sur le plot the starting date @@ -163,7 +166,7 @@ namespace plot * @brief Créer un axe Y pour accueillir les valeurs calculées de l'axe Y * */ - void createYAxis(); + void createYAxis(std::string paramId, bool isSpectro); /** * @brief Créer un axe X pour accueillir les valeurs calculées de l'axe X * @@ -184,7 +187,7 @@ namespace plot * @param id id pseudo param * @param param_id id du paramètre */ - void compute(AMDA::Common::ParameterIndexComponent pParamIndex, plot::ParameterData data, std::string id, std::string param_id); + void compute(AMDA::Common::ParameterIndexComponent pParamIndex, plot::ParameterData &data, SeriesProperties *pSerie, SpectroProperties *pSpectro, std::string paramOriginID); /** * @brief Une map pour stocker les valeurs calculées de l'axe X associés aux pseudo paramètres crées localement diff --git a/src/ParamOutputImpl/Plot/InstantPlot/PlotFunctionNode.cc b/src/ParamOutputImpl/Plot/InstantPlot/PlotFunctionNode.cc index 6b2bc80..ca64bae 100644 --- a/src/ParamOutputImpl/Plot/InstantPlot/PlotFunctionNode.cc +++ b/src/ParamOutputImpl/Plot/InstantPlot/PlotFunctionNode.cc @@ -67,8 +67,8 @@ namespace plot plot->setFunction(PlotFunction::Function::AVG); else if (strcmp(valueString, PlotFunctuion_Type_FFT) == 0) plot->setFunction(PlotFunction::Function::FFT); - else - plot->setFunction(PlotFunction::Function::NONE); + else if (strcmp(valueString, PlotFunctuion_Type_SUM) == 0) + plot->setFunction(PlotFunction::Function::SUM); xmlFree(value); } diff --git a/src/ParamOutputImpl/Plot/PanelPlotOutput.cc b/src/ParamOutputImpl/Plot/PanelPlotOutput.cc index b24c6bf..3061d13 100644 --- a/src/ParamOutputImpl/Plot/PanelPlotOutput.cc +++ b/src/ParamOutputImpl/Plot/PanelPlotOutput.cc @@ -2188,6 +2188,8 @@ namespace plot if (!isStandalone()) return; + LOG4CXX_DEBUG(gLogger, "here 0"); + writer.startElement("panel"); _panel->writeContext(_pls, writer); diff --git a/src/ParamOutputImpl/Plot/PanelPlotOutput.hh b/src/ParamOutputImpl/Plot/PanelPlotOutput.hh index 4830109..28a0a52 100644 --- a/src/ParamOutputImpl/Plot/PanelPlotOutput.hh +++ b/src/ParamOutputImpl/Plot/PanelPlotOutput.hh @@ -8,592 +8,600 @@ #ifndef PANELPLOTOUTPUT_HH_ #define PANELPLOTOUTPUT_HH_ -#include "ParamOutput.hh" +#include "ContextFileWriter.hh" +#include "Layout.hh" #include "Panel.hh" +#include "PanelPlotOutputException.hh" +#include "ParamOutput.hh" #include "ParameterAxes.hh" -#include -#include #include "ParameterData.hh" +#include "PlotLogger.hh" #include #include -#include "PlotLogger.hh" -#include "PanelPlotOutputException.hh" -#include "Layout.hh" -#include "ContextFileWriter.hh" +#include +#include #include -namespace plot { - -// 0 => xmin -// 1 => xmax -// 2 => ymin -// 3 => ymax -typedef std::tuple PlWindow; -// 0 => x major tick space -// 1 => x minor tick number -// 2 => y major tick space -// 3 => y minor tick number -typedef std::tuple TickConf; - -/** - * Margin. - */ -struct Margin { - double _left; - double _right; - double _top; - double _bottom; -}; - -class PanelPlotOutput { -public: - static const float DEFAULT_TICK_LENGTH_FACTOR; - - /** - * Width character proportion is approximatively 0.83 times smaller than height. - */ - static const float CHAR_RATIO; - - /** - * This two next attribute tell from which tick length plplot is insufficient to calculate space between tickmarks and ticks. - * Space between the two is static and can't be modified by user request. - * So when limit is reached we must bypass problem by setting two different viewport to let sufficient space between tickmarks and ticks. - */ - static const float VERTICAL_TICK_LENGTH_LIMIT; - static const float HORIZONTAL_TICK_LENGTH_LIMIT; - static const float YAXISMARGIN; +namespace plot +{ - PanelPlotOutput(AMDA::Parameters::ParameterManager& manager, - boost::shared_ptr panel, bool isStandalone = true); - virtual ~PanelPlotOutput(); + // 0 => xmin + // 1 => xmax + // 2 => ymin + // 3 => ymax + typedef std::tuple PlWindow; + // 0 => x major tick space + // 1 => x minor tick number + // 2 => y major tick space + // 3 => y minor tick number + typedef std::tuple TickConf; /** - * type name. This name is used to identify nodes in xml config - * and xml request. - * @return + * Margin. */ - virtual const std::string typeName() = 0; - - /** - * @brief Compute the initial plot area for the panel - */ - virtual void preparePlotArea (double startTime, double stopTime, int intervalIndex); - - /** - * @brief Retrieve plot area bounds for the panel - */ - virtual void getPlotAreaBounds (Bounds &plotAreaBounds); - - /** - * @brief Force the plot area horizontal position and width - */ - virtual void forcePlotAreaPosAndWidth(double plotAreaX, double plotAreaWidth); - - /** - * @brief Retrieve left axis tickMark width - */ - virtual int getLeftAxisTickMarkWidth (void); - - /** - * @brief Force left axis tickmark width for the panel - */ - virtual void forceLeftAxisTickMarkWidth(int leftAxisTickMarkWidth); - - /** - * @brief draw the plot for the current time interval - */ - virtual bool draw(double startTime, double stopTime, int intervalIndex, bool isFirstInterval, bool isLastInterval); - - /** - * @brief Write plot context - */ - void writeContext(ContextFileWriter &writer, AMDA::Parameters::TimeIntervalList::iterator currentTimeInterval); - - /* - * @brief Set a pointer to the time intervals list - */ - void setTimeIntervalListPtr(AMDA::Parameters::TimeIntervalList *timeIntervalListPtr); - - /** - * Sets PLplot stream to draw panel and plot - */ - virtual void setPlStream(std::shared_ptr& pls); - - /** - * Adds a parameter - */ - virtual void addParam(const std::string& name) { - ParameterAxes newParameter(name); - _parameterAxesList.push_back(newParameter); - } - - virtual ParameterAxes& getParameter(const std::string& name) { - for (ParameterAxes& param : _parameterAxesList) { - if (param._originalParamId == name) { - return param; - } - } - ParameterAxes newParameter(name); - _parameterAxesList.push_back(newParameter); - return _parameterAxesList.back(); - } - - /* - * Create a sampled parameter from an original parameter and a sampling value - */ - AMDA::Parameters::ParameterSPtr createSampledParameter(AMDA::Parameters::ParameterSPtr& originalParam, float samplingValue); - - /* - * Create a sampled parameter from an original parameter and a reference parameter for time definition - */ - AMDA::Parameters::ParameterSPtr createSampledParameterUnderReferenceParameter(AMDA::Parameters::ParameterSPtr& originalParam, - AMDA::Parameters::ParameterSPtr& refParam); - - /** - * Create parameters needed for this plot - * By default, the creation method create parameters for a time serie. - * Override it for other plot type - */ - virtual void createParameters(std::list& usedParametersId_); - - /** - * Get related ParameterAxes for a given color serie id - */ - ParameterAxes* getParameterAxesByColorSerieId(int colorSerieId); - - /** - * Get related ParameterAxes for a given x serie id - */ - ParameterAxes* getParameterAxesByXSerieId(int xSerieId); - - /** - * Gets sampling value from resolution (point-per-plot) according to - * the plot time interval and the base parameter sampling value. - */ - virtual double getCorrectedSamplingValue(int maxResolution, double samplingValue); - - /** - * @brief Get the list of indexes used for a parameter - */ - virtual std::vector getParamUsedIndexes(std::string paramId, int dim1Size, int dim2Size = -1); - - const Margin getMargin(){ - Bounds panelBounds(_panel->getBoundsInPlPage()); - - Margin m; - m._left = _plotAreaBounds._x - panelBounds._x; - m._right = (panelBounds._x + panelBounds._width) - (_plotAreaBounds._x + _plotAreaBounds._width); - m._top = (panelBounds._y + panelBounds._height) - (_plotAreaBounds._y + _plotAreaBounds._height); - m._bottom = _plotAreaBounds._y - panelBounds._y; - return m; - } - - /** - * @brief reset plot - */ - virtual void resetPlot() { - if (_panel != nullptr) - _panel->resetPlot(); - _automaticSerieColorCursor = 0; - _nbSeriesByYAxisMap.clear(); - _pls.reset(); - } - - /* - * @brief Set pointer to params values - */ - void setParameterValues(std::map *pParameterValues); - - /* - * @brief Get computed values (in relation with the y axis definition) for a y serie, an index of the serie and a time interval - * Do not forget to delete (*computedValues) !! - * Do not delete (*timeValues), the buffer is not copied !! - */ - bool getComputedValuesFromSerieAndInterval(double startDate, double stopDate, SeriesProperties &rSeriesProperties, - AMDA::Common::ParameterIndexComponent index, double** computedValues, double** timeValues, int& nbValues); - - /* - * @brief Get computed values (in relation with the color axis definition) for a color serie and a time interval - * Do not forget to delete computedValues !! - * Don't delete timeValues !! - */ - bool getColoredComputedValuesFromSerieAndInterval(double startDate, double stopDate, SeriesProperties &rSeriesProperties, - double** computedValues, double** timeValues, int& nbValues); - - /* - * @brief Get computed values (in relation with the y axis definition) for a y serie and a time interval - * Do not forget to delete computedValues !! - * Don't delete timeValues !! - */ - bool getErrorComputedValuesFromSerieAndInterval(double startDate, double stopDate, SeriesProperties &rSeriesProperties, - double** minComputedValues, double** minTimeValues, int& nbMinValues, - double** maxComputedValues, double** maxTimeValues, int& nbMaxValues); - - /** - *@brief Defines the layout constraint to be used for the panel when used within a layout - */ - virtual PanelConstraint getLayoutConstraint (void) { - return PanelConstraint::MaxWidth; - } - - /** - * @brief Get nb series to draw by y axis - */ - std::map& getNbSeriesByYAxis(); - - /* - * @brief Return the color to draw the line of a serie - */ - Color getSerieLineColor(SeriesProperties &rSeriesProperties, bool moreThanOneSerieForAxis); - - /** - * @brief Plot container - */ - boost::shared_ptr _panel; - - /** - * @brief Parameters and series info - */ - ParameterAxesList _parameterAxesList; - - /* - * @brief Type used to define a matrix grid - */ - struct GridPart + struct Margin { - double x[2]; - double y[2]; - double value; - double isColorIndex; + double _left; + double _right; + double _top; + double _bottom; }; - typedef std::vector MatrixGrid; - - // datastore for sauvaud plot - struct SauvaudPart + class PanelPlotOutput { - double x[2]; - double y[2]; - std::vector value; - double isColorIndex; - }; - - typedef std::vector SauvaudGrid; - - /* - * @brief Draw a matrix - */ - void drawMatrix(MatrixGrid& matrixGrid, double minDataVal, double maxDataVal, - Color minValColor, Color maxValColor, int colorMapIndex, bool useLog0AsMin = false); - - void draw2DMatrix(SauvaudGrid& sauvaudGrid, double minDataVal, double maxDataVal, - Color minValColor, Color maxValColor, int colorMapIndex, bool useLog0AsMin = false); - - /** - * @brief Reset cursor used to attribute automatically a color to a serie - */ - void resetAutomaticSerieColorCursor() { - _automaticSerieColorCursor = 0; - } - - /** - * Draw a rectangle - */ - void drawRectangle(double xmin, double xmax, double ymin, double ymax, Color& pColor, double alpha = 1.); - - bool isStandalone() { - return _isStandalone; - } - - AMDA::Parameters::ParameterManager& _parameterManager; - - std::map *_pParameterValues; - -protected: - - AMDA::Parameters::TimeIntervalList* _timeIntervalListPtr; - - /** - * @brief Compute plot area. - * @note If ratio need to be kept, ratio will be kept between width and height. - * @param bounds_ plot area bounds. It is updated by this method. - */ - virtual void calculatePlotArea(const Bounds& panelBounds_, Bounds& bounds_); - - /** - *@brief computes Panel Plot XY ratio - */ - void computePanelPlotXYRatio(void); - - /** - * @brief Get colored value associated to a data value. Return false if the value is filtered. - */ - bool getColoredValue(double value, double filterMin, double filterMax, bool useLog0AsMin, PLFLT &col); - - /** - *@brief Draw fill area between parameter and constant or between parameters - */ - virtual void drawFills(double startDate, double stopDate); - - /** - * Draw list of symbols - */ - void drawSymbols(SymbolType pType, int pSize, double pFactor, Color pColor, - int pNbData, double* pXData, double* pYData, - double* pZData = NULL, double filterZMin = -DBL_MAX, double filterZMax = DBL_MAX); - - /** - * Draw list of lines - */ - void drawLines(LineType pType, LineStyle pStyle, int pWidth, Color& pColor, - int pNbData, double* pXData, double* pYData, - double* pZData = NULL, double filterZMin = -DBL_MAX, double filterZMax = DBL_MAX); - - /** - * Draw errors segments - */ - void drawYErrors (LineType pType, LineStyle pStyle, int pWidth, Color& pColor, - int pNbData, double* pXData, double* pYMinData, double* pYMaxData); - - /** - *@brief Draw the serie of a parameter component on plot. - */ - virtual void drawSeries(double startDate, double stopDate, int intervalIndex, std::string pParamId, SeriesProperties& pSeries, - AMDA::Common::ParameterIndexComponent pParamIndex, ParameterAxes& param, bool moreThanOneSerieForAxis); - - /** - *@brief Draw the spectro of a parameter on plot. - */ - virtual void drawSpectro(double startDate, double stopDate, std::string pParamId, - SpectroProperties& pSpectro); - - /** - *@brief Draw sauvaud plot of a parameter on plot. - */ - virtual void drawSauvaud(double startDate, double stopDate, std::string pParamId, - SauvaudProperties& pSauvaud, int subIndex, int subsNumber, std::string opositeLegend); - - virtual void drawIntervals(double startDate, double stopDate, std::string pParamId, - IntervalsProperties& pIntervals); - - /* - * @brief Draw interval - */ - virtual void drawSerieInterval(SeriesProperties& pSeries, - double* xValues, double* yValues, double* timeValues, - int nbValues, int intervalIndex); - - /** - * Draw an horizontal axis. - * Subclasses may override it to take into account decorator attached to that axis (for instance). - * @param pXAxis axis to draw. - * @param pPlWindow real word ranges. - * @param pPlotAreaSize plot ranges. - * @param pTickConf ticks configuration. - */ - virtual void drawXAxis(boost::shared_ptr pXAxis, PlWindow& pPlWindow, Bounds& pPlotAreaSize, TickConf& pTickConf); - /** - * Draw a vertical axis. - * Subclasses may override it to take into account decorator attached to that axis (for instance). - * @param pXAxis axis to draw. - * @param pPlWindow real word ranges. - * @param pPlotAreaSize plot ranges. - * @param pTickConf ticks configuration. - */ - virtual void drawYAxis(boost::shared_ptr pXAxis, PlWindow& pPlWindow, Bounds& pPlotAreaSize, TickConf& pTickConf); - /** - * @brief Draw legend for each axis. - * @param pAxis axis to draw. - * @param pPlWindow real word ranges. - * @param pPlotAreaSize plot ranges. - */ - virtual void drawLegends(boost::shared_ptr& pAxis, PlWindow& pPlWindow, Bounds& pPlotAreaSize); - - /** - * @brief Draw parameters legend. - */ - virtual void drawParamsLegend(void); - - /** - * @brief Draw text legends. - */ - virtual void drawTextLegends(void); - - /** - * Convert an X axis string value to a double X value - * Subclasses may override it to take into account specific value meaning. - * @param value string value to convert. - */ - virtual double convertXAxisValue(const std::string &value); - - /** - * Convert an Y axis string value to a double Y value - * Subclasses may override it to take into account specific value meaning. - * @param value string value to convert. - */ - virtual double convertYAxisValue(const std::string &value); - - /** - * Draw X constant lines linked to an axis. - * Subclasses may override it to take into account decorator attached (for instance). - * @param pXAxis axis to draw. - * @param pPlWindow real word ranges. - */ - virtual void drawXConstantLines(boost::shared_ptr pAxis, PlWindow& pPlWindow); - /** - * Draw X constant lines linked to an axis. - * Subclasses may override it to take into account decorator attached (for instance). - * @param pXAxis axis to draw. - * @param pPlWindow real word ranges. - */ - virtual void drawYConstantLines(boost::shared_ptr pAxis, PlWindow& pPlWindow); - /** - * Draw textPlots for a panel. - * Subclasses may override it for specific drawings. - * @param pPlWindow real word ranges. - */ - virtual void drawTextPlots(boost::shared_ptr pXAxis, boost::shared_ptr pYAxis, PlWindow& pPlWindow, const TextPlots &textPlots); - - - /** - * Draw curvePlot for a panel. - * Subclasses may override it for specific drawings. - * @param curvePlot curve properties. - */ - virtual void drawCurvePlot(CurvePlot &curvePlot); - - /** - * @brief Identify if other side of the plot area need to be drawn or not. - * @note A plot area side need to be drawn when there is no axis associated to it. - */ - virtual std::string drawOppositeSide(boost::shared_ptr pAxis); - - /** - *@brief Draw additional objects on plot. - */ - virtual void drawAdditionalObjects (); - - /** - * Draw a z axis - */ - virtual void drawZAxis(boost::shared_ptr pZAxis, PlWindow& pPlWindow, Bounds& pPlotAreaSize, TickConf& pTickConf); - - - /** - * Get X Axis range for a serie - */ - Range getXAxisRange (SeriesProperties& pSeries, boost::shared_ptr pAxis); - - /** - * Get Y Axis range for a serie - */ - Range getYAxisRange (SeriesProperties& pSeries, boost::shared_ptr pAxis); - - /** - * Get Z Axis range for a serie - */ - Range getZAxisRange (SeriesProperties& pSeries, boost::shared_ptr pAxis); - - /* - * @brief Return the color to draw the symbols of a serie - */ - Color getSerieSymbolColor(SeriesProperties &rSeriesProperties, Color &pLineColor); - - /** - * @brief Configure params legend for a plot. - */ - virtual void configureParamsLegend(double startTime, double stopTime, int intervalIndex); - - /** - * @brief Add a serie to the param legend - */ - void addSerieToParamsLegend(SeriesProperties& lSeriesProperties, - AMDA::Common::ParameterIndexComponent& index, std::string originalParamId, - Color& lineColor, Color& symbolColor, - double startTime, double stopTime, int intervalIndex); - - /* - * @brief Return the associated params legend to a serie - */ - virtual std::string getSerieParamsLegendString(SeriesProperties &rSeriesProperties, - AMDA::Common::ParameterIndexComponent& index, std::string originalParamId); + public: + static const float DEFAULT_TICK_LENGTH_FACTOR; + + /** + * Width character proportion is approximatively 0.83 times smaller than height. + */ + static const float CHAR_RATIO; + + /** + * This two next attribute tell from which tick length plplot is insufficient to calculate space between tickmarks and ticks. + * Space between the two is static and can't be modified by user request. + * So when limit is reached we must bypass problem by setting two different viewport to let sufficient space between tickmarks and ticks. + */ + static const float VERTICAL_TICK_LENGTH_LIMIT; + static const float HORIZONTAL_TICK_LENGTH_LIMIT; + static const float YAXISMARGIN; + + PanelPlotOutput(AMDA::Parameters::ParameterManager &manager, + boost::shared_ptr panel, bool isStandalone = true); + virtual ~PanelPlotOutput(); + + /** + * type name. This name is used to identify nodes in xml config + * and xml request. + * @return + */ + virtual const std::string typeName() = 0; + + /** + * @brief Compute the initial plot area for the panel + */ + virtual void preparePlotArea(double startTime, double stopTime, int intervalIndex); + + /** + * @brief Retrieve plot area bounds for the panel + */ + virtual void getPlotAreaBounds(Bounds &plotAreaBounds); + + /** + * @brief Force the plot area horizontal position and width + */ + virtual void forcePlotAreaPosAndWidth(double plotAreaX, double plotAreaWidth); + + /** + * @brief Retrieve left axis tickMark width + */ + virtual int getLeftAxisTickMarkWidth(void); + + /** + * @brief Force left axis tickmark width for the panel + */ + virtual void forceLeftAxisTickMarkWidth(int leftAxisTickMarkWidth); + + /** + * @brief draw the plot for the current time interval + */ + virtual bool draw(double startTime, double stopTime, int intervalIndex, bool isFirstInterval, bool isLastInterval); + + /** + * @brief Write plot context + */ + virtual void writeContext(ContextFileWriter &writer, AMDA::Parameters::TimeIntervalList::iterator currentTimeInterval); + + /* + * @brief Set a pointer to the time intervals list + */ + void setTimeIntervalListPtr(AMDA::Parameters::TimeIntervalList *timeIntervalListPtr); + + /** + * Sets PLplot stream to draw panel and plot + */ + virtual void setPlStream(std::shared_ptr &pls); + + /** + * Adds a parameter + */ + virtual void addParam(const std::string &name) + { + ParameterAxes newParameter(name); + _parameterAxesList.push_back(newParameter); + } - /** - * @brief plplot stream - */ - std::shared_ptr _pls; + virtual ParameterAxes &getParameter(const std::string &name) + { + for (ParameterAxes ¶m : _parameterAxesList) + { + if (param._originalParamId == name) + { + return param; + } + } + ParameterAxes newParameter(name); + _parameterAxesList.push_back(newParameter); + return _parameterAxesList.back(); + } - /* - * Dumps properties for test. - */ - virtual void dump(std::ostream& out_); + /* + * Create a sampled parameter from an original parameter and a sampling value + */ + AMDA::Parameters::ParameterSPtr createSampledParameter(AMDA::Parameters::ParameterSPtr &originalParam, float samplingValue); + + /* + * Create a sampled parameter from an original parameter and a reference parameter for time definition + */ + AMDA::Parameters::ParameterSPtr createSampledParameterUnderReferenceParameter(AMDA::Parameters::ParameterSPtr &originalParam, + AMDA::Parameters::ParameterSPtr &refParam); + + /** + * Create parameters needed for this plot + * By default, the creation method create parameters for a time serie. + * Override it for other plot type + */ + virtual void createParameters(std::list &usedParametersId_); + + /** + * Get related ParameterAxes for a given color serie id + */ + ParameterAxes *getParameterAxesByColorSerieId(int colorSerieId); + + /** + * Get related ParameterAxes for a given x serie id + */ + ParameterAxes *getParameterAxesByXSerieId(int xSerieId); + + /** + * Gets sampling value from resolution (point-per-plot) according to + * the plot time interval and the base parameter sampling value. + */ + virtual double getCorrectedSamplingValue(int maxResolution, double samplingValue); + + /** + * @brief Get the list of indexes used for a parameter + */ + virtual std::vector getParamUsedIndexes(std::string paramId, int dim1Size, int dim2Size = -1); + + const Margin getMargin() + { + Bounds panelBounds(_panel->getBoundsInPlPage()); + + Margin m; + m._left = _plotAreaBounds._x - panelBounds._x; + m._right = (panelBounds._x + panelBounds._width) - (_plotAreaBounds._x + _plotAreaBounds._width); + m._top = (panelBounds._y + panelBounds._height) - (_plotAreaBounds._y + _plotAreaBounds._height); + m._bottom = _plotAreaBounds._y - panelBounds._y; + return m; + } - /** - * @brief Fill the background of the plot area - * - * @param pls - */ + /** + * @brief reset plot + */ + virtual void resetPlot() + { + if (_panel != nullptr) + _panel->resetPlot(); + _automaticSerieColorCursor = 0; + _nbSeriesByYAxisMap.clear(); + _pls.reset(); + } - void fillBackground(std::shared_ptr &pls); + /* + * @brief Set pointer to params values + */ + void setParameterValues(std::map *pParameterValues); + + /* + * @brief Get computed values (in relation with the y axis definition) for a y serie, an index of the serie and a time interval + * Do not forget to delete (*computedValues) !! + * Do not delete (*timeValues), the buffer is not copied !! + */ + bool getComputedValuesFromSerieAndInterval(double startDate, double stopDate, SeriesProperties &rSeriesProperties, + AMDA::Common::ParameterIndexComponent index, double **computedValues, double **timeValues, int &nbValues); + + /* + * @brief Get computed values (in relation with the color axis definition) for a color serie and a time interval + * Do not forget to delete computedValues !! + * Don't delete timeValues !! + */ + bool getColoredComputedValuesFromSerieAndInterval(double startDate, double stopDate, SeriesProperties &rSeriesProperties, + double **computedValues, double **timeValues, int &nbValues); + + /* + * @brief Get computed values (in relation with the y axis definition) for a y serie and a time interval + * Do not forget to delete computedValues !! + * Don't delete timeValues !! + */ + bool getErrorComputedValuesFromSerieAndInterval(double startDate, double stopDate, SeriesProperties &rSeriesProperties, + double **minComputedValues, double **minTimeValues, int &nbMinValues, + double **maxComputedValues, double **maxTimeValues, int &nbMaxValues); + + /** + *@brief Defines the layout constraint to be used for the panel when used within a layout + */ + virtual PanelConstraint getLayoutConstraint(void) + { + return PanelConstraint::MaxWidth; + } -private: + /** + * @brief Get nb series to draw by y axis + */ + std::map &getNbSeriesByYAxis(); + + /* + * @brief Return the color to draw the line of a serie + */ + Color getSerieLineColor(SeriesProperties &rSeriesProperties, bool moreThanOneSerieForAxis); + + /** + * @brief Plot container + */ + boost::shared_ptr _panel; + + /** + * @brief Parameters and series info + */ + ParameterAxesList _parameterAxesList; + + /* + * @brief Type used to define a matrix grid + */ + struct GridPart + { + double x[2]; + double y[2]; + double value; + double isColorIndex; + }; + + typedef std::vector MatrixGrid; + + // datastore for sauvaud plot + struct SauvaudPart + { + double x[2]; + double y[2]; + std::vector value; + double isColorIndex; + }; + + typedef std::vector SauvaudGrid; + + /* + * @brief Draw a matrix + */ + void drawMatrix(MatrixGrid &matrixGrid, double minDataVal, double maxDataVal, + Color minValColor, Color maxValColor, int colorMapIndex, bool useLog0AsMin = false); + + void draw2DMatrix(SauvaudGrid &sauvaudGrid, double minDataVal, double maxDataVal, + Color minValColor, Color maxValColor, int colorMapIndex, bool useLog0AsMin = false); + + /** + * @brief Reset cursor used to attribute automatically a color to a serie + */ + void resetAutomaticSerieColorCursor() + { + _automaticSerieColorCursor = 0; + } - void drawAxis(boost::shared_ptr pAxis, TickConf& pTickConf, std::string pXAxisOptions, - std::string pYAxisOptions); + /** + * Draw a rectangle + */ + void drawRectangle(double xmin, double xmax, double ymin, double ymax, Color &pColor, double alpha = 1.); - double estimateZAxisWidth(boost::shared_ptr pZAxis); + bool isStandalone() + { + return _isStandalone; + } - /** - * @brief _plotAreaSideSet Store which side of plot area is linked to an axis. - */ - std::map _plotAreaSideSet; + AMDA::Parameters::ParameterManager &_parameterManager; + + std::map *_pParameterValues; + + protected: + AMDA::Parameters::TimeIntervalList *_timeIntervalListPtr; + + /** + * @brief Compute plot area. + * @note If ratio need to be kept, ratio will be kept between width and height. + * @param bounds_ plot area bounds. It is updated by this method. + */ + virtual void calculatePlotArea(const Bounds &panelBounds_, Bounds &bounds_); + + /** + *@brief computes Panel Plot XY ratio + */ + void computePanelPlotXYRatio(void); + + /** + * @brief Get colored value associated to a data value. Return false if the value is filtered. + */ + bool getColoredValue(double value, double filterMin, double filterMax, bool useLog0AsMin, PLFLT &col); + + /** + *@brief Draw fill area between parameter and constant or between parameters + */ + virtual void drawFills(double startDate, double stopDate); + + /** + * Draw list of symbols + */ + void drawSymbols(SymbolType pType, int pSize, double pFactor, Color pColor, + int pNbData, double *pXData, double *pYData, + double *pZData = NULL, double filterZMin = -DBL_MAX, double filterZMax = DBL_MAX); + + /** + * Draw list of lines + */ + void drawLines(LineType pType, LineStyle pStyle, int pWidth, Color &pColor, + int pNbData, double *pXData, double *pYData, + double *pZData = NULL, double filterZMin = -DBL_MAX, double filterZMax = DBL_MAX); + + /** + * Draw errors segments + */ + void drawYErrors(LineType pType, LineStyle pStyle, int pWidth, Color &pColor, + int pNbData, double *pXData, double *pYMinData, double *pYMaxData); + + /** + *@brief Draw the serie of a parameter component on plot. + */ + virtual void drawSeries(double startDate, double stopDate, int intervalIndex, std::string pParamId, SeriesProperties &pSeries, + AMDA::Common::ParameterIndexComponent pParamIndex, ParameterAxes ¶m, bool moreThanOneSerieForAxis); + + /** + *@brief Draw the spectro of a parameter on plot. + */ + virtual void drawSpectro(double startDate, double stopDate, std::string pParamId, + SpectroProperties &pSpectro); + + /** + *@brief Draw sauvaud plot of a parameter on plot. + */ + virtual void drawSauvaud(double startDate, double stopDate, std::string pParamId, + SauvaudProperties &pSauvaud, int subIndex, int subsNumber, std::string opositeLegend); + + virtual void drawIntervals(double startDate, double stopDate, std::string pParamId, + IntervalsProperties &pIntervals); + + /* + * @brief Draw interval + */ + virtual void drawSerieInterval(SeriesProperties &pSeries, + double *xValues, double *yValues, double *timeValues, + int nbValues, int intervalIndex); + + /** + * Draw an horizontal axis. + * Subclasses may override it to take into account decorator attached to that axis (for instance). + * @param pXAxis axis to draw. + * @param pPlWindow real word ranges. + * @param pPlotAreaSize plot ranges. + * @param pTickConf ticks configuration. + */ + virtual void drawXAxis(boost::shared_ptr pXAxis, PlWindow &pPlWindow, Bounds &pPlotAreaSize, TickConf &pTickConf); + /** + * Draw a vertical axis. + * Subclasses may override it to take into account decorator attached to that axis (for instance). + * @param pXAxis axis to draw. + * @param pPlWindow real word ranges. + * @param pPlotAreaSize plot ranges. + * @param pTickConf ticks configuration. + */ + virtual void drawYAxis(boost::shared_ptr pXAxis, PlWindow &pPlWindow, Bounds &pPlotAreaSize, TickConf &pTickConf); + /** + * @brief Draw legend for each axis. + * @param pAxis axis to draw. + * @param pPlWindow real word ranges. + * @param pPlotAreaSize plot ranges. + */ + virtual void drawLegends(boost::shared_ptr &pAxis, PlWindow &pPlWindow, Bounds &pPlotAreaSize); + + /** + * @brief Draw parameters legend. + */ + virtual void drawParamsLegend(void); + + /** + * @brief Draw text legends. + */ + virtual void drawTextLegends(void); + + /** + * Convert an X axis string value to a double X value + * Subclasses may override it to take into account specific value meaning. + * @param value string value to convert. + */ + virtual double convertXAxisValue(const std::string &value); + + /** + * Convert an Y axis string value to a double Y value + * Subclasses may override it to take into account specific value meaning. + * @param value string value to convert. + */ + virtual double convertYAxisValue(const std::string &value); + + /** + * Draw X constant lines linked to an axis. + * Subclasses may override it to take into account decorator attached (for instance). + * @param pXAxis axis to draw. + * @param pPlWindow real word ranges. + */ + virtual void drawXConstantLines(boost::shared_ptr pAxis, PlWindow &pPlWindow); + /** + * Draw X constant lines linked to an axis. + * Subclasses may override it to take into account decorator attached (for instance). + * @param pXAxis axis to draw. + * @param pPlWindow real word ranges. + */ + virtual void drawYConstantLines(boost::shared_ptr pAxis, PlWindow &pPlWindow); + /** + * Draw textPlots for a panel. + * Subclasses may override it for specific drawings. + * @param pPlWindow real word ranges. + */ + virtual void drawTextPlots(boost::shared_ptr pXAxis, boost::shared_ptr pYAxis, PlWindow &pPlWindow, const TextPlots &textPlots); + + /** + * Draw curvePlot for a panel. + * Subclasses may override it for specific drawings. + * @param curvePlot curve properties. + */ + virtual void drawCurvePlot(CurvePlot &curvePlot); + + /** + * @brief Identify if other side of the plot area need to be drawn or not. + * @note A plot area side need to be drawn when there is no axis associated to it. + */ + virtual std::string drawOppositeSide(boost::shared_ptr pAxis); + + /** + *@brief Draw additional objects on plot. + */ + virtual void drawAdditionalObjects(); + + /** + * Draw a z axis + */ + virtual void drawZAxis(boost::shared_ptr pZAxis, PlWindow &pPlWindow, Bounds &pPlotAreaSize, TickConf &pTickConf); + + /** + * Get X Axis range for a serie + */ + Range getXAxisRange(SeriesProperties &pSeries, boost::shared_ptr pAxis); + + /** + * Get Y Axis range for a serie + */ + Range getYAxisRange(SeriesProperties &pSeries, boost::shared_ptr pAxis); + + /** + * Get Z Axis range for a serie + */ + Range getZAxisRange(SeriesProperties &pSeries, boost::shared_ptr pAxis); + + /* + * @brief Return the color to draw the symbols of a serie + */ + Color getSerieSymbolColor(SeriesProperties &rSeriesProperties, Color &pLineColor); + + /** + * @brief Configure params legend for a plot. + */ + virtual void configureParamsLegend(double startTime, double stopTime, int intervalIndex); + + /** + * @brief Add a serie to the param legend + */ + void addSerieToParamsLegend(SeriesProperties &lSeriesProperties, + AMDA::Common::ParameterIndexComponent &index, std::string originalParamId, + Color &lineColor, Color &symbolColor, + double startTime, double stopTime, int intervalIndex); + + /* + * @brief Return the associated params legend to a serie + */ + virtual std::string getSerieParamsLegendString(SeriesProperties &rSeriesProperties, + AMDA::Common::ParameterIndexComponent &index, std::string originalParamId); + + /** + * @brief plplot stream + */ + std::shared_ptr _pls; + + /* + * Dumps properties for test. + */ + virtual void dump(std::ostream &out_); + + /** + * @brief Fill the background of the plot area + * + * @param pls + */ + + void fillBackground(std::shared_ptr &pls); + + private: + void drawAxis(boost::shared_ptr pAxis, TickConf &pTickConf, std::string pXAxisOptions, + std::string pYAxisOptions); + + double estimateZAxisWidth(boost::shared_ptr pZAxis); + + /** + * @brief _plotAreaSideSet Store which side of plot area is linked to an axis. + */ + std::map _plotAreaSideSet; + + /** + * @brief nb series to draw by y axis + */ + std::map _nbSeriesByYAxisMap; + + /** + * @brief plot array on which to draw data. + */ + Bounds _plotAreaBounds; + + /* + * @brief Panel XY ratio used for angular conversion + */ + double _panelPlotXYRatio; + + /* + * @brief Panel left axis tickmark width + */ + double _leftAxisTickMarkWidth; + + /* + * @brief cursor use to set a default color to a serie + */ + int _automaticSerieColorCursor; + + /* + * + */ + bool _isStandalone; + + void reserveSpaceForAxis(boost::shared_ptr &pAxis, double titleHeight, std::map nbAxesBySide, + double &topSpace, double &bottomSpace, double &leftSpace, double &rightSpace); + + void reserveSpaceForTextLegend(boost::shared_ptr &pTextLegendProp, double titleHeight, double &topSpace, double &bottomSpace, double &leftSpace, double &rightSpace); + }; /** - * @brief nb series to draw by y axis + * Calculate room taken by tick. */ - std::map _nbSeriesByYAxisMap; + double getHorizontalTickLength(Axis *pAxis, double charHeight); /** - * @brief plot array on which to draw data. + * Calculate room taken by tick. */ - Bounds _plotAreaBounds; - - /* - * @brief Panel XY ratio used for angular conversion - */ - double _panelPlotXYRatio; - - /* - * @brief Panel left axis tickmark width - */ - double _leftAxisTickMarkWidth; - - /* - * @brief cursor use to set a default color to a serie - */ - int _automaticSerieColorCursor; - - /* - * - */ - bool _isStandalone; - - void reserveSpaceForAxis (boost::shared_ptr& pAxis, double titleHeight, std::map nbAxesBySide, - double& topSpace, double& bottomSpace, double& leftSpace, double& rightSpace); - - void reserveSpaceForTextLegend (boost::shared_ptr& pTextLegendProp, double titleHeight, double& topSpace, double& bottomSpace, double& leftSpace, double& rightSpace); -}; - -/** - * Calculate room taken by tick. - */ -double getHorizontalTickLength(Axis* pAxis, double charHeight); - -/** - * Calculate room taken by tick. - */ -double getVerticalTickLength(Axis* pAxis, double charHeight); + double getVerticalTickLength(Axis *pAxis, double charHeight); } /* namespace plot */ #endif /* PANELPLOTOUTPUT_HH_ */ diff --git a/src/Parameters/fonctions/fourier/DiscreteFourierTransform.cc b/src/Parameters/fonctions/fourier/DiscreteFourierTransform.cc index e8a4bbd..77ea707 100644 --- a/src/Parameters/fonctions/fourier/DiscreteFourierTransform.cc +++ b/src/Parameters/fonctions/fourier/DiscreteFourierTransform.cc @@ -7,38 +7,172 @@ DiscreteFourierTransform::DiscreteFourierTransform(int nbEchantillons_, ve nbEchantillons = nbEchantillons_; frequenceEchantillonnage = frequenceEchantillonnage_; signal = signal_; + + // Padding the input isgnal with 0's if it's small than nbEchantillons + + while (signal.size() < nbEchantillons) + { + signal.push_back((T)0); + } } template void DiscreteFourierTransform::compute() { - for (int k = 0; k < nbEchantillons; k++) + const int N = signal.size(); + if (DiscreteFourierTransform::isPowerOfTwo(N)) + { + phasors = DiscreteFourierTransform::fft(signal); + } + else + { + phasors = DiscreteFourierTransform::dft(signal); + } +} + +template +std::vector DiscreteFourierTransform::createTestPoints(int N, double sampleSpacing) +{ + std::vector out; + const E t = (E)sampleSpacing; + for (int i = 0; i < N; i++) + { + out.push_back((E)t * i); + } + return out; +} + +template +std::vector DiscreteFourierTransform::createTestFunction(std::vector x) +{ + const int N = x.size(); + std::vector out; + for (int i = 0; i < N; i++) + { + const E val = (E)sin(50.0 * 2.0 * M_PI * x[i]) + 0.5 * sin(80.0 * 2.0 * M_PI * x[i]); + out.push_back(val); + } + return out; +} + +/** + * @brief We use Cooley-Tukey FFT Algorithm if the size of the signal is a power of 2 otherwise you should DFT brut. In The future we will use bluestein algorithm instead of DFT. + * Cooley-Tukey FFT Algorithms: http://people.scs.carleton.ca/~maheshwa/courses/5703COMP/16Fall/FFT_Report.pdf + * + * @tparam T template type of input data + * @tparam E template type of output data + * @param sig the signal as an input + * @return std::vector> the phasors (array of complex number) + */ +template +std::vector> DiscreteFourierTransform::fft(std::vector sig) +{ + const int N = sig.size(); + if (N == 1) { - E xR = 0; - E yI = 0; - E fk = (E)(k * frequenceEchantillonnage) / (E)nbEchantillons; - // E fk = (E)(k * 1.0 / nbEchantillons); - for (int n = 0; n < signal.size(); n++) + std::vector> out; + const std::complex temp((E)sig[0], (E)0); + out.push_back(temp); + return out; + } + + const std::complex WN = (complex)std::polar(1.0, 2 * M_PI / N); + std::complex W((E)1, (E)0); + + // divide and conquer: + // Recurse: all even samples + std::vector> + x_evens = fft(getEven(sig)); + + // Recurse: all odd samples + std::vector> x_odds = fft(getOdd(sig)); + + // Now, combine and perform N/2 operations! + std::complex zeroComplex((E)0, (E)0); + std::vector> x(N, zeroComplex); + for (int k = 0; k < N / 2; k++) + { + x[k] = x_evens[k] + W * x_odds[k]; + x[k + (N / 2)] = x_evens[k] - W * x_odds[k]; + W = W * WN; + } + return x; +} + +template +std::vector> DiscreteFourierTransform::dft(std::vector x) +{ + const int N = x.size(); + std::complex zeroComplex((E)0, (E)0); + std::vector> out(N, zeroComplex); + for (int k = 0; k < N; k++) + { + for (int n = 0; n < N; n++) { - const T val = signal[n]; - if (!isNAN(val)) - { - const double angle = 2 * M_PI * n * fk; - xR += (E)cos(angle) * val; - yI += (E)sin(angle) * val; - } + const std::complex expVal = (complex)std::polar(1.0, -2 * k * n * M_PI / N); + out[k] += ((E)x[n]) * expVal; } + } + return out; +} + +template +std::vector DiscreteFourierTransform::computeDSP(std::vector> x) +{ + const int N = x.size(); + std::vector out; + for (int k = 0; k < N / 2; k++) + { + const E magnitude = (E)pow(abs(x[k]), 1); + const E dsp = (E)(2.0 / N) * magnitude; + out.push_back(dsp); + } - E amplitude = (E)sqrt(xR * xR + yI * yI); - E phase = (E)atan2(yI, xR); + return out; +} - amplitudes.push_back(amplitude); - phases.push_back(phase); - frequences.push_back(fk); - if (fk == (E)0) - periodes.push_back((E)0); - else - periodes.push_back((E)(1.0 / fk)); - sort(periodes.begin(), periodes.end()); +template +std::vector DiscreteFourierTransform::getFreq(std::vector> x, double d) +{ + const int N = x.size(); + const double stepFreq = 1.0 / (d * N); + const int N1 = (N - 1) / 2 + 1; + std::vector out; + for (int k = 0; k < N / 2; k++) + { + const E freq = (E)k * stepFreq; + out.push_back(freq); } + + return out; } + +template +std::vector DiscreteFourierTransform::getOdd(std::vector x) +{ + std::vector odd; + for (int i = 0; i < x.size(); i++) + { + if (i % 2 != 0) + odd.push_back(x[i]); + } + return odd; +} + +template +std::vector DiscreteFourierTransform::getEven(std::vector x) +{ + std::vector even; + for (int i = 0; i < x.size(); i++) + { + if (i % 2 == 0) + even.push_back(x[i]); + } + return even; +} + +template +bool DiscreteFourierTransform::isPowerOfTwo(int N) +{ + return (N & (N - 1)) == 0; +} \ No newline at end of file diff --git a/src/Parameters/fonctions/fourier/DiscreteFourierTransform.hh b/src/Parameters/fonctions/fourier/DiscreteFourierTransform.hh index 4bf5204..47eab5c 100644 --- a/src/Parameters/fonctions/fourier/DiscreteFourierTransform.hh +++ b/src/Parameters/fonctions/fourier/DiscreteFourierTransform.hh @@ -3,7 +3,10 @@ #define _DISCRETEFOURIERTRANSFORM_H #include "plplot/plplot.h" + +#include #include + #include using namespace std; @@ -36,6 +39,16 @@ public: */ DiscreteFourierTransform(int nbEchantillons_, vector signal_, double frequenceEchantillonnage_); + std::vector> fft(std::vector sig); + std::vector> dft(std::vector sig); + std::vector getEven(std::vector x); + std::vector getOdd(std::vector x); + std::vector computeDSP(std::vector> x); + std::vector getFreq(std::vector> x, double d); + std::vector createTestPoints(int N, double sampleSpacing); + std::vector createTestFunction(std::vector x); + bool isPowerOfTwo(int N); + /** * @brief Calcul de la TFD * @@ -82,6 +95,16 @@ public: return periodes; } + std::vector> getPhasors() + { + return phasors; + } + + void setPhasors(std::vector> x) + { + phasors = x; + } + private: /** * @brief Le nombre total d’échantillons (points qu’on a mesurés) @@ -118,6 +141,8 @@ private: * */ vector periodes; + + std::vector> phasors; }; #endif \ No newline at end of file -- libgit2 0.21.2