Commit 3cf118118221e740de4f2e3907900973ec700c34

Authored by Menouard AZIB
1 parent dc7a34dc

FFT Validated and I add Test fucntions

src/ParamOutputImpl/Plot/InstantPlot/PlotFunction.cc
... ... @@ -14,6 +14,7 @@
14 14 #include "fonctions/fourier/DiscreteFourierTransform.cc"
15 15 #include "fonctions/fourier/DiscreteFourierTransform.hh"
16 16 #include <algorithm>
  17 +#include <complex>
17 18 #include <limits>
18 19 #include <numeric>
19 20  
... ... @@ -45,14 +46,162 @@ namespace plot
45 46 }
46 47 }
47 48  
  49 + void PlotFunction::createParameters(std::list<std::string> &usedParametersId_)
  50 + {
  51 + PanelPlotOutput::createParameters(usedParametersId_);
  52 + }
  53 +
  54 + void PlotFunction::writeContext(ContextFileWriter &writer, AMDA::Parameters::TimeIntervalList::iterator currentTimeInterval)
  55 + {
  56 + writer.startElement("panel");
  57 + _panel->writeContext(_pls, writer);
  58 +
  59 + writer.startElement("parameters");
  60 +
  61 + for (ParameterAxesList::iterator it = _parameterAxesList.begin();
  62 + it != _parameterAxesList.end(); ++it)
  63 + {
  64 + AMDA::Parameters::ParameterSPtr originalParam =
  65 + _parameterManager.getParameter(it->_originalParamId);
  66 +
  67 + // Retrieve ParamInfo Manager
  68 + ParamMgr *piMgr = ParamMgr::getInstance();
  69 + ParamInfoSPtr paramInfo = piMgr->getParamInfoFromId(it->_originalParamId);
  70 +
  71 + double resol = originalParam->getDataWriterTemplate()->getMinSampling();
  72 + std::string resolstr = std::to_string(resol);
  73 +
  74 + writer.startElement("parameter");
  75 + writer.addAttribute("id", paramInfo->getName().c_str());
  76 + writer.addAttribute("name", paramInfo->getName().c_str());
  77 + writer.addAttribute("shortname", paramInfo->getShortName().c_str());
  78 + writer.addAttribute("MinSampling", resolstr.c_str());
  79 + writer.addAttribute("unit", paramInfo->getUnits().c_str());
  80 +
  81 + std::ostringstream legends;
  82 +
  83 + for (auto lSeries : it->getYSeriePropertiesList())
  84 + {
  85 + writer.startElement("serie");
  86 + writer.addAttribute("id", std::to_string(lSeries.getId()).c_str());
  87 +
  88 + std::ostringstream labels;
  89 + for (auto lIndex : lSeries.getIndexList(_pParameterValues))
  90 + {
  91 + std::string label = PanelPlotOutput::getSerieParamsLegendString(lSeries, lIndex, it->_originalParamId);
  92 + labels << label << ";";
  93 + }
  94 +
  95 + writer.addAttribute("serie_label", labels.str().c_str());
  96 + writer.addAttribute("dimSize", "-1");
  97 +
  98 + std::ostringstream values;
  99 +
  100 + plot::ParameterData &data = (*_pParameterValues)[lSeries.getParamId()];
  101 + for (int index_time = 0; index_time < data.getSize(); index_time++)
  102 + {
  103 + double time = data.getTimes()[index_time];
  104 + values << std::fixed << time;
  105 +
  106 + for (auto lIndex : lSeries.getIndexList(_pParameterValues))
  107 + {
  108 + double value = data.getValues(lIndex)[index_time];
  109 + values << ";" << std::fixed << value;
  110 + }
  111 + values << "|";
  112 + }
  113 + writer.addAttribute("data", values.str().c_str());
  114 + writer.endElement();
  115 + }
  116 +
  117 + if (it->getSpectroProperties() != nullptr)
  118 + {
  119 + plot::ParameterData &data = (*_pParameterValues)[it->getSpectroProperties()->getParamId()];
  120 + SpectroProperties *pSpectro = it->getSpectroProperties().get();
  121 + int dimSize = -1;
  122 + if (pSpectro->getRelatedDim() == 0)
  123 + dimSize = data.getDim1Size();
  124 + else
  125 + dimSize = data.getDim2Size();
  126 +
  127 + std::ostringstream values;
  128 + for (int index_time = 0; index_time < data.getSize(); index_time++)
  129 + {
  130 + double time = data.getTimes()[index_time];
  131 + values << std::fixed << time;
  132 + double valueTemp = 0.0;
  133 + for (int j = 0; j < dimSize; j++)
  134 + {
  135 + double value;
  136 + if (pSpectro->getRelatedDim() == 0)
  137 + value = data.getValues(AMDA::Common::ParameterIndexComponent(j, -1), 0)[index_time];
  138 + else
  139 + value = data.getValues(AMDA::Common::ParameterIndexComponent(-1, j), 0)[index_time];
  140 + valueTemp += value;
  141 + }
  142 + values << ";" << std::fixed << valueTemp << "|";
  143 + LOG4CXX_DEBUG(gLogger, time << std::fixed << " COUCOU " << valueTemp);
  144 + }
  145 +
  146 + writer.startElement("serie");
  147 + writer.addAttribute("id", "1");
  148 + writer.addAttribute("serie_label", ";");
  149 + writer.addAttribute("dimSize", std::to_string(dimSize).c_str());
  150 + writer.addAttribute("data", values.str().c_str());
  151 + writer.endElement();
  152 + }
  153 + writer.endElement();
  154 + }
  155 + writer.endElement();
  156 + writer.endElement();
  157 + }
  158 +
  159 + void PlotFunction::applyFunction()
  160 + {
  161 + std::string paramId = "";
  162 + bool isSpectro = false;
  163 + SeriesProperties lSeries;
  164 + for (auto parameter : _parameterAxesList)
  165 + {
  166 + paramId = parameter._originalParamId;
  167 + for (auto lSeries : parameter.getYSeriePropertiesList())
  168 + {
  169 + for (auto lIndex : lSeries.getIndexList(_pParameterValues))
  170 + {
  171 + std::string id = std::to_string(lSeries.getId()) + "_" + lSeries.getParamId() + "_" + std::to_string(lIndex.getDim1Index());
  172 + plot::ParameterData &data = (*_pParameterValues)[lSeries.getParamId()];
  173 + PlotFunction::compute(lIndex, data, &lSeries, nullptr, parameter._originalParamId);
  174 + }
  175 + }
  176 + }
  177 +
  178 + for (auto parameter : _parameterAxesList)
  179 + {
  180 + paramId = parameter._originalParamId;
  181 + if (parameter.getSpectroProperties() != nullptr)
  182 + {
  183 + isSpectro = true;
  184 + ParameterData &data = (*_pParameterValues)[parameter.getSpectroProperties()->getParamId()];
  185 + SpectroProperties *pSpectro = parameter.getSpectroProperties().get();
  186 + PlotFunction::compute(AMDA::Common::ParameterIndexComponent(-1, -1), data, nullptr, pSpectro, parameter._originalParamId);
  187 + }
  188 + }
  189 +
  190 + PlotFunction::createXAxis();
  191 + PlotFunction::createYAxis(paramId, isSpectro);
  192 + }
  193 +
48 194 void PlotFunction::drawSeries(double startDate, double stopDate, int intervalIndex, std::string pParamId,
49 195 SeriesProperties &pSerie,
50 196 AMDA::Common::ParameterIndexComponent pParamIndex,
51 197 ParameterAxes &param, bool moreThanOneSerieForAxis)
52 198 {
53 199 std::string id = std::to_string(pSerie.getId()) + "_" + pSerie.getParamId() + "_" + std::to_string(pParamIndex.getDim1Index());
  200 + LOG4CXX_DEBUG(gLogger, " id Serie " << id);
54 201 std::vector<double> xValues = xValuesMap[id];
55 202 std::vector<double> yValues = yValuesMap[id];
  203 + std::string ss = PanelPlotOutput::getSerieParamsLegendString(pSerie, pParamIndex, pParamId);
  204 + LOG4CXX_DEBUG(gLogger, " HHHHH" << ss);
56 205  
57 206 double *coloredComputedValues = NULL;
58 207 int nbValues = yValues.size();
... ... @@ -83,28 +232,46 @@ namespace plot
83 232 nbValues, xValuesTemp, yValuesTemp, coloredComputedValues);
84 233 }
85 234  
86   - void PlotFunction::configureSeriesAxis()
  235 + void PlotFunction::drawInstantPlot()
87 236 {
88   - //_panel->_leftMargin = 10;
89   - //_panel->_rightMargin = 5;
90   - //_panel->_bottomMargin = 4;
91   -
92   - SeriesProperties lSeries;
93 237 for (auto parameter : _parameterAxesList)
94 238 {
95   - for (auto lSeries : parameter.getYSeriePropertiesList())
  239 + if (parameter.getSpectroProperties() != nullptr)
96 240 {
97   - for (auto lIndex : lSeries.getIndexList(_pParameterValues))
98   - {
99   - std::string id = std::to_string(lSeries.getId()) + "_" + lSeries.getParamId() + "_" + std::to_string(lIndex.getDim1Index());
100   - plot::ParameterData data = (*_pParameterValues)[lSeries.getParamId()];
101   - PlotFunction::compute(lIndex, data, id, lSeries.getParamId());
102   - }
  241 + std::string pramId = parameter.getSpectroProperties()->getParamId();
  242 + std::vector<double> xValues = xValuesMap[pramId];
  243 + std::vector<double> yValues = yValuesMap[pramId];
  244 + plot::SeriesProperties *pSerie = new plot::SeriesProperties();
  245 +
  246 + double *coloredComputedValues = NULL;
  247 + int nbValues = yValues.size();
  248 +
  249 + double *yValuesTemp = &yValues[0];
  250 + double *xValuesTemp = &xValues[0];
  251 +
  252 + pSerie->setXAxisId(X_AXIS_ID);
  253 + pSerie->setYAxisId(Y_AXIS_ID);
  254 +
  255 + PanelPlotOutput::drawSeries(0, 0, 0, "",
  256 + *pSerie, AMDA::Common::ParameterIndexComponent(-1, -1), parameter, false);
  257 +
  258 + Color lineColor = getSerieLineColor(*pSerie, false);
  259 + Color symbolColor = getSerieSymbolColor(*pSerie, lineColor);
  260 +
  261 + drawSymbols(
  262 + pSerie->getSymbolProperties().getType(),
  263 + pSerie->getSymbolProperties().getSize(), 1.,
  264 + symbolColor,
  265 + nbValues, xValuesTemp, yValuesTemp, coloredComputedValues);
  266 +
  267 + drawLines(
  268 + pSerie->getLineProperties().getType(),
  269 + pSerie->getLineProperties().getStyle(),
  270 + pSerie->getLineProperties().getWidth(),
  271 + lineColor,
  272 + nbValues, xValuesTemp, yValuesTemp, coloredComputedValues);
103 273 }
104 274 }
105   -
106   - PlotFunction::createXAxis();
107   - PlotFunction::createYAxis();
108 275 }
109 276  
110 277 void PlotFunction::createXAxis()
... ... @@ -112,6 +279,8 @@ namespace plot
112 279 double minValue = 0;
113 280 double maxValue = 0;
114 281 PlotFunction::getMinMax(xValuesMap, &minValue, &maxValue);
  282 + LOG4CXX_DEBUG(gLogger, " min X " << minValue);
  283 + LOG4CXX_DEBUG(gLogger, " man X " << maxValue);
