Blame view

src/ParamOutputImpl/Plot/InstantPlot/PlotFunction.cc 13 KB
99ff615c   Menouard AZIB   Change nbEchantil...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <boost/lexical_cast.hpp>
#include <fstream>
#include <iomanip>

#include "AxesNode.hh"
#include "AxisLegendManager.hh"
#include "ParamMgr.hh"
#include "ParamsNode.hh"
#include "PlPlotUtil.hh"
#include "PlotFunction.hh"
#include "PlotLogger.hh"
#include "PlotOutput.hh"
#include "TimeUtil.hh"
#include "fonctions/fourier/DiscreteFourierTransform.cc"
#include "fonctions/fourier/DiscreteFourierTransform.hh"
#include <algorithm>
#include <limits>
#include <numeric>

#include "DefaultTimeAxisDecorator.hh"

#include "TimeAxisDecorator.hh"

using namespace AMDA::Parameters;
using namespace AMDA::Info;

namespace plot
{
    QSASConfig *PlotFunction::qsasconfig = NULL;

    PlotFunction::PlotFunction(AMDA::Parameters::ParameterManager &manager,
                               boost::shared_ptr<Panel> panel, TimeAxisDecorator *timeAxisDecorator) : PanelPlotOutput(manager, panel), function(PlotFunction::Function::NONE), abscisse("Time. ", "(s)", Abscisse::Abscisse_Type::TIME)

    {
        LOG4CXX_DEBUG(gLogger, "Function to apply " << function);
        setTimeAxisDecorator(std::shared_ptr<TimeAxisDecorator>(timeAxisDecorator));
    }

    PlotFunction::~PlotFunction()
    {
        if (qsasconfig != NULL)
        {
            free(qsasconfig);
            qsasconfig = nullptr;
        }
    }

    void PlotFunction::drawSeries(double startDate, double stopDate, int intervalIndex, std::string pParamId,
                                  SeriesProperties &pSerie,
                                  AMDA::Common::ParameterIndexComponent pParamIndex,
                                  ParameterAxes &param, bool moreThanOneSerieForAxis)
    {
        std::string id = std::to_string(pSerie.getId()) + "_" + pSerie.getParamId() + "_" + std::to_string(pParamIndex.getDim1Index());
        std::vector<double> xValues = xValuesMap[id];
        std::vector<double> yValues = yValuesMap[id];

        double *coloredComputedValues = NULL;
        int nbValues = yValues.size();

        double *yValuesTemp = &yValues[0];
        double *xValuesTemp = &xValues[0];

        pSerie.setXAxisId(X_AXIS_ID);
        pSerie.setYAxisId(Y_AXIS_ID);

        PanelPlotOutput::drawSeries(startDate, stopDate, intervalIndex, pParamId,
                                    pSerie, pParamIndex, param, moreThanOneSerieForAxis);
        // draw serie
        Color lineColor = getSerieLineColor(pSerie, moreThanOneSerieForAxis);
        Color symbolColor = getSerieSymbolColor(pSerie, lineColor);

        drawSymbols(
            pSerie.getSymbolProperties().getType(),
            pSerie.getSymbolProperties().getSize(), 1.,
            symbolColor,
            nbValues, xValuesTemp, yValuesTemp, coloredComputedValues);

        drawLines(
            pSerie.getLineProperties().getType(),
            pSerie.getLineProperties().getStyle(),
5a638eb1   Menouard AZIB   Adding comments
81
            pSerie.getLineProperties().getWidth(),
99ff615c   Menouard AZIB   Change nbEchantil...
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
            lineColor,
            nbValues, xValuesTemp, yValuesTemp, coloredComputedValues);
    }

    void PlotFunction::configureSeriesAxis()
    {
        //_panel->_leftMargin = 10;
        //_panel->_rightMargin = 5;
        //_panel->_bottomMargin = 4;

        SeriesProperties lSeries;
        for (auto parameter : _parameterAxesList)
        {
            for (auto lSeries : parameter.getYSeriePropertiesList())
            {
                for (auto lIndex : lSeries.getIndexList(_pParameterValues))
                {
                    std::string id = std::to_string(lSeries.getId()) + "_" + lSeries.getParamId() + "_" + std::to_string(lIndex.getDim1Index());
                    plot::ParameterData data = (*_pParameterValues)[lSeries.getParamId()];
318630e4   Menouard AZIB   Refactoring of pl...
101
                    PlotFunction::compute(lIndex, data, id, lSeries.getParamId());
99ff615c   Menouard AZIB   Change nbEchantil...
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
                }
            }
        }

        PlotFunction::createXAxis();
        PlotFunction::createYAxis();
    }

