void tst_QtConcurrentIterateKernel::multipleResults()
{
    QFuture<int> f = startThreadEngine(new MultipleResultsFor(0, 10)).startAsynchronously();
    QCOMPARE(f.results().count() , 10);
    QCOMPARE(f.resultAt(0), 0);
    QCOMPARE(f.resultAt(5), 5);
    QCOMPARE(f.resultAt(9), 9);
    f.waitForFinished();
}
예제 #2
0
QList<LocatorFilterEntry> BasicLocatorFilterTest::matchesFor(const QString &searchText)
{
    doBeforeLocatorRun();
    const QList<ILocatorFilter *> filters = QList<ILocatorFilter *>() << m_filter;
    QFuture<LocatorFilterEntry> locatorSearch = QtConcurrent::run(Core::Internal::runSearch,
                                                           filters, searchText);
    locatorSearch.waitForFinished();
    doAfterLocatorRun();
    return locatorSearch.results();
}
void tst_QtConcurrentThreadEngine::multipleResults()
{
    MultipleResultsUser *engine =  new MultipleResultsUser();
    QFuture<int> f = engine->startAsynchronously();
    QCOMPARE(f.results().count() , 10);
    QCOMPARE(f.resultAt(0), 0);
    QCOMPARE(f.resultAt(5), 5);
    QCOMPARE(f.resultAt(9), 9);
    f.waitForFinished();
}
예제 #4
0
QList<LocatorFilterEntry> BasicLocatorFilterTest::matchesFor(const QString &searchText)
{
    doBeforeLocatorRun();
    const QList<ILocatorFilter *> filters = QList<ILocatorFilter *>() << m_filter;
    m_filter->prepareSearch(searchText);
    QFuture<LocatorFilterEntry> locatorSearch = Utils::runAsync(&Internal::runSearch, filters,
                                                                searchText);
    locatorSearch.waitForFinished();
    doAfterLocatorRun();
    return locatorSearch.results();
}
예제 #5
0
bool ActivitySessionData::setCurrentActivity(const QString &activityId)
{
    QFuture<bool> rv;
    QMetaObject::invokeMethod(m_activitiesProxy, "setCurrentActivity",
                              Qt::BlockingQueuedConnection,
                              Q_RETURN_ARG(QFuture<bool>, rv),
                              Q_ARG(QString, activityId));
    rv.waitForFinished();

    //TODO: this shows one of the weaknesses in the QFuture based APIs ....
    bool value = rv.results().isEmpty() ? false : rv.result();
    return value;
}
예제 #6
0
void tst_QFuture::resultsAsList()
{
    IntResult a;
    a.reportStarted();
    QFuture<int> f = a.future();

    int result;
    result = 1;
    a.reportResult(&result);
    result = 2;
    a.reportResult(&result);

    a.reportFinished();

    QList<int> results = f.results();
    QCOMPARE(results, QList<int>() << 1 << 2);
}
예제 #7
0
/*
    Tests that a QFuture can return multiple results.
*/
void tst_QFuture::multipleResults()
{
    IntResult a;
    a.reportStarted();
    QFuture<int> f = a.future();

    QFuture<int> copy = f;
    int result;

    result = 1;
    a.reportResult(&result);
    QCOMPARE(f.resultAt(0), 1);

    result = 2;
    a.reportResult(&result);
    QCOMPARE(f.resultAt(1), 2);

    result = 3;
    a.reportResult(&result);

    result = 4;
    a.reportFinished(&result);

    QCOMPARE(f.results(), QList<int>() << 1 << 2 << 3 << 4);

    // test foreach
    QList<int> fasit = QList<int>() << 1 << 2 << 3 << 4;
    {
        QList<int> results;
        foreach(int result, f)
            results.append(result);
        QCOMPARE(results, fasit);
    }
    {
        QList<int> results;
        foreach(int result, copy)
            results.append(result);
        QCOMPARE(results, fasit);
    }
}
예제 #8
0
void tst_QFuture::iterators()
{
    {
        QFutureInterface<int> e;
        e.reportStarted();
        QFuture<int> f = e.future();

        int result;
        result = 1;
        e.reportResult(&result);
        result = 2;
        e.reportResult(&result);
        result = 3;
        e.reportResult(&result);
        e.reportFinished();

        QList<int> results;
        QFutureIterator<int> i(f);
        while (i.hasNext()) {
            results.append(i.next());
        }

        QCOMPARE(results, f.results());

        QFuture<int>::const_iterator i1 = f.begin(), i2 = i1 + 1;
        QFuture<int>::const_iterator c1 = i1, c2 = c1 + 1;

        QCOMPARE(i1, i1);
        QCOMPARE(i1, c1);
        QCOMPARE(c1, i1);
        QCOMPARE(c1, c1);
        QCOMPARE(i2, i2);
        QCOMPARE(i2, c2);
        QCOMPARE(c2, i2);
        QCOMPARE(c2, c2);

        QVERIFY(i1 != i2);
        QVERIFY(i1 != c2);
        QVERIFY(c1 != i2);
        QVERIFY(c1 != c2);
        QVERIFY(i2 != i1);
        QVERIFY(i2 != c1);
        QVERIFY(c2 != i1);
        QVERIFY(c2 != c1);

        int x1 = *i1;
        Q_UNUSED(x1);
        int x2 = *i2;
        Q_UNUSED(x2);
        int y1 = *c1;
        Q_UNUSED(y1);
        int y2 = *c2;
        Q_UNUSED(y2);
    }

    {
        QFutureInterface<QString> e;
        e.reportStarted();
        QFuture<QString> f =  e.future();

        e.reportResult(QString("one"));
        e.reportResult(QString("two"));
        e.reportResult(QString("three"));
        e.reportFinished();

        QList<QString> results;
        QFutureIterator<QString> i(f);
        while (i.hasNext()) {
            results.append(i.next());
        }

        QCOMPARE(results, f.results());

        QFuture<QString>::const_iterator i1 = f.begin(), i2 = i1 + 1;
        QFuture<QString>::const_iterator c1 = i1, c2 = c1 + 1;

        QCOMPARE(i1, i1);
        QCOMPARE(i1, c1);
        QCOMPARE(c1, i1);
        QCOMPARE(c1, c1);
        QCOMPARE(i2, i2);
        QCOMPARE(i2, c2);
        QCOMPARE(c2, i2);
        QCOMPARE(c2, c2);

        QVERIFY(i1 != i2);
        QVERIFY(i1 != c2);
        QVERIFY(c1 != i2);
        QVERIFY(c1 != c2);
        QVERIFY(i2 != i1);
        QVERIFY(i2 != c1);
        QVERIFY(c2 != i1);
        QVERIFY(c2 != c1);

        QString x1 = *i1;
        QString x2 = *i2;
        QString y1 = *c1;
        QString y2 = *c2;

        QCOMPARE(x1, y1);
        QCOMPARE(x2, y2);

        int i1Size = i1->size();
        int i2Size = i2->size();
        int c1Size = c1->size();
        int c2Size = c2->size();

        QCOMPARE(i1Size, c1Size);
        QCOMPARE(i2Size, c2Size);
    }

    {
        const int resultCount = 20;

        QFutureInterface<int> e;
        e.reportStarted();
        QFuture<int> f =  e.future();

        for (int i = 0; i < resultCount; ++i) {
            e.reportResult(i);
        }

        e.reportFinished();

        {
            QFutureIterator<int> it(f);
            QFutureIterator<int> it2(it);
        }

        {
            QFutureIterator<int> it(f);

            for (int i = 0; i < resultCount - 1; ++i) {
                QVERIFY(it.hasNext());
                QCOMPARE(it.peekNext(), i);
                QCOMPARE(it.next(), i);
            }

            QVERIFY(it.hasNext());
            QCOMPARE(it.peekNext(), resultCount - 1);
            QCOMPARE(it.next(), resultCount - 1);
            QVERIFY(!it.hasNext());
        }

        {
            QFutureIterator<int> it(f);
            QVERIFY(it.hasNext());
            it.toBack();
            QVERIFY(!it.hasNext());
            it.toFront();
            QVERIFY(it.hasNext());
        }
    }
}
예제 #9
0
/*
    Test out-of-order result reporting using indexes
*/
void tst_QFuture::indexedResults()
{
    {
        QFutureInterface<QChar> Interface;
        QFuture<QChar> f;
        QVERIFY(f.isStarted());

        Interface.reportStarted();
        f = Interface.future();

        QVERIFY(f.isStarted());

        QChar result;

        result = 'B';
        Interface.reportResult(&result, 1);

        QCOMPARE(f.resultAt(1), result);

        result = 'A';
        Interface.reportResult(&result, 0);
        QCOMPARE(f.resultAt(0), result);

        result = 'C';
        Interface.reportResult(&result); // no index
        QCOMPARE(f.resultAt(2), result);

        Interface.reportFinished();

        QCOMPARE(f.results(), QList<QChar>() << 'A' << 'B' << 'C');
    }

    {
        // Test result reporting with a missing result in the middle
        QFutureInterface<int> Interface;
        Interface.reportStarted();
        QFuture<int> f = Interface.future();
        int result;

        result = 0;
        Interface.reportResult(&result, 0);
        QVERIFY(f.isResultReadyAt(0));
        QCOMPARE(f.resultAt(0), 0);

        result = 3;
        Interface.reportResult(&result, 3);
        QVERIFY(f.isResultReadyAt(3));
        QCOMPARE(f.resultAt(3), 3);

        result = 2;
        Interface.reportResult(&result, 2);
        QVERIFY(f.isResultReadyAt(2));
        QCOMPARE(f.resultAt(2), 2);

        result = 4;
        Interface.reportResult(&result); // no index
        QVERIFY(f.isResultReadyAt(4));
        QCOMPARE(f.resultAt(4), 4);

        Interface.reportFinished();

        QCOMPARE(f.results(), QList<int>() << 0 << 2 << 3 << 4);
    }
}
예제 #10
0
void tst_QFuture::cancel()
{
    {
        QFuture<void> f;
        QFutureInterface<void> result;

        result.reportStarted();
        f = result.future();
        QVERIFY(!f.isCanceled());
        result.reportCanceled();
        QVERIFY(f.isCanceled());
        result.reportFinished();
        QVERIFY(f.isCanceled());
        f.waitForFinished();
        QVERIFY(f.isCanceled());
    }

    // Cancel from the QFuture side and test if the result
    // interface detects it.
    {
        QFutureInterface<void> result;

        QFuture<void> f;
        QVERIFY(f.isStarted());

        result.reportStarted();
        f = result.future();

        QVERIFY(f.isStarted());

        QVERIFY(!result.isCanceled());
        f.cancel();

        QVERIFY(result.isCanceled());

        result.reportFinished();
    }

    // Test that finished futures can be canceled.
    {
        QFutureInterface<void> result;

        QFuture<void> f;
        QVERIFY(f.isStarted());

        result.reportStarted();
        f = result.future();

        QVERIFY(f.isStarted());

        result.reportFinished();

        f.cancel();

        QVERIFY(result.isCanceled());
        QVERIFY(f.isCanceled());
    }

    // Results reported after canceled is called should not be propagated.
    {

        QFutureInterface<int> futureInterface;
        futureInterface.reportStarted();
        QFuture<int> f = futureInterface.future();

        int result = 0;
        futureInterface.reportResult(&result);
        result = 1;
        futureInterface.reportResult(&result);
        f.cancel();
        result = 2;
        futureInterface.reportResult(&result);
        result = 3;
        futureInterface.reportResult(&result);
        futureInterface.reportFinished();
        QCOMPARE(f.results(), QList<int>());
    }
}
예제 #11
0
파일: bci.cpp 프로젝트: Lx37/mne-cpp
void BCI::run()
{
    while(m_bIsRunning)
    {
        // Wait for fiff Info if not yet received - this is needed because we have to wait until the buffers are firstly initiated in the update functions
        while(!m_pFiffInfo_Sensor)
            msleep(10);

        // Start filling buffers with data from the inputs
        m_bProcessData = true;

        // Sensor level: Fill matrices with data
        if(m_bFillSensorWindowFirstTime) // Sensor level: Fill m_matSlidingWindowSensor with data for the first time
        {
            if(m_iTBWIndexSensor < m_matSlidingWindowSensor.cols())
            {
                //cout<<"About to pop matrix"<<endl;
                MatrixXd t_mat = m_pBCIBuffer_Sensor->pop();
                //cout<<"poped matrix"<<endl;

                // Get only the rows from the matrix which correspond with the selected features, namely electrodes on sensor level and destrieux clustered regions on source level
                for(int i = 0; i < m_matSlidingWindowSensor.rows(); i++)
                    m_matSlidingWindowSensor.block(i, m_iTBWIndexSensor, 1, t_mat.cols()) = t_mat.block(m_mapElectrodePinningScheme[m_slChosenFeatureSensor.at(i)], 0, 1, t_mat.cols());

                m_matStimChannelSensor.block(0, m_iTBWIndexSensor, 1, t_mat.cols()) = t_mat.block(136, 0, 1, t_mat.cols());

                m_iTBWIndexSensor = m_iTBWIndexSensor + t_mat.cols();
            }
            else // m_matSlidingWindowSensor is full for the first time
            {
                m_iTBWIndexSensor = 0;
                m_bFillSensorWindowFirstTime = false;
            }
        }
        else // Sensor level: Fill m_matTimeBetweenWindowsSensor matrix until full -> Then -> recalculate m_matSlidingWindowSensor, calculate features and classify
        {
            if(m_iTBWIndexSensor < m_matTimeBetweenWindowsSensor.cols())
            {
                //cout<<"About to pop matrix"<<endl;
                MatrixXd t_mat = m_pBCIBuffer_Sensor->pop();
                //cout<<"poped matrix"<<endl;

                // Get only the rows from the matrix which correspond with the selected features, namely electrodes on sensor level and destrieux clustered regions on source level
                for(int i = 0; i < m_matTimeBetweenWindowsSensor.rows(); i++)
                    m_matTimeBetweenWindowsSensor.block(i, m_iTBWIndexSensor, 1, t_mat.cols()) = t_mat.block(m_mapElectrodePinningScheme[m_slChosenFeatureSensor.at(i)], 0, 1, t_mat.cols());

                m_matTimeBetweenWindowsStimSensor.block(0, m_iTBWIndexSensor, 1, t_mat.cols()) = t_mat.block(136, 0, 1, t_mat.cols());

                m_iTBWIndexSensor = m_iTBWIndexSensor + t_mat.cols();
            }
            else // Recalculate m_matSlidingWindowSensor -> Calculate features, classify and store results
            {
                // ----1---- Recalculate m_matSlidingWindowSensor
                //cout<<"----1----"<<endl;
                //Move block from the right to the left -> use eval() to resolve Eigens aliasing problem
                m_matSlidingWindowSensor.block(0, 0, m_matSlidingWindowSensor.rows(), m_matSlidingWindowSensor.cols()-m_matTimeBetweenWindowsSensor.cols()) = m_matSlidingWindowSensor.block(0, m_matTimeBetweenWindowsSensor.cols(), m_matSlidingWindowSensor.rows(), m_matSlidingWindowSensor.cols()-m_matTimeBetweenWindowsSensor.cols()).eval();
                m_matStimChannelSensor.block(0, 0, m_matStimChannelSensor.rows(), m_matStimChannelSensor.cols()-m_matTimeBetweenWindowsStimSensor.cols()) = m_matStimChannelSensor.block(0, m_matTimeBetweenWindowsStimSensor.cols(), m_matStimChannelSensor.rows(), m_matStimChannelSensor.cols()-m_matTimeBetweenWindowsStimSensor.cols()).eval();

                // push m_matTimeBetweenWindowsSensor from the right
                m_matSlidingWindowSensor.block(0, m_matSlidingWindowSensor.cols()-m_matTimeBetweenWindowsSensor.cols(), m_matTimeBetweenWindowsSensor.rows(), m_matTimeBetweenWindowsSensor.cols()) = m_matTimeBetweenWindowsSensor;
                m_matStimChannelSensor.block(0, m_matStimChannelSensor.cols()-m_matTimeBetweenWindowsStimSensor.cols(), m_matTimeBetweenWindowsStimSensor.rows(), m_matTimeBetweenWindowsStimSensor.cols()) = m_matTimeBetweenWindowsStimSensor;

                //cout<<m_matStimChannelSensor;

                // Test if data is correctly streamed to this plugin
                if(m_slChosenFeatureSensor.contains("TEST"))
                {
                    cout<<"Recalculate matrix"<<endl;

                    for(int i = 0; i<m_matSlidingWindowSensor.cols() ; i++)
                        cout << m_matSlidingWindowSensor(m_matSlidingWindowSensor.rows()-1,i) <<endl;

//                    for(int i = 1; i<m_matSlidingWindowSensor.cols() ; i++)
//                    {
//                        cout << m_matSlidingWindowSensor(m_matSlidingWindowSensor.rows()-1,i-1) <<endl;
//                        if(m_matSlidingWindowSensor(m_matSlidingWindowSensor.rows()-1,i) - m_matSlidingWindowSensor(m_matSlidingWindowSensor.rows()-1,i-1) != 1)
//                            cout<<"Sequence error while streaming from tmsi plugin at position: "<<i<<endl;
//                    }
                }

                // ----2---- Transform matrix into QList structure, so that QTConcurrent can handle it properly
                //cout<<"----2----"<<endl;
                QList< QPair<int,RowVectorXd> > qlMatrixRows;
                for(int i = 0; i< m_matSlidingWindowSensor.rows(); i++)
                    qlMatrixRows << QPair<int,RowVectorXd>(i, m_matSlidingWindowSensor.row(i));

                int iNumberOfFeatures = qlMatrixRows.size();

                // ----3---- Subtract mean in m_matSlidingWindowSensor concurrently using map()
                //cout<<"----3----"<<endl;
                if(m_bSubtractMean)
                {
                    QFuture<void> futureMean = QtConcurrent::map(qlMatrixRows,[this](QPair<int,RowVectorXd>& rowdata) {
                        applyMeanCorrectionConcurrently(rowdata);
                    });

                    futureMean.waitForFinished();
                }           

                // ----4---- Do simple threshold artefact reduction
                //cout<<"----4----"<<endl;
                if(hasThresholdArtefact(qlMatrixRows) == false)
                {
                    // Look for trigger flag
                    if(lookForTrigger(m_matStimChannelSensor) && !m_bTriggerActivated)
                    {
                        // cout << "Trigger activated" << endl;
                        //QFuture<void> future = QtConcurrent::run(Beep, 450, 700);
                        m_bTriggerActivated = true;
                    }

                    // ----5---- Filter data in m_matSlidingWindowSensor concurrently using map()
                    //cout<<"----5----"<<endl;
                    // TODO: work only on qlMatrixRows -> filteredRows doesnt need to be created -> more efficient
                    QList< QPair<int,RowVectorXd> > filteredRows = qlMatrixRows;

                    if(m_bUseFilter)
                    {
                        QFuture<void> futureFilter = QtConcurrent::map(filteredRows,[this](QPair<int,RowVectorXd>& chdata) {
                            applyFilterOperatorConcurrently(chdata);
                        });

                        futureFilter.waitForFinished();
                    }

//                    // Write data before and after filtering to debug file
//                    for(int i=0; i<qlMatrixRows.size(); i++)
//                        m_outStreamDebug << "qlMatrixRows at row " << i << ": " << qlMatrixRows.at(i).second << "\n";

//                    m_outStreamDebug<<endl;

//                    for(int i=0; i<filteredRows.size(); i++)
//                        m_outStreamDebug << "filteredRows at row " << i << ": " << filteredRows.at(i).second << "\n";

//                    m_outStreamDebug << endl << "---------------------------------------------------------" << endl << endl;

//                    // Write filtered data continously to file
//                    for(int i = 0; i<filteredRows.at(0).second.size() ;i++)
//                        m_outStreamDebug << filteredRows.at(0).second(i)<<endl;

                    // ----6---- Calculate features concurrently using mapped()
                    //cout<<"----6----"<<endl;
                    std::function< QPair<int,QList<double> > (QPair<int,RowVectorXd>&)> applyOpsFeatures = [this](QPair<int,RowVectorXd>& chdata) -> QPair< int,QList<double> > {
                        return applyFeatureCalcConcurrentlyOnSensorLevel(chdata);
                    };

                    QFuture< QPair< int,QList<double> > > futureCalculatedFeatures = QtConcurrent::mapped(filteredRows.begin(), filteredRows.end(), applyOpsFeatures);

                    futureCalculatedFeatures.waitForFinished();

                    m_iNumberOfCalculatedFeatures++;

                    // ----7---- Store features
                    //cout<<"----7----"<<endl;
                    m_lFeaturesSensor.append(futureCalculatedFeatures.results());

                    // ----8---- If enough features (windows) have been calculated (processed) -> classify all features and average results
                    //cout<<"----8----"<<endl;
                    if(m_iNumberOfCalculatedFeatures == m_iNumberFeatures)
                    {
                        // Transform m_lFeaturesSensor into an easier file structure -> create feature points
                        QList< QList<double> > lFeaturesSensor_new;

                        for(int i = 0; i<m_lFeaturesSensor.size()-iNumberOfFeatures+1; i = i + iNumberOfFeatures) // iterate over QPair feature List
                            for(int z = 0; z<m_lFeaturesSensor.at(0).second.size(); z++) // iterate over number of sub signals
                            {
                                QList<double> temp;
                                for(int t = 0; t<iNumberOfFeatures; t++) // iterate over chosen features (electrodes)
                                    temp.append(m_lFeaturesSensor.at(i+t).second.at(z));
                                lFeaturesSensor_new.append(temp);
                            }

//                        //Check sizes
//                        cout<<"lFeaturesSensor_new.size()"<<lFeaturesSensor_new.size()<<endl;
//                        cout<<"lFeaturesSensor_new.at(0).size()"<<lFeaturesSensor_new.at(0).size()<<endl;
//                        cout<<"m_lFeaturesSensor.size()"<<m_lFeaturesSensor.size()<<endl;

                        // Display features
                        if(m_bDisplayFeatures)
                            emit paintFeatures((MyQList)lFeaturesSensor_new, m_bTriggerActivated);

                        // Reset trigger
                        m_bTriggerActivated = false;

                        // ----9---- Classify features concurrently using mapped() ----------
                        //cout<<"----9----"<<endl;

                        std::function<double (QList<double>&)> applyOpsClassification = [this](QList<double>& featData){
                            return applyClassificationCalcConcurrentlyOnSensorLevel(featData);
                        };

                        QFuture<double> futureClassificationResults = QtConcurrent::mapped(lFeaturesSensor_new.begin(), lFeaturesSensor_new.end(), applyOpsClassification);

                        futureClassificationResults.waitForFinished();

                        // ----10---- Generate final classification result -> average all classification results
                        //cout<<"----10----"<<endl;
                        double dfinalResult = 0;

                        for(int i = 0; i<futureClassificationResults.resultCount() ;i++)
                            dfinalResult += futureClassificationResults.resultAt(i);

                        dfinalResult = dfinalResult/futureClassificationResults.resultCount();
                        //cout << "dfinalResult" << dfinalResult << endl << endl;

                        // ----11---- Store final result
                        //cout<<"----11----"<<endl;
                        m_lClassResultsSensor.append(dfinalResult);

                        // ----12---- Send result to the output stream, i.e. which is connected to the triggerbox
                        //cout<<"----12----"<<endl;
                        VectorXd variances(iNumberOfFeatures);
                        variances.setZero();

                        for(int i = 0; i<lFeaturesSensor_new.size(); i++)
                            for(int t = 0; t<iNumberOfFeatures; t++)
                                variances(t) = variances(t) + lFeaturesSensor_new.at(i).at(t);

                        variances = variances/lFeaturesSensor_new.size();

                        m_pBCIOutputOne->data()->setValue(dfinalResult);
                        m_pBCIOutputTwo->data()->setValue(variances(0));
                        m_pBCIOutputThree->data()->setValue(variances(1));

                        for(int i = 0; i<filteredRows.at(0).second.cols() ; i++)
                        {
                            m_pBCIOutputFour->data()->setValue(filteredRows.at(0).second(0,i));
                            m_pBCIOutputFive->data()->setValue(filteredRows.at(1).second(0,i));
                        }

                        // Clear classifications
                        clearFeatures();

                        // Reset counter
                        m_iNumberOfCalculatedFeatures = 0;
                    } // End if enough features (windows) have been calculated (processed)
                } // End if artefact reduction
                else
                {
                    // If trial has been rejected -> plot zeros as result and the filtered electrode channel
                    m_pBCIOutputOne->data()->setValue(0);
                    m_pBCIOutputTwo->data()->setValue(0);
                    m_pBCIOutputThree->data()->setValue(0);

                    QList< QPair<int,RowVectorXd> > filteredRows = qlMatrixRows;

                    if(m_bUseFilter)
                    {
                        QFuture<void> futureFilter = QtConcurrent::map(filteredRows,[this](QPair<int,RowVectorXd>& chdata) {
                            applyFilterOperatorConcurrently(chdata);
                        });

                        futureFilter.waitForFinished();
                    }

                    for(int i = 0; i<filteredRows.at(0).second.cols() ; i++)
                    {
                        m_pBCIOutputFour->data()->setValue(filteredRows.at(0).second(0,i));
                        m_pBCIOutputFive->data()->setValue(filteredRows.at(1).second(0,i));
                    }
                }

                m_iTBWIndexSensor = 0;
            }
        }
    }
}