i0mmonplot.cpp 9.55 KB
Newer Older
Giacomo Strangolino's avatar
Giacomo Strangolino committed
1
2
3
4
#include "i0mmonplot.h"
#include <cumbiapool.h>
#include <cucontrolsfactorypool.h>
#include <quplotcurve.h>
5
6
#include <qutimescaledraw.h>
#include <qwt_symbol.h>
7
#include <qwt_legend.h>
8
#include <qwt_date_scale_engine.h>
9
#include <qwt_transform.h>
Giacomo Strangolino's avatar
Giacomo Strangolino committed
10
11
12
13
14
15
16
17

#include <cupluginloader.h>
#include <qumultireaderplugininterface.h>
#include <cumacros.h>

#include <QtDebug>

#ifdef QUMBIA_TANGO_CONTROLS_VERSION
18
#include <QRegularExpression>
Giacomo Strangolino's avatar
Giacomo Strangolino committed
19
20
21
#include <cutreader.h>
#endif

22
23
24
25
26
27
28
29
30
31
32
class LogTransform : public QwtLogTransform {
public:
    LogTransform() : QwtLogTransform() { printf("LOG TRANSFORM\n"); }
    // QwtTransform interface
public:
    double bounded(double v) const{
        return qBound(0.01, v, LogMax);
    }
};


Giacomo Strangolino's avatar
Giacomo Strangolino committed
33
I0MMonPlot::I0MMonPlot(QWidget *parent, CumbiaPool *cup, const CuControlsFactoryPool &fpoo)
Giacomo Strangolino's avatar
Giacomo Strangolino committed
34
    : QuPlotBase(parent),
35
36
37
38
      m_symstyles (QList<QwtSymbol::Style> () <<  QwtSymbol::Ellipse
                                               << QwtSymbol::Rect << QwtSymbol::Triangle <<
                                                  QwtSymbol::Star1 << QwtSymbol::Diamond <<
                                                  QwtSymbol::Cross<< QwtSymbol::XCross) {
Giacomo Strangolino's avatar
Giacomo Strangolino committed
39
40
    m_ctrl_fpool = fpoo;
    m_cu_poo = cup;
Giacomo Strangolino's avatar
Giacomo Strangolino committed
41
    m_time_mode = m_empty = true;
42
    m_numsamples = 1;
Giacomo Strangolino's avatar
Giacomo Strangolino committed
43
    m_ymin = m_ymax = 0;
44
    m_log_scale = false;
Giacomo Strangolino's avatar
Giacomo Strangolino committed
45
46
47
48
49
50
    CuPluginLoader plo;
    QObject *plugin_qob;
    m_multiread_plu_i = plo.get<QuMultiReaderPluginInterface>("libcumbia-multiread-plugin.so", &plugin_qob);
    if(!m_multiread_plu_i)
        perr("I0MMonPlot: failed to load plugin \"libcumbia-multiread-plugin.so\"");
    else {
51
52
        qDebug() << __PRETTY_FUNCTION__ << "initializing plugin multiread" << m_multiread_plu_i;
        m_multiread_plu_i->init(cup, fpoo, QuMultiReaderPluginInterface::SequentialReads); // 0 sync mode
Giacomo Strangolino's avatar
Giacomo Strangolino committed
53
54
55
        connect(m_multiread_plu_i->get_qobject(), SIGNAL(onSeqReadComplete(const QList<CuData> &)),
                this, SLOT(onDataReady(const QList<CuData> &)));
    }
Giacomo Strangolino's avatar
Giacomo Strangolino committed
56
57
58

    setXAxisAutoscaleEnabled(false);
    setYAxisAutoscaleEnabled(false);
59
    insertLegend( new QwtLegend() );
60
61
62

    m_colormap << "#ff5555" <<  "#c8ff00" <<  "#2882ff"  <<  "#7fffff" ;

Giacomo Strangolino's avatar
Giacomo Strangolino committed
63
64
}

65
66
67
68
I0MMonPlot::~I0MMonPlot() {
    if(m_multiread_plu_i) m_multiread_plu_i->unsetSources();
}

