Qt C++ 数据预处理笔记(2)——一阶差分

多线程,一阶差分,减少数据相关性。

#include "DiffWorker.h"

#include <QThread>

#include <QFileInfo>
#include <QDir>

DiffWorker::DiffWorker(QString oStrDir, int iRow, QString oStrFileName, qint64 iTimestampStart, qint64 iTimestampEnd, QObject* parent)
    : QObject{parent}, oStrDir(oStrDir), iRow(iRow), oStrFileName(oStrFileName), iTimestampStart(iTimestampStart), iTimestampEnd(iTimestampEnd)
{
    this->setAutoDelete(true);

    oHead = PF::readHead(oStrFileName);
}

void DiffWorker::run()
{
    qDebugV0() << "Time Domain Work: " << QThread::currentThread();

    QElapsedTimer time;
    time.start();

    QFile oFileRaw(oStrFileName);//原始文件

    if( !oFileRaw.open(QIODevice::ReadOnly) )
    {
        emit sigMsg("一阶差分操作时,打开原始文件失败!  " + oStrFileName);
        return;
    }

    //获取新的文件名,梳妆滤波后的文件
    QString oStrHead = PF::readHeadString(oStrFileName);

    QStringList aoStrHead = oStrHead.split(',', Qt::KeepEmptyParts);

    aoStrHead.replace(RAW_HEADER_DATA_CNT, QString::number(oHead.uiFS * (iTimestampEnd - iTimestampStart)));

    aoStrHead.replace(RAW_HEADER_START_TIME, QString::number(iTimestampStart));
    aoStrHead.replace(RAW_HEADER_SAMP_TIME, QString::number(iTimestampEnd - iTimestampStart));

    QString oStrHeadNew = aoStrHead.join(",");

    int iIndexStart = oStrFileName.lastIndexOf("_");
    int iIndexEnd = oStrFileName.lastIndexOf(".");

    QString oStrIndex = oStrFileName.mid(iIndexStart + 1, iIndexEnd - iIndexStart - 1);

    QString oStrBaseName = QString("%1_L(%2)_S(%3)_D(%4)_CH%5_%6_%7_%8.dat")
                           .arg(oHead.oStrTaskName)
                           .arg(oHead.oStrLine)
                           .arg(oHead.oStrSite)
                           .arg(oHead.uiDev)
                           .arg(oHead.uiCh)
                           .arg(oHead.oStrRAW_COMPONENT)
                           .arg(QDateTime::fromSecsSinceEpoch(iTimestampStart).toString("yyyyMMddHHmmss"))
                           .arg(oStrIndex);

    QString oStrFileNameNew = oStrDir + QDir::separator() + oStrBaseName;

    qDebugV0() << oStrFileNameNew;

    //结果文件
    QFile oFileNew(oStrFileNameNew);
    if( !oFileNew.open(QIODevice::WriteOnly | QIODevice::Truncate) )
    {
        emit sigMsg("一阶差分操作时,创建结果文件失败!  " + oStrFileNameNew);
        return;
    }

    oFileNew.write(oStrHeadNew.toUtf8(), LENGTH_178_BYTE);

    QDataStream oStreamNew(&oFileNew);
    oStreamNew.setByteOrder(QDataStream::BigEndian);
    oStreamNew.setFloatingPointPrecision(QDataStream::SinglePrecision);

    QDataStream oStreamRaw(&oFileRaw);
    oStreamRaw.setByteOrder(QDataStream::BigEndian);
    oStreamRaw.setFloatingPointPrecision(QDataStream::SinglePrecision);

    oStreamRaw.skipRawData(LENGTH_178_BYTE);

    for(int i = 0; i < (iTimestampStart - oHead.iStartTimestamp); ++i)
    {
        oStreamRaw.skipRawData(LENGTH_4_BYTE * oHead.uiFS);
    }

    quint32 uiPercentage = PROGRESS_STEP;

    oStreamRaw.startTransaction();
    oStreamNew.startTransaction();

    qDebugV0() << oHead.uiFS << iTimestampEnd << iTimestampStart;

    for(qint64 i = 0; i < (iTimestampEnd - iTimestampStart); ++i)
    {
        for(qint64 j = 0; j < oHead.uiFS; ++j )
        {
            oStreamRaw >> fValueCurr;

            fValueRst = fValueCurr - fValuePrev;

            oStreamNew << fValueRst;

            fValuePrev = fValueCurr; //计算完毕后,将当前值 存做上一个值,供下一步计算
        }

        float fProgress = ((float)i / ((float)(iTimestampEnd - iTimestampStart))) * 100;//这样就是一秒来验算一次,满足跨度就可以emit 出去了。

        if(fProgress >= uiPercentage)
        {
            emit sigProgress(iRow, "一阶差分~ ", fProgress);

            uiPercentage = uiPercentage + PROGRESS_STEP;
        }
    }

    oStreamRaw.commitTransaction();
    oFileRaw.close();

    oStreamNew.commitTransaction();
    oFileNew.flush();
    oFileNew.close();

    emit sigProgress(iRow, "一阶差分完毕!", 100.00f);

    qint64 milsec = time.elapsed();

    emit sigMsg(QString("行号:%1\t处理采样点数:%2\t耗时:%3s\t一阶差分")
                .arg(iRow + 1)
                .arg(oHead.uiFS * (iTimestampEnd - iTimestampStart))
                .arg(QString::number(milsec / 1000.00, 'f', 3)));
}
#ifndef DIFFWORKER_H
#define DIFFWORKER_H

