Commit 3cf118118221e740de4f2e3907900973ec700c34
1 parent
dc7a34dc
Exists in
master
and in
37 other branches
FFT Validated and I add Test fucntions
Showing
7 changed files
with
1074 additions
and
678 deletions
Show diff stats
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 ¶m, bool moreThanOneSerieForAxis) | 197 | ParameterAxes ¶m, 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 ¶m : _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 ¶m, 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<T, E>::DiscreteFourierTransform(int nbEchantillons_, ve | @@ -7,38 +7,172 @@ DiscreteFourierTransform<T, E>::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 |