T
T
tugo2014-05-01 18:36:33
Programming
tugo, 2014-05-01 18:36:33

What approach, pattern to choose for data processing?

Hello!
I write in C++/Qt.
There is a data set ("raw"), its graph is built. The user can select a window on this graph for processing.
Data processing - a sequence of operations - smoothing, averaging, derivative, second derivative, convolution and other transformations. Each operation takes some time - 1-2 seconds.
Processing is on the fly, the user has changed something - all operations are immediately recalculated.
The question is how to stop the execution of a sequence of operations if the user constantly changes the window on the chart?
There are operations when a raw data set is used and a set after processing. It turns out that the raw set has already changed, and a certain set after processing is still old.
Somehow you can do it, enter flags, mutexes or something else.
I want a beautiful, perhaps a hundred times described campaign.
This is where the data sets are stored after each operation:

typedef std::vector<Graph> GraphSet;
std::map<Set, GraphSet> m_fullDataSet;

enum class Set
{
    Raw,
    Smooth,
    Window,
    Average,
    Variance,
    Gauss
};

Here is a typical operation. After completion, I emit a signal:
void Calculator::accumulatedAverage()
{
    m_fullDataSet[Set::Average].clear();

    const GraphSet & windowSet = m_fullDataSet[Set::Window];

    for (const Graph & graph: windowSet)
    {
        Curve average;
        average.x = graph.curve.x;

        double sum = 0;
        double amount = 0;
        for (double point: graph.curve.y)
        {
            sum += point; // накапливаем сумму точек
            amount += 1; // количество точек

            average.y.push_back(sum/amount);
        }
        m_fullDataSet[Set::Average].push_back(Graph(graph.name, "", average, graph.color));
    }
    emit averageSetChanged();
}

The sequence of operations is given as follows:
void Calculator::path()
{
    connect(this, &Calculator::rawSetChanged,        this, [&](){ smoothData(Set::Raw, Set::Smooth); },                          Qt::QueuedConnection);
    connect(this, &Calculator::smoothSetChanged,     this, [&](Set set){ if (set == Set::Smooth) pickGraphs(); }, Qt::QueuedConnection);
    connect(this, &Calculator::bordersChanged,       this, [&](){ if (m_border1 != m_border2) cutWindow(); }, Qt::QueuedConnection);
    connect(this, &Calculator::windowSetChanged,     this, [&](){ accumulatedAverage(); }, Qt::QueuedConnection);
    connect(this, &Calculator::averageSetChanged,    this, [&](){ variance(); }, Qt::QueuedConnection);
    connect(this, &Calculator::varianceSetChanged,   this, [&](){ gauss(); }, Qt::QueuedConnection);
}

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question