多线程,一阶差分,减少数据相关性。
#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);
}
}