115 284 // Create X axis
116 285 boost::shared_ptr<TimeAxis> lXAxis(new TimeAxis());
117 286 lXAxis.get()->_timeFormat = "%H:%M";
... ... @@ -132,18 +301,22 @@ namespace plot
132 301 _panel->addAxis(X_AXIS_ID, lXAxis);
133 302 }
134 303  
135   - void PlotFunction::createYAxis()
  304 + void PlotFunction::createYAxis(std::string paramId, bool isSpectro)
136 305 {
137 306 std::string y_label = "";
138 307 if (function == PlotFunction::Function::AVG)
139   - y_label = "AVG";
140   - else
141   - y_label = "Amplitude";
  308 + y_label = "";
  309 + else if (function == PlotFunction::Function::SUM)
  310 + y_label = "";
  311 + else if (function == PlotFunction::Function::FFT)
  312 + y_label = "DSP";
142 313  
143 314 double minValue = 0;
144 315 double maxValue = 0;
145 316  
146 317 PlotFunction::getMinMax(yValuesMap, &minValue, &maxValue);
  318 + LOG4CXX_DEBUG(gLogger, " min Y " << minValue);
  319 + LOG4CXX_DEBUG(gLogger, " man Y " << maxValue);
147 320 // Create X axis
148 321 boost::shared_ptr<Axis> lYAxis(new Axis(false));
149 322 plot::Range range_x = Range(minValue - abs(minValue) * 0.10, maxValue + abs(maxValue) * 0.1);
... ... @@ -159,6 +332,16 @@ namespace plot
159 332 lYAxis.get()->_showTickMark = true;
160 333 lYAxis.get()->_used = true;
161 334 // add X Axis to panel
  335 + if (isSpectro)
  336 + {
  337 + AxisLegendManager::setAxisLegendForSpectro(this, lYAxis, paramId);
  338 + }
  339 + else
  340 + {
  341 + AxisLegendManager::AxisParamsComponents axisParamsComponents;
  342 + axisParamsComponents[paramId].push_back(ParameterIndexComponentColor(1, -1, lYAxis->_color));
  343 + AxisLegendManager::setAxisLegendForSeries(this, lYAxis, axisParamsComponents);
  344 + }
162 345 _panel->addAxis(Y_AXIS_ID, lYAxis);
163 346 }
164 347  
... ... @@ -181,12 +364,24 @@ namespace plot
181 364 *maxToFill = maxValue;
182 365 }
183 366  
184   - void PlotFunction::compute(AMDA::Common::ParameterIndexComponent pParamIndex, plot::ParameterData data, std::string id, std::string param_id)
  367 + void PlotFunction::compute(AMDA::Common::ParameterIndexComponent pParamIndex, plot::ParameterData &data, SeriesProperties *pSerie, SpectroProperties *pSpectro, std::string paramOriginID)