    void PlotFunction::createXAxis()
    {
        double minValue = 0;
        double maxValue = 0;
        PlotFunction::getMinMax(xValuesMap, &minValue, &maxValue);
        // Create X axis
        boost::shared_ptr<TimeAxis> lXAxis(new TimeAxis());
        lXAxis.get()->_timeFormat = "%H:%M";
        plot::Range range_x = Range(minValue, maxValue);
        lXAxis.get()->setRange(range_x);
        lXAxis.get()->_drawn = false;
        lXAxis.get()->_position = PlotCommon::Position::POS_BOTTOM;
        Label label1 = Label();
        // lXAxis.get()->setLegendOffset(0.03);
        label1._text = abscisse.getLabel() + abscisse.getUnit();
        lXAxis.get()->_legend.pushLabel(label1);
        lXAxis.get()->_scale = abscisseScale;
        lXAxis.get()->_showLegend = true;
        lXAxis.get()->_showTickMark = true;
        lXAxis.get()->_used = true;

        //  add X Axis to panel
        _panel->addAxis(X_AXIS_ID, lXAxis);
    }

    void PlotFunction::createYAxis()
    {
        std::string y_label = "";
5a638eb1   Menouard AZIB   Adding comments
138
139
        if (function == PlotFunction::Function::AVG)
            y_label = "AVG";
99ff615c   Menouard AZIB   Change nbEchantil...
140
141
142
143
144
145
146
        else
            y_label = "Amplitude";

        double minValue = 0;
        double maxValue = 0;

        PlotFunction::getMinMax(yValuesMap, &minValue, &maxValue);
99ff615c   Menouard AZIB   Change nbEchantil...
147
148
        // Create X axis
        boost::shared_ptr<Axis> lYAxis(new Axis(false));
5a638eb1   Menouard AZIB   Adding comments
149
        plot::Range range_x = Range(minValue - abs(minValue) * 0.10, maxValue + abs(maxValue) * 0.1);
99ff615c   Menouard AZIB   Change nbEchantil...
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
        lYAxis.get()->setRange(range_x);
        lYAxis.get()->_drawn = false;
        lYAxis.get()->_position = PlotCommon::Position::POS_LEFT;
        Label label1 = Label();
        // lYAxis.get()->setLegendOffset(0.05);
        label1._text = y_label;
        lYAxis.get()->_legend.pushLabel(label1);
        lYAxis.get()->_scale = ordonneeScale;
        lYAxis.get()->_showLegend = true;
        lYAxis.get()->_showTickMark = true;
        lYAxis.get()->_used = true;
        //  add X Axis to panel
        _panel->addAxis(Y_AXIS_ID, lYAxis);
    }