Giacomo Strangolino's avatar
Giacomo Strangolino committed
69
70
71
72
bool I0MMonPlot::pluginLoaded() const {
    return m_multiread_plu_i != nullptr;
}

Giacomo Strangolino's avatar
Giacomo Strangolino committed
73
74
75
bool I0MMonPlot::yAutoScale() const {
    return m_ymax == m_ymin;
}
Giacomo Strangolino's avatar
Giacomo Strangolino committed
76
void I0MMonPlot::setSources(const QString &x, const QString &y, const QMap<int, double> lambdamap, int nsamples)
Giacomo Strangolino's avatar
Giacomo Strangolino committed
77
{
Giacomo Strangolino's avatar
Giacomo Strangolino committed
78
    qDebug() << __PRETTY_FUNCTION__ << x << y << lambdamap;
Giacomo Strangolino's avatar
Giacomo Strangolino committed
79
    QuPlotBase::clearPlot();
80
    m_multiread_plu_i->unsetSources();
Giacomo Strangolino's avatar
Giacomo Strangolino committed
81
82
    m_curvesymap.clear();
    m_empty = true;
83
    m_numsamples = nsamples;
Giacomo Strangolino's avatar
Giacomo Strangolino committed
84
85
    m_lambdas = lambdamap;
    m_time_mode = (x == "time");
86
    m_reset_scales();
87
    int la = 1, cc = 0;;
Giacomo Strangolino's avatar
Giacomo Strangolino committed
88
89
90
91
92
93
    foreach(double l, lambdamap.values()) {
        QString cuna = QString("lambda %1").arg(l);
        QuPlotCurve *crv = curve(cuna);
        if(!crv) {
            crv = new QuPlotCurve(cuna);
            addCurve(cuna, crv);
94
            QPen p = crv->pen();
95
            p.setColor(m_colormap[cc % m_colormap.size()]);
96
97
            p.setWidthF(2.5);
            crv->setPen(p);
98
            crv->setTitle(QString("λ %1").arg(la++));
99
            cc++;
100
        }
Giacomo Strangolino's avatar
Giacomo Strangolino committed
101
102
        m_curvesymap[cuna] = m_symstyles[m_curvesymap.size() % m_symstyles.size()];
    }
103
    qDebug() << __PRETTY_FUNCTION__ << "settings sources: x " <<  x << " y " << y  << "time mode" << m_time_mode;
Giacomo Strangolino's avatar
Giacomo Strangolino committed
104
    if(m_time_mode) {
105
106
107
108
109
        if(m_multiread_plu_i)
            m_multiread_plu_i->insertSource(y, 0);
    }
    else {
        if(m_multiread_plu_i ) {
110
111
112
            QString xsrc;
            x.contains(QRegularExpression("\\(\\d,%\\d\\)")) ? xsrc = QString(x).arg(nsamples) : xsrc = x;
            m_multiread_plu_i->insertSource(xsrc, 0);
113
114
115
            m_multiread_plu_i->insertSource(y, 1);
        }
    }
116
    updateLegend();
117
}
Giacomo Strangolino's avatar
Giacomo Strangolino committed
118

Giacomo Strangolino's avatar
Giacomo Strangolino committed
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
void I0MMonPlot::setYBounds(double ymi, double yma) {
    if(ymi != yma && ymi < yma)  {
        m_ymin = ymi;
        m_ymax = yma;
        setYLowerBound(ymi);
        setYUpperBound(yma);
    }
}

void I0MMonPlot::setYBoundsAuto(bool a) {
    if(a) {
        m_ymin = m_ymax = 0;
        m_empty = true;
    }
}

135
136
137
138
139
140
141
142
143
144
145
146
void I0MMonPlot::setYLogScale(bool a) {
    m_log_scale = a;
    QwtScaleEngine *se;
    a ? se = new QwtLogScaleEngine : se = new QwtLinearScaleEngine;
    if(a) {
        se->setTransformation(new LogTransform);
        setYLowerBound(yLowerBound() <=0 ? 0.01 : yLowerBound());
    }
    setAxisScaleEngine(QwtPlot::yLeft, se);
    replot();
}