185 368 {
186 369 double samplingValue = 60.0;
187 370 int nb_points = data.getSize();
  371 + std::string param_id, id;
188 372  
189   - auto it = find(paramsNbPoints.begin(), paramsNbPoints.end(), param_id);
  373 + if (pSerie == nullptr)
  374 + {
  375 + param_id = pSpectro->getParamId();
  376 + id = param_id;
  377 + }
  378 + else
  379 + {
  380 + param_id = pSerie->getParamId();
  381 + id = std::to_string(pSerie->getId()) + "_" + param_id + "_" + std::to_string(pParamIndex.getDim1Index());
  382 + }
  383 +
  384 + auto it = find(paramsNbPoints.begin(), paramsNbPoints.end(), paramOriginID);
190 385 // If parameter was found
191 386 if (it != paramsNbPoints.end())
192 387 {
... ... @@ -196,57 +391,129 @@ namespace plot
196 391 }
197 392 else
198 393 {
199   - std::stringstream lError;
  394 + /*std::stringstream lError;
200 395 lError << "PlotFunction::compute"
201   - << ": param with id " << param_id << " is not found in param_nb_points xml node.";
  396 + << ": param with id " << paramOriginID << " is not found in param_nb_points xml node.";
202 397 LOG4CXX_DEBUG(gLogger, lError.str());
203   - BOOST_THROW_EXCEPTION(PanelPlotOutputException() << AMDA::errno_code(AMDA_ERROR_PLOTFUNCTION_PARAM_NOT_FOUND) << AMDA::ex_msg(lError.str()));
  398 + BOOST_THROW_EXCEPTION(PanelPlotOutputException() << AMDA::errno_code(AMDA_ERROR_PLOTFUNCTION_PARAM_NOT_FOUND) << AMDA::ex_msg(lError.str()));*/
204 399 }
205 400  
206   - double *values = data.getValues(pParamIndex, 0);
  401 + std::vector<double> xValues;
  402 + std::vector<double> yValues;
207 403  
208   - double *timeValues = &data.getTimes()[0];
  404 + int dimSize = -1;
  405 + if (pSpectro != nullptr)
  406 + if (pSpectro->getRelatedDim() == 0)
  407 + dimSize = data.getDim1Size();
  408 + else
  409 + dimSize = data.getDim2Size();
209 410  
210   - std::vector<double> signal;
211   - for (int i = 0; i < data.getSize(); i++)
212   - signal.push_back(values[i]);
  411 + for (int index_time = 0; index_time < data.getSize(); index_time++)
  412 + {
  413 + double time = data.getTimes()[index_time];
  414 + xValues.push_back(time);
213 415  
214   - std::vector<double> xValues;
215   - std::vector<double> yValues;
  416 + double valueTemp = 0.0;
  417 + for (int j = 0; j < dimSize; j++)
  418 + {
  419 + double value;
  420 + if (pSpectro->getRelatedDim() == 0)
  421 + value = data.getValues(AMDA::Common::ParameterIndexComponent(j, -1), 0)[index_time];
  422 + else
  423 + value = data.getValues(AMDA::Common::ParameterIndexComponent(-1, j), 0)[index_time];
  424 + valueTemp += value;
  425 + }
216 426  
217   - if (function == PlotFunction::Function::AVG)
  427 + LOG4CXX_DEBUG(gLogger, time << std::fixed << " " << valueTemp);
  428 + if (dimSize < 0)
  429 + valueTemp = data.getValues(pParamIndex, 0)[index_time];
  430 +
  431 + yValues.push_back(valueTemp);
  432 + }
  433 +
  434 + if (function == PlotFunction::Function::SUM)
218 435 {
219   - double sum = std::accumulate(signal.begin(), signal.end(), 0);
220   - for (int i = 0; i < data.getSize(); i++)
  436 + if (dimSize < 0)
221 437 {
222   - yValues.push_back(sum / data.getSize());
223   - xValues.push_back(timeValues[i]);
  438 + double sum = std::accumulate(yValues.begin(), yValues.end(), 0);
  439 + yValues.assign(yValues.size(), sum);
224 440 }
225 441 }
226   - else
  442 + else if (function == PlotFunction::Function::AVG)
  443 + {
  444 + int size = dimSize;
  445 + if (dimSize < 0)
  446 + {
  447 + double sum = std::accumulate(yValues.begin(), yValues.end(), 0);
  448 + yValues.assign(yValues.size(), sum);
  449 + size = data.getSize();
  450 + }
  451 +
  452 + transform(yValues.begin(), yValues.end(), yValues.begin(), [size](double &c)
  453 + { return c / size; });
  454 + }
  455 + else if (function == PlotFunction::Function::FFT)
227 456 {
228   - DiscreteFourierTransform<double, double> DFT(std::min(nb_points, data.getSize()), signal, 1 / samplingValue);
229   - DFT.compute();
  457 + DiscreteFourierTransform<double, double> DFT(std::min(nb_points, data.getSize()), yValues, 1.0 / samplingValue);
  458 + // DFT.compute();
  459 +
  460 + std::vector<double> vect;
  461 + vect.push_back(1);
  462 + vect.push_back(2);
  463 + vect.push_back(1);
  464 + vect.push_back(-1);
  465 + vect.push_back(1.5);
  466 +
  467 + std::vector<std::complex<double>> vectOUT = DFT.fft(vect);
  468 + for (int u = 0; u < vectOUT.size(); u++)
  469 + {
  470 + LOG4CXX_DEBUG(gLogger, "Real part: " << real(vectOUT[u]) << " Imaginary part: " << imag(vectOUT[u]) << " " << abs(vectOUT[u]));
  471 + }
230 472  
231   - yValues = DFT.getAmplitudes();
  473 + vectOUT = DFT.dft(vect);
  474 + for (int u = 0; u < vectOUT.size(); u++)
  475 + {
  476 + LOG4CXX_DEBUG(gLogger, "Real part: " << real(vectOUT[u]) << " Imaginary part: " << imag(vectOUT[u]) << " " << abs(vectOUT[u]));
  477 + }
  478 +
  479 + std::vector<double> x_ = DFT.createTestPoints(600, 1.0 / 800);
  480 + std::vector<double> y_ = DFT.createTestFunction(x_);
  481 + std::vector<std::complex<double>> ph = DFT.dft(y_);
  482 + LOG4CXX_DEBUG(gLogger, "size of x_ : " << x_.size() << " size of y " << y_.size() << " size of phasors " << ph.size());
  483 + DFT.setPhasors(ph);
  484 + for (int u = 0; u < ph.size(); u++)
  485 + {
  486 + std::complex<double> mycomplex = ph[u];
  487 + }
  488 + std::vector<double> dsp = DFT.computeDSP(ph);
  489 + for (int u = 0; u < dsp.size(); u++)
  490 + {
  491 + LOG4CXX_DEBUG(gLogger, " DSP " << dsp[u]);
  492 + }
  493 +
  494 + yValues = dsp;
  495 + // dsp; // DFT.getAmplitudes();
232 496  
233 497 if (abscisse.getType() == Abscisse::Abscisse_Type::FREQUENCY)
234   - xValues = DFT.getFrequences();
  498 + {
  499 + xValues = DFT.getFreq(ph, 1.0 / 800); // DFT.getFrequences();
  500 + for (int u = 0; u < xValues.size(); u++)
  501 + {
  502 + LOG4CXX_DEBUG(gLogger, " indice " << u << " freq " << xValues[u]);
  503 + }
  504 + }
235 505 else
236 506 xValues = DFT.getPeriodes();
  507 + // xValues = x_;
237 508 }
238 509  
239 510 if (ordonneeScale == Axis::Scale::LOGARITHMIC)
240   - {
241 511 std::for_each(yValues.begin(), yValues.end(), [&](double &i)
242 512 { return log10(i); });
243   - }
244 513  
245 514 if (abscisseScale == Axis::Scale::LOGARITHMIC)
246   - {
247 515 std::for_each(xValues.begin(), xValues.end(), [&](double &i)
248 516 { return log10(i); });
249   - }
250 517  
251 518 PlotFunction::xValuesMap[id] = xValues;
252 519 PlotFunction::yValuesMap[id] = yValues;
... ... @@ -302,7 +569,7 @@ namespace plot
302 569  
303 570 void PlotFunction::preparePlotArea(double startTime, double stopTime, int intervalIndex)
304 571 {
305   - PlotFunction::configureSeriesAxis();
  572 + PlotFunction::applyFunction();
306 573  
307 574 if (abscisse.getType() == Abscisse::TIME)
308 575 {
... ... @@ -310,32 +577,9 @@ namespace plot
310 577 getTimeAxisDecorator()->configure(this, dynamic_cast<TimeAxis *>(xAxis.get()), startTime, stopTime, _pParameterValues);
311 578 _pls->timefmt(getTimeAxisDecorator()->getPlFormat().c_str());
312 579 }
313   - PanelPlotOutput::preparePlotArea(startTime, stopTime, intervalIndex);
314   - }
315   -
316   - void PlotFunction::createParameters(std::list<std::string> &usedParametersId_)
317   - {
318   -
319   - for (ParameterAxesList::iterator it = _parameterAxesList.begin();
320   - it != _parameterAxesList.end(); ++it)
321   - {
322   - AMDA::Parameters::ParameterSPtr originalParam =
323   - _parameterManager.getParameter(it->_originalParamId);
  580 + PanelPlotOutput::configureParamsLegend(startTime, stopTime, intervalIndex);
324 581  
325   - // For each series
326   - std::vector<SeriesProperties>::iterator ity;
327   - for (ity = it->getYSeriePropertiesList().begin(); ity != it->getYSeriePropertiesList().end();
328   - ++ity)
329   - {
330   - // Add parameter to parameters list
331   - if (std::find(usedParametersId_.begin(), usedParametersId_.end(),
332   - originalParam->getId()) == usedParametersId_.end())
333   - usedParametersId_.push_back(originalParam->getId());
334   -
335   - // link this paramter to the serie
336   - ity->setParamId(originalParam->getId());
337   - }
338   - }
  582 + PanelPlotOutput::preparePlotArea(startTime, stopTime, intervalIndex);
339 583 }
340 584  
341 585 /**
... ... @@ -349,23 +593,6 @@ namespace plot
349 593 _panel->draw(_pls);
350 594 fillBackground(_pls);
351 595  
352   - bool noData = true;
353   -
354   - if (_parameterAxesList.empty())
355   - {
356   - noData = false; // Do not draw No Data if the panel is empty
357   - _panel->drawEmptyPanel(_pls);
358   - }
359   -
360   - // Set pointer to ParameterData list
361   - if (_pParameterValues == NULL)
362   - {
363   - std::stringstream lError;
364   - lError << "PanelPlotOutput::draw - Pointer to parameterValues is not set";
365   - BOOST_THROW_EXCEPTION(
366   - PanelPlotOutputException() << AMDA::ex_msg(lError.str()));
367   - }
368   -
369 596 // Compute nb series to draw by y axis
370 597 std::map<std::string, int> nbSeriesByYAxisMap = getNbSeriesByYAxis();
371 598 SeriesProperties lSeries;
... ... @@ -386,10 +613,6 @@ namespace plot
386 613 drawSeries(startTime, stopTime, intervalIndex, parameter._originalParamId,
387 614 lSeries, lIndex, parameter, moreThanOneSerieForYAxis);
388 615 ParameterData &data = (*_pParameterValues)[lSeries.getParamId()];
389   - if (noData)
390   - {
391   - noData = data.noData(lIndex);
392   - }
393 616 }
394 617 }
395 618 }
... ... @@ -400,6 +623,7 @@ namespace plot
400 623 PlotFunction::drawStartDate(_timeFormat, startTime, stopTime);
401 624 }
402 625  
403   - return noData;
  626 + PlotFunction::drawInstantPlot();
  627 + return true;
404 628 }
405 629 }
... ...
src/ParamOutputImpl/Plot/InstantPlot/PlotFunction.hh
... ... @@ -148,8 +148,11 @@ namespace plot
148 148 virtual bool draw(double startTime, double stopTime, int intervalIndex,
149 149 bool isFirstInterval, bool isLastInterval);
150 150  
  151 + virtual void writeContext(ContextFileWriter &writer, AMDA::Parameters::TimeIntervalList::iterator currentTimeInterval);
  152 +
151 153 private:
152   - void configureSeriesAxis();
  154 + void drawInstantPlot();
  155 + void applyFunction();
153 156 void configureAxisLegend();
154 157 /**
155 158 * @brief Afficher sur le plot the starting date
... ... @@ -163,7 +166,7 @@ namespace plot
163 166 * @brief Créer un axe Y pour accueillir les valeurs calculées de l'axe Y
164 167 *
165 168 */
166   - void createYAxis();
  169 + void createYAxis(std::string paramId, bool isSpectro);
167 170 /**
168 171 * @brief Créer un axe X pour accueillir les valeurs calculées de l'axe X
169 172 *
... ... @@ -184,7 +187,7 @@ namespace plot
184 187 * @param id id pseudo param
185 188 * @param param_id id du paramètre
186 189 */
187   - void compute(AMDA::Common::ParameterIndexComponent pParamIndex, plot::ParameterData data, std::string id, std::string param_id);
  190 + void compute(AMDA::Common::ParameterIndexComponent pParamIndex, plot::ParameterData &data, SeriesProperties *pSerie, SpectroProperties *pSpectro, std::string paramOriginID);
188 191  
189 192 /**
190 193 * @brief Une map pour stocker les valeurs calculées de l'axe X associés aux pseudo paramètres crées localement
... ...
src/ParamOutputImpl/Plot/InstantPlot/PlotFunctionNode.cc
... ... @@ -67,8 +67,8 @@ namespace plot
67 67 plot->setFunction(PlotFunction::Function::AVG);
68 68 else if (strcmp(valueString, PlotFunctuion_Type_FFT) == 0)
69 69 plot->setFunction(PlotFunction::Function::FFT);
70   - else
71   - plot->setFunction(PlotFunction::Function::NONE);
  70 + else if (strcmp(valueString, PlotFunctuion_Type_SUM) == 0)
  71 + plot->setFunction(PlotFunction::Function::SUM);
72 72 xmlFree(value);
73 73 }
74 74  
... ...
src/ParamOutputImpl/Plot/PanelPlotOutput.cc
... ... @@ -2188,6 +2188,8 @@ namespace plot
2188 2188 if (!isStandalone())
2189 2189 return;
2190 2190  
  2191 + LOG4CXX_DEBUG(gLogger, "here 0");
  2192 +
2191 2193 writer.startElement("panel");
2192 2194 _panel->writeContext(_pls, writer);
2193 2195  
... ...
src/ParamOutputImpl/Plot/PanelPlotOutput.hh
... ... @@ -8,592 +8,600 @@
8 8 #ifndef PANELPLOTOUTPUT_HH_
9 9 #define PANELPLOTOUTPUT_HH_
10 10  
11   -#include "ParamOutput.hh"
  11 +#include "ContextFileWriter.hh"
  12 +#include "Layout.hh"
12 13 #include "Panel.hh"
  14 +#include "PanelPlotOutputException.hh"
  15 +#include "ParamOutput.hh"
13 16 #include "ParameterAxes.hh"
14   -#include <vector>
15   -#include <tuple>
16 17 #include "ParameterData.hh"
  18 +#include "PlotLogger.hh"
17 19 #include <AMDA_exception.hh>
18 20 #include <cxxabi.h>
19   -#include "PlotLogger.hh"
20   -#include "PanelPlotOutputException.hh"
21   -#include "Layout.hh"
22   -#include "ContextFileWriter.hh"
  21 +#include <tuple>
  22 +#include <vector>
23 23  
24 24 #include <cfloat>
25 25  
26   -namespace plot {
27   -
28   -// 0 => xmin
29   -// 1 => xmax
30   -// 2 => ymin
31   -// 3 => ymax
32   -typedef std::tuple<double, double, double, double> PlWindow;
33   -// 0 => x major tick space
34   -// 1 => x minor tick number
35   -// 2 => y major tick space
36   -// 3 => y minor tick number
37   -typedef std::tuple<double, double, double, double> TickConf;
38   -
39   -/**
40   - * Margin.
41   - */
42   -struct Margin {
43   - double _left;
44   - double _right;
45   - double _top;
46   - double _bottom;
47   -};
48   -
49   -class PanelPlotOutput {
50   -public:
51   - static const float DEFAULT_TICK_LENGTH_FACTOR;
52   -
53   - /**
54   - * Width character proportion is approximatively 0.83 times smaller than height.
55   - */
56   - static const float CHAR_RATIO;
57   -
58   - /**
59   - * This two next attribute tell from which tick length plplot is insufficient to calculate space between tickmarks and ticks.
60   - * Space between the two is static and can't be modified by user request.
61   - * So when limit is reached we must bypass problem by setting two different viewport to let sufficient space between tickmarks and ticks.
62   - */
63   - static const float VERTICAL_TICK_LENGTH_LIMIT;
64   - static const float HORIZONTAL_TICK_LENGTH_LIMIT;
65   - static const float YAXISMARGIN;
  26 +namespace plot
  27 +{
66 28  
67   - PanelPlotOutput(AMDA::Parameters::ParameterManager& manager,
68   - boost::shared_ptr<Panel> panel, bool isStandalone = true);
69   - virtual ~PanelPlotOutput();
  29 + // 0 => xmin
  30 + // 1 => xmax
  31 + // 2 => ymin
  32 + // 3 => ymax
  33 + typedef std::tuple<double, double, double, double> PlWindow;
  34 + // 0 => x major tick space
  35 + // 1 => x minor tick number
  36 + // 2 => y major tick space
  37 + // 3 => y minor tick number
  38 + typedef std::tuple<double, double, double, double> TickConf;
70 39  
71 40 /**
72   - * type name. This name is used to identify nodes in xml config
73   - * and xml request.
74   - * @return
  41 + * Margin.
75 42 */
76   - virtual const std::string typeName() = 0;
77   -
78   - /**
79   - * @brief Compute the initial plot area for the panel
80   - */
81   - virtual void preparePlotArea (double startTime, double stopTime, int intervalIndex);
82   -
83   - /**
84   - * @brief Retrieve plot area bounds for the panel
85   - */
86   - virtual void getPlotAreaBounds (Bounds &plotAreaBounds);
87   -
88   - /**
89   - * @brief Force the plot area horizontal position and width
90   - */
91   - virtual void forcePlotAreaPosAndWidth(double plotAreaX, double plotAreaWidth);
92   -
93   - /**
94   - * @brief Retrieve left axis tickMark width
95   - */
96   - virtual int getLeftAxisTickMarkWidth (void);
97   -
98   - /**
99   - * @brief Force left axis tickmark width for the panel
100   - */
101   - virtual void forceLeftAxisTickMarkWidth(int leftAxisTickMarkWidth);
102   -
103   - /**
104   - * @brief draw the plot for the current time interval
105   - */
106   - virtual bool draw(double startTime, double stopTime, int intervalIndex, bool isFirstInterval, bool isLastInterval);
107   -
108   - /**
109   - * @brief Write plot context
110   - */
111   - void writeContext(ContextFileWriter &writer, AMDA::Parameters::TimeIntervalList::iterator currentTimeInterval);
112   -
113   - /*
114   - * @brief Set a pointer to the time intervals list
115   - */
116   - void setTimeIntervalListPtr(AMDA::Parameters::TimeIntervalList *timeIntervalListPtr);
117   -
118   - /**
119   - * Sets PLplot stream to draw panel and plot
120   - */
121   - virtual void setPlStream(std::shared_ptr<plstream>& pls);
122   -
123   - /**
124   - * Adds a parameter
125   - */
126   - virtual void addParam(const std::string& name) {
127   - ParameterAxes newParameter(name);
128   - _parameterAxesList.push_back(newParameter);
129   - }
130   -
131   - virtual ParameterAxes& getParameter(const std::string& name) {
132   - for (ParameterAxes& param : _parameterAxesList) {
133   - if (param._originalParamId == name) {
134   - return param;
135   - }
136   - }
137   - ParameterAxes newParameter(name);
138   - _parameterAxesList.push_back(newParameter);
139   - return _parameterAxesList.back();
140   - }
141   -
142   - /*
143   - * Create a sampled parameter from an original parameter and a sampling value
144   - */
145   - AMDA::Parameters::ParameterSPtr createSampledParameter(AMDA::Parameters::ParameterSPtr& originalParam, float samplingValue);
146   -
147   - /*
148   - * Create a sampled parameter from an original parameter and a reference parameter for time definition
149   - */
150   - AMDA::Parameters::ParameterSPtr createSampledParameterUnderReferenceParameter(AMDA::Parameters::ParameterSPtr& originalParam,
151   - AMDA::Parameters::ParameterSPtr& refParam);
152   -
153   - /**
154   - * Create parameters needed for this plot
155   - * By default, the creation method create parameters for a time serie.
156   - * Override it for other plot type
157   - */
158   - virtual void createParameters(std::list<std::string>& usedParametersId_);
159   -
160   - /**
161   - * Get related ParameterAxes for a given color serie id
162   - */
163   - ParameterAxes* getParameterAxesByColorSerieId(int colorSerieId);
164   -
165   - /**
166   - * Get related ParameterAxes for a given x serie id
167   - */
168   - ParameterAxes* getParameterAxesByXSerieId(int xSerieId);
169   -
170   - /**
171   - * Gets sampling value from resolution (point-per-plot) according to
172   - * the plot time interval and the base parameter sampling value.
173   - */
174   - virtual double getCorrectedSamplingValue(int maxResolution, double samplingValue);
175   -
176   - /**
177   - * @brief Get the list of indexes used for a parameter
178   - */
179   - virtual std::vector<AMDA::Common::ParameterIndexComponent> getParamUsedIndexes(std::string paramId, int dim1Size, int dim2Size = -1);
180   -
181   - const Margin getMargin(){
182   - Bounds panelBounds(_panel->getBoundsInPlPage());
183   -
184   - Margin m;
185   - m._left = _plotAreaBounds._x - panelBounds._x;
186   - m._right = (panelBounds._x + panelBounds._width) - (_plotAreaBounds._x + _plotAreaBounds._width);
187   - m._top = (panelBounds._y + panelBounds._height) - (_plotAreaBounds._y + _plotAreaBounds._height);
188   - m._bottom = _plotAreaBounds._y - panelBounds._y;
189   - return m;
190   - }
191   -
192   - /**
193   - * @brief reset plot
194   - */
195   - virtual void resetPlot() {
196   - if (_panel != nullptr)
197   - _panel->resetPlot();
198   - _automaticSerieColorCursor = 0;
199   - _nbSeriesByYAxisMap.clear();
200   - _pls.reset();
201   - }
202   -
203   - /*
204   - * @brief Set pointer to params values
205   - */
206   - void setParameterValues(std::map<std::string, ParameterData> *pParameterValues);
207   -
208   - /*
209   - * @brief Get computed values (in relation with the y axis definition) for a y serie, an index of the serie and a time interval
210   - * Do not forget to delete (*computedValues) !!
211   - * Do not delete (*timeValues), the buffer is not copied !!
212   - */
213   - bool getComputedValuesFromSerieAndInterval(double startDate, double stopDate, SeriesProperties &rSeriesProperties,
214   - AMDA::Common::ParameterIndexComponent index, double** computedValues, double** timeValues, int& nbValues);
215   -
216   - /*
217   - * @brief Get computed values (in relation with the color axis definition) for a color serie and a time interval
218   - * Do not forget to delete computedValues !!
219   - * Don't delete timeValues !!
220   - */
221   - bool getColoredComputedValuesFromSerieAndInterval(double startDate, double stopDate, SeriesProperties &rSeriesProperties,
222   - double** computedValues, double** timeValues, int& nbValues);
223   -
224   - /*
225   - * @brief Get computed values (in relation with the y axis definition) for a y serie and a time interval
226   - * Do not forget to delete computedValues !!
227   - * Don't delete timeValues !!
228   - */
229   - bool getErrorComputedValuesFromSerieAndInterval(double startDate, double stopDate, SeriesProperties &rSeriesProperties,
230   - double** minComputedValues, double** minTimeValues, int& nbMinValues,
231   - double** maxComputedValues, double** maxTimeValues, int& nbMaxValues);
232   -
233   - /**
234   - *@brief Defines the layout constraint to be used for the panel when used within a layout
235   - */
236   - virtual PanelConstraint getLayoutConstraint (void) {
237   - return PanelConstraint::MaxWidth;
238   - }
239   -
240   - /**
241   - * @brief Get nb series to draw by y axis
242   - */
243   - std::map<std::string,int>& getNbSeriesByYAxis();
244   -
245   - /*
246   - * @brief Return the color to draw the line of a serie
247   - */
248   - Color getSerieLineColor(SeriesProperties &rSeriesProperties, bool moreThanOneSerieForAxis);
249   -
250   - /**
251   - * @brief Plot container
252   - */
253   - boost::shared_ptr<Panel> _panel;
254   -
255   - /**
256   - * @brief Parameters and series info
257   - */
258   - ParameterAxesList _parameterAxesList;
259   -
260   - /*
261   - * @brief Type used to define a matrix grid
262   - */
263   - struct GridPart
  43 + struct Margin
264 44 {
265   - double x[2];
266   - double y[2];
267   - double value;
268   - double isColorIndex;
  45 + double _left;
  46 + double _right;
  47 + double _top;
  48 + double _bottom;
269 49 };
270 50  
271   - typedef std::vector<GridPart> MatrixGrid;
272   -
273   - // datastore for sauvaud plot
274   - struct SauvaudPart
  51 + class PanelPlotOutput
275 52 {
276   - double x[2];
277   - double y[2];
278   - std::vector<double> value;
279   - double isColorIndex;
280   - };
281   -
282   - typedef std::vector<SauvaudPart> SauvaudGrid;
283   -
284   - /*
285   - * @brief Draw a matrix
286   - */
287   - void drawMatrix(MatrixGrid& matrixGrid, double minDataVal, double maxDataVal,
288   - Color minValColor, Color maxValColor, int colorMapIndex, bool useLog0AsMin = false);
289   -
290   - void draw2DMatrix(SauvaudGrid& sauvaudGrid, double minDataVal, double maxDataVal,
291   - Color minValColor, Color maxValColor, int colorMapIndex, bool useLog0AsMin = false);
292   -
293   - /**
294   - * @brief Reset cursor used to attribute automatically a color to a serie
295   - */
296   - void resetAutomaticSerieColorCursor() {
297   - _automaticSerieColorCursor = 0;
298   - }
299   -
300   - /**
301   - * Draw a rectangle
302   - */
303   - void drawRectangle(double xmin, double xmax, double ymin, double ymax, Color& pColor, double alpha = 1.);
304   -
305   - bool isStandalone() {
306   - return _isStandalone;
307   - }
308   -
309   - AMDA::Parameters::ParameterManager& _parameterManager;
310   -
311   - std::map<std::string, ParameterData> *_pParameterValues;
312   -
313   -protected:
314   -
315   - AMDA::Parameters::TimeIntervalList* _timeIntervalListPtr;
316   -
317   - /**
318   - * @brief Compute plot area.
319   - * @note If ratio need to be kept, ratio will be kept between width and height.
320   - * @param bounds_ plot area bounds. It is updated by this method.
321   - */
322   - virtual void calculatePlotArea(const Bounds& panelBounds_, Bounds& bounds_);
323   -
324   - /**
325   - *@brief computes Panel Plot XY ratio
326   - */
327   - void computePanelPlotXYRatio(void);
328   -
329   - /**
330   - * @brief Get colored value associated to a data value. Return false if the value is filtered.
331   - */
332   - bool getColoredValue(double value, double filterMin, double filterMax, bool useLog0AsMin, PLFLT &col);
333   -
334   - /**
335   - *@brief Draw fill area between parameter and constant or between parameters
336   - */
337   - virtual void drawFills(double startDate, double stopDate);
338   -
339   - /**
340   - * Draw list of symbols
341   - */
342   - void drawSymbols(SymbolType pType, int pSize, double pFactor, Color pColor,
343   - int pNbData, double* pXData, double* pYData,
344   - double* pZData = NULL, double filterZMin = -DBL_MAX, double filterZMax = DBL_MAX);
345   -
346   - /**
347   - * Draw list of lines
348   - */
349   - void drawLines(LineType pType, LineStyle pStyle, int pWidth, Color& pColor,
350   - int pNbData, double* pXData, double* pYData,
351   - double* pZData = NULL, double filterZMin = -DBL_MAX, double filterZMax = DBL_MAX);
352   -
353   - /**
354   - * Draw errors segments
355   - */
356   - void drawYErrors (LineType pType, LineStyle pStyle, int pWidth, Color& pColor,
357   - int pNbData, double* pXData, double* pYMinData, double* pYMaxData);
358   -
359   - /**
360   - *@brief Draw the serie of a parameter component on plot.
361   - */
362   - virtual void drawSeries(double startDate, double stopDate, int intervalIndex, std::string pParamId, SeriesProperties& pSeries,
363   - AMDA::Common::ParameterIndexComponent pParamIndex, ParameterAxes& param, bool moreThanOneSerieForAxis);
364   -
365   - /**
366   - *@brief Draw the spectro of a parameter on plot.
367   - */
368   - virtual void drawSpectro(double startDate, double stopDate, std::string pParamId,
369   - SpectroProperties& pSpectro);
370   -
371   - /**
372   - *@brief Draw sauvaud plot of a parameter on plot.
373   - */
374   - virtual void drawSauvaud(double startDate, double stopDate, std::string pParamId,
375   - SauvaudProperties& pSauvaud, int subIndex, int subsNumber, std::string opositeLegend);
376   -
377   - virtual void drawIntervals(double startDate, double stopDate, std::string pParamId,
378   - IntervalsProperties& pIntervals);
379   -
380   - /*
381   - * @brief Draw interval
382   - */
383   - virtual void drawSerieInterval(SeriesProperties& pSeries,
384   - double* xValues, double* yValues, double* timeValues,
385   - int nbValues, int intervalIndex);
386   -
387   - /**
388   - * Draw an horizontal axis.
389   - * Subclasses may override it to take into account decorator attached to that axis (for instance).
390   - * @param pXAxis axis to draw.
391   - * @param pPlWindow real word ranges.
392   - * @param pPlotAreaSize plot ranges.
393   - * @param pTickConf ticks configuration.
394   - */
395   - virtual void drawXAxis(boost::shared_ptr<Axis> pXAxis, PlWindow& pPlWindow, Bounds& pPlotAreaSize, TickConf& pTickConf);
396   - /**
397   - * Draw a vertical axis.
398   - * Subclasses may override it to take into account decorator attached to that axis (for instance).
399   - * @param pXAxis axis to draw.
400   - * @param pPlWindow real word ranges.
401   - * @param pPlotAreaSize plot ranges.
402   - * @param pTickConf ticks configuration.
403   - */
404   - virtual void drawYAxis(boost::shared_ptr<Axis> pXAxis, PlWindow& pPlWindow, Bounds& pPlotAreaSize, TickConf& pTickConf);
405   - /**
406   - * @brief Draw legend for each axis.
407   - * @param pAxis axis to draw.
408   - * @param pPlWindow real word ranges.
409   - * @param pPlotAreaSize plot ranges.
410   - */
411   - virtual void drawLegends(boost::shared_ptr<Axis>& pAxis, PlWindow& pPlWindow, Bounds& pPlotAreaSize);
412   -
413   - /**
414   - * @brief Draw parameters legend.
415   - */
416   - virtual void drawParamsLegend(void);
417   -
418   - /**
419   - * @brief Draw text legends.
420   - */
421   - virtual void drawTextLegends(void);
422   -
423   - /**
424   - * Convert an X axis string value to a double X value
425   - * Subclasses may override it to take into account specific value meaning.
426   - * @param value string value to convert.
427   - */
428   - virtual double convertXAxisValue(const std::string &value);
429   -
430   - /**
431   - * Convert an Y axis string value to a double Y value
432   - * Subclasses may override it to take into account specific value meaning.
433   - * @param value string value to convert.
434   - */
435   - virtual double convertYAxisValue(const std::string &value);
436   -
437   - /**
438   - * Draw X constant lines linked to an axis.
439   - * Subclasses may override it to take into account decorator attached (for instance).
440   - * @param pXAxis axis to draw.
441   - * @param pPlWindow real word ranges.
442   - */
443   - virtual void drawXConstantLines(boost::shared_ptr<Axis> pAxis, PlWindow& pPlWindow);
444   - /**
445   - * Draw X constant lines linked to an axis.
446   - * Subclasses may override it to take into account decorator attached (for instance).
447   - * @param pXAxis axis to draw.
448   - * @param pPlWindow real word ranges.
449   - */
450   - virtual void drawYConstantLines(boost::shared_ptr<Axis> pAxis, PlWindow& pPlWindow);
451   - /**
452   - * Draw textPlots for a panel.
453   - * Subclasses may override it for specific drawings.
454   - * @param pPlWindow real word ranges.
455   - */
456   - virtual void drawTextPlots(boost::shared_ptr<Axis> pXAxis, boost::shared_ptr<Axis> pYAxis, PlWindow& pPlWindow, const TextPlots &textPlots);
457   -
458   -
459   - /**
460   - * Draw curvePlot for a panel.
461   - * Subclasses may override it for specific drawings.
462   - * @param curvePlot curve properties.
463   - */
464   - virtual void drawCurvePlot(CurvePlot &curvePlot);
465   -
466   - /**
467   - * @brief Identify if other side of the plot area need to be drawn or not.
468   - * @note A plot area side need to be drawn when there is no axis associated to it.
469   - */
470   - virtual std::string drawOppositeSide(boost::shared_ptr<Axis> pAxis);
471   -
472   - /**
473   - *@brief Draw additional objects on plot.
474   - */
475   - virtual void drawAdditionalObjects ();
476   -
477   - /**
478   - * Draw a z axis
479   - */
480   - virtual void drawZAxis(boost::shared_ptr<Axis> pZAxis, PlWindow& pPlWindow, Bounds& pPlotAreaSize, TickConf& pTickConf);
481   -
482   -
483   - /**
484   - * Get X Axis range for a serie
485   - */
486   - Range getXAxisRange (SeriesProperties& pSeries, boost::shared_ptr<Axis> pAxis);
487   -
488   - /**
489   - * Get Y Axis range for a serie
490   - */
491   - Range getYAxisRange (SeriesProperties& pSeries, boost::shared_ptr<Axis> pAxis);
492   -
493   - /**
494   - * Get Z Axis range for a serie
495   - */
496   - Range getZAxisRange (SeriesProperties& pSeries, boost::shared_ptr<Axis> pAxis);
497   -
498   - /*
499   - * @brief Return the color to draw the symbols of a serie
500   - */
501   - Color getSerieSymbolColor(SeriesProperties &rSeriesProperties, Color &pLineColor);
502   -
503   - /**
504   - * @brief Configure params legend for a plot.
505   - */
506   - virtual void configureParamsLegend(double startTime, double stopTime, int intervalIndex);
507   -
508   - /**
509   - * @brief Add a serie to the param legend
510   - */
511   - void addSerieToParamsLegend(SeriesProperties& lSeriesProperties,
512   - AMDA::Common::ParameterIndexComponent& index, std::string originalParamId,
513   - Color& lineColor, Color& symbolColor,
514   - double startTime, double stopTime, int intervalIndex);
515   -
516   - /*
517   - * @brief Return the associated params legend to a serie
518   - */
519   - virtual std::string getSerieParamsLegendString(SeriesProperties &rSeriesProperties,
520   - AMDA::Common::ParameterIndexComponent& index, std::string originalParamId);
  53 + public:
  54 + static const float DEFAULT_TICK_LENGTH_FACTOR;
  55 +
  56 + /**
  57 + * Width character proportion is approximatively 0.83 times smaller than height.
  58 + */
  59 + static const float CHAR_RATIO;
  60 +
  61 + /**
  62 + * This two next attribute tell from which tick length plplot is insufficient to calculate space between tickmarks and ticks.
  63 + * Space between the two is static and can't be modified by user request.
  64 + * So when limit is reached we must bypass problem by setting two different viewport to let sufficient space between tickmarks and ticks.
  65 + */
  66 + static const float VERTICAL_TICK_LENGTH_LIMIT;
  67 + static const float HORIZONTAL_TICK_LENGTH_LIMIT;
  68 + static const float YAXISMARGIN;
  69 +
  70 + PanelPlotOutput(AMDA::Parameters::ParameterManager &manager,
  71 + boost::shared_ptr<Panel> panel, bool isStandalone = true);
  72 + virtual ~PanelPlotOutput();
  73 +
  74 + /**
  75 + * type name. This name is used to identify nodes in xml config
  76 + * and xml request.
  77 + * @return
  78 + */
  79 + virtual const std::string typeName() = 0;
  80 +
  81 + /**
  82 + * @brief Compute the initial plot area for the panel
  83 + */
  84 + virtual void preparePlotArea(double startTime, double stopTime, int intervalIndex);
  85 +
  86 + /**
  87 + * @brief Retrieve plot area bounds for the panel
  88 + */
  89 + virtual void getPlotAreaBounds(Bounds &plotAreaBounds);
  90 +
  91 + /**
  92 + * @brief Force the plot area horizontal position and width
  93 + */
  94 + virtual void forcePlotAreaPosAndWidth(double plotAreaX, double plotAreaWidth);
  95 +
  96 + /**
  97 + * @brief Retrieve left axis tickMark width
  98 + */
  99 + virtual int getLeftAxisTickMarkWidth(void);
  100 +
  101 + /**
  102 + * @brief Force left axis tickmark width for the panel
  103 + */
  104 + virtual void forceLeftAxisTickMarkWidth(int leftAxisTickMarkWidth);
  105 +
  106 + /**
  107 + * @brief draw the plot for the current time interval
  108 + */
  109 + virtual bool draw(double startTime, double stopTime, int intervalIndex, bool isFirstInterval, bool isLastInterval);
  110 +
  111 + /**
  112 + * @brief Write plot context
  113 + */
  114 + virtual void writeContext(ContextFileWriter &writer, AMDA::Parameters::TimeIntervalList::iterator currentTimeInterval);
  115 +
  116 + /*
  117 + * @brief Set a pointer to the time intervals list
  118 + */
  119 + void setTimeIntervalListPtr(AMDA::Parameters::TimeIntervalList *timeIntervalListPtr);
  120 +
  121 + /**
  122 + * Sets PLplot stream to draw panel and plot
  123 + */
  124 + virtual void setPlStream(std::shared_ptr<plstream> &pls);
  125 +
  126 + /**
  127 + * Adds a parameter
  128 + */
  129 + virtual void addParam(const std::string &name)
  130 + {
  131 + ParameterAxes newParameter(name);
  132 + _parameterAxesList.push_back(newParameter);
  133 + }
521 134  
522   - /**
523   - * @brief plplot stream
524   - */
525   - std::shared_ptr<plstream> _pls;
  135 + virtual ParameterAxes &getParameter(const std::string &name)
  136 + {
  137 + for (ParameterAxes &param : _parameterAxesList)
  138 + {
  139 + if (param._originalParamId == name)
  140 + {
  141 + return param;
  142 + }
  143 + }
  144 + ParameterAxes newParameter(name);
  145 + _parameterAxesList.push_back(newParameter);
  146 + return _parameterAxesList.back();
  147 + }
526 148  
527   - /*
528   - * Dumps properties for test.
529   - */
530   - virtual void dump(std::ostream& out_);
  149 + /*
  150 + * Create a sampled parameter from an original parameter and a sampling value
  151 + */
  152 + AMDA::Parameters::ParameterSPtr createSampledParameter(AMDA::Parameters::ParameterSPtr &originalParam, float samplingValue);
  153 +
  154 + /*
  155 + * Create a sampled parameter from an original parameter and a reference parameter for time definition
  156 + */
  157 + AMDA::Parameters::ParameterSPtr createSampledParameterUnderReferenceParameter(AMDA::Parameters::ParameterSPtr &originalParam,
  158 + AMDA::Parameters::ParameterSPtr &refParam);
  159 +
  160 + /**
  161 + * Create parameters needed for this plot
  162 + * By default, the creation method create parameters for a time serie.
  163 + * Override it for other plot type
  164 + */
  165 + virtual void createParameters(std::list<std::string> &usedParametersId_);
  166 +
  167 + /**
  168 + * Get related ParameterAxes for a given color serie id
  169 + */
  170 + ParameterAxes *getParameterAxesByColorSerieId(int colorSerieId);
  171 +
  172 + /**
  173 + * Get related ParameterAxes for a given x serie id
  174 + */
  175 + ParameterAxes *getParameterAxesByXSerieId(int xSerieId);
  176 +
  177 + /**
  178 + * Gets sampling value from resolution (point-per-plot) according to
  179 + * the plot time interval and the base parameter sampling value.
  180 + */
  181 + virtual double getCorrectedSamplingValue(int maxResolution, double samplingValue);
  182 +
  183 + /**
  184 + * @brief Get the list of indexes used for a parameter
  185 + */
  186 + virtual std::vector<AMDA::Common::ParameterIndexComponent> getParamUsedIndexes(std::string paramId, int dim1Size, int dim2Size = -1);
  187 +
  188 + const Margin getMargin()
  189 + {
  190 + Bounds panelBounds(_panel->getBoundsInPlPage());
  191 +
  192 + Margin m;
  193 + m._left = _plotAreaBounds._x - panelBounds._x;
  194 + m._right = (panelBounds._x + panelBounds._width) - (_plotAreaBounds._x + _plotAreaBounds._width);
  195 + m._top = (panelBounds._y + panelBounds._height) - (_plotAreaBounds._y + _plotAreaBounds._height);
  196 + m._bottom = _plotAreaBounds._y - panelBounds._y;
  197 + return m;
  198 + }
531 199  
532   - /**
533   - * @brief Fill the background of the plot area
534   - *
535   - * @param pls
536   - */
  200 + /**
  201 + * @brief reset plot
  202 + */
  203 + virtual void resetPlot()
  204 + {
  205 + if (_panel != nullptr)
  206 + _panel->resetPlot();
  207 + _automaticSerieColorCursor = 0;
  208 + _nbSeriesByYAxisMap.clear();
  209 + _pls.reset();
  210 + }
537 211  
538   - void fillBackground(std::shared_ptr<plstream> &pls);
  212 + /*
  213 + * @brief Set pointer to params values
  214 + */
  215 + void setParameterValues(std::map<std::string, ParameterData> *pParameterValues);
  216 +
  217 + /*
  218 + * @brief Get computed values (in relation with the y axis definition) for a y serie, an index of the serie and a time interval
  219 + * Do not forget to delete (*computedValues) !!
  220 + * Do not delete (*timeValues), the buffer is not copied !!
  221 + */
  222 + bool getComputedValuesFromSerieAndInterval(double startDate, double stopDate, SeriesProperties &rSeriesProperties,
  223 + AMDA::Common::ParameterIndexComponent index, double **computedValues, double **timeValues, int &nbValues);
  224 +
  225 + /*
  226 + * @brief Get computed values (in relation with the color axis definition) for a color serie and a time interval
  227 + * Do not forget to delete computedValues !!
  228 + * Don't delete timeValues !!
  229 + */
  230 + bool getColoredComputedValuesFromSerieAndInterval(double startDate, double stopDate, SeriesProperties &rSeriesProperties,
  231 + double **computedValues, double **timeValues, int &nbValues);
  232 +
  233 + /*
  234 + * @brief Get computed values (in relation with the y axis definition) for a y serie and a time interval
  235 + * Do not forget to delete computedValues !!
  236 + * Don't delete timeValues !!
  237 + */
  238 + bool getErrorComputedValuesFromSerieAndInterval(double startDate, double stopDate, SeriesProperties &rSeriesProperties,
  239 + double **minComputedValues, double **minTimeValues, int &nbMinValues,
  240 + double **maxComputedValues, double **maxTimeValues, int &nbMaxValues);
  241 +
  242 + /**
  243 + *@brief Defines the layout constraint to be used for the panel when used within a layout
  244 + */
  245 + virtual PanelConstraint getLayoutConstraint(void)
  246 + {
  247 + return PanelConstraint::MaxWidth;
  248 + }
539 249  
540   -private:
  250 + /**
  251 + * @brief Get nb series to draw by y axis
  252 + */
  253 + std::map<std::string, int> &getNbSeriesByYAxis();
  254 +
  255 + /*
  256 + * @brief Return the color to draw the line of a serie
  257 + */
  258 + Color getSerieLineColor(SeriesProperties &rSeriesProperties, bool moreThanOneSerieForAxis);
  259 +
  260 + /**
  261 + * @brief Plot container
  262 + */
  263 + boost::shared_ptr<Panel> _panel;
  264 +
  265 + /**
  266 + * @brief Parameters and series info
  267 + */
  268 + ParameterAxesList _parameterAxesList;
  269 +
  270 + /*
  271 + * @brief Type used to define a matrix grid
  272 + */
  273 + struct GridPart
  274 + {
  275 + double x[2];
  276 + double y[2];
  277 + double value;
  278 + double isColorIndex;
  279 + };
  280 +
  281 + typedef std::vector<GridPart> MatrixGrid;
  282 +
  283 + // datastore for sauvaud plot
  284 + struct SauvaudPart
  285 + {
  286 + double x[2];
  287 + double y[2];
  288 + std::vector<double> value;
  289 + double isColorIndex;
  290 + };
  291 +
  292 + typedef std::vector<SauvaudPart> SauvaudGrid;
  293 +
  294 + /*
  295 + * @brief Draw a matrix
  296 + */
  297 + void drawMatrix(MatrixGrid &matrixGrid, double minDataVal, double maxDataVal,
  298 + Color minValColor, Color maxValColor, int colorMapIndex, bool useLog0AsMin = false);
  299 +
  300 + void draw2DMatrix(SauvaudGrid &sauvaudGrid, double minDataVal, double maxDataVal,
  301 + Color minValColor, Color maxValColor, int colorMapIndex, bool useLog0AsMin = false);
  302 +
  303 + /**
  304 + * @brief Reset cursor used to attribute automatically a color to a serie
  305 + */
  306 + void resetAutomaticSerieColorCursor()
  307 + {
  308 + _automaticSerieColorCursor = 0;
  309 + }
541 310  
542   - void drawAxis(boost::shared_ptr<Axis> pAxis, TickConf& pTickConf, std::string pXAxisOptions,
543   - std::string pYAxisOptions);
  311 + /**
  312 + * Draw a rectangle
  313 + */
  314 + void drawRectangle(double xmin, double xmax, double ymin, double ymax, Color &pColor, double alpha = 1.);
544 315  
545   - double estimateZAxisWidth(boost::shared_ptr<Axis> pZAxis);
  316 + bool isStandalone()
  317 + {
  318 + return _isStandalone;
  319 + }
546 320  
547   - /**
548   - * @brief _plotAreaSideSet Store which side of plot area is linked to an axis.
549   - */
550   - std::map<PlotCommon::Position, bool> _plotAreaSideSet;
  321 + AMDA::Parameters::ParameterManager &_parameterManager;
  322 +
  323 + std::map<std::string, ParameterData> *_pParameterValues;
  324 +
  325 + protected:
  326 + AMDA::Parameters::TimeIntervalList *_timeIntervalListPtr;
  327 +
  328 + /**
  329 + * @brief Compute plot area.
  330 + * @note If ratio need to be kept, ratio will be kept between width and height.
  331 + * @param bounds_ plot area bounds. It is updated by this method.
  332 + */
  333 + virtual void calculatePlotArea(const Bounds &panelBounds_, Bounds &bounds_);
  334 +
  335 + /**
  336 + *@brief computes Panel Plot XY ratio
  337 + */
  338 + void computePanelPlotXYRatio(void);
  339 +
  340 + /**
  341 + * @brief Get colored value associated to a data value. Return false if the value is filtered.
  342 + */
  343 + bool getColoredValue(double value, double filterMin, double filterMax, bool useLog0AsMin, PLFLT &col);
  344 +
  345 + /**
  346 + *@brief Draw fill area between parameter and constant or between parameters
  347 + */
  348 + virtual void drawFills(double startDate, double stopDate);
  349 +
  350 + /**
  351 + * Draw list of symbols
  352 + */
  353 + void drawSymbols(SymbolType pType, int pSize, double pFactor, Color pColor,
  354 + int pNbData, double *pXData, double *pYData,
  355 + double *pZData = NULL, double filterZMin = -DBL_MAX, double filterZMax = DBL_MAX);
  356 +
  357 + /**
  358 + * Draw list of lines
  359 + */
  360 + void drawLines(LineType pType, LineStyle pStyle, int pWidth, Color &pColor,
  361 + int pNbData, double *pXData, double *pYData,
  362 + double *pZData = NULL, double filterZMin = -DBL_MAX, double filterZMax = DBL_MAX);
  363 +
  364 + /**
  365 + * Draw errors segments
  366 + */
  367 + void drawYErrors(LineType pType, LineStyle pStyle, int pWidth, Color &pColor,
  368 + int pNbData, double *pXData, double *pYMinData, double *pYMaxData);
  369 +
  370 + /**
  371 + *@brief Draw the serie of a parameter component on plot.
  372 + */
  373 + virtual void drawSeries(double startDate, double stopDate, int intervalIndex, std::string pParamId, SeriesProperties &pSeries,
  374 + AMDA::Common::ParameterIndexComponent pParamIndex, ParameterAxes &param, bool moreThanOneSerieForAxis);
  375 +
  376 + /**
  377 + *@brief Draw the spectro of a parameter on plot.
  378 + */
  379 + virtual void drawSpectro(double startDate, double stopDate, std::string pParamId,
  380 + SpectroProperties &pSpectro);
  381 +
  382 + /**
  383 + *@brief Draw sauvaud plot of a parameter on plot.
  384 + */
  385 + virtual void drawSauvaud(double startDate, double stopDate, std::string pParamId,
  386 + SauvaudProperties &pSauvaud, int subIndex, int subsNumber, std::string opositeLegend);
  387 +
  388 + virtual void drawIntervals(double startDate, double stopDate, std::string pParamId,
  389 + IntervalsProperties &pIntervals);
  390 +
  391 + /*
  392 + * @brief Draw interval
  393 + */
  394 + virtual void drawSerieInterval(SeriesProperties &pSeries,
  395 + double *xValues, double *yValues, double *timeValues,
  396 + int nbValues, int intervalIndex);
  397 +
  398 + /**
  399 + * Draw an horizontal axis.
  400 + * Subclasses may override it to take into account decorator attached to that axis (for instance).
  401 + * @param pXAxis axis to draw.
  402 + * @param pPlWindow real word ranges.
  403 + * @param pPlotAreaSize plot ranges.
  404 + * @param pTickConf ticks configuration.
  405 + */
  406 + virtual void drawXAxis(boost::shared_ptr<Axis> pXAxis, PlWindow &pPlWindow, Bounds &pPlotAreaSize, TickConf &pTickConf);
  407 + /**
  408 + * Draw a vertical axis.
  409 + * Subclasses may override it to take into account decorator attached to that axis (for instance).
  410 + * @param pXAxis axis to draw.
  411 + * @param pPlWindow real word ranges.
  412 + * @param pPlotAreaSize plot ranges.
  413 + * @param pTickConf ticks configuration.
  414 + */
  415 + virtual void drawYAxis(boost::shared_ptr<Axis> pXAxis, PlWindow &pPlWindow, Bounds &pPlotAreaSize, TickConf &pTickConf);
  416 + /**
  417 + * @brief Draw legend for each axis.
  418 + * @param pAxis axis to draw.
  419 + * @param pPlWindow real word ranges.
  420 + * @param pPlotAreaSize plot ranges.
  421 + */
  422 + virtual void drawLegends(boost::shared_ptr<Axis> &pAxis, PlWindow &pPlWindow, Bounds &pPlotAreaSize);
  423 +
  424 + /**
  425 + * @brief Draw parameters legend.
  426 + */
  427 + virtual void drawParamsLegend(void);
  428 +
  429 + /**
  430 + * @brief Draw text legends.
  431 + */
  432 + virtual void drawTextLegends(void);
  433 +
  434 + /**
  435 + * Convert an X axis string value to a double X value
  436 + * Subclasses may override it to take into account specific value meaning.
  437 + * @param value string value to convert.
  438 + */
  439 + virtual double convertXAxisValue(const std::string &value);
  440 +
  441 + /**
  442 + * Convert an Y axis string value to a double Y value
  443 + * Subclasses may override it to take into account specific value meaning.
  444 + * @param value string value to convert.
  445 + */
  446 + virtual double convertYAxisValue(const std::string &value);
  447 +
  448 + /**
  449 + * Draw X constant lines linked to an axis.
  450 + * Subclasses may override it to take into account decorator attached (for instance).
  451 + * @param pXAxis axis to draw.
  452 + * @param pPlWindow real word ranges.
  453 + */
  454 + virtual void drawXConstantLines(boost::shared_ptr<Axis> pAxis, PlWindow &pPlWindow);
  455 + /**
  456 + * Draw X constant lines linked to an axis.
  457 + * Subclasses may override it to take into account decorator attached (for instance).
  458 + * @param pXAxis axis to draw.
  459 + * @param pPlWindow real word ranges.
  460 + */
  461 + virtual void drawYConstantLines(boost::shared_ptr<Axis> pAxis, PlWindow &pPlWindow);
  462 + /**
  463 + * Draw textPlots for a panel.
  464 + * Subclasses may override it for specific drawings.
  465 + * @param pPlWindow real word ranges.
  466 + */
  467 + virtual void drawTextPlots(boost::shared_ptr<Axis> pXAxis, boost::shared_ptr<Axis> pYAxis, PlWindow &pPlWindow, const TextPlots &textPlots);
  468 +
  469 + /**
  470 + * Draw curvePlot for a panel.
  471 + * Subclasses may override it for specific drawings.
  472 + * @param curvePlot curve properties.
  473 + */
  474 + virtual void drawCurvePlot(CurvePlot &curvePlot);
  475 +
  476 + /**
  477 + * @brief Identify if other side of the plot area need to be drawn or not.
  478 + * @note A plot area side need to be drawn when there is no axis associated to it.
  479 + */
  480 + virtual std::string drawOppositeSide(boost::shared_ptr<Axis> pAxis);
  481 +
  482 + /**
  483 + *@brief Draw additional objects on plot.
  484 + */
  485 + virtual void drawAdditionalObjects();
  486 +
  487 + /**
  488 + * Draw a z axis
  489 + */
  490 + virtual void drawZAxis(boost::shared_ptr<Axis> pZAxis, PlWindow &pPlWindow, Bounds &pPlotAreaSize, TickConf &pTickConf);
  491 +
  492 + /**
  493 + * Get X Axis range for a serie
  494 + */
  495 + Range getXAxisRange(SeriesProperties &pSeries, boost::shared_ptr<Axis> pAxis);
  496 +
  497 + /**
  498 + * Get Y Axis range for a serie
  499 + */
  500 + Range getYAxisRange(SeriesProperties &pSeries, boost::shared_ptr<Axis> pAxis);
  501 +
  502 + /**
  503 + * Get Z Axis range for a serie
  504 + */
  505 + Range getZAxisRange(SeriesProperties &pSeries, boost::shared_ptr<Axis> pAxis);
  506 +
  507 + /*
  508 + * @brief Return the color to draw the symbols of a serie
  509 + */
  510 + Color getSerieSymbolColor(SeriesProperties &rSeriesProperties, Color &pLineColor);
  511 +
  512 + /**
  513 + * @brief Configure params legend for a plot.
  514 + */
  515 + virtual void configureParamsLegend(double startTime, double stopTime, int intervalIndex);
  516 +
  517 + /**
  518 + * @brief Add a serie to the param legend
  519 + */
  520 + void addSerieToParamsLegend(SeriesProperties &lSeriesProperties,
  521 + AMDA::Common::ParameterIndexComponent &index, std::string originalParamId,
  522 + Color &lineColor, Color &symbolColor,
  523 + double startTime, double stopTime, int intervalIndex);
  524 +
  525 + /*
  526 + * @brief Return the associated params legend to a serie
  527 + */
  528 + virtual std::string getSerieParamsLegendString(SeriesProperties &rSeriesProperties,
  529 + AMDA::Common::ParameterIndexComponent &index, std::string originalParamId);
  530 +
  531 + /**
  532 + * @brief plplot stream
  533 + */
  534 + std::shared_ptr<plstream> _pls;
  535 +
  536 + /*
  537 + * Dumps properties for test.
  538 + */
  539 + virtual void dump(std::ostream &out_);
  540 +
  541 + /**
  542 + * @brief Fill the background of the plot area
  543 + *
  544 + * @param pls
  545 + */
  546 +
  547 + void fillBackground(std::shared_ptr<plstream> &pls);
  548 +
  549 + private:
  550 + void drawAxis(boost::shared_ptr<Axis> pAxis, TickConf &pTickConf, std::string pXAxisOptions,
  551 + std::string pYAxisOptions);
  552 +
  553 + double estimateZAxisWidth(boost::shared_ptr<Axis> pZAxis);
  554 +
  555 + /**
  556 + * @brief _plotAreaSideSet Store which side of plot area is linked to an axis.
  557 + */
  558 + std::map<PlotCommon::Position, bool> _plotAreaSideSet;
  559 +
  560 + /**
  561 + * @brief nb series to draw by y axis
  562 + */
  563 + std::map<std::string, int> _nbSeriesByYAxisMap;
  564 +
  565 + /**
  566 + * @brief plot array on which to draw data.
  567 + */
  568 + Bounds _plotAreaBounds;
  569 +
  570 + /*
  571 + * @brief Panel XY ratio used for angular conversion
  572 + */
  573 + double _panelPlotXYRatio;
  574 +
  575 + /*
  576 + * @brief Panel left axis tickmark width
  577 + */
  578 + double _leftAxisTickMarkWidth;
  579 +
  580 + /*
  581 + * @brief cursor use to set a default color to a serie
  582 + */
  583 + int _automaticSerieColorCursor;
  584 +
  585 + /*
  586 + *
  587 + */
  588 + bool _isStandalone;
  589 +
  590 + void reserveSpaceForAxis(boost::shared_ptr<Axis> &pAxis, double titleHeight, std::map<PlotCommon::Position, int> nbAxesBySide,
  591 + double &topSpace, double &bottomSpace, double &leftSpace, double &rightSpace);
  592 +
  593 + void reserveSpaceForTextLegend(boost::shared_ptr<TextLegendProperties> &pTextLegendProp, double titleHeight, double &topSpace, double &bottomSpace, double &leftSpace, double &rightSpace);
  594 + };
551 595  
552 596 /**
553   - * @brief nb series to draw by y axis
  597 + * Calculate room taken by tick.
554 598 */
555   - std::map<std::string,int> _nbSeriesByYAxisMap;
  599 + double getHorizontalTickLength(Axis *pAxis, double charHeight);
556 600  
557 601 /**
558   - * @brief plot array on which to draw data.
  602 + * Calculate room taken by tick.
559 603 */
560   - Bounds _plotAreaBounds;
561   -
562   - /*
563   - * @brief Panel XY ratio used for angular conversion
564   - */
565   - double _panelPlotXYRatio;
566   -
567   - /*
568   - * @brief Panel left axis tickmark width
569   - */
570   - double _leftAxisTickMarkWidth;
571   -
572   - /*
573   - * @brief cursor use to set a default color to a serie
574   - */
575   - int _automaticSerieColorCursor;
576   -
577   - /*
578   - *
579   - */
580   - bool _isStandalone;
581   -
582   - void reserveSpaceForAxis (boost::shared_ptr<Axis>& pAxis, double titleHeight, std::map<PlotCommon::Position, int> nbAxesBySide,
583   - double& topSpace, double& bottomSpace, double& leftSpace, double& rightSpace);
584   -
585   - void reserveSpaceForTextLegend (boost::shared_ptr<TextLegendProperties>& pTextLegendProp, double titleHeight, double& topSpace, double& bottomSpace, double& leftSpace, double& rightSpace);
586   -};
587   -
588   -/**
589   - * Calculate room taken by tick.
590   - */
591   -double getHorizontalTickLength(Axis* pAxis, double charHeight);
592   -
593   -/**
594   - * Calculate room taken by tick.
595   - */
596   -double getVerticalTickLength(Axis* pAxis, double charHeight);
  604 + double getVerticalTickLength(Axis *pAxis, double charHeight);
597 605  
598 606 } /* namespace plot */
599 607 #endif /* PANELPLOTOUTPUT_HH_ */
... ...
src/Parameters/fonctions/fourier/DiscreteFourierTransform.cc
... ... @@ -7,38 +7,172 @@ DiscreteFourierTransform&lt;T, E&gt;::DiscreteFourierTransform(int nbEchantillons_, ve
7 7 nbEchantillons = nbEchantillons_;
8 8 frequenceEchantillonnage = frequenceEchantillonnage_;
9 9 signal = signal_;
  10 +
  11 + // Padding the input isgnal with 0's if it's small than nbEchantillons
  12 +
  13 + while (signal.size() < nbEchantillons)
  14 + {
  15 + signal.push_back((T)0);
  16 + }
10 17 }
11 18  
12 19 template <class T, class E>
13 20 void DiscreteFourierTransform<T, E>::compute()
14 21 {
15   - for (int k = 0; k < nbEchantillons; k++)
  22 + const int N = signal.size();
  23 + if (DiscreteFourierTransform<T, E>::isPowerOfTwo(N))
  24 + {
  25 + phasors = DiscreteFourierTransform<T, E>::fft(signal);
  26 + }
  27 + else
  28 + {
  29 + phasors = DiscreteFourierTransform<T, E>::dft(signal);
  30 + }
  31 +}
  32 +
  33 +template <class T, class E>
  34 +std::vector<E> DiscreteFourierTransform<T, E>::createTestPoints(int N, double sampleSpacing)
  35 +{
  36 + std::vector<E> out;
  37 + const E t = (E)sampleSpacing;
  38 + for (int i = 0; i < N; i++)
  39 + {
  40 + out.push_back((E)t * i);
  41 + }
  42 + return out;
  43 +}
  44 +
  45 +template <class T, class E>
  46 +std::vector<E> DiscreteFourierTransform<T, E>::createTestFunction(std::vector<E> x)
  47 +{
  48 + const int N = x.size();
  49 + std::vector<E> out;
  50 + for (int i = 0; i < N; i++)
  51 + {
  52 + const E val = (E)sin(50.0 * 2.0 * M_PI * x[i]) + 0.5 * sin(80.0 * 2.0 * M_PI * x[i]);
  53 + out.push_back(val);
  54 + }
  55 + return out;
  56 +}
  57 +
  58 +/**
  59 + * @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.
  60 + * Cooley-Tukey FFT Algorithms: http://people.scs.carleton.ca/~maheshwa/courses/5703COMP/16Fall/FFT_Report.pdf
  61 + *
  62 + * @tparam T template type of input data
  63 + * @tparam E template type of output data
  64 + * @param sig the signal as an input
  65 + * @return std::vector<std::complex<E>> the phasors (array of complex number)
  66 + */
  67 +template <class T, class E>
  68 +std::vector<std::complex<E>> DiscreteFourierTransform<T, E>::fft(std::vector<T> sig)
  69 +{
  70 + const int N = sig.size();
  71 + if (N == 1)
16 72 {
17   - E xR = 0;
18   - E yI = 0;
19   - E fk = (E)(k * frequenceEchantillonnage) / (E)nbEchantillons;
20   - // E fk = (E)(k * 1.0 / nbEchantillons);
21   - for (int n = 0; n < signal.size(); n++)
  73 + std::vector<std::complex<E>> out;
  74 + const std::complex<E> temp((E)sig[0], (E)0);
  75 + out.push_back(temp);
  76 + return out;
  77 + }
  78 +
  79 + const std::complex<E> WN = (complex<E>)std::polar(1.0, 2 * M_PI / N);
  80 + std::complex<E> W((E)1, (E)0);
  81 +
  82 + // divide and conquer:
  83 + // Recurse: all even samples
  84 + std::vector<std::complex<E>>
  85 + x_evens = fft(getEven(sig));
  86 +
  87 + // Recurse: all odd samples
  88 + std::vector<std::complex<E>> x_odds = fft(getOdd(sig));
  89 +
  90 + // Now, combine and perform N/2 operations!
  91 + std::complex<E> zeroComplex((E)0, (E)0);
  92 + std::vector<std::complex<E>> x(N, zeroComplex);
  93 + for (int k = 0; k < N / 2; k++)
  94 + {
  95 + x[k] = x_evens[k] + W * x_odds[k];
  96 + x[k + (N / 2)] = x_evens[k] - W * x_odds[k];
  97 + W = W * WN;
  98 + }
  99 + return x;
  100 +}
  101 +
  102 +template <class T, class E>
  103 +std::vector<std::complex<E>> DiscreteFourierTransform<T, E>::dft(std::vector<T> x)
  104 +{
  105 + const int N = x.size();
  106 + std::complex<E> zeroComplex((E)0, (E)0);
  107 + std::vector<std::complex<E>> out(N, zeroComplex);
  108 + for (int k = 0; k < N; k++)
  109 + {
  110 + for (int n = 0; n < N; n++)
22 111 {
23   - const T val = signal[n];
24   - if (!isNAN(val))
25   - {
26   - const double angle = 2 * M_PI * n * fk;
27   - xR += (E)cos(angle) * val;
28   - yI += (E)sin(angle) * val;
29   - }
  112 + const std::complex<E> expVal = (complex<E>)std::polar(1.0, -2 * k * n * M_PI / N);
  113 + out[k] += ((E)x[n]) * expVal;
30 114 }
  115 + }
  116 + return out;
  117 +}
  118 +
  119 +template <class T, class E>
  120 +std::vector<E> DiscreteFourierTransform<T, E>::computeDSP(std::vector<std::complex<E>> x)
  121 +{
  122 + const int N = x.size();
  123 + std::vector<E> out;
  124 + for (int k = 0; k < N / 2; k++)
  125 + {
  126 + const E magnitude = (E)pow(abs(x[k]), 1);
  127 + const E dsp = (E)(2.0 / N) * magnitude;
  128 + out.push_back(dsp);
  129 + }
31 130  
32   - E amplitude = (E)sqrt(xR * xR + yI * yI);
33   - E phase = (E)atan2(yI, xR);
  131 + return out;
  132 +}