    void PlotFunction::getMinMax(std::map<std::string, std::vector<double>> dataMap, double *minToFill, double *maxToFill)
    {
        double maxValue = INT_MIN;
        double minValue = INT_MAX;
        std::map<std::string, std::vector<double>>::iterator it;
        for (it = dataMap.begin(); it != dataMap.end(); it++)
        {
            std::vector<double> data = it->second;
            double max_x = *max_element(data.begin(), data.end());
            double min_x = *min_element(data.begin(), data.end());
            if (max_x > maxValue)
                maxValue = max_x;
            if (min_x < minValue)
                minValue = min_x;
        }
        *minToFill = minValue;
        *maxToFill = maxValue;
    }

318630e4   Menouard AZIB   Refactoring of pl...
184
    void PlotFunction::compute(AMDA::Common::ParameterIndexComponent pParamIndex, plot::ParameterData data, std::string id, std::string param_id)
99ff615c   Menouard AZIB   Change nbEchantil...
185
186
    {
        double samplingValue = 60.0;
bc850076   Menouard AZIB   Re-factoring de l...
187
        int nb_points = data.getSize();
318630e4   Menouard AZIB   Refactoring of pl...
188

bc850076   Menouard AZIB   Re-factoring de l...
189
        auto it = find(paramsNbPoints.begin(), paramsNbPoints.end(), param_id);
318630e4   Menouard AZIB   Refactoring of pl...
190
191
192
193
194
        // If parameter was found
        if (it != paramsNbPoints.end())
        {
            int index = it - paramsNbPoints.begin();
            samplingValue = stod(paramsNbPoints[index + 1]);
bc850076   Menouard AZIB   Re-factoring de l...
195
            nb_points = stoi(paramsNbPoints[index + 2]);
318630e4   Menouard AZIB   Refactoring of pl...
196
197
198
199
200
        }
        else
        {
            std::stringstream lError;
            lError << "PlotFunction::compute"
d9c8118b   Menouard AZIB   Re-factoring de l...
201
202
                   << ": param with id " << param_id << " is not found in param_nb_points xml node.";
            LOG4CXX_DEBUG(gLogger, lError.str());
bc850076   Menouard AZIB   Re-factoring de l...
203
            BOOST_THROW_EXCEPTION(PanelPlotOutputException() << AMDA::errno_code(AMDA_ERROR_PLOTFUNCTION_PARAM_NOT_FOUND) << AMDA::ex_msg(lError.str()));
318630e4   Menouard AZIB   Refactoring of pl...
204
205
        }

99ff615c   Menouard AZIB   Change nbEchantil...
206
        double *values = data.getValues(pParamIndex, 0);
99ff615c   Menouard AZIB   Change nbEchantil...
207
208

        double *timeValues = &data.getTimes()[0];
99ff615c   Menouard AZIB   Change nbEchantil...
209
210
211
212
213
214
215
216

        std::vector<double> signal;
        for (int i = 0; i < data.getSize(); i++)
            signal.push_back(values[i]);

        std::vector<double> xValues;
        std::vector<double> yValues;

5a638eb1   Menouard AZIB   Adding comments
217
        if (function == PlotFunction::Function::AVG)
99ff615c   Menouard AZIB   Change nbEchantil...
218
219
220
221
        {
            double sum = std::accumulate(signal.begin(), signal.end(), 0);
            for (int i = 0; i < data.getSize(); i++)
            {
5a638eb1   Menouard AZIB   Adding comments
222
                yValues.push_back(sum / data.getSize());
99ff615c   Menouard AZIB   Change nbEchantil...
223
224
225
226
227
                xValues.push_back(timeValues[i]);
            }
        }
        else
        {
bc850076   Menouard AZIB   Re-factoring de l...
228
            DiscreteFourierTransform<double, double> DFT(std::min(nb_points, data.getSize()), signal, 1 / samplingValue);
99ff615c   Menouard AZIB   Change nbEchantil...
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
            DFT.compute();

            yValues = DFT.getAmplitudes();

            if (abscisse.getType() == Abscisse::Abscisse_Type::FREQUENCY)
                xValues = DFT.getFrequences();
            else
                xValues = DFT.getPeriodes();
        }

        if (ordonneeScale == Axis::Scale::LOGARITHMIC)
        {
            std::for_each(yValues.begin(), yValues.end(), [&](double &i)
                          { return log10(i); });
        }

        if (abscisseScale == Axis::Scale::LOGARITHMIC)
        {
            std::for_each(xValues.begin(), xValues.end(), [&](double &i)
                          { return log10(i); });
        }

        PlotFunction::xValuesMap[id] = xValues;
        PlotFunction::yValuesMap[id] = yValues;
    }

    void PlotFunction::configureAxisLegend()
    {
        // Y axis
        AxisLegendManager::configureYAxisLegendForSpectro(this);
        AxisLegendManager::configureYAxisLegendForSeries(this);

        // Z axis
        AxisLegendManager::configureColorAxisLegendForSpectro(this);
        AxisLegendManager::configureColorAxisLegendForSeries(this);
    }

    void PlotFunction::drawStartDate(std::string _timeFormat, double startTime, double stopTime)
    {
        Font font(_panel->getFont());
        Bounds lPanelBounds(_panel->getBoundsInPlPage());

        PLFLT lXMin, lXMax, lYMin, lYMax;
        _pls->gvpd(lXMin, lXMax, lYMin, lYMax);

        float lPosition = 0.0;
        // display it one line above the main panel bottom border :
        float disp = -1;

        long int lTime = static_cast<long int>(startTime);
        tm *lTimeTm = gmtime(&lTime);
        char lTimeChr[80];

        // Format date.
        strftime(lTimeChr, 80,
                 getPlStartTimeFormat(_timeFormat,
                                      startTime,
                                      stopTime)
                     .c_str(),
                 lTimeTm);

        PLFLT mxmin, mxmax, mymin, mymax;
        plgspa(&mxmin, &mxmax, &mymin, &mymax);
        float x_subpage_per_mm = 1. / (mxmax - mxmin);

        LOG4CXX_DEBUG(gLogger, "Start date to draw : " << lTimeChr);

        // Set font
        PlPlotUtil::setPlFont(font);

        PLFLT dateWidthInMm;
        dateWidthInMm = plstrl(lTimeChr);

        // set viewport for start date :
        _pls->vpor(lXMin, lXMax, lPanelBounds._y, lPanelBounds._y + lPanelBounds._height);

        lPosition = 0.;
        if (dateWidthInMm * x_subpage_per_mm > lXMin - lPanelBounds._x)
            lPosition = (dateWidthInMm * x_subpage_per_mm - lXMin + lPanelBounds._x) / (lXMax - lXMin);
        _pls->mtex("b", disp, lPosition, 1., lTimeChr);

        // restore viewport :
        _pls->vpor(lXMin, lXMax, lYMin, lYMax);
    }

