From 558a3256e0ec180003b1a9019d3c45a10979fe69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B5=B7?= Date: Sat, 21 Mar 2026 00:26:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=83=BD=E9=87=8F=E8=AE=A1?= =?UTF-8?q?=E6=95=B0=E6=95=B0=E6=8D=AE=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/DataCalcProcess/EnergyEfficiencyFit.cpp | 4 +- src/DataCalcProcess/MathModelDefine.cpp | 2 +- src/DataProcessWorkPool.cpp | 80 +++++++++++++++---- src/DataProcessWorkPool.h | 5 +- src/EnergyScaleDataModel.cpp | 20 +++++ src/EnergyScaleDataModel.h | 6 ++ src/MainWindow.cpp | 4 +- .../BatchEnergyScaleDialog.cpp | 2 +- .../MeasureAnalysisParticleCountPlotView.cpp | 4 +- src/NewMeasureAnalysisDlg.cpp | 13 +-- 10 files changed, 109 insertions(+), 31 deletions(-) diff --git a/src/DataCalcProcess/EnergyEfficiencyFit.cpp b/src/DataCalcProcess/EnergyEfficiencyFit.cpp index ae89a4c..08a00ff 100644 --- a/src/DataCalcProcess/EnergyEfficiencyFit.cpp +++ b/src/DataCalcProcess/EnergyEfficiencyFit.cpp @@ -12,7 +12,7 @@ arma::vec EnergyEfficiencyFit::SemiEmpiricalFit(const arma::vec &E, const arma:: { // 输入数据有效性检查 if (E.n_elem != eps.n_elem) { - throw(string("错误:能量数据和效率数据长度不匹配!")); + throw(string("错误:能量数据和效率数据长度不匹配!")); } if (E.n_elem <= order) { stringstream ss_error; @@ -22,7 +22,7 @@ arma::vec EnergyEfficiencyFit::SemiEmpiricalFit(const arma::vec &E, const arma:: } if (order < 0) { stringstream ss_error; - ss_error << "错误:多项式阶数不能为负数!"; + ss_error << "错误:多项式阶数不能为负数!"; throw(ss_error.str()); } diff --git a/src/DataCalcProcess/MathModelDefine.cpp b/src/DataCalcProcess/MathModelDefine.cpp index 1acbe52..f4239eb 100644 --- a/src/DataCalcProcess/MathModelDefine.cpp +++ b/src/DataCalcProcess/MathModelDefine.cpp @@ -237,7 +237,7 @@ double EfficiencyExperimentalCalc(int N, double A, double P, double t) double EnergyEfficiency(double E, const vec &coeffs) { if (E <= 0) { - throw std::string("能量数据必须为正数!"); + throw std::string("能量数据必须为正数!"); } double tmp_value = 0.0f; diff --git a/src/DataProcessWorkPool.cpp b/src/DataProcessWorkPool.cpp index 39df6f9..841bb7c 100644 --- a/src/DataProcessWorkPool.cpp +++ b/src/DataProcessWorkPool.cpp @@ -234,7 +234,7 @@ bool EveryChannelParticleCountDataTask::processEveryChannelParticleData() try { // 统计每个通道的粒子计数(相同板卡号通道号相同道址) - QMap> channel_address_counts; // 通道号 -> 地址 -> 计数 + QMap> channel_address_counts; // 通道号 -> 地址 -> 计数 // 统计所有通道的粒子计数(不同板卡号通道号相同道址) // QMap all_channel_address_counts; // 地址 -> 计数 @@ -263,7 +263,7 @@ bool EveryChannelParticleCountDataTask::processEveryChannelParticleData() // 统计每个通道的粒子计数 if (!channel_address_counts.contains(channel_num)) { - channel_address_counts[channel_num] = QMap(); + channel_address_counts[channel_num] = QMap(); } channel_address_counts[channel_num][address]++; @@ -289,12 +289,12 @@ bool EveryChannelParticleCountDataTask::processEveryChannelParticleData() // 批量写入数据 for (auto channel_it = channel_address_counts.begin(); channel_it != channel_address_counts.end(); ++channel_it) { uint channel_num = channel_it.key(); - const QMap& address_counts = channel_it.value(); + const QMap& address_counts = channel_it.value(); auto out_stream = channel_file_streams[channel_num]; for (auto address_it = address_counts.begin(); address_it != address_counts.end(); ++address_it) { uint address = address_it.key(); - uint count = address_it.value(); + unsigned long long count = address_it.value(); *out_stream << address << "," << count << std::endl; } } @@ -731,15 +731,20 @@ bool ChannelEnergyScaleFittingTask::processTask() return true; } -bool ApplyEnergyScaleTask::scaleParticleData(EnergyScaleDataModel& energy_scale_data_model, const QString& data_filename, const QString& out_filename) +bool ApplyEnergyScaleTask::scaleParticleData(MeasureAnalysisProjectModel* project_model, EnergyScaleDataModel& energy_scale_data_model) { bool ok = true; + const QString& all_channel_particle_data_filename = project_model->GetAllChannelParticleDataFilename(); + if (all_channel_particle_data_filename.isEmpty()) { + return ok &= false; + } + const QString& energy_spectrum_filename = QDir(project_model->GetProjectDir()).filePath(QStringLiteral(u"能谱数据.csv")); std::string board_id_str = QString(QStringLiteral(u"板卡号")).toStdString(); std::string channel_id_str = QString(QStringLiteral(u"通道号")).toStdString(); std::string address_str = QString(QStringLiteral(u"道址")).toStdString(); std::string energy_str = QString(QStringLiteral(u"能量(KeV)")).toStdString(); std::string time_str = QString(QStringLiteral(u"时间计数")).toStdString(); - std::ofstream out(QStrToSysPath(out_filename)); + std::ofstream out(QStrToSysPath(energy_spectrum_filename)); out << board_id_str << "," << channel_id_str << "," << energy_str << "," << time_str<< "\n" ; try { io::CSVReader< @@ -748,7 +753,7 @@ bool ApplyEnergyScaleTask::scaleParticleData(EnergyScaleDataModel& energy_scale_ io::double_quote_escape<',', '"'>, io::throw_on_overflow, io::empty_line_comment> - reader(QStrToSysPath(data_filename)); + reader(QStrToSysPath(all_channel_particle_data_filename)); reader.read_header(io::ignore_extra_column, board_id_str, channel_id_str, address_str, time_str); uint board_id; uint channel_id; @@ -764,14 +769,62 @@ bool ApplyEnergyScaleTask::scaleParticleData(EnergyScaleDataModel& energy_scale_ out.close(); } catch (const std::exception& e) { out.close(); - std::remove(QStrToSysPath(out_filename)); + std::remove(QStrToSysPath(energy_spectrum_filename)); + ok &= false; + const QString& e_what = QString::fromStdString(e.what()); + LOG_WARN(QStringLiteral(u"能谱数据异常:%1").arg(e_what)); } return ok; } -bool ApplyEnergyScaleTask::energyCountProcess() +bool ApplyEnergyScaleTask::energyCountProcess(MeasureAnalysisProjectModel* project_model, EnergyScaleDataModel& energy_scale_data_model) { bool ok = true; + const QMap& ch_addr_count_filename_list = project_model->GetChannelAddressCountDataFilenameList(); + if (ch_addr_count_filename_list.isEmpty()) { + LOG_WARN(QStringLiteral(u"能量计数统计需要的通道道址计数文件异常!")); + return ok &= false; + } + const QString& out_path = QDir(project_model->GetProjectDir()).filePath(QStringLiteral(u"能量计数")); + if ( !QDir(out_path).mkpath(out_path) ) { + LOG_WARN(QStringLiteral(u"创建能量计数数据目录\"%1\"异常!").arg(out_path)); + return ok &= false; + } + QMap every_ch_energy_count_filename_list; + for (const int& channel_num : ch_addr_count_filename_list.keys()) { + const QString& channel_name = QStringLiteral(u"通道%1").arg(channel_num); + const QString& data_filename = ch_addr_count_filename_list[channel_num]; + std::string address_str = QString(QStringLiteral(u"道址")).toStdString(); + std::string energy_str = QString(QStringLiteral(u"能量(KeV)")).toStdString(); + std::string count_str = QString(QStringLiteral(u"计数")).toStdString(); + const QString& out_filename = QDir(out_path).filePath(channel_name + ".csv"); + std::ofstream out(QStrToSysPath(out_filename)); + out << energy_str << "," << count_str << "\n" ; + try { + io::CSVReader< + 2, + io::trim_chars<' ', '\t'>, + io::double_quote_escape<',', '"'>, + io::throw_on_overflow, + io::empty_line_comment> + reader(QStrToSysPath(data_filename)); + reader.read_header(io::ignore_extra_column, address_str, count_str); + uint address; + unsigned long long count; + while (reader.read_row(address, count)) { + auto coeffs = energy_scale_data_model.GetEnergyFitResultCoeffs(channel_name); + double energy = GaussPolyCoe::Predict(coeffs, address); + out << energy << "," << count << "\n"; + } + out.close(); + every_ch_energy_count_filename_list[channel_num] = out_filename; + } catch (const std::exception& e) { + out.close(); + std::remove(QStrToSysPath(out_filename)); + const QString& e_what = QString::fromStdString(e.what()); + LOG_WARN(QStringLiteral(u"%1能量计数异常:%2").arg(channel_name).arg(e_what)); + } + } return ok; } @@ -795,15 +848,10 @@ bool ApplyEnergyScaleTask::processTask() if (!energy_scale_data_model.IsValid()) { return false; } - const QString& all_channel_particle_data_filename = project_model->GetAllChannelParticleDataFilename(); - if (all_channel_particle_data_filename.isEmpty()) { + if (!scaleParticleData(project_model, energy_scale_data_model)) { return false; } - const QString& energy_spectrum_filename = QDir(project_model->GetProjectDir()).filePath(QStringLiteral(u"能谱数据.csv")); - if (!scaleParticleData(energy_scale_data_model, all_channel_particle_data_filename, energy_spectrum_filename)) { - return false; - } - if (!energyCountProcess()) { + if (!energyCountProcess(project_model, energy_scale_data_model)) { return false; } if (!coincidenceProcess()) { diff --git a/src/DataProcessWorkPool.h b/src/DataProcessWorkPool.h index 65af2b8..24d20f1 100644 --- a/src/DataProcessWorkPool.h +++ b/src/DataProcessWorkPool.h @@ -9,6 +9,7 @@ #include class EnergyScaleDataModel; +class MeasureAnalysisProjectModel; namespace DataProcessWorkPool { @@ -130,8 +131,8 @@ namespace DataProcessWorkPool class ApplyEnergyScaleTask : public DataProcessTask { private: - bool scaleParticleData(EnergyScaleDataModel &energy_scale_data_model, const QString& data_filename, const QString& out_filename); - bool energyCountProcess(); + bool scaleParticleData(MeasureAnalysisProjectModel* project_model, EnergyScaleDataModel &energy_scale_data_model); + bool energyCountProcess(MeasureAnalysisProjectModel* project_model, EnergyScaleDataModel& energy_scale_data_model); bool coincidenceProcess(); virtual bool processTask() override; private: diff --git a/src/EnergyScaleDataModel.cpp b/src/EnergyScaleDataModel.cpp index 5007a99..c841bcd 100644 --- a/src/EnergyScaleDataModel.cpp +++ b/src/EnergyScaleDataModel.cpp @@ -62,6 +62,26 @@ bool EnergyScaleDataModel::IsValid() return b_is_valid; } +void EnergyScaleDataModel::SetName(const QString &name) +{ + _energy_scale_data_map["Name"] = name; +} + +QString EnergyScaleDataModel::GetName() +{ + return _energy_scale_data_map.value("Name", QString()).toString(); +} + +void EnergyScaleDataModel::SetDescription(const QString &description) +{ + _energy_scale_data_map["Description"] = description; +} + +QString EnergyScaleDataModel::GetDescription() +{ + return _energy_scale_data_map.value("Description", QString()).toString(); +} + void EnergyScaleDataModel::SetChannelEnergyScaleDataMap(const QString& channel_name, const QVariantMap& ch_energy_scale_data_map) { if (!ch_energy_scale_data_map.isEmpty()) { diff --git a/src/EnergyScaleDataModel.h b/src/EnergyScaleDataModel.h index 57f5f8b..2f2cfea 100644 --- a/src/EnergyScaleDataModel.h +++ b/src/EnergyScaleDataModel.h @@ -17,6 +17,12 @@ public: bool SaveData(); bool IsValid(); + void SetName(const QString& name); + QString GetName(); + + void SetDescription(const QString& description); + QString GetDescription(); + void SetChannelEnergyScaleDataMap(const QString& channel_name, const QVariantMap& ch_energy_scale_data_map); QVariantMap GetChannelEnergyScaleDataMap(const QString& channel_name); diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 7e1c88e..9bccdaf 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -175,7 +175,7 @@ void MainWindow::initAction() } QFileInfo file_info(filename); if (file_info.size() == 0) { - QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"选择的测量分析项目文件为空文件!")); + QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"选择的测量分析项目文件为空文件!")); return; } MeasureAnalysisProjectModel* model = new MeasureAnalysisProjectModel; @@ -192,7 +192,7 @@ void MainWindow::initAction() const QString& info_text = QStringLiteral(u"保存测量分析项目\"%1\"完成.").arg(project_name); LOG_INFO(info_text); } else { - const QString& warn_text = QStringLiteral(u"保存测量分析项目\"%1\"失败!").arg(project_name); + const QString& warn_text = QStringLiteral(u"保存测量分析项目\"%1\"失败!").arg(project_name); LOG_WARN(warn_text); } } diff --git a/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp b/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp index 200a0d5..c70decf 100644 --- a/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp +++ b/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp @@ -361,7 +361,7 @@ void BatchEnergyScaleDialog::applyEnergyScaleFitResultData() LOG_WARN(QStringLiteral(u"应用能量刻度异常,无法配置到测量分析[%1]!").arg(project_model->GetProjectName())); } } else { - QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"不能应用非完整的能量刻度!")); + QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"不能应用非完整的能量刻度!")); } } diff --git a/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp b/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp index a53c5e6..452d213 100644 --- a/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp +++ b/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp @@ -212,8 +212,8 @@ void MeasureAnalysisParticleCountPlotView::loadDataFromFile(const QString& data_ reader.read_header(io::ignore_extra_column, address_str, count_str); int address; - int particle_count; - QVector x, y; + unsigned long long particle_count; + QVector x, y; while (reader.read_row(address, particle_count)) { x.push_back(address); diff --git a/src/NewMeasureAnalysisDlg.cpp b/src/NewMeasureAnalysisDlg.cpp index b41de85..7b39e66 100644 --- a/src/NewMeasureAnalysisDlg.cpp +++ b/src/NewMeasureAnalysisDlg.cpp @@ -66,7 +66,7 @@ void NewMeasureAnalysisDlg::initialization() } QFileInfo file_info(filename); if (file_info.size() == 0) { - QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"选择的粒子数据文件为空文件!")); + QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"选择的粒子数据文件为空文件!")); return; } ui->lineEdit_filename->setText(file_info.fileName()); @@ -179,7 +179,7 @@ void NewMeasureAnalysisDlg::on_btn_ok_clicked() { const QString& project_name = ui->lineEdit_name->text(); if (project_name.isEmpty()) { - QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"请输入测量分析名称!")); + QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"请输入测量分析名称!")); return; } QString projects_dir_path = QDir(qApp->applicationDirPath()).filePath("Projects"); @@ -187,14 +187,17 @@ void NewMeasureAnalysisDlg::on_btn_ok_clicked() QString project_dir_path = projects_dir.filePath(project_name); QDir project_dir(project_dir_path); if (project_dir.exists()) { - QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"测量分析名称已存在,请重新输入!")); + QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"测量分析名称已存在,请重新输入!")); + return; + } + if ( !project_dir.mkpath(project_dir_path) ) { + QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"创建测量分析项目工作目录失败:\n%1!").arg(project_dir_path)); return; } - project_dir.mkpath(project_dir_path); if ( ui->checkBox_file_data->isChecked() ) { const QString& data_file_path = ui->lineEdit_filename->property("data_file_path").toString(); if (data_file_path.isEmpty()) { - QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"请选择粒子数据文件!")); + QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"请选择粒子数据文件!")); return; } auto separate_task = new DataProcessWorkPool::ParticleDataSortTask;