34 133  
35   - amplitudes.push_back(amplitude);
36   - phases.push_back(phase);
37   - frequences.push_back(fk);
38   - if (fk == (E)0)
39   - periodes.push_back((E)0);
40   - else
41   - periodes.push_back((E)(1.0 / fk));
42   - sort(periodes.begin(), periodes.end());
  134 +template <class T, class E>
  135 +std::vector<E> DiscreteFourierTransform<T, E>::getFreq(std::vector<std::complex<E>> x, double d)
  136 +{
  137 + const int N = x.size();
  138 + const double stepFreq = 1.0 / (d * N);
  139 + const int N1 = (N - 1) / 2 + 1;
  140 + std::vector<E> out;
  141 + for (int k = 0; k < N / 2; k++)
  142 + {
  143 + const E freq = (E)k * stepFreq;
  144 + out.push_back(freq);
43 145 }
  146 +
  147 + return out;
44 148 }
  149 +
  150 +template <class T, class E>
  151 +std::vector<T> DiscreteFourierTransform<T, E>::getOdd(std::vector<T> x)
  152 +{
  153 + std::vector<T> odd;
  154 + for (int i = 0; i < x.size(); i++)
  155 + {
  156 + if (i % 2 != 0)
  157 + odd.push_back(x[i]);
  158 + }
  159 + return odd;
  160 +}
  161 +
  162 +template <class T, class E>
  163 +std::vector<T> DiscreteFourierTransform<T, E>::getEven(std::vector<T> x)
  164 +{
  165 + std::vector<T> even;
  166 + for (int i = 0; i < x.size(); i++)
  167 + {
  168 + if (i % 2 == 0)
  169 + even.push_back(x[i]);
  170 + }
  171 + return even;
  172 +}
  173 +
  174 +template <class T, class E>
  175 +bool DiscreteFourierTransform<T, E>::isPowerOfTwo(int N)
  176 +{
  177 + return (N & (N - 1)) == 0;
  178 +}