Giacomo Strangolino's avatar
Giacomo Strangolino committed
147
void I0MMonPlot::m_set_bounds(const QVector<double> &xv, const QVector<double> &yv)
148
{
149
    qDebug() << __PRETTY_FUNCTION__ << "y" << m_ymin << m_ymax << "m_empty ? " << m_empty  << yv;
Giacomo Strangolino's avatar
Giacomo Strangolino committed
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
    if(m_ymin == m_ymax) { // auto scale Y
        double ylb, yub;
        const auto [ym, yM] = std::minmax_element(begin(yv), end(yv));
                ylb = m_empty ? (*ym) : yLowerBound();
                yub = m_empty ? (*yM) : yUpperBound();
                // y auto scale?
                if(*yM == *ym) {
            if(ylb >= *ym)
                ylb = (*ym - 0.5);
            if(yub <= *yM)
                yub = (*yM + 0.5);
        } else {
            if(ylb >= *ym)
                ylb = (*ym - 0.15 * (*yM - *ym));
            if(yub <= *yM)
                yub = (*yM + 0.15 * (*yM - *ym));
        }
167

Giacomo Strangolino's avatar
Giacomo Strangolino committed
168
        if(ylb != yLowerBound())
169
            setYLowerBound( (m_log_scale && ylb) <= 0 ? 0.01 : ylb);
Giacomo Strangolino's avatar
Giacomo Strangolino committed
170
171
        if(yub != yUpperBound())
            setYUpperBound(yub);
172
        qDebug() << __PRETTY_FUNCTION__ << "y" <<  ylb << "->" << yub << "ym, yM" << *ym << *yM;
Giacomo Strangolino's avatar
Giacomo Strangolino committed
173
174
175
176
177
178
    }

    const auto [xm, xM] = std::minmax_element(begin(xv), end(xv));
    double xlb, xub;
    xlb = m_empty ? (*xm) : xLowerBound();
    xub = m_empty ? (*xM) : xUpperBound();
179

Giacomo Strangolino's avatar
Giacomo Strangolino committed
180
    if(*xm == *xM) {
181
182
183
184
185
        if(xlb >= *xm)
            xlb = (*xm - 0.5);
        if(xub <= *xM)
            xub = (*xM + 0.5);
    } else {
186
        if(xlb >= *xm)
Giacomo Strangolino's avatar
Giacomo Strangolino committed
187
            xlb = (*xm - 0.15 * (*xM - *xm));
188
        if(xub <= *xM)
Giacomo Strangolino's avatar
Giacomo Strangolino committed
189
            xub = (*xM + 0.15 * (*xM - *xm));
190
    }
Giacomo Strangolino's avatar
Giacomo Strangolino committed
191

192
193
194
195
    if(xlb != xLowerBound())
        setXLowerBound(xlb);
    if(xub != xUpperBound())
        setXUpperBound(xub);
196
    qDebug() << __PRETTY_FUNCTION__ << "x" <<  xlb << "->" << xub << "xm, xM" << *xm << *xM << xv;
197
198
}

Giacomo Strangolino's avatar
Giacomo Strangolino committed
199
200
201
202
203
204
205
206
207

void I0MMonPlot::onDataReady(const QList<CuData> &dl) {
    qDebug() << __PRETTY_FUNCTION__ << "data szi" <<  dl.size();
    double x = 0.0;

    if(!m_time_mode && dl.size() == 2) { // correlate
        QVector<double> yv, xv;
        const CuData& xd = dl[0];
        const CuData& yd = dl[1];
208
209
210
        printf("\e[1;33mI0MMonPlot::onDataReady xd %s\e[0m\n", datos(xd));
        printf("\e[0;33mI0MMonPlot::onDataReady yd %s\e[0m\n", datos(yd));

Giacomo Strangolino's avatar
Giacomo Strangolino committed
211
        printf("\e[1;35mx %s , y %s\e[0m\n", vtoc2(xd, "value"), vtoc2(yd, "value"));
212
        if(xd.has("data_format_str", "vector") || xd.has("dfs", "vector")) { // cumbia 1.3.0 data_format_str -> dfs
Giacomo Strangolino's avatar
Giacomo Strangolino committed
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
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
            // average
            double sum = 0.0;
            const std::vector<double> &v = xd["value"].toDoubleVector();
            for(size_t i = 0; i < v.size(); i++)
                sum += v[i];
            x = sum / m_numsamples;
            printf("x (%f) averaged across %ld samples\n", x, v.size());
        }
        else
            x = xd["value"].toDouble();
        // y
        const std::vector<double> &yt = yd["value"].toDoubleVector();
        foreach(int i, m_lambdas.keys()) {
            if(i < static_cast<int>(yt.size()) ) {
                appendData(QString("lambda %1").arg(m_lambdas[i]), x, yt[i]);
                yv << yt[i];
                xv << x;
            }
        }
        m_set_bounds(xv, yv);
    }
    else if(m_time_mode) { // trend in time

        const CuData &da = dl[0];
        const std::vector<double> &ystdv = da["value"].toDoubleVector();
        QVector<double> xv {0.0}; // m_set_bounds needs a vector, say 0 and data size
#if QT_VERSION < QT_VERSION_CHECK(5, 12, 0)
        const QVector<double> yv = QVector<double>::fromStdVector(ystdv);
#else
        const QVector<double> yv(ystdv.begin(), ystdv.end());
#endif
        foreach(int idx, m_lambdas.keys()) {
            const QString curveName = QString("lambda %1").arg(m_lambdas[idx]);
            const QuPlotCurve *c = curve(curveName);
            xv << c->data()->size();
            if(idx < static_cast<int>(yv.size()) && curve(curveName) != nullptr ) {
                m_set_bounds(xv, yv);
                appendData(curveName, xv[1], yv[idx]);
            }
        }
    }
    else {
        printf("\e[1;31mI0MMonPlot::onDataReady: no time mode: data size %d\e[0m\n", dl.size());
        for(int i = 0; i < dl.size(); i++)
            printf("\e[1;31mI0MMonPlot::onDataReady: %s\e[0m\n", datos(dl[i]));
    }
    m_curves_style();
    m_empty = false;
}

263
void I0MMonPlot::m_reset_scales() {
Giacomo Strangolino's avatar
Giacomo Strangolino committed
264
265
266
267
268
269
    setXLowerBound(-0.5);
    setXUpperBound(0.5);
    if(m_ymin == m_ymax) {
        setYLowerBound(-0.5);
        setYUpperBound(0.5);
    }
270
}
Giacomo Strangolino's avatar
Giacomo Strangolino committed
271

Giacomo Strangolino's avatar
Giacomo Strangolino committed
272
273
274
275
276
277
278
279
280
281
282
283
void I0MMonPlot::m_curves_style() {
    foreach(QString cn, m_curvesymap.keys()) {
        QuPlotCurve *c = curve(cn);
        if(c && c->style() != QwtPlotCurve::Dots) {
            c->setStyle(QwtPlotCurve::Dots);
            //            QPen p = c->pen();
            //            p.setWidthF(2.0f);
            //            c->setPen(p);
        }
#if CUMBIA_QTCONTROLS_VERSION > 0x010202
        c->setMaxDataSizeForSymbol(0); // disable first points symbol
#endif
284
285
286
287
        if(!c->symbol() || c->symbol()->style() != m_curvesymap[cn]) {
            QBrush bru(c->pen().color()); // fill symbol
            c->setSymbol(new QwtSymbol(m_curvesymap[cn], bru, c->pen(), QSize(10, 10)));
        }
Giacomo Strangolino's avatar
Giacomo Strangolino committed
288
    }
Giacomo Strangolino's avatar
Giacomo Strangolino committed
289
}
Giacomo Strangolino's avatar
Giacomo Strangolino committed
290