#include "PF.h"
#include <QObject>
#include <QRunnable>

class DiffWorker : public QObject, public QRunnable
{
    Q_OBJECT
public:
    explicit DiffWorker(QString oStrDir, int iRow, QString oStrFileName, qint64 iTimestampStart, qint64 iTimestampEnd, QObject* parent = nullptr);

    void run() override;

signals:
    void sigMsg(QString);

    void sigProgress(int, QString, float);

private:
    QString oStrDir;//存储目录

    int iRow;//来源于主界面TableWidget 上的行号

    QString oStrFileName;

    qint64 iTimestampStart;
    qint64 iTimestampEnd;

    HEAD oHead;


    float fValuePrev = 0.00f;//上一个数值

    float fValueCurr = 0.00f;//当前值

    float fValueRst  = 0.00f;//结果值
};

#endif // DIFFWORKER_H
//Diff 
void MainWindow::on_pushButtonDiff_clicked()
{
    QList<int> aiRow = PF::getSelectedRows(ui->tableWidget);

    if(aiRow.isEmpty())
    {
        return;
    }

    //选结果存放目录
    QString oStrPath = poSet->value("PATH_SAVE").toString();

    if(oStrPath.isEmpty())
    {
        oStrPath = QCoreApplication::applicationDirPath();
    }

    QString oStrDir = QFileDialog::getExistingDirectory(this, tr("选择一阶差分结果保存目录!"), oStrPath, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);

    if(!oStrDir.isEmpty())
    {
        poSet->setValue("PATH_SAVE", oStrDir);
    }
    else
    {
        this->recvMsg("请选保存目录!");

        QMessageBox::warning(nullptr, "警告", "请选保存目录!");
        return;
    }

    for(int i : aiRow)
    {
        QString oStrFileName = ui->tableWidget->item(aiRow.at(i), TABLE_HEADER_FILE_NAME)->data(Qt::DisplayRole).toString();

        qint64 iTimestampStart = ((QDateTimeEdit*)ui->tableWidget->cellWidget(aiRow.at(i), TABLE_HEADER_START_TIME))->dateTime().toSecsSinceEpoch();
        qint64 iTimestampEnd   = ((QDateTimeEdit*)ui->tableWidget->cellWidget(aiRow.at(i), TABLE_HEADER_END_TIME  ))->dateTime().toSecsSinceEpoch();

        DiffWorker* poWorker = new DiffWorker(oStrDir, i, oStrFileName, iTimestampStart, iTimestampEnd);
        poWorker->setParent(nullptr);
        connect(poWorker, &DiffWorker::sigProgress, this, &MainWindow::recvProgress);
        connect(poWorker, &DiffWorker::sigMsg,      this, &MainWindow::recvMsg);

        QThreadPool::globalInstance()->start(poWorker);
    }
}

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值