45 179 \ No newline at end of file
... ...
src/Parameters/fonctions/fourier/DiscreteFourierTransform.hh
... ... @@ -3,7 +3,10 @@
3 3 #define _DISCRETEFOURIERTRANSFORM_H
4 4  
5 5 #include "plplot/plplot.h"
  6 +
  7 +#include <complex>
6 8 #include <math.h>
  9 +
7 10 #include <vector>
8 11  
9 12 using namespace std;
... ... @@ -36,6 +39,16 @@ public:
36 39 */
37 40 DiscreteFourierTransform(int nbEchantillons_, vector<T> signal_, double frequenceEchantillonnage_);
38 41  
  42 + std::vector<std::complex<E>> fft(std::vector<T> sig);
  43 + std::vector<std::complex<E>> dft(std::vector<T> sig);
  44 + std::vector<T> getEven(std::vector<T> x);
  45 + std::vector<T> getOdd(std::vector<T> x);
  46 + std::vector<E> computeDSP(std::vector<std::complex<E>> x);
  47 + std::vector<E> getFreq(std::vector<std::complex<E>> x, double d);
  48 + std::vector<E> createTestPoints(int N, double sampleSpacing);
  49 + std::vector<E> createTestFunction(std::vector<E> x);
  50 + bool isPowerOfTwo(int N);
  51 +
39 52 /**
40 53 * @brief Calcul de la TFD
41 54 *
... ... @@ -82,6 +95,16 @@ public:
82 95 return periodes;
83 96 }
84 97  
  98 + std::vector<std::complex<E>> getPhasors()
  99 + {
  100 + return phasors;
  101 + }
  102 +
  103 + void setPhasors(std::vector<std::complex<E>> x)
  104 + {
  105 + phasors = x;
  106 + }
  107 +
85 108 private:
86 109 /**
87 110 * @brief Le nombre total d’échantillons (points qu’on a mesurés)
... ... @@ -118,6 +141,8 @@ private:
118 141 *
119 142 */
120 143 vector<E> periodes;
  144 +
  145 + std::vector<std::complex<E>> phasors;
121 146 };
122 147  
123 148 #endif
124 149 \ No newline at end of file
... ...