    void PlotFunction::preparePlotArea(double startTime, double stopTime, int intervalIndex)
    {
        PlotFunction::configureSeriesAxis();

        if (abscisse.getType() == Abscisse::TIME)
        {
            boost::shared_ptr<Axis> xAxis = _panel->getAxis(X_AXIS_ID);
            getTimeAxisDecorator()->configure(this, dynamic_cast<TimeAxis *>(xAxis.get()), startTime, stopTime, _pParameterValues);
            _pls->timefmt(getTimeAxisDecorator()->getPlFormat().c_str());
        }
347ee32b   Menouard AZIB   Change ParamNbPoi...
324
325
        PanelPlotOutput::preparePlotArea(startTime, stopTime, intervalIndex);
    }
99ff615c   Menouard AZIB   Change nbEchantil...
326

347ee32b   Menouard AZIB   Change ParamNbPoi...
327
328
    void PlotFunction::createParameters(std::list<std::string> &usedParametersId_)
    {
d9c8118b   Menouard AZIB   Re-factoring de l...
329

347ee32b   Menouard AZIB   Change ParamNbPoi...
330
331
        for (ParameterAxesList::iterator it = _parameterAxesList.begin();
             it != _parameterAxesList.end(); ++it)
99ff615c   Menouard AZIB   Change nbEchantil...
332
        {
347ee32b   Menouard AZIB   Change ParamNbPoi...
333
334
            AMDA::Parameters::ParameterSPtr originalParam =
                _parameterManager.getParameter(it->_originalParamId);
99ff615c   Menouard AZIB   Change nbEchantil...
335

347ee32b   Menouard AZIB   Change ParamNbPoi...
336
337
338
339
340
            // For each series
            std::vector<SeriesProperties>::iterator ity;
            for (ity = it->getYSeriePropertiesList().begin(); ity != it->getYSeriePropertiesList().end();
                 ++ity)
            {
d9c8118b   Menouard AZIB   Re-factoring de l...
341
                // Add  parameter to parameters list
347ee32b   Menouard AZIB   Change ParamNbPoi...
342
                if (std::find(usedParametersId_.begin(), usedParametersId_.end(),
d9c8118b   Menouard AZIB   Re-factoring de l...
343
344
                              originalParam->getId()) == usedParametersId_.end())
                    usedParametersId_.push_back(originalParam->getId());
347ee32b   Menouard AZIB   Change ParamNbPoi...
345
346

                // link this paramter to the serie
d9c8118b   Menouard AZIB   Re-factoring de l...
347
                ity->setParamId(originalParam->getId());
99ff615c   Menouard AZIB   Change nbEchantil...
348
349
            }
        }
347ee32b   Menouard AZIB   Change ParamNbPoi...
350
    }
99ff615c   Menouard AZIB   Change nbEchantil...
351

347ee32b   Menouard AZIB   Change ParamNbPoi...
352
353
354
355
356
357
358
    /**
     * @brief draw the plot for the current time interval
     */
    bool PlotFunction::draw(double startTime, double stopTime, int intervalIndex,
                            bool isFirstInterval, bool isLastInterval)
    {
        bool out = PanelPlotOutput::draw(startTime, stopTime, intervalIndex, isFirstInterval, isLastInterval);
99ff615c   Menouard AZIB   Change nbEchantil...
359

347ee32b   Menouard AZIB   Change ParamNbPoi...
360
361
362
363
364
        if (abscisse.getType() == Abscisse::TIME)
        {
            std::string _timeFormat = "hh:mm:ss";
            PlotFunction::drawStartDate(_timeFormat, startTime, stopTime);
        }
99ff615c   Menouard AZIB   Change nbEchantil...
365
366
367
368

        return out;
    }
}