i0mmonplot.cpp 7.73 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
7
#include <qutimescaledraw.h>
#include <qwt_symbol.h>
#include <qwt_date_scale_engine.h>
Giacomo Strangolino's avatar
Giacomo Strangolino committed
8
9
10
11
12
13
14
15

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

#include <QtDebug>

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

I0MMonPlot::I0MMonPlot(QWidget *parent, CumbiaPool *cup, const CuControlsFactoryPool &fpoo)
Giacomo Strangolino's avatar
Giacomo Strangolino committed
21
22
    : QuPlotBase(parent),
      m_symstyles (QList<QwtSymbol::Style> () <<  QwtSymbol::XCross << QwtSymbol::Cross
Giacomo Strangolino's avatar
Giacomo Strangolino committed
23
                                               << QwtSymbol::Rect << QwtSymbol::Triangle << QwtSymbol::Star1 << QwtSymbol::Diamond << QwtSymbol::Ellipse) {
Giacomo Strangolino's avatar
Giacomo Strangolino committed
24
25
    m_ctrl_fpool = fpoo;
    m_cu_poo = cup;
Giacomo Strangolino's avatar
Giacomo Strangolino committed
26
    m_time_mode = m_empty = true;
27
    m_numsamples = 1;
Giacomo Strangolino's avatar
Giacomo Strangolino committed
28
    m_ymin = m_ymax = 0;
Giacomo Strangolino's avatar
Giacomo Strangolino committed
29
30
31
32
33
34
    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 {
35
36
        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
37
38
39
        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
40
41
42

    setXAxisAutoscaleEnabled(false);
    setYAxisAutoscaleEnabled(false);
Giacomo Strangolino's avatar
Giacomo Strangolino committed
43
44
45
46
47
48
}

bool I0MMonPlot::pluginLoaded() const {
    return m_multiread_plu_i != nullptr;
}

Giacomo Strangolino's avatar
Giacomo Strangolino committed
49
50
51
bool I0MMonPlot::yAutoScale() const {
    return m_ymax == m_ymin;
}
Giacomo Strangolino's avatar
Giacomo Strangolino committed
52
void I0MMonPlot::setSources(const QString &x, const QString &y, const QMap<int, double> lambdamap, int nsamples)
Giacomo Strangolino's avatar
Giacomo Strangolino committed
53
{
Giacomo Strangolino's avatar
Giacomo Strangolino committed
54
    qDebug() << __PRETTY_FUNCTION__ << x << y << lambdamap;
Giacomo Strangolino's avatar
Giacomo Strangolino committed
55
    QuPlotBase::clearPlot();
56
    m_multiread_plu_i->unsetSources();
Giacomo Strangolino's avatar
Giacomo Strangolino committed
57
58
    m_curvesymap.clear();
    m_empty = true;
59
    m_numsamples = nsamples;
Giacomo Strangolino's avatar
Giacomo Strangolino committed
60
61
    m_lambdas = lambdamap;
    m_time_mode = (x == "time");
62
    m_reset_scales();
Giacomo Strangolino's avatar
Giacomo Strangolino committed
63
64
65
66
67
68
    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);
69
        }
Giacomo Strangolino's avatar
Giacomo Strangolino committed
70
71
        m_curvesymap[cuna] = m_symstyles[m_curvesymap.size() % m_symstyles.size()];
    }
72
    qDebug() << __PRETTY_FUNCTION__ << "settings sources: x " <<  x << " y " << y  << "time mode" << m_time_mode;
Giacomo Strangolino's avatar
Giacomo Strangolino committed
73
    if(m_time_mode) {
74
75
76
77
78
        if(m_multiread_plu_i)
            m_multiread_plu_i->insertSource(y, 0);
    }
    else {
        if(m_multiread_plu_i ) {
79
80
81
            QString xsrc;
            x.contains(QRegularExpression("\\(\\d,%\\d\\)")) ? xsrc = QString(x).arg(nsamples) : xsrc = x;
            m_multiread_plu_i->insertSource(xsrc, 0);
82
83
84
85
            m_multiread_plu_i->insertSource(y, 1);
        }
    }
}
Giacomo Strangolino's avatar
Giacomo Strangolino committed
86

Giacomo Strangolino's avatar
Giacomo Strangolino committed
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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;
    }
}

Giacomo Strangolino's avatar
Giacomo Strangolino committed
103
void I0MMonPlot::m_set_bounds(const QVector<double> &xv, const QVector<double> &yv)
104
{
Giacomo Strangolino's avatar
Giacomo Strangolino committed
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
    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));
        }
122

Giacomo Strangolino's avatar
Giacomo Strangolino committed
123
124
125
126
127
128
129
130
131
132
        if(ylb != yLowerBound())
            setYLowerBound(ylb);
        if(yub != yUpperBound())
            setYUpperBound(yub);
    }

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

Giacomo Strangolino's avatar
Giacomo Strangolino committed
134
    if(*xm == *xM) {
135
136
137
138
139
        if(xlb >= *xm)
            xlb = (*xm - 0.5);
        if(xub <= *xM)
            xub = (*xM + 0.5);
    } else {
140
        if(xlb >= *xm)
Giacomo Strangolino's avatar
Giacomo Strangolino committed
141
            xlb = (*xm - 0.15 * (*xM - *xm));
142
        if(xub <= *xM)
Giacomo Strangolino's avatar
Giacomo Strangolino committed
143
            xub = (*xM + 0.15 * (*xM - *xm));
144
    }
Giacomo Strangolino's avatar
Giacomo Strangolino committed
145

146
147
148
149
150
151
    if(xlb != xLowerBound())
        setXLowerBound(xlb);
    if(xub != xUpperBound())
        setXUpperBound(xub);
}

Giacomo Strangolino's avatar
Giacomo Strangolino committed
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

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];
        printf("\e[1;35mx %s , y %s\e[0m\n", vtoc2(xd, "value"), vtoc2(yd, "value"));
        if(xd.has("data_format_str", "vector")) {
            // 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;
}

213
void I0MMonPlot::m_reset_scales() {
Giacomo Strangolino's avatar
Giacomo Strangolino committed
214
215
216
217
218
219
    setXLowerBound(-0.5);
    setXUpperBound(0.5);
    if(m_ymin == m_ymax) {
        setYLowerBound(-0.5);
        setYUpperBound(0.5);
    }
220
}
Giacomo Strangolino's avatar
Giacomo Strangolino committed
221

Giacomo Strangolino's avatar
Giacomo Strangolino committed
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
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
        if(!c->symbol() || c->symbol()->style() != m_curvesymap[cn])
            c->setSymbol(new QwtSymbol(m_curvesymap[cn], c->brush(), c->pen(), QSize(6, 6)));
    }
Giacomo Strangolino's avatar
Giacomo Strangolino committed
237
}
Giacomo Strangolino's avatar
Giacomo Strangolino committed
238