Merge branch 'dev' of http://git.hivekion.com:3000/xuhai_cpp/EnergySpectrumAnalyer into dev_xuh
This commit is contained in:
commit
68c2207110
|
|
@ -69,6 +69,7 @@ void EnergyScaleForm::SetAnalyzeDataFilename(const QMap<QString, QVariant> &data
|
||||||
QString baseName =QString("[%1]%2").arg(dir.dirName()).arg(fileInfo.baseName());
|
QString baseName =QString("[%1]%2").arg(dir.dirName()).arg(fileInfo.baseName());
|
||||||
ui->lineEdit_name->setText(baseName);
|
ui->lineEdit_name->setText(baseName);
|
||||||
ui->lineEdit_name->setReadOnly(true);
|
ui->lineEdit_name->setReadOnly(true);
|
||||||
|
ui->groupBox_2->hide();
|
||||||
ui->pBtn_SaveAs->setText(QStringLiteral(u"保存到系统"));
|
ui->pBtn_SaveAs->setText(QStringLiteral(u"保存到系统"));
|
||||||
m_currentFilePath = data_filename;
|
m_currentFilePath = data_filename;
|
||||||
QString errorMsg;
|
QString errorMsg;
|
||||||
|
|
@ -970,7 +971,7 @@ void EnergyScaleForm::on_pBtn_SaveAs_clicked()
|
||||||
systemEnble = false;
|
systemEnble = false;
|
||||||
// 选择保存路径
|
// 选择保存路径
|
||||||
QString defaultDir = QDir(qApp->applicationDirPath()).filePath("configure/EnergyScale");
|
QString defaultDir = QDir(qApp->applicationDirPath()).filePath("configure/EnergyScale");
|
||||||
QString targetFilePath = QFileDialog::getSaveFileName(this,
|
targetFilePath = QFileDialog::getSaveFileName(this,
|
||||||
"另存为能量刻度文件",
|
"另存为能量刻度文件",
|
||||||
defaultDir,
|
defaultDir,
|
||||||
"JSON文件 (*.json);;所有文件 (*.*)");
|
"JSON文件 (*.json);;所有文件 (*.*)");
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QDoubleSpinBox>
|
#include <QDoubleSpinBox>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QList>
|
||||||
#include "DeviceParamsSaveToSysDlg.h"
|
#include "DeviceParamsSaveToSysDlg.h"
|
||||||
|
|
||||||
static QStringList s_addr_count_list { "256", "512", "1024", "2048", "4096", "8192", "16384" };
|
static QStringList s_addr_count_list { "256", "512", "1024", "2048", "4096", "8192", "16384" };
|
||||||
|
|
@ -386,12 +387,17 @@ void DeviceParamsTableForm::onCfgChannelSelectBtnClicked()
|
||||||
int num_columns = std::sqrt(32);
|
int num_columns = std::sqrt(32);
|
||||||
if (num_columns == 0)
|
if (num_columns == 0)
|
||||||
num_columns = 1;
|
num_columns = 1;
|
||||||
|
|
||||||
|
QList<QCheckBox*> all_checkboxes;
|
||||||
|
|
||||||
QVBoxLayout* checkbox_layout = new QVBoxLayout();
|
QVBoxLayout* checkbox_layout = new QVBoxLayout();
|
||||||
QHBoxLayout* checkbox_column_layout = new QHBoxLayout();
|
QHBoxLayout* checkbox_column_layout = new QHBoxLayout();
|
||||||
for (int row = 0; row < 32; ++row) {
|
for (int row = 0; row < 32; ++row) {
|
||||||
QCheckBox* check_box = new QCheckBox(QStringLiteral(u"通道%1").arg(row + 1));
|
QCheckBox* check_box = new QCheckBox(QStringLiteral(u"通道%1").arg(row + 1));
|
||||||
check_box->setChecked(!ui->params_cfg_table->isRowHidden(row));
|
check_box->setChecked(!ui->params_cfg_table->isRowHidden(row));
|
||||||
checkbox_column_layout->addWidget(check_box);
|
checkbox_column_layout->addWidget(check_box);
|
||||||
|
all_checkboxes.append(check_box);
|
||||||
|
|
||||||
connect(check_box, &QCheckBox::stateChanged, [this, row](int state) {
|
connect(check_box, &QCheckBox::stateChanged, [this, row](int state) {
|
||||||
ui->params_cfg_table->setRowHidden(row, state == Qt::Unchecked);
|
ui->params_cfg_table->setRowHidden(row, state == Qt::Unchecked);
|
||||||
});
|
});
|
||||||
|
|
@ -407,16 +413,18 @@ void DeviceParamsTableForm::onCfgChannelSelectBtnClicked()
|
||||||
// 全选和反选
|
// 全选和反选
|
||||||
QHBoxLayout* button_layout = new QHBoxLayout();
|
QHBoxLayout* button_layout = new QHBoxLayout();
|
||||||
QPushButton* btn_all_select = new QPushButton(QString(QStringLiteral(u"全选")));
|
QPushButton* btn_all_select = new QPushButton(QString(QStringLiteral(u"全选")));
|
||||||
connect(btn_all_select, &QPushButton::clicked, [this]() {
|
connect(btn_all_select, &QPushButton::clicked, [this, all_checkboxes]() {
|
||||||
for (int row = 0; row < 32; ++row) {
|
for (int row = 0; row < 32; ++row) {
|
||||||
ui->params_cfg_table->setRowHidden(row, true);
|
ui->params_cfg_table->setRowHidden(row, false);
|
||||||
|
all_checkboxes[row]->setChecked(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
button_layout->addWidget(btn_all_select);
|
button_layout->addWidget(btn_all_select);
|
||||||
QPushButton* btn_reserve_select = new QPushButton(QString(QStringLiteral(u"反选")));
|
QPushButton* btn_reserve_select = new QPushButton(QString(QStringLiteral(u"反选")));
|
||||||
connect(btn_reserve_select, &QPushButton::clicked, [this]() {
|
connect(btn_reserve_select, &QPushButton::clicked, [this, all_checkboxes]() {
|
||||||
for (int row = 0; row < 32; ++row) {
|
for (int row = 0; row < 32; ++row) {
|
||||||
ui->params_cfg_table->setRowHidden(row, !ui->params_cfg_table->isRowHidden(row));
|
ui->params_cfg_table->setRowHidden(row, !ui->params_cfg_table->isRowHidden(row));
|
||||||
|
all_checkboxes[row]->setChecked(!all_checkboxes[row]->isChecked());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
button_layout->addWidget(btn_reserve_select);
|
button_layout->addWidget(btn_reserve_select);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonValue>
|
||||||
#include "DataProcessWorkPool.h"
|
#include "DataProcessWorkPool.h"
|
||||||
#include "GlobalDefine.h"
|
#include "GlobalDefine.h"
|
||||||
NewMeasureAnalysisDlg::NewMeasureAnalysisDlg(QWidget *parent)
|
NewMeasureAnalysisDlg::NewMeasureAnalysisDlg(QWidget *parent)
|
||||||
|
|
@ -33,7 +36,9 @@ NewMeasureAnalysisDlg::~NewMeasureAnalysisDlg()
|
||||||
void NewMeasureAnalysisDlg::initialization()
|
void NewMeasureAnalysisDlg::initialization()
|
||||||
{
|
{
|
||||||
ui->progressBar->setVisible(false);
|
ui->progressBar->setVisible(false);
|
||||||
|
ui->comboBox_measure_param->addItem(QStringLiteral(u"无"));
|
||||||
|
ui->comboBox_energy_scale->addItem(QStringLiteral(u"无"));
|
||||||
|
ui->comboBox_efficiency_scale->addItem(QStringLiteral(u"无"));
|
||||||
QRegExp rx(R"(^[^\\/:*?"<>|]+$)");
|
QRegExp rx(R"(^[^\\/:*?"<>|]+$)");
|
||||||
QValidator *validator = new QRegExpValidator(rx, this);
|
QValidator *validator = new QRegExpValidator(rx, this);
|
||||||
ui->lineEdit_name->setValidator(validator);
|
ui->lineEdit_name->setValidator(validator);
|
||||||
|
|
@ -173,7 +178,8 @@ void NewMeasureAnalysisDlg::newProject(const QString& particle_data_filename)
|
||||||
QString project_energy_scale_filename = QDir(project_dir_path).filePath(QStringLiteral(u"能量刻度.json"));
|
QString project_energy_scale_filename = QDir(project_dir_path).filePath(QStringLiteral(u"能量刻度.json"));
|
||||||
QFileInfo energy_scale_file_info(energy_scale_filename);
|
QFileInfo energy_scale_file_info(energy_scale_filename);
|
||||||
if (energy_scale_file_info.exists()) {
|
if (energy_scale_file_info.exists()) {
|
||||||
QFile::copy(energy_scale_filename, project_energy_scale_filename);
|
readJsonAsSave(energy_scale_filename,project_energy_scale_filename);
|
||||||
|
// QFile::copy(energy_scale_filename, project_energy_scale_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_measure_complete = !particle_data_filename.isEmpty();
|
bool is_measure_complete = !particle_data_filename.isEmpty();
|
||||||
|
|
@ -346,3 +352,38 @@ void NewMeasureAnalysisDlg::startParticleSortTask(const QString& data_file_path,
|
||||||
separate_task->SetFinishedNotifier(this, "onNewProjectFromFileFinished", project_name);
|
separate_task->SetFinishedNotifier(this, "onNewProjectFromFileFinished", project_name);
|
||||||
separate_task->StartTask();
|
separate_task->StartTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NewMeasureAnalysisDlg::readJsonAsSave(QString sourceFile, QString targetFile)
|
||||||
|
{
|
||||||
|
QFile file(sourceFile);
|
||||||
|
|
||||||
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
qDebug() << "无法打开文件:" << sourceFile;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray jsonData = file.readAll();
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
QJsonParseError parseError;
|
||||||
|
QJsonDocument doc = QJsonDocument::fromJson(jsonData, &parseError);
|
||||||
|
|
||||||
|
if (parseError.error != QJsonParseError::NoError) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject rootObj = doc.object();
|
||||||
|
|
||||||
|
if (rootObj.contains("Remark")) {
|
||||||
|
rootObj.remove("Remark");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonDocument newDoc(rootObj);
|
||||||
|
|
||||||
|
QFile saveFile(targetFile);
|
||||||
|
if (saveFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||||
|
saveFile.write(newDoc.toJson(QJsonDocument::Indented));
|
||||||
|
saveFile.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ private:
|
||||||
void startParticleSortTask(const QString& data_file_path,
|
void startParticleSortTask(const QString& data_file_path,
|
||||||
const QString& project_name,
|
const QString& project_name,
|
||||||
const QString& project_dir_path);
|
const QString& project_dir_path);
|
||||||
|
void readJsonAsSave(QString sourceFile,QString targetFile);
|
||||||
private slots:
|
private slots:
|
||||||
void onNewProjectFromFileFinished(bool ok, const QString& project_name, const QVariant &data);
|
void onNewProjectFromFileFinished(bool ok, const QString& project_name, const QVariant &data);
|
||||||
void on_btn_ok_clicked();
|
void on_btn_ok_clicked();
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>550</width>
|
<width>631</width>
|
||||||
<height>278</height>
|
<height>314</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
|
|
||||||
14
src/RegionOfInterest/RegionOfInterest.cpp
Normal file
14
src/RegionOfInterest/RegionOfInterest.cpp
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include "RegionOfInterest.h"
|
||||||
|
#include "ui_RegionOfInterest.h"
|
||||||
|
|
||||||
|
RegionOfInterest::RegionOfInterest(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, ui(new Ui::RegionOfInterest)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionOfInterest::~RegionOfInterest()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
22
src/RegionOfInterest/RegionOfInterest.h
Normal file
22
src/RegionOfInterest/RegionOfInterest.h
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef REGIONOFINTEREST_H
|
||||||
|
#define REGIONOFINTEREST_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class RegionOfInterest;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RegionOfInterest : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit RegionOfInterest(QWidget *parent = nullptr);
|
||||||
|
~RegionOfInterest();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::RegionOfInterest *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // REGIONOFINTEREST_H
|
||||||
19
src/RegionOfInterest/RegionOfInterest.ui
Normal file
19
src/RegionOfInterest/RegionOfInterest.ui
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>RegionOfInterest</class>
|
||||||
|
<widget class="QWidget" name="RegionOfInterest">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>711</width>
|
||||||
|
<height>505</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
|
|
@ -38,7 +38,6 @@ QJsonObject ConformityHistoryItem::toJson() const
|
||||||
obj["secondaryEnergyStart"] = secondaryEnergyStart;
|
obj["secondaryEnergyStart"] = secondaryEnergyStart;
|
||||||
obj["secondaryEnergyEnd"] = secondaryEnergyEnd;
|
obj["secondaryEnergyEnd"] = secondaryEnergyEnd;
|
||||||
|
|
||||||
// ✅ 修复致命BUG:不再无限递归嵌套
|
|
||||||
QJsonArray boardChannelJson;
|
QJsonArray boardChannelJson;
|
||||||
for (int board = 0; board < MAX_BOARD; ++board) {
|
for (int board = 0; board < MAX_BOARD; ++board) {
|
||||||
QJsonArray channelJson;
|
QJsonArray channelJson;
|
||||||
|
|
@ -55,6 +54,24 @@ QJsonObject ConformityHistoryItem::toJson() const
|
||||||
}
|
}
|
||||||
obj["firstParticleData"] = firstParticleJson;
|
obj["firstParticleData"] = firstParticleJson;
|
||||||
|
|
||||||
|
QJsonArray matrixJson;
|
||||||
|
for (int pBoard = 0; pBoard < MAX_BOARD; ++pBoard) {
|
||||||
|
QJsonArray pChannelArray;
|
||||||
|
for (int pChannel = 0; pChannel < MAX_CHANNEL; ++pChannel) {
|
||||||
|
QJsonArray sBoardArray;
|
||||||
|
for (int sBoard = 0; sBoard < MAX_BOARD; ++sBoard) {
|
||||||
|
QJsonArray sChannelArray;
|
||||||
|
for (int sChannel = 0; sChannel < MAX_CHANNEL; ++sChannel) {
|
||||||
|
sChannelArray.append(coincidenceMatrix[pBoard][pChannel][sBoard][sChannel]);
|
||||||
|
}
|
||||||
|
sBoardArray.append(sChannelArray);
|
||||||
|
}
|
||||||
|
pChannelArray.append(sBoardArray);
|
||||||
|
}
|
||||||
|
matrixJson.append(pChannelArray);
|
||||||
|
}
|
||||||
|
obj["coincidenceMatrix"] = matrixJson;
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,6 +87,7 @@ ConformityHistoryItem ConformityHistoryItem::fromJson(const QJsonObject& obj)
|
||||||
item.secondaryEnergyStart = obj["secondaryEnergyStart"].toDouble();
|
item.secondaryEnergyStart = obj["secondaryEnergyStart"].toDouble();
|
||||||
item.secondaryEnergyEnd = obj["secondaryEnergyEnd"].toDouble();
|
item.secondaryEnergyEnd = obj["secondaryEnergyEnd"].toDouble();
|
||||||
|
|
||||||
|
// 板卡通道数据
|
||||||
memset(item.boardChannelData, 0, sizeof(item.boardChannelData));
|
memset(item.boardChannelData, 0, sizeof(item.boardChannelData));
|
||||||
QJsonArray boardChannelJson = obj["boardChannelData"].toArray();
|
QJsonArray boardChannelJson = obj["boardChannelData"].toArray();
|
||||||
for (int board = 0; board < MAX_BOARD && board < boardChannelJson.size(); ++board) {
|
for (int board = 0; board < MAX_BOARD && board < boardChannelJson.size(); ++board) {
|
||||||
|
|
@ -79,12 +97,30 @@ ConformityHistoryItem ConformityHistoryItem::fromJson(const QJsonObject& obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 初级粒子数据
|
||||||
QJsonObject firstParticleJson = obj["firstParticleData"].toObject();
|
QJsonObject firstParticleJson = obj["firstParticleData"].toObject();
|
||||||
for (const QString& key : firstParticleJson.keys()) {
|
for (const QString& key : firstParticleJson.keys()) {
|
||||||
item.firstParticleData[key] = firstParticleJson[key].toInt();
|
item.firstParticleData[key] = firstParticleJson[key].toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增:符合矩阵数据
|
||||||
|
memset(item.coincidenceMatrix, 0, sizeof(item.coincidenceMatrix));
|
||||||
|
QJsonArray matrixJson = obj["coincidenceMatrix"].toArray();
|
||||||
|
for (int pBoard = 0; pBoard < MAX_BOARD && pBoard < matrixJson.size(); ++pBoard) {
|
||||||
|
QJsonArray pChannelArray = matrixJson[pBoard].toArray();
|
||||||
|
for (int pChannel = 0; pChannel < MAX_CHANNEL && pChannel < pChannelArray.size(); ++pChannel) {
|
||||||
|
QJsonArray sBoardArray = pChannelArray[pChannel].toArray();
|
||||||
|
for (int sBoard = 0; sBoard < MAX_BOARD && sBoard < sBoardArray.size(); ++sBoard) {
|
||||||
|
QJsonArray sChannelArray = sBoardArray[sBoard].toArray();
|
||||||
|
for (int sChannel = 0; sChannel < MAX_CHANNEL && sChannel < sChannelArray.size(); ++sChannel) {
|
||||||
|
item.coincidenceMatrix[pBoard][pChannel][sBoard][sChannel] = sChannelArray[sChannel].toInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
item.surfaceData.clear();
|
item.surfaceData.clear();
|
||||||
|
item.channelSurfaceData.clear();
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -99,7 +135,9 @@ ConformityCalculatedResult ConformityHistoryItem::toCalculatedResult() const
|
||||||
result.secondaryEnergyStart = secondaryEnergyStart;
|
result.secondaryEnergyStart = secondaryEnergyStart;
|
||||||
result.secondaryEnergyEnd = secondaryEnergyEnd;
|
result.secondaryEnergyEnd = secondaryEnergyEnd;
|
||||||
memcpy(result.boardChannelData, boardChannelData, sizeof(boardChannelData));
|
memcpy(result.boardChannelData, boardChannelData, sizeof(boardChannelData));
|
||||||
|
memcpy(result.coincidenceMatrix, coincidenceMatrix, sizeof(coincidenceMatrix));
|
||||||
result.firstParticleData = firstParticleData;
|
result.firstParticleData = firstParticleData;
|
||||||
|
result.channelSurfaceData = channelSurfaceData;
|
||||||
result.surfaceData = surfaceData;
|
result.surfaceData = surfaceData;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -116,7 +154,9 @@ ConformityHistoryItem ConformityHistoryItem::fromCalculatedResult(const Conformi
|
||||||
item.secondaryEnergyStart = result.secondaryEnergyStart;
|
item.secondaryEnergyStart = result.secondaryEnergyStart;
|
||||||
item.secondaryEnergyEnd = result.secondaryEnergyEnd;
|
item.secondaryEnergyEnd = result.secondaryEnergyEnd;
|
||||||
memcpy(item.boardChannelData, result.boardChannelData, sizeof(result.boardChannelData));
|
memcpy(item.boardChannelData, result.boardChannelData, sizeof(result.boardChannelData));
|
||||||
|
memcpy(item.coincidenceMatrix, result.coincidenceMatrix, sizeof(result.coincidenceMatrix));
|
||||||
item.firstParticleData = result.firstParticleData;
|
item.firstParticleData = result.firstParticleData;
|
||||||
|
item.channelSurfaceData = result.channelSurfaceData;
|
||||||
item.surfaceData = result.surfaceData;
|
item.surfaceData = result.surfaceData;
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
@ -171,12 +211,47 @@ void ConformityAnalysis::InitViewWorkspace(const QString &project_name)
|
||||||
|
|
||||||
void ConformityAnalysis::SetAnalyzeDataFilename(const QMap<QString, QVariant> &data_files_set)
|
void ConformityAnalysis::SetAnalyzeDataFilename(const QMap<QString, QVariant> &data_files_set)
|
||||||
{
|
{
|
||||||
if (data_files_set.isEmpty()) return;
|
// if (data_files_set.isEmpty()) return;
|
||||||
|
|
||||||
|
// clearAllCachedData();
|
||||||
|
// freeEventVector(_currentSpectrumData);
|
||||||
|
// m_conformFileMap.clear();
|
||||||
|
|
||||||
|
// for (const QString& key : data_files_set.keys()) {
|
||||||
|
// bool ok;
|
||||||
|
// int cnt = key.toInt(&ok);
|
||||||
|
// if (ok && cnt >=2 && cnt <=9) {
|
||||||
|
// m_conformFileMap[cnt] = data_files_set[key].toString();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (m_conformFileMap.isEmpty()) {
|
||||||
|
// qWarning() << "[ConformityAnalysis] 未找到任何有效的符合数数据文件";
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (m_conformFileMap.contains(2)) {
|
||||||
|
|
||||||
|
// ConformityCalculatedResult result = streamParseAndCalculate(2, m_conformFileMap[2]);
|
||||||
|
|
||||||
|
// QMutexLocker cacheLocker(&m_cacheMutex);
|
||||||
|
// m_calculatedCache[2] = result;
|
||||||
|
// cacheLocker.unlock();
|
||||||
|
|
||||||
|
// displayConformData(2);
|
||||||
|
|
||||||
|
// QMetaObject::invokeMethod(this, [=]() {
|
||||||
|
// saveResultToHistory(result);
|
||||||
|
// }, Qt::QueuedConnection);
|
||||||
|
// }
|
||||||
|
// m_isParsing = true;
|
||||||
|
// parseAllConformDataInBackground();
|
||||||
|
|
||||||
|
if (data_files_set.isEmpty()) return;
|
||||||
clearAllCachedData();
|
clearAllCachedData();
|
||||||
freeEventVector(_currentSpectrumData);
|
|
||||||
m_conformFileMap.clear();
|
m_conformFileMap.clear();
|
||||||
|
|
||||||
|
// 构建符合数->文件路径映射
|
||||||
for (const QString& key : data_files_set.keys()) {
|
for (const QString& key : data_files_set.keys()) {
|
||||||
bool ok;
|
bool ok;
|
||||||
int cnt = key.toInt(&ok);
|
int cnt = key.toInt(&ok);
|
||||||
|
|
@ -190,22 +265,108 @@ void ConformityAnalysis::SetAnalyzeDataFilename(const QMap<QString, QVariant> &d
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_conformFileMap.contains(2)) {
|
// 重新加载最新的历史数据
|
||||||
|
loadHistoryFromFile();
|
||||||
|
|
||||||
|
// 检查每个文件是否需要重新解析
|
||||||
|
QList<int> needParseConformCounts;
|
||||||
|
QList<int> canUseHistoryConformCounts;
|
||||||
|
|
||||||
|
for (int conformCount : m_conformFileMap.keys()) {
|
||||||
|
QString fileName = m_conformFileMap[conformCount];
|
||||||
|
QFileInfo fileInfo(fileName);
|
||||||
|
|
||||||
|
// 查找对应的历史记录
|
||||||
|
int historyIdx = findHistoryIndex(fileName, conformCount);
|
||||||
|
|
||||||
|
if (historyIdx >= 0 && fileInfo.exists()) {
|
||||||
|
const ConformityHistoryItem& historyItem = _conformityHistoryList[historyIdx];
|
||||||
|
// 比较文件最后修改时间和历史记录时间戳
|
||||||
|
// 如果文件修改时间早于历史记录保存时间,说明文件未变,可以使用历史数据
|
||||||
|
if (fileInfo.lastModified() <= historyItem.timestamp) {
|
||||||
|
// 直接将历史数据转换为预计算结果存入缓存
|
||||||
|
ConformityCalculatedResult result = historyItem.toCalculatedResult();
|
||||||
|
QMutexLocker cacheLocker(&m_cacheMutex);
|
||||||
|
m_calculatedCache[conformCount] = result;
|
||||||
|
canUseHistoryConformCounts.append(conformCount);
|
||||||
|
qDebug() << "[ConformityAnalysis] " << conformCount << "重符合数据使用历史缓存,跳过解析";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件不存在或已修改,需要重新解析
|
||||||
|
needParseConformCounts.append(conformCount);
|
||||||
|
qDebug() << "[ConformityAnalysis] " << conformCount << "重符合数据需要重新解析";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 优先显示2重符合数据(如果有历史缓存)
|
||||||
|
if (canUseHistoryConformCounts.contains(2)) {
|
||||||
|
displayConformData(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有需要解析的文件,启动后台解析
|
||||||
|
if (!needParseConformCounts.isEmpty()) {
|
||||||
|
m_isParsing = true;
|
||||||
|
// 先解析2重符合(如果需要),保证界面快速显示
|
||||||
|
if (needParseConformCounts.contains(2)) {
|
||||||
ConformityCalculatedResult result = streamParseAndCalculate(2, m_conformFileMap[2]);
|
ConformityCalculatedResult result = streamParseAndCalculate(2, m_conformFileMap[2]);
|
||||||
|
|
||||||
QMutexLocker cacheLocker(&m_cacheMutex);
|
QMutexLocker cacheLocker(&m_cacheMutex);
|
||||||
m_calculatedCache[2] = result;
|
m_calculatedCache[2] = result;
|
||||||
cacheLocker.unlock();
|
cacheLocker.unlock();
|
||||||
|
|
||||||
displayConformData(2);
|
displayConformData(2);
|
||||||
|
|
||||||
QMetaObject::invokeMethod(this, [=]() {
|
QMetaObject::invokeMethod(this, [=]() {
|
||||||
saveResultToHistory(result);
|
saveResultToHistory(result);
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
|
needParseConformCounts.removeOne(2);
|
||||||
}
|
}
|
||||||
m_isParsing = true;
|
|
||||||
parseAllConformDataInBackground();
|
// 后台解析剩余的符合数
|
||||||
|
parseRemainingConformDataInBackground(needParseConformCounts);
|
||||||
|
} else {
|
||||||
|
m_isParsing = false;
|
||||||
|
qDebug() << "[ConformityAnalysis] 所有数据均使用历史缓存,无需解析";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConformityAnalysis::parseRemainingConformDataInBackground(const QList<int>& conformCounts)
|
||||||
|
{
|
||||||
|
if (conformCounts.isEmpty()) {
|
||||||
|
m_isParsing = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<int> sortedCounts = conformCounts;
|
||||||
|
std::sort(sortedCounts.begin(), sortedCounts.end());
|
||||||
|
|
||||||
|
auto parseTask = [this, sortedCounts]() {
|
||||||
|
for (int conformCount : sortedCounts) {
|
||||||
|
if (m_parseWatcher && m_parseWatcher->isCanceled())
|
||||||
|
break;
|
||||||
|
QString fileName = m_conformFileMap[conformCount];
|
||||||
|
ConformityCalculatedResult result = streamParseAndCalculate(conformCount, fileName);
|
||||||
|
QMutexLocker cacheLocker(&m_cacheMutex);
|
||||||
|
m_calculatedCache[conformCount] = result;
|
||||||
|
cacheLocker.unlock();
|
||||||
|
if (conformCount == m_currentConformCount) {
|
||||||
|
QMetaObject::invokeMethod(this, "displayConformData", Qt::QueuedConnection,
|
||||||
|
Q_ARG(int, conformCount));
|
||||||
|
}
|
||||||
|
QMetaObject::invokeMethod(this, [=]() {
|
||||||
|
saveResultToHistory(result);
|
||||||
|
}, Qt::QueuedConnection);
|
||||||
|
QMetaObject::invokeMethod(this, "onSingleParseFinished", Qt::QueuedConnection, Q_ARG(int, conformCount));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (m_parseWatcher) {
|
||||||
|
m_parseWatcher->cancel();
|
||||||
|
m_parseWatcher->waitForFinished();
|
||||||
|
delete m_parseWatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_parseWatcher = new QFutureWatcher<void>(this);
|
||||||
|
connect(m_parseWatcher, &QFutureWatcher<void>::finished, this, &ConformityAnalysis::onAllParseFinished);
|
||||||
|
m_parseWatcher->setFuture(QtConcurrent::run(parseTask));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConformityAnalysis::parseAllConformDataInBackground()
|
void ConformityAnalysis::parseAllConformDataInBackground()
|
||||||
|
|
@ -219,21 +380,15 @@ void ConformityAnalysis::parseAllConformDataInBackground()
|
||||||
for (int conformCount : conformCounts) {
|
for (int conformCount : conformCounts) {
|
||||||
if (m_parseWatcher && m_parseWatcher->isCanceled())
|
if (m_parseWatcher && m_parseWatcher->isCanceled())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
QString fileName = m_conformFileMap[conformCount];
|
QString fileName = m_conformFileMap[conformCount];
|
||||||
|
|
||||||
|
|
||||||
ConformityCalculatedResult result = streamParseAndCalculate(conformCount, fileName);
|
ConformityCalculatedResult result = streamParseAndCalculate(conformCount, fileName);
|
||||||
|
|
||||||
QMutexLocker cacheLocker(&m_cacheMutex);
|
QMutexLocker cacheLocker(&m_cacheMutex);
|
||||||
m_calculatedCache[conformCount] = result;
|
m_calculatedCache[conformCount] = result;
|
||||||
cacheLocker.unlock();
|
cacheLocker.unlock();
|
||||||
|
|
||||||
if (conformCount == m_currentConformCount) {
|
if (conformCount == m_currentConformCount) {
|
||||||
QMetaObject::invokeMethod(this, "displayConformData", Qt::QueuedConnection,
|
QMetaObject::invokeMethod(this, "displayConformData", Qt::QueuedConnection,
|
||||||
Q_ARG(int, conformCount));
|
Q_ARG(int, conformCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
QMetaObject::invokeMethod(this, [=]() {
|
QMetaObject::invokeMethod(this, [=]() {
|
||||||
saveResultToHistory(result);
|
saveResultToHistory(result);
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
|
|
@ -252,12 +407,14 @@ ConformityCalculatedResult ConformityAnalysis::streamParseAndCalculate(int confo
|
||||||
ConformityCalculatedResult result;
|
ConformityCalculatedResult result;
|
||||||
result.conformCount = conformCount;
|
result.conformCount = conformCount;
|
||||||
result.dataFileName = fileName;
|
result.dataFileName = fileName;
|
||||||
|
|
||||||
memset(result.boardChannelData, 0, sizeof(result.boardChannelData));
|
memset(result.boardChannelData, 0, sizeof(result.boardChannelData));
|
||||||
for (int board = 1; board <= 8; ++board) {
|
memset(result.coincidenceMatrix, 0, sizeof(result.coincidenceMatrix));
|
||||||
for (int channel = 1; channel <= 4; ++channel) {
|
|
||||||
|
for (int board = 1; board <= MAX_BOARD; ++board) {
|
||||||
|
for (int channel = 1; channel <= MAX_CHANNEL; ++channel) {
|
||||||
QString key = QStringLiteral(u"widget_%1_%2").arg(board).arg(channel);
|
QString key = QStringLiteral(u"widget_%1_%2").arg(board).arg(channel);
|
||||||
result.firstParticleData[key] = 0;
|
result.firstParticleData[key] = 0;
|
||||||
|
result.channelSurfaceData[key] = QVector<SurfacePoint>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,13 +423,11 @@ ConformityCalculatedResult ConformityAnalysis::streamParseAndCalculate(int confo
|
||||||
double minSecondVal = std::numeric_limits<double>::max();
|
double minSecondVal = std::numeric_limits<double>::max();
|
||||||
double maxSecondVal = 0.0;
|
double maxSecondVal = 0.0;
|
||||||
|
|
||||||
|
QVector<particleCoincidenceEvent> currentEventParticles;
|
||||||
int currentEventId = -1;
|
int currentEventId = -1;
|
||||||
float primaryEnergy = 0.0f;
|
|
||||||
float secondaryEnergySum = 0.0f;
|
|
||||||
int eventCount = 0;
|
int eventCount = 0;
|
||||||
|
|
||||||
if (!QFileInfo::exists(fileName)) {
|
if (!QFileInfo::exists(fileName)) {
|
||||||
qCritical() << "[ConformityAnalysis] CSV文件不存在:" << fileName;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -294,25 +449,49 @@ ConformityCalculatedResult ConformityAnalysis::streamParseAndCalculate(int confo
|
||||||
particleCoincidenceEvent event;
|
particleCoincidenceEvent event;
|
||||||
while (reader.read_row(event.eventId, event.board, event.channel, event.energy, event.timeCounter)) {
|
while (reader.read_row(event.eventId, event.board, event.channel, event.energy, event.timeCounter)) {
|
||||||
eventCount++;
|
eventCount++;
|
||||||
|
|
||||||
result.boardChannelData[event.board][event.channel]++;
|
result.boardChannelData[event.board][event.channel]++;
|
||||||
|
|
||||||
if (event.eventId != currentEventId) {
|
if (event.eventId != currentEventId) {
|
||||||
if (currentEventId != -1) {
|
if (currentEventId != -1 && !currentEventParticles.isEmpty()) {
|
||||||
SurfacePoint point;
|
SurfacePoint globalPoint;
|
||||||
point.primaryEnergy = primaryEnergy;
|
const auto& primaryParticle = currentEventParticles.first();
|
||||||
point.secondaryEnergySum = secondaryEnergySum;
|
globalPoint.primaryEnergy = static_cast<float>(primaryParticle.energy);
|
||||||
point.count = 1;
|
globalPoint.secondaryEnergySum = 0.0f;
|
||||||
result.surfaceData.append(point);
|
|
||||||
|
for (int i = 1; i < currentEventParticles.size(); ++i) {
|
||||||
|
globalPoint.secondaryEnergySum += static_cast<float>(currentEventParticles[i].energy);
|
||||||
|
}
|
||||||
|
globalPoint.count = 1;
|
||||||
|
result.surfaceData.append(globalPoint);
|
||||||
|
|
||||||
|
int primaryBoard = primaryParticle.board;
|
||||||
|
int primaryChannel = primaryParticle.channel;
|
||||||
|
QString primaryKey = QStringLiteral(u"widget_%1_%2").arg(primaryBoard + 1).arg(primaryChannel + 1);
|
||||||
|
|
||||||
|
SurfacePoint channelPoint;
|
||||||
|
channelPoint.primaryEnergy = static_cast<float>(primaryParticle.energy);
|
||||||
|
channelPoint.secondaryEnergySum = 0.0f;
|
||||||
|
|
||||||
|
for (int secondaryIdx = 1; secondaryIdx < currentEventParticles.size(); ++secondaryIdx) {
|
||||||
|
const auto& secondaryParticle = currentEventParticles[secondaryIdx];
|
||||||
|
int secondaryBoard = secondaryParticle.board;
|
||||||
|
int secondaryChannel = secondaryParticle.channel;
|
||||||
|
|
||||||
|
result.coincidenceMatrix[primaryBoard][primaryChannel][secondaryBoard][secondaryChannel]++;
|
||||||
|
channelPoint.secondaryEnergySum += static_cast<float>(secondaryParticle.energy);
|
||||||
|
}
|
||||||
|
|
||||||
|
channelPoint.count = 1;
|
||||||
|
result.channelSurfaceData[primaryKey].append(channelPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentEventId = event.eventId;
|
currentEventId = event.eventId;
|
||||||
primaryEnergy = static_cast<float>(event.energy);
|
currentEventParticles.clear();
|
||||||
secondaryEnergySum = 0.0f;
|
currentEventParticles.append(event);
|
||||||
|
|
||||||
int boardId = event.board + 1;
|
int boardId = event.board + 1;
|
||||||
int channelId = event.channel + 1;
|
int channelId = event.channel + 1;
|
||||||
if (boardId >= 1 && boardId <= 8 && channelId >= 1 && channelId <= 4) {
|
if (boardId >= 1 && boardId <= MAX_BOARD && channelId >= 1 && channelId <= MAX_CHANNEL) {
|
||||||
QString key = QStringLiteral(u"widget_%1_%2").arg(boardId).arg(channelId);
|
QString key = QStringLiteral(u"widget_%1_%2").arg(boardId).arg(channelId);
|
||||||
result.firstParticleData[key]++;
|
result.firstParticleData[key]++;
|
||||||
}
|
}
|
||||||
|
|
@ -320,23 +499,48 @@ ConformityCalculatedResult ConformityAnalysis::streamParseAndCalculate(int confo
|
||||||
if (event.energy < minFirstVal) minFirstVal = event.energy;
|
if (event.energy < minFirstVal) minFirstVal = event.energy;
|
||||||
if (event.energy > maxFirstVal) maxFirstVal = event.energy;
|
if (event.energy > maxFirstVal) maxFirstVal = event.energy;
|
||||||
} else {
|
} else {
|
||||||
secondaryEnergySum += static_cast<float>(event.energy);
|
currentEventParticles.append(event);
|
||||||
|
|
||||||
if (event.energy < minSecondVal) minSecondVal = event.energy;
|
if (event.energy < minSecondVal) minSecondVal = event.energy;
|
||||||
if (event.energy > maxSecondVal) maxSecondVal = event.energy;
|
if (event.energy > maxSecondVal) maxSecondVal = event.energy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentEventId != -1) {
|
if (currentEventId != -1 && !currentEventParticles.isEmpty()) {
|
||||||
SurfacePoint point;
|
SurfacePoint globalPoint;
|
||||||
point.primaryEnergy = primaryEnergy;
|
const auto& primaryParticle = currentEventParticles.first();
|
||||||
point.secondaryEnergySum = secondaryEnergySum;
|
globalPoint.primaryEnergy = static_cast<float>(primaryParticle.energy);
|
||||||
point.count = 1;
|
globalPoint.secondaryEnergySum = 0.0f;
|
||||||
result.surfaceData.append(point);
|
|
||||||
|
for (int i = 1; i < currentEventParticles.size(); ++i) {
|
||||||
|
globalPoint.secondaryEnergySum += static_cast<float>(currentEventParticles[i].energy);
|
||||||
|
}
|
||||||
|
globalPoint.count = 1;
|
||||||
|
result.surfaceData.append(globalPoint);
|
||||||
|
|
||||||
|
int primaryBoard = primaryParticle.board;
|
||||||
|
int primaryChannel = primaryParticle.channel;
|
||||||
|
QString primaryKey = QStringLiteral(u"widget_%1_%2").arg(primaryBoard + 1).arg(primaryChannel + 1);
|
||||||
|
|
||||||
|
SurfacePoint channelPoint;
|
||||||
|
channelPoint.primaryEnergy = static_cast<float>(primaryParticle.energy);
|
||||||
|
channelPoint.secondaryEnergySum = 0.0f;
|
||||||
|
|
||||||
|
for (int secondaryIdx = 1; secondaryIdx < currentEventParticles.size(); ++secondaryIdx) {
|
||||||
|
const auto& secondaryParticle = currentEventParticles[secondaryIdx];
|
||||||
|
int secondaryBoard = secondaryParticle.board;
|
||||||
|
int secondaryChannel = secondaryParticle.channel;
|
||||||
|
result.coincidenceMatrix[primaryBoard][primaryChannel][secondaryBoard][secondaryChannel]++;
|
||||||
|
channelPoint.secondaryEnergySum += static_cast<float>(secondaryParticle.energy);
|
||||||
|
}
|
||||||
|
|
||||||
|
channelPoint.count = 1;
|
||||||
|
result.channelSurfaceData[primaryKey].append(channelPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.surfaceData.squeeze();
|
result.surfaceData.squeeze();
|
||||||
|
for (auto& vec : result.channelSurfaceData) {
|
||||||
|
vec.squeeze();
|
||||||
|
}
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
qCritical() << "[ConformityAnalysis] CSV解析异常:" << e.what();
|
qCritical() << "[ConformityAnalysis] CSV解析异常:" << e.what();
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -347,19 +551,18 @@ ConformityCalculatedResult ConformityAnalysis::streamParseAndCalculate(int confo
|
||||||
result.primaryEnergyEnd = maxFirstVal;
|
result.primaryEnergyEnd = maxFirstVal;
|
||||||
result.secondaryEnergyStart = (minSecondVal == std::numeric_limits<double>::max()) ? 0.0 : minSecondVal;
|
result.secondaryEnergyStart = (minSecondVal == std::numeric_limits<double>::max()) ? 0.0 : minSecondVal;
|
||||||
result.secondaryEnergyEnd = maxSecondVal;
|
result.secondaryEnergyEnd = maxSecondVal;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConformityAnalysis::saveResultToHistory(const ConformityCalculatedResult& result)
|
void ConformityAnalysis::saveResultToHistory(const ConformityCalculatedResult& result)
|
||||||
{
|
{
|
||||||
|
|
||||||
QMutexLocker locker(&m_historyMutex);
|
QMutexLocker locker(&m_historyMutex);
|
||||||
ConformityHistoryItem item = ConformityHistoryItem::fromCalculatedResult(result);
|
ConformityHistoryItem item = ConformityHistoryItem::fromCalculatedResult(result);
|
||||||
|
// 保存JSON元数据
|
||||||
// 1. 流式写入JSON(零大小限制)
|
|
||||||
saveJsonStream(result.conformCount, item);
|
saveJsonStream(result.conformCount, item);
|
||||||
// 2. 二进制保存超大曲面数据
|
// 保存二进制曲面数据(全局+所有通道)
|
||||||
saveSurfaceDataToBinary(result.conformCount, item.surfaceData);
|
saveSurfaceDataToBinary(result.conformCount, item.surfaceData, item.channelSurfaceData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConformityAnalysis::saveJsonStream(int conformCount, const ConformityHistoryItem& item)
|
void ConformityAnalysis::saveJsonStream(int conformCount, const ConformityHistoryItem& item)
|
||||||
|
|
@ -367,13 +570,11 @@ void ConformityAnalysis::saveJsonStream(int conformCount, const ConformityHistor
|
||||||
QDir dir(_workspace);
|
QDir dir(_workspace);
|
||||||
dir.mkpath(".");
|
dir.mkpath(".");
|
||||||
QString path = dir.filePath(QString("conformity_%1.json").arg(conformCount));
|
QString path = dir.filePath(QString("conformity_%1.json").arg(conformCount));
|
||||||
|
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
|
||||||
qCritical() << "无法打开文件写入:" << file.errorString();
|
qCritical() << "无法打开文件写入:" << file.errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextStream stream(&file);
|
QTextStream stream(&file);
|
||||||
stream.setCodec("UTF-8");
|
stream.setCodec("UTF-8");
|
||||||
// 强制浮点数用固定小数格式,避免科学计数法
|
// 强制浮点数用固定小数格式,避免科学计数法
|
||||||
|
|
@ -406,7 +607,6 @@ void ConformityAnalysis::saveJsonStream(int conformCount, const ConformityHistor
|
||||||
};
|
};
|
||||||
|
|
||||||
stream << "{" << '\n';
|
stream << "{" << '\n';
|
||||||
|
|
||||||
stream << " \"timestamp\": \"" << escapeJson(item.timestamp.toString(Qt::ISODate)) << "\"," << '\n';
|
stream << " \"timestamp\": \"" << escapeJson(item.timestamp.toString(Qt::ISODate)) << "\"," << '\n';
|
||||||
stream << " \"dataFileName\": \"" << escapeJson(item.dataFileName) << "\"," << '\n';
|
stream << " \"dataFileName\": \"" << escapeJson(item.dataFileName) << "\"," << '\n';
|
||||||
stream << " \"conformCount\": " << item.conformCount << "," << '\n';
|
stream << " \"conformCount\": " << item.conformCount << "," << '\n';
|
||||||
|
|
@ -416,6 +616,7 @@ void ConformityAnalysis::saveJsonStream(int conformCount, const ConformityHistor
|
||||||
stream << " \"secondaryEnergyStart\": " << item.secondaryEnergyStart << "," << '\n';
|
stream << " \"secondaryEnergyStart\": " << item.secondaryEnergyStart << "," << '\n';
|
||||||
stream << " \"secondaryEnergyEnd\": " << item.secondaryEnergyEnd << "," << '\n';
|
stream << " \"secondaryEnergyEnd\": " << item.secondaryEnergyEnd << "," << '\n';
|
||||||
|
|
||||||
|
// 板卡通道数据
|
||||||
stream << " \"boardChannelData\": [" << '\n';
|
stream << " \"boardChannelData\": [" << '\n';
|
||||||
for (int board = 0; board < MAX_BOARD; ++board) {
|
for (int board = 0; board < MAX_BOARD; ++board) {
|
||||||
stream << " [";
|
stream << " [";
|
||||||
|
|
@ -429,6 +630,7 @@ void ConformityAnalysis::saveJsonStream(int conformCount, const ConformityHistor
|
||||||
}
|
}
|
||||||
stream << " ]," << '\n';
|
stream << " ]," << '\n';
|
||||||
|
|
||||||
|
// 初级粒子数据
|
||||||
stream << " \"firstParticleData\": {" << '\n';
|
stream << " \"firstParticleData\": {" << '\n';
|
||||||
QList<QString> keys = item.firstParticleData.keys();
|
QList<QString> keys = item.firstParticleData.keys();
|
||||||
for (int i = 0; i < keys.size(); ++i) {
|
for (int i = 0; i < keys.size(); ++i) {
|
||||||
|
|
@ -436,26 +638,55 @@ void ConformityAnalysis::saveJsonStream(int conformCount, const ConformityHistor
|
||||||
if (i < keys.size() - 1) stream << ",";
|
if (i < keys.size() - 1) stream << ",";
|
||||||
stream << '\n';
|
stream << '\n';
|
||||||
}
|
}
|
||||||
stream << " }" << '\n';
|
stream << " }," << '\n';
|
||||||
|
|
||||||
|
// 符合矩阵数据
|
||||||
|
stream << " \"coincidenceMatrix\": [" << '\n';
|
||||||
|
for (int pBoard = 0; pBoard < MAX_BOARD; ++pBoard) {
|
||||||
|
stream << " [" << '\n';
|
||||||
|
for (int pChannel = 0; pChannel < MAX_CHANNEL; ++pChannel) {
|
||||||
|
stream << " [";
|
||||||
|
for (int sBoard = 0; sBoard < MAX_BOARD; ++sBoard) {
|
||||||
|
stream << "[";
|
||||||
|
for (int sChannel = 0; sChannel < MAX_CHANNEL; ++sChannel) {
|
||||||
|
stream << item.coincidenceMatrix[pBoard][pChannel][sBoard][sChannel];
|
||||||
|
if (sChannel < MAX_CHANNEL - 1) stream << ", ";
|
||||||
|
}
|
||||||
|
stream << "]";
|
||||||
|
if (sBoard < MAX_BOARD - 1) stream << ", ";
|
||||||
|
}
|
||||||
|
stream << "]";
|
||||||
|
if (pChannel < MAX_CHANNEL - 1) stream << ",";
|
||||||
|
stream << '\n';
|
||||||
|
}
|
||||||
|
stream << " ]";
|
||||||
|
if (pBoard < MAX_BOARD - 1) stream << ",";
|
||||||
|
stream << '\n';
|
||||||
|
}
|
||||||
|
stream << " ]" << '\n';
|
||||||
|
|
||||||
stream << "}" << '\n';
|
stream << "}" << '\n';
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConformityAnalysis::saveSurfaceDataToBinary(int conformCount, const QVector<SurfacePoint>& data)
|
|
||||||
|
void ConformityAnalysis::saveSurfaceDataToBinary(int conformCount, const QVector<SurfacePoint> &globalData, const QMap<QString, QVector<SurfacePoint> > &channelData)
|
||||||
{
|
{
|
||||||
QDir dir(_workspace);
|
QDir dir(_workspace);
|
||||||
QString path = dir.filePath(QString("surface_%1.bin").arg(conformCount));
|
QString path = dir.filePath(QString("surface_%1.bin").arg(conformCount));
|
||||||
|
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
if (!file.open(QIODevice::WriteOnly)) {
|
if (!file.open(QIODevice::WriteOnly)) {
|
||||||
qCritical() << "无法打开二进制文件写入:" << file.errorString();
|
qCritical() << "无法打开二进制文件写入:" << file.errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream stream(&file);
|
QDataStream stream(&file);
|
||||||
stream << data;
|
// 先保存全局曲面数据
|
||||||
|
stream << globalData;
|
||||||
|
// 再保存通道曲面数据数量和内容
|
||||||
|
stream << channelData.size();
|
||||||
|
for (auto it = channelData.begin(); it != channelData.end(); ++it) {
|
||||||
|
stream << it.key() << it.value();
|
||||||
|
}
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -465,12 +696,9 @@ void ConformityAnalysis::loadHistoryFromFile()
|
||||||
for (int c = 2; c <= 9; ++c) {
|
for (int c = 2; c <= 9; ++c) {
|
||||||
QString jsonPath = QDir(_workspace).filePath(QString("conformity_%1.json").arg(c));
|
QString jsonPath = QDir(_workspace).filePath(QString("conformity_%1.json").arg(c));
|
||||||
QString binPath = QDir(_workspace).filePath(QString("surface_%1.bin").arg(c));
|
QString binPath = QDir(_workspace).filePath(QString("surface_%1.bin").arg(c));
|
||||||
|
|
||||||
if (!QFile::exists(jsonPath)) {
|
if (!QFile::exists(jsonPath)) {
|
||||||
// qDebug() << "[ConformityAnalysis] " << c << "重符合历史文件不存在:" << jsonPath;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
QFile f(jsonPath);
|
QFile f(jsonPath);
|
||||||
if (!f.open(QIODevice::ReadOnly)) {
|
if (!f.open(QIODevice::ReadOnly)) {
|
||||||
qWarning() << "[ConformityAnalysis] 无法打开JSON文件:" << jsonPath;
|
qWarning() << "[ConformityAnalysis] 无法打开JSON文件:" << jsonPath;
|
||||||
|
|
@ -478,7 +706,6 @@ void ConformityAnalysis::loadHistoryFromFile()
|
||||||
}
|
}
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(f.readAll());
|
QJsonDocument doc = QJsonDocument::fromJson(f.readAll());
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
ConformityHistoryItem item = ConformityHistoryItem::fromJson(doc.object());
|
ConformityHistoryItem item = ConformityHistoryItem::fromJson(doc.object());
|
||||||
|
|
||||||
if (QFile::exists(binPath)) {
|
if (QFile::exists(binPath)) {
|
||||||
|
|
@ -486,18 +713,23 @@ void ConformityAnalysis::loadHistoryFromFile()
|
||||||
if (binFile.open(QIODevice::ReadOnly)) {
|
if (binFile.open(QIODevice::ReadOnly)) {
|
||||||
QDataStream stream(&binFile);
|
QDataStream stream(&binFile);
|
||||||
stream >> item.surfaceData;
|
stream >> item.surfaceData;
|
||||||
|
int channelCount;
|
||||||
|
stream >> channelCount;
|
||||||
|
for (int i = 0; i < channelCount; ++i) {
|
||||||
|
QString key;
|
||||||
|
QVector<SurfacePoint> data;
|
||||||
|
stream >> key >> data;
|
||||||
|
item.channelSurfaceData[key] = data;
|
||||||
|
}
|
||||||
binFile.close();
|
binFile.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_conformityHistoryList.append(item);
|
_conformityHistoryList.append(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 单个符合数解析完成 ====================
|
|
||||||
void ConformityAnalysis::onSingleParseFinished(int conformCount)
|
void ConformityAnalysis::onSingleParseFinished(int conformCount)
|
||||||
{
|
{
|
||||||
qDebug() << "[ConformityAnalysis] " << conformCount << "重符合数据处理完成";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConformityAnalysis::onAllParseFinished()
|
void ConformityAnalysis::onAllParseFinished()
|
||||||
|
|
@ -535,7 +767,6 @@ void ConformityAnalysis::displayConformData(int conformCount)
|
||||||
setAllBoardData();
|
setAllBoardData();
|
||||||
setThreeUiData();
|
setThreeUiData();
|
||||||
ui->widget_3D->setSurfaceData(m_surfaceData);
|
ui->widget_3D->setSurfaceData(m_surfaceData);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConformityAnalysis::slot_ConformCountChanged(int index)
|
void ConformityAnalysis::slot_ConformCountChanged(int index)
|
||||||
|
|
@ -552,7 +783,6 @@ QVector<particleCoincidenceEvent*> ConformityAnalysis::readCsv(const QString& fi
|
||||||
QVector<particleCoincidenceEvent*> dataList;
|
QVector<particleCoincidenceEvent*> dataList;
|
||||||
|
|
||||||
if (!QFileInfo::exists(fileName)) {
|
if (!QFileInfo::exists(fileName)) {
|
||||||
qWarning() << "[ConformityAnalysis] 文件不存在:" << fileName;
|
|
||||||
return dataList;
|
return dataList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -590,7 +820,6 @@ QVector<particleCoincidenceEvent*> ConformityAnalysis::readCsv(const QString& fi
|
||||||
return dataList;
|
return dataList;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 释放事件数组内存
|
|
||||||
void ConformityAnalysis::freeEventVector(QVector<particleCoincidenceEvent*>& vec)
|
void ConformityAnalysis::freeEventVector(QVector<particleCoincidenceEvent*>& vec)
|
||||||
{
|
{
|
||||||
qDeleteAll(vec);
|
qDeleteAll(vec);
|
||||||
|
|
@ -752,46 +981,65 @@ void ConformityAnalysis::slot_ClickedBoard(int board,int channel)
|
||||||
if (!m_calculatedCache.contains(m_currentConformCount)) {
|
if (!m_calculatedCache.contains(m_currentConformCount)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QString fileName = m_calculatedCache[m_currentConformCount].dataFileName;
|
const ConformityCalculatedResult& result = m_calculatedCache[m_currentConformCount];
|
||||||
locker.unlock();
|
locker.unlock();
|
||||||
|
|
||||||
if (_currentSpectrumData.isEmpty()) {
|
QString primaryKey = QStringLiteral(u"widget_%1_%2").arg(board).arg(channel);
|
||||||
_currentSpectrumData = readCsv(fileName);
|
if (!result.channelSurfaceData.contains(primaryKey)) {
|
||||||
|
qWarning() << "[ConformityAnalysis] 通道数据不存在:" << primaryKey;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<particleCoincidenceEvent*> data = handleBasicSubordinate(board, channel, _currentSpectrumData);
|
const QVector<SurfacePoint>& channelSurface = result.channelSurfaceData[primaryKey];
|
||||||
if(data.size() <= 0) return;
|
ui->widget_3D->setSurfaceData(channelSurface);
|
||||||
|
|
||||||
QVector<SurfacePoint> tempSurface = generateSurfaceData(data);
|
double localFirstStart = std::numeric_limits<double>::max();
|
||||||
ui->widget_3D->setSurfaceData(tempSurface);
|
double localFirstEnd = 0.0;
|
||||||
|
double localSecondStart = std::numeric_limits<double>::max();
|
||||||
m_iComply = data.size();
|
double localSecondEnd = 0.0;
|
||||||
|
for (const auto& point : channelSurface) {
|
||||||
double localFirstStart, localFirstEnd;
|
if (point.primaryEnergy < localFirstStart) localFirstStart = point.primaryEnergy;
|
||||||
double localSecondStart, localSecondEnd;
|
if (point.primaryEnergy > localFirstEnd) localFirstEnd = point.primaryEnergy;
|
||||||
calculateFirstSecondRange(data, localFirstStart, localFirstEnd, localSecondStart, localSecondEnd);
|
if (point.secondaryEnergySum < localSecondStart) localSecondStart = point.secondaryEnergySum;
|
||||||
|
if (point.secondaryEnergySum > localSecondEnd) localSecondEnd = point.secondaryEnergySum;
|
||||||
m_dFirstStart = localFirstStart;
|
}
|
||||||
|
m_dFirstStart = (localFirstStart == std::numeric_limits<double>::max()) ? 0.0 : localFirstStart;
|
||||||
m_dFirstEnd = localFirstEnd;
|
m_dFirstEnd = localFirstEnd;
|
||||||
m_dSecondStart = localSecondStart;
|
m_dSecondStart = (localSecondStart == std::numeric_limits<double>::max()) ? 0.0 : localSecondStart;
|
||||||
m_dSecondEnd = localSecondEnd;
|
m_dSecondEnd = localSecondEnd;
|
||||||
|
m_iComply = channelSurface.size();
|
||||||
setThreeUiData();
|
setThreeUiData();
|
||||||
|
|
||||||
m_subordinate = handleSubordinate(data, board, channel);
|
m_subordinate.clear();
|
||||||
int maxSubordinate = 0;
|
int maxSubordinate = 0;
|
||||||
for (int val : m_subordinate.values()) {
|
int primaryBoardIdx = board - 1;
|
||||||
if (val > maxSubordinate) maxSubordinate = val;
|
int primaryChannelIdx = channel - 1;
|
||||||
|
|
||||||
|
for (int sBoard = 0; sBoard < MAX_BOARD; ++sBoard) {
|
||||||
|
for (int sChannel = 0; sChannel < MAX_CHANNEL; ++sChannel) {
|
||||||
|
QString key = QStringLiteral(u"widget_%1_%2").arg(sBoard + 1).arg(sChannel + 1);
|
||||||
|
int count = result.coincidenceMatrix[primaryBoardIdx][primaryChannelIdx][sBoard][sChannel];
|
||||||
|
m_subordinate[key] = count;
|
||||||
|
if (count > maxSubordinate) maxSubordinate = count;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ui->widget->setAllWidgetColorMaxValue(maxSubordinate);
|
ui->widget->setAllWidgetColorMaxValue(maxSubordinate);
|
||||||
for (int i = 0; i < m_subordinate.keys().size();i++) {
|
for (int sBoard = 1; sBoard <= MAX_BOARD; ++sBoard) {
|
||||||
QString objectName =m_subordinate.keys().at(i);
|
for (int sChannel = 1; sChannel <= MAX_CHANNEL; ++sChannel) {
|
||||||
QStringList parts = objectName.split('_');
|
if (sBoard == board && sChannel == channel) {
|
||||||
int bd = parts[1].toInt();
|
continue;
|
||||||
int ch = parts[2].toInt();
|
|
||||||
ui->widget->setWidgetData(bd,ch,m_boardChannel[bd - 1][ch - 1],m_subordinate[objectName]);
|
|
||||||
}
|
}
|
||||||
ui->widget->setWidgetData(board,channel,m_boardChannel[board - 1][channel - 1],data.size());
|
QString key = QStringLiteral(u"widget_%1_%2").arg(sBoard).arg(sChannel);
|
||||||
|
int totalCount = m_boardChannel[sBoard - 1][sChannel - 1];
|
||||||
|
int secondCount = m_subordinate[key];
|
||||||
|
ui->widget->setWidgetData(sBoard, sChannel, totalCount, secondCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int primaryTotalCount = m_boardChannel[primaryBoardIdx][primaryChannelIdx];
|
||||||
|
int primaryCount = channelSurface.size();
|
||||||
|
ui->widget->setWidgetData(board, channel, primaryTotalCount, primaryCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString, int> ConformityAnalysis::handleSubordinate(QVector<particleCoincidenceEvent*> &eventData,int Board, int Channel)
|
QMap<QString, int> ConformityAnalysis::handleSubordinate(QVector<particleCoincidenceEvent*> &eventData,int Board, int Channel)
|
||||||
|
|
@ -851,7 +1099,9 @@ void ConformityAnalysis::saveHistoryToFile()
|
||||||
int idx = findHistoryIndex(m_conformFileMap.value(conformCount), conformCount);
|
int idx = findHistoryIndex(m_conformFileMap.value(conformCount), conformCount);
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
saveJsonStream(conformCount, _conformityHistoryList[idx]);
|
saveJsonStream(conformCount, _conformityHistoryList[idx]);
|
||||||
saveSurfaceDataToBinary(conformCount, _conformityHistoryList[idx].surfaceData);
|
saveSurfaceDataToBinary(conformCount,
|
||||||
|
_conformityHistoryList[idx].surfaceData,
|
||||||
|
_conformityHistoryList[idx].channelSurfaceData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -897,9 +1147,19 @@ int ConformityAnalysis::saveCurrentAnalysisToHistory(int conformCount)
|
||||||
|
|
||||||
int ConformityAnalysis::findHistoryIndex(const QString& fileName, int conformCount) const
|
int ConformityAnalysis::findHistoryIndex(const QString& fileName, int conformCount) const
|
||||||
{
|
{
|
||||||
|
// for (int i = 0; i < _conformityHistoryList.size(); ++i) {
|
||||||
|
// const ConformityHistoryItem& item = _conformityHistoryList[i];
|
||||||
|
// if (item.dataFileName == fileName && item.conformCount == conformCount) {
|
||||||
|
// return i;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return -1;
|
||||||
|
|
||||||
|
QString absoluteFileName = QFileInfo(fileName).absoluteFilePath();
|
||||||
for (int i = 0; i < _conformityHistoryList.size(); ++i) {
|
for (int i = 0; i < _conformityHistoryList.size(); ++i) {
|
||||||
const ConformityHistoryItem& item = _conformityHistoryList[i];
|
const ConformityHistoryItem& item = _conformityHistoryList[i];
|
||||||
if (item.dataFileName == fileName && item.conformCount == conformCount) {
|
if (QFileInfo(item.dataFileName).absoluteFilePath() == absoluteFileName
|
||||||
|
&& item.conformCount == conformCount) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ struct ConformityCalculatedResult {
|
||||||
int conformCount; // 符合粒子数
|
int conformCount; // 符合粒子数
|
||||||
QString dataFileName; // 原始CSV文件名
|
QString dataFileName; // 原始CSV文件名
|
||||||
int totalEvents; // 符合事件总计数
|
int totalEvents; // 符合事件总计数
|
||||||
|
int totalParticles; // 总粒子数
|
||||||
double primaryEnergyStart; // 初级粒子能量范围-起始
|
double primaryEnergyStart; // 初级粒子能量范围-起始
|
||||||
double primaryEnergyEnd; // 初级粒子能量范围-结束
|
double primaryEnergyEnd; // 初级粒子能量范围-结束
|
||||||
double secondaryEnergyStart; // 次级粒子能量范围-起始
|
double secondaryEnergyStart; // 次级粒子能量范围-起始
|
||||||
|
|
@ -44,14 +45,21 @@ struct ConformityCalculatedResult {
|
||||||
|
|
||||||
// 板卡通道计数数据(8板×4通道)
|
// 板卡通道计数数据(8板×4通道)
|
||||||
int boardChannelData[MAX_BOARD][MAX_CHANNEL];
|
int boardChannelData[MAX_BOARD][MAX_CHANNEL];
|
||||||
|
|
||||||
// 初级粒子计数数据
|
// 初级粒子计数数据
|
||||||
QMap<QString, int> firstParticleData;
|
QMap<QString, int> firstParticleData;
|
||||||
// 三维曲面数据
|
|
||||||
|
int coincidenceMatrix[MAX_BOARD][MAX_CHANNEL][MAX_BOARD][MAX_CHANNEL];
|
||||||
|
|
||||||
|
QMap<QString, QVector<SurfacePoint>> channelSurfaceData;
|
||||||
|
|
||||||
|
// 三维曲面数据(全局)
|
||||||
QVector<SurfacePoint> surfaceData;
|
QVector<SurfacePoint> surfaceData;
|
||||||
|
|
||||||
// 构造函数
|
// 构造函数
|
||||||
ConformityCalculatedResult() {
|
ConformityCalculatedResult() {
|
||||||
memset(boardChannelData, 0, sizeof(boardChannelData));
|
memset(boardChannelData, 0, sizeof(boardChannelData));
|
||||||
|
memset(coincidenceMatrix, 0, sizeof(coincidenceMatrix)); // 初始化符合矩阵
|
||||||
totalEvents = 0;
|
totalEvents = 0;
|
||||||
primaryEnergyStart = primaryEnergyEnd = 0.0;
|
primaryEnergyStart = primaryEnergyEnd = 0.0;
|
||||||
secondaryEnergyStart = secondaryEnergyEnd = 0.0;
|
secondaryEnergyStart = secondaryEnergyEnd = 0.0;
|
||||||
|
|
@ -75,6 +83,11 @@ struct ConformityHistoryItem {
|
||||||
int boardChannelData[MAX_BOARD][MAX_CHANNEL];
|
int boardChannelData[MAX_BOARD][MAX_CHANNEL];
|
||||||
// 初级粒子计数数据
|
// 初级粒子计数数据
|
||||||
QMap<QString, int> firstParticleData;
|
QMap<QString, int> firstParticleData;
|
||||||
|
|
||||||
|
int coincidenceMatrix[MAX_BOARD][MAX_CHANNEL][MAX_BOARD][MAX_CHANNEL];
|
||||||
|
|
||||||
|
QMap<QString, QVector<SurfacePoint>> channelSurfaceData;
|
||||||
|
|
||||||
// 三维曲面数据
|
// 三维曲面数据
|
||||||
QVector<SurfacePoint> surfaceData;
|
QVector<SurfacePoint> surfaceData;
|
||||||
|
|
||||||
|
|
@ -148,7 +161,8 @@ private:
|
||||||
// 流式写入JSON(零大小限制)
|
// 流式写入JSON(零大小限制)
|
||||||
void saveJsonStream(int conformCount, const ConformityHistoryItem& item);
|
void saveJsonStream(int conformCount, const ConformityHistoryItem& item);
|
||||||
// 二进制保存超大曲面数据
|
// 二进制保存超大曲面数据
|
||||||
void saveSurfaceDataToBinary(int conformCount, const QVector<SurfacePoint>& data);
|
void saveSurfaceDataToBinary(int conformCount, const QVector<SurfacePoint>& globalData, const QMap<QString, QVector<SurfacePoint>>& channelData);
|
||||||
|
|
||||||
// 仅保存指定符合数的历史记录到对应文件
|
// 仅保存指定符合数的历史记录到对应文件
|
||||||
void saveSingleHistoryToFile(int conformCount, const ConformityHistoryItem& item);
|
void saveSingleHistoryToFile(int conformCount, const ConformityHistoryItem& item);
|
||||||
int saveCurrentAnalysisToHistory(int conformCount);
|
int saveCurrentAnalysisToHistory(int conformCount);
|
||||||
|
|
@ -167,6 +181,9 @@ private:
|
||||||
QVector<particleCoincidenceEvent*> readCsv(const QString& fileName);
|
QVector<particleCoincidenceEvent*> readCsv(const QString& fileName);
|
||||||
// 释放事件数组内存
|
// 释放事件数组内存
|
||||||
void freeEventVector(QVector<particleCoincidenceEvent*>& vec);
|
void freeEventVector(QVector<particleCoincidenceEvent*>& vec);
|
||||||
|
// 后台解析剩余的符合数数据
|
||||||
|
void parseRemainingConformDataInBackground(const QList<int>& conformCounts);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ConformityAnalysis *ui;
|
Ui::ConformityAnalysis *ui;
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ DetectorStatusSummary::~DetectorStatusSummary()
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 原有接口(仅修改样式表相关部分) ==========
|
|
||||||
void DetectorStatusSummary::setName(QString name)
|
void DetectorStatusSummary::setName(QString name)
|
||||||
{
|
{
|
||||||
ui->label_name->setText(name);
|
ui->label_name->setText(name);
|
||||||
|
|
@ -76,7 +75,6 @@ void DetectorStatusSummary::setColorMaxValue(int maxValue)
|
||||||
m_nMaxValue = maxValue;
|
m_nMaxValue = maxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关键:移除所有硬编码的样式表背景色
|
|
||||||
void DetectorStatusSummary::setInitWidgetColor()
|
void DetectorStatusSummary::setInitWidgetColor()
|
||||||
{
|
{
|
||||||
m_backgroundColor = QColor("#0E508A");
|
m_backgroundColor = QColor("#0E508A");
|
||||||
|
|
|
||||||
|
|
@ -209,12 +209,10 @@ void ThreeDDisplay::_updateSurfaceData()
|
||||||
// m_surface->axisZ()->setRange(minSecondary, maxSecondary);
|
// m_surface->axisZ()->setRange(minSecondary, maxSecondary);
|
||||||
if (flag)
|
if (flag)
|
||||||
{
|
{
|
||||||
qDebug()<< maxPrimary << maxSecondary;
|
|
||||||
m_surface->axisX()->setRange(0, maxPrimary);
|
m_surface->axisX()->setRange(0, maxPrimary);
|
||||||
m_surface->axisZ()->setRange(0, maxSecondary);
|
m_surface->axisZ()->setRange(0, maxSecondary);
|
||||||
flag = false;
|
flag = false;
|
||||||
}
|
}
|
||||||
qDebug()<<getMaxCount(dataMatrix);
|
|
||||||
m_surface->axisY()->setRange(0, getMaxCount(dataMatrix));
|
m_surface->axisY()->setRange(0, getMaxCount(dataMatrix));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ int main(int argc, char *argv[])
|
||||||
// 设置应用信息
|
// 设置应用信息
|
||||||
app.setApplicationName("EnergySpectrumAnalyer");
|
app.setApplicationName("EnergySpectrumAnalyer");
|
||||||
app.setApplicationVersion(QVersionNumber(1, 0, 0).toString());
|
app.setApplicationVersion(QVersionNumber(1, 0, 0).toString());
|
||||||
app.setApplicationDisplayName(QStringLiteral(u"符合能谱分测量析软件"));
|
app.setApplicationDisplayName(QStringLiteral(u"符合能谱测量分析软件"));
|
||||||
app.setOrganizationName(QStringLiteral("NINT,4,4"));
|
app.setOrganizationName(QStringLiteral("NINT,4,4"));
|
||||||
QString app_desc = QStringLiteral(u"\
|
QString app_desc = QStringLiteral(u"\
|
||||||
符合能谱测量分析软件是面向核物理符合测量场景的专用分析工具,\
|
符合能谱测量分析软件是面向核物理符合测量场景的专用分析工具,\
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ SOURCES += \
|
||||||
MeasureAnalysisProjectModel.cpp \
|
MeasureAnalysisProjectModel.cpp \
|
||||||
ParticleInjectTimeView/ParticleInjectTimeAnalysisView.cpp \
|
ParticleInjectTimeView/ParticleInjectTimeAnalysisView.cpp \
|
||||||
ParticleTimeDifferenceView/ParticleTimeDifferenceView.cpp \
|
ParticleTimeDifferenceView/ParticleTimeDifferenceView.cpp \
|
||||||
|
RegionOfInterest/RegionOfInterest.cpp \
|
||||||
VirtualTable/CsvDataSource.cpp \
|
VirtualTable/CsvDataSource.cpp \
|
||||||
VirtualTable/SampleDataSource.cpp \
|
VirtualTable/SampleDataSource.cpp \
|
||||||
VirtualTable/VirtualTableModel.cpp \
|
VirtualTable/VirtualTableModel.cpp \
|
||||||
|
|
@ -161,6 +162,7 @@ HEADERS += \
|
||||||
MeasureAnalysisProjectModel.h \
|
MeasureAnalysisProjectModel.h \
|
||||||
ParticleInjectTimeView/ParticleInjectTimeAnalysisView.h \
|
ParticleInjectTimeView/ParticleInjectTimeAnalysisView.h \
|
||||||
ParticleTimeDifferenceView/ParticleTimeDifferenceView.h \
|
ParticleTimeDifferenceView/ParticleTimeDifferenceView.h \
|
||||||
|
RegionOfInterest/RegionOfInterest.h \
|
||||||
VirtualTable/CsvDataSource.h \
|
VirtualTable/CsvDataSource.h \
|
||||||
VirtualTable/DataSource.h \
|
VirtualTable/DataSource.h \
|
||||||
VirtualTable/SampleDataSource.h \
|
VirtualTable/SampleDataSource.h \
|
||||||
|
|
@ -187,6 +189,7 @@ FORMS += \
|
||||||
MeasureDeviceParamsConfigView/DeviceParamsTableForm.ui \
|
MeasureDeviceParamsConfigView/DeviceParamsTableForm.ui \
|
||||||
ParticleCountPlotView/BatchEnergyScaleDialog.ui \
|
ParticleCountPlotView/BatchEnergyScaleDialog.ui \
|
||||||
NewMeasureAnalysisDlg.ui \
|
NewMeasureAnalysisDlg.ui \
|
||||||
|
RegionOfInterest/RegionOfInterest.ui \
|
||||||
ThreeDimensionalConformityAnalysisView/DetectorStatusSummary.ui \
|
ThreeDimensionalConformityAnalysisView/DetectorStatusSummary.ui \
|
||||||
ThreeDimensionalConformityAnalysisView/ParticleDataStatistics.ui \
|
ThreeDimensionalConformityAnalysisView/ParticleDataStatistics.ui \
|
||||||
ThreeDimensionalConformityAnalysisView/ThreeDDisplay.ui \
|
ThreeDimensionalConformityAnalysisView/ThreeDDisplay.ui \
|
||||||
|
|
@ -203,3 +206,4 @@ contains(DEFINES, ENABLE_DEBUG) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user