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();
}
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();
}
예제 #3
0
void SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd(
        SyntaxHighlighter *highlighter,
        const QFuture<HighlightingResult> &future)
{
    // find block number of last result
    int lastBlockNumber = 0;
    for (int i = future.resultCount() - 1; i >= 0; --i) {
        const HighlightingResult &result = future.resultAt(i);
        if (result.line) {
            lastBlockNumber = result.line - 1;
            break;
        }
    }

    QTextDocument *doc = highlighter->document();

    const int firstBlockToClear = lastBlockNumber + 1;
    if (firstBlockToClear <= doc->blockCount())
        return;

    QTextBlock b = doc->findBlockByNumber(firstBlockToClear);

    while (b.isValid()) {
        QVector<QTextLayout::FormatRange> noFormats;
        highlighter->setExtraFormats(b, noFormats);
        b = b.next();
    }
}
예제 #4
0
/*
    Test that results reported after finished are ignored.
*/
void tst_QFuture::resultsAfterFinished()
{
    {
        IntResult a;
        a.reportStarted();
        QFuture<int> f =  a.future();
        int result;

        QCOMPARE(f.resultCount(), 0);

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

        a.reportFinished();

        QCOMPARE(f.resultAt(0), 1);
        QCOMPARE(f.resultCount(), 1);
        result = 2;
        a.reportResult(&result);
        QCOMPARE(f.resultCount(), 1);
    }
    // cancel it
    {
        IntResult a;
        a.reportStarted();
        QFuture<int> f =  a.future();
        int result;

        QCOMPARE(f.resultCount(), 0);

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

        a.reportCanceled();

        QCOMPARE(f.resultAt(0), 1);
        QCOMPARE(f.resultCount(), 1);

        result = 2;
        a.reportResult(&result);
        a.reportFinished();
    }
}
예제 #5
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);
    }
}
예제 #6
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);
    }
}
예제 #7
0
void tst_QFuture::futureInterface()
{
    {
        QFuture<void> future;
        {
            QFutureInterface<void> i;
            i.reportStarted();
            future = i.future();
            i.reportFinished();
        }
    }
    {
        QFuture<int> future;
        {
            QFutureInterface<int> i;
            i.reportStarted();
            i.reportResult(10);
            future = i.future();
            i.reportFinished();
        }
        QCOMPARE(future.resultAt(0), 10);
    }

    {
        QFuture<int> intFuture;

        QCOMPARE(intFuture.isStarted(), true);
        QCOMPARE(intFuture.isFinished(), true);

        IntResult result;

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

        QCOMPARE(intFuture.isStarted(), true);
        QCOMPARE(intFuture.isFinished(), false);

        result.reportFinished(&value);

        QCOMPARE(intFuture.isStarted(), true);
        QCOMPARE(intFuture.isFinished(), true);

        int e = intFuture.result();

        QCOMPARE(intFuture.isStarted(), true);
        QCOMPARE(intFuture.isFinished(), true);
        QCOMPARE(intFuture.isCanceled(), false);

        QCOMPARE(e, value);
        intFuture.waitForFinished();

        IntResult intAlgo;
        intFuture = intAlgo.run();
        QFuture<int> intFuture2(intFuture);
        QCOMPARE(intFuture.result(), value);
        QCOMPARE(intFuture2.result(), value);
        intFuture.waitForFinished();

        VoidResult a;
        a.run().waitForFinished();
    }
}
예제 #8
0
void SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
        SyntaxHighlighter *highlighter,
        const QFuture<HighlightingResult> &future,
        int from, int to,
        const QHash<int, QTextCharFormat> &kindToFormat)
{
    if (to <= from)
        return;

    const int firstResultBlockNumber = future.resultAt(from).line - 1;

    // blocks between currentBlockNumber and the last block with results will
    // be cleaned of additional extra formats if they have no results
    int currentBlockNumber = 0;
    for (int i = from - 1; i >= 0; --i) {
        const HighlightingResult &result = future.resultAt(i);
        const int blockNumber = result.line - 1;
        if (blockNumber < firstResultBlockNumber) {
            // stop! found where last format stopped
            currentBlockNumber = blockNumber + 1;
            // add previous results for the same line to avoid undoing their formats
            from = i + 1;
            break;
        }
    }

    QTextDocument *doc = highlighter->document();
    QTC_ASSERT(currentBlockNumber < doc->blockCount(), return);
    QTextBlock b = doc->findBlockByNumber(currentBlockNumber);

    HighlightingResult result = future.resultAt(from);
    for (int i = from; i < to && b.isValid(); ) {
        const int blockNumber = result.line - 1;
        QTC_ASSERT(blockNumber < doc->blockCount(), return);

        // clear formats of blocks until blockNumber
        while (currentBlockNumber < blockNumber) {
            QVector<QTextLayout::FormatRange> noFormats;
            highlighter->setExtraFormats(b, noFormats);
            b = b.next();
            ++currentBlockNumber;
        }

        // collect all the formats for the current line
        QVector<QTextLayout::FormatRange> formats;
        formats.reserve(to - from);
        forever {
            QTextLayout::FormatRange formatRange;

            formatRange.format = textCharFormatForResult(result, kindToFormat);
            if (formatRange.format.isValid()) {
                formatRange.start = result.column - 1;
                formatRange.length = result.length;
                formats.append(formatRange);
            }

            ++i;
            if (i >= to)
                break;
            result = future.resultAt(i);
            const int nextBlockNumber = result.line - 1;
            if (nextBlockNumber != blockNumber)
                break;
        }
        highlighter->setExtraFormats(b, formats);
        b = b.next();
        ++currentBlockNumber;
    }
}
예제 #9
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;
            }
        }
    }
}