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,6 +14,7 @@
14 #include "fonctions/fourier/DiscreteFourierTransform.cc" 14 #include "fonctions/fourier/DiscreteFourierTransform.cc"
15 #include "fonctions/fourier/DiscreteFourierTransform.hh" 15 #include "fonctions/fourier/DiscreteFourierTransform.hh"
16 #include <algorithm> 16 #include <algorithm>
  17 +#include <complex>
17 #include <limits> 18 #include <limits>
18 #include <numeric> 19 #include <numeric>
19 20
@@ -45,14 +46,162 @@ namespace plot @@ -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 void PlotFunction::drawSeries(double startDate, double stopDate, int intervalIndex, std::string pParamId, 194 void PlotFunction::drawSeries(double startDate, double stopDate, int intervalIndex, std::string pParamId,
49 SeriesProperties &pSerie, 195 SeriesProperties &pSerie,
50 AMDA::Common::ParameterIndexComponent pParamIndex, 196 AMDA::Common::ParameterIndexComponent pParamIndex,
51 ParameterAxes &param, bool moreThanOneSerieForAxis) 197 ParameterAxes &param, bool moreThanOneSerieForAxis)
52 { 198 {
53 std::string id = std::to_string(pSerie.getId()) + "_" + pSerie.getParamId() + "_" + std::to_string(pParamIndex.getDim1Index()); 199 std::string id = std::to_string(pSerie.getId()) + "_" + pSerie.getParamId() + "_" + std::to_string(pParamIndex.getDim1Index());
  200 + LOG4CXX_DEBUG(gLogger, " id Serie " << id);
54 std::vector<double> xValues = xValuesMap[id]; 201 std::vector<double> xValues = xValuesMap[id];
55 std::vector<double> yValues = yValuesMap[id]; 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 double *coloredComputedValues = NULL; 206 double *coloredComputedValues = NULL;
58 int nbValues = yValues.size(); 207 int nbValues = yValues.size();
@@ -83,28 +232,46 @@ namespace plot @@ -83,28 +232,46 @@ namespace plot
83 nbValues, xValuesTemp, yValuesTemp, coloredComputedValues); 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 for (auto parameter : _parameterAxesList) 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 void PlotFunction::createXAxis() 277 void PlotFunction::createXAxis()
@@ -112,6 +279,8 @@ namespace plot @@ -112,6 +279,8 @@ namespace plot
112 double minValue = 0; 279 double minValue = 0;
113 double maxValue = 0; 280 double maxValue = 0;
114 PlotFunction::getMinMax(xValuesMap, &minValue, &maxValue); 281 PlotFunction::getMinMax(xValuesMap, &minValue, &maxValue);
  282 + LOG4CXX_DEBUG(gLogger, " min X " << minValue);
  283 + LOG4CXX_DEBUG(gLogger, " man X " << maxValue);
115 // Create X axis 284 // Create X axis
116 boost::shared_ptr<TimeAxis> lXAxis(new TimeAxis()); 285 boost::shared_ptr<TimeAxis> lXAxis(new TimeAxis());
117 lXAxis.get()->_timeFormat = "%H:%M"; 286 lXAxis.get()->_timeFormat = "%H:%M";
@@ -132,18 +301,22 @@ namespace plot @@ -132,18 +301,22 @@ namespace plot
132 _panel->addAxis(X_AXIS_ID, lXAxis); 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 std::string y_label = ""; 306 std::string y_label = "";
138 if (function == PlotFunction::Function::AVG) 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 double minValue = 0; 314 double minValue = 0;
144 double maxValue = 0; 315 double maxValue = 0;
145 316
146 PlotFunction::getMinMax(yValuesMap, &minValue, &maxValue); 317 PlotFunction::getMinMax(yValuesMap, &minValue, &maxValue);
  318 + LOG4CXX_DEBUG(gLogger, " min Y " << minValue);
  319 + LOG4CXX_DEBUG(gLogger, " man Y " << maxValue);
147 // Create X axis 320 // Create X axis
148 boost::shared_ptr<Axis> lYAxis(new Axis(false)); 321 boost::shared_ptr<Axis> lYAxis(new Axis(false));
149 plot::Range range_x = Range(minValue - abs(minValue) * 0.10, maxValue + abs(maxValue) * 0.1); 322 plot::Range range_x = Range(minValue - abs(minValue) * 0.10, maxValue + abs(maxValue) * 0.1);
@@ -159,6 +332,16 @@ namespace plot @@ -159,6 +332,16 @@ namespace plot
159 lYAxis.get()->_showTickMark = true; 332 lYAxis.get()->_showTickMark = true;
160 lYAxis.get()->_used = true; 333 lYAxis.get()->_used = true;
161 // add X Axis to panel 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 _panel->addAxis(Y_AXIS_ID, lYAxis); 345 _panel->addAxis(Y_AXIS_ID, lYAxis);
163 } 346 }
164 347
@@ -181,12 +364,24 @@ namespace plot @@ -181,12 +364,24 @@ namespace plot
181 *maxToFill = maxValue; 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 double samplingValue = 60.0; 369 double samplingValue = 60.0;
187 int nb_points = data.getSize(); 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 // If parameter was found 385 // If parameter was found
191 if (it != paramsNbPoints.end()) 386 if (it != paramsNbPoints.end())
192 { 387 {
@@ -196,57 +391,129 @@ namespace plot @@ -196,57 +391,129 @@ namespace plot
196 } 391 }
197 else 392 else
198 { 393 {
199 - std::stringstream lError; 394 + /*std::stringstream lError;
200 lError << "PlotFunction::compute" 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 LOG4CXX_DEBUG(gLogger, lError.str()); 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 if (abscisse.getType() == Abscisse::Abscisse_Type::FREQUENCY) 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 else 505 else
236 xValues = DFT.getPeriodes(); 506 xValues = DFT.getPeriodes();
  507 + // xValues = x_;
237 } 508 }
238 509
239 if (ordonneeScale == Axis::Scale::LOGARITHMIC) 510 if (ordonneeScale == Axis::Scale::LOGARITHMIC)
240 - {  
241 std::for_each(yValues.begin(), yValues.end(), [&](double &i) 511 std::for_each(yValues.begin(), yValues.end(), [&](double &i)
242 { return log10(i); }); 512 { return log10(i); });
243 - }  
244 513
245 if (abscisseScale == Axis::Scale::LOGARITHMIC) 514 if (abscisseScale == Axis::Scale::LOGARITHMIC)
246 - {  
247 std::for_each(xValues.begin(), xValues.end(), [&](double &i) 515 std::for_each(xValues.begin(), xValues.end(), [&](double &i)
248 { return log10(i); }); 516 { return log10(i); });
249 - }  
250 517
251 PlotFunction::xValuesMap[id] = xValues; 518 PlotFunction::xValuesMap[id] = xValues;
252 PlotFunction::yValuesMap[id] = yValues; 519 PlotFunction::yValuesMap[id] = yValues;
@@ -302,7 +569,7 @@ namespace plot @@ -302,7 +569,7 @@ namespace plot
302 569
303 void PlotFunction::preparePlotArea(double startTime, double stopTime, int intervalIndex) 570 void PlotFunction::preparePlotArea(double startTime, double stopTime, int intervalIndex)
304 { 571 {
305 - PlotFunction::configureSeriesAxis(); 572 + PlotFunction::applyFunction();
306 573
307 if (abscisse.getType() == Abscisse::TIME) 574 if (abscisse.getType() == Abscisse::TIME)
308 { 575 {
@@ -310,32 +577,9 @@ namespace plot @@ -310,32 +577,9 @@ namespace plot
310 getTimeAxisDecorator()->configure(this, dynamic_cast<TimeAxis *>(xAxis.get()), startTime, stopTime, _pParameterValues); 577 getTimeAxisDecorator()->configure(this, dynamic_cast<TimeAxis *>(xAxis.get()), startTime, stopTime, _pParameterValues);
311 _pls->timefmt(getTimeAxisDecorator()->getPlFormat().c_str()); 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,23 +593,6 @@ namespace plot
349 _panel->draw(_pls); 593 _panel->draw(_pls);
350 fillBackground(_pls); 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 // Compute nb series to draw by y axis 596 // Compute nb series to draw by y axis
370 std::map<std::string, int> nbSeriesByYAxisMap = getNbSeriesByYAxis(); 597 std::map<std::string, int> nbSeriesByYAxisMap = getNbSeriesByYAxis();
371 SeriesProperties lSeries; 598 SeriesProperties lSeries;
@@ -386,10 +613,6 @@ namespace plot @@ -386,10 +613,6 @@ namespace plot
386 drawSeries(startTime, stopTime, intervalIndex, parameter._originalParamId, 613 drawSeries(startTime, stopTime, intervalIndex, parameter._originalParamId,
387 lSeries, lIndex, parameter, moreThanOneSerieForYAxis); 614 lSeries, lIndex, parameter, moreThanOneSerieForYAxis);
388 ParameterData &data = (*_pParameterValues)[lSeries.getParamId()]; 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,6 +623,7 @@ namespace plot
400 PlotFunction::drawStartDate(_timeFormat, startTime, stopTime); 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,8 +148,11 @@ namespace plot
148 virtual bool draw(double startTime, double stopTime, int intervalIndex, 148 virtual bool draw(double startTime, double stopTime, int intervalIndex,
149 bool isFirstInterval, bool isLastInterval); 149 bool isFirstInterval, bool isLastInterval);
150 150
  151 + virtual void writeContext(ContextFileWriter &writer, AMDA::Parameters::TimeIntervalList::iterator currentTimeInterval);
  152 +
151 private: 153 private:
152 - void configureSeriesAxis(); 154 + void drawInstantPlot();
  155 + void applyFunction();
153 void configureAxisLegend(); 156 void configureAxisLegend();
154 /** 157 /**
155 * @brief Afficher sur le plot the starting date 158 * @brief Afficher sur le plot the starting date
@@ -163,7 +166,7 @@ namespace plot @@ -163,7 +166,7 @@ namespace plot
163 * @brief Créer un axe Y pour accueillir les valeurs calculées de l'axe Y 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 * @brief Créer un axe X pour accueillir les valeurs calculées de l'axe X 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,7 +187,7 @@ namespace plot
184 * @param id id pseudo param 187 * @param id id pseudo param
185 * @param param_id id du paramètre 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 * @brief Une map pour stocker les valeurs calculées de l'axe X associés aux pseudo paramètres crées localement 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,8 +67,8 @@ namespace plot
67 plot->setFunction(PlotFunction::Function::AVG); 67 plot->setFunction(PlotFunction::Function::AVG);
68 else if (strcmp(valueString, PlotFunctuion_Type_FFT) == 0) 68 else if (strcmp(valueString, PlotFunctuion_Type_FFT) == 0)
69 plot->setFunction(PlotFunction::Function::FFT); 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 xmlFree(value); 72 xmlFree(value);
73 } 73 }
74 74
src/ParamOutputImpl/Plot/PanelPlotOutput.cc
@@ -2188,6 +2188,8 @@ namespace plot @@ -2188,6 +2188,8 @@ namespace plot
2188 if (!isStandalone()) 2188 if (!isStandalone())
2189 return; 2189 return;
2190 2190
  2191 + LOG4CXX_DEBUG(gLogger, "here 0");
  2192 +
2191 writer.startElement("panel"); 2193 writer.startElement("panel");
2192 _panel->writeContext(_pls, writer); 2194 _panel->writeContext(_pls, writer);
2193 2195
src/ParamOutputImpl/Plot/PanelPlotOutput.hh
@@ -8,592 +8,600 @@ @@ -8,592 +8,600 @@
8 #ifndef PANELPLOTOUTPUT_HH_ 8 #ifndef PANELPLOTOUTPUT_HH_
9 #define PANELPLOTOUTPUT_HH_ 9 #define PANELPLOTOUTPUT_HH_
10 10
11 -#include "ParamOutput.hh" 11 +#include "ContextFileWriter.hh"
  12 +#include "Layout.hh"
12 #include "Panel.hh" 13 #include "Panel.hh"
  14 +#include "PanelPlotOutputException.hh"
  15 +#include "ParamOutput.hh"
13 #include "ParameterAxes.hh" 16 #include "ParameterAxes.hh"
14 -#include <vector>  
15 -#include <tuple>  
16 #include "ParameterData.hh" 17 #include "ParameterData.hh"
  18 +#include "PlotLogger.hh"
17 #include <AMDA_exception.hh> 19 #include <AMDA_exception.hh>
18 #include <cxxabi.h> 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 #include <cfloat> 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 } /* namespace plot */ 606 } /* namespace plot */
599 #endif /* PANELPLOTOUTPUT_HH_ */ 607 #endif /* PANELPLOTOUTPUT_HH_ */
src/Parameters/fonctions/fourier/DiscreteFourierTransform.cc
@@ -7,38 +7,172 @@ DiscreteFourierTransform&lt;T, E&gt;::DiscreteFourierTransform(int nbEchantillons_, ve @@ -7,38 +7,172 @@ DiscreteFourierTransform&lt;T, E&gt;::DiscreteFourierTransform(int nbEchantillons_, ve
7 nbEchantillons = nbEchantillons_; 7 nbEchantillons = nbEchantillons_;
8 frequenceEchantillonnage = frequenceEchantillonnage_; 8 frequenceEchantillonnage = frequenceEchantillonnage_;
9 signal = signal_; 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 template <class T, class E> 19 template <class T, class E>
13 void DiscreteFourierTransform<T, E>::compute() 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 \ No newline at end of file 179 \ No newline at end of file
src/Parameters/fonctions/fourier/DiscreteFourierTransform.hh
@@ -3,7 +3,10 @@ @@ -3,7 +3,10 @@
3 #define _DISCRETEFOURIERTRANSFORM_H 3 #define _DISCRETEFOURIERTRANSFORM_H
4 4
5 #include "plplot/plplot.h" 5 #include "plplot/plplot.h"
  6 +
  7 +#include <complex>
6 #include <math.h> 8 #include <math.h>
  9 +
7 #include <vector> 10 #include <vector>
8 11
9 using namespace std; 12 using namespace std;
@@ -36,6 +39,16 @@ public: @@ -36,6 +39,16 @@ public:
36 */ 39 */
37 DiscreteFourierTransform(int nbEchantillons_, vector<T> signal_, double frequenceEchantillonnage_); 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 * @brief Calcul de la TFD 53 * @brief Calcul de la TFD
41 * 54 *
@@ -82,6 +95,16 @@ public: @@ -82,6 +95,16 @@ public:
82 return periodes; 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 private: 108 private:
86 /** 109 /**
87 * @brief Le nombre total d’échantillons (points qu’on a mesurés) 110 * @brief Le nombre total d’échantillons (points qu’on a mesurés)
@@ -118,6 +141,8 @@ private: @@ -118,6 +141,8 @@ private:
118 * 141 *
119 */ 142 */
120 vector<E> periodes; 143 vector<E> periodes;
  144 +
  145 + std::vector<std::complex<E>> phasors;
121 }; 146 };
122 147
123 #endif 148 #endif
124 \ No newline at end of file 149 \ No newline at end of file