From 2c38e2414aa9e3a43dcf359bba0dc6b98eeea0cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B5=B7?= Date: Fri, 20 Mar 2026 19:12:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=83=BD=E8=B0=B1=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=94=9F=E6=88=90=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/DataCalcProcess/GaussPolyCoe.cpp | 5 +- src/DataCalcProcess/MathModelDefine.cpp | 4 +- src/DataProcessWorkPool.cpp | 85 ++++++++++++++++--- src/DataProcessWorkPool.h | 5 ++ .../BatchEnergyScaleDialog.cpp | 8 ++ src/MeasureAnalysisProjectModel.cpp | 20 +---- src/MeasureAnalysisProjectModel.h | 23 +---- 7 files changed, 99 insertions(+), 51 deletions(-) diff --git a/src/DataCalcProcess/GaussPolyCoe.cpp b/src/DataCalcProcess/GaussPolyCoe.cpp index 8cb6007..cca7f91 100644 --- a/src/DataCalcProcess/GaussPolyCoe.cpp +++ b/src/DataCalcProcess/GaussPolyCoe.cpp @@ -1,4 +1,4 @@ -#include "GaussPolyCoe.h" +#include "GaussPolyCoe.h" using namespace std; @@ -78,10 +78,11 @@ vector GaussPolyCoe::PolynomialFit(const vector& x, const vector double GaussPolyCoe::Predict(const vector& coeffs, double x) { - double result = 0.0; + double result = 0.0f; for (int i = 0; i < coeffs.size(); ++i) { result += coeffs[i] * pow(x, i); } + result = round(result * 1000) / 1000.0f; return result; } diff --git a/src/DataCalcProcess/MathModelDefine.cpp b/src/DataCalcProcess/MathModelDefine.cpp index e9f9908..1acbe52 100644 --- a/src/DataCalcProcess/MathModelDefine.cpp +++ b/src/DataCalcProcess/MathModelDefine.cpp @@ -43,7 +43,9 @@ double FwhmModel(double E, const vec& p) { double k = p(0); double c = p(1); - return k * sqrt(E) + c; + double fwhm = k * sqrt(E) + c; + fwhm = round(fwhm * 1000) / 1000.0f; + return fwhm; } // 高斯模型: y = A * exp(-pow(x - mu, 2) / (2 * pow(sigma, 2))) diff --git a/src/DataProcessWorkPool.cpp b/src/DataProcessWorkPool.cpp index 1f04f85..39df6f9 100644 --- a/src/DataProcessWorkPool.cpp +++ b/src/DataProcessWorkPool.cpp @@ -147,14 +147,12 @@ bool EveryChannelParticleDataSeparateTask::processEveryChannelParticleData() uint address; unsigned long long time; while (reader.read_row(board_id, channel_id, address, time)) { - // 板卡和通道号计算,通道号 = 板卡号 * 4 + 通道号 int channel_num = (board_id) * 4 + (channel_id + 1); QString particle_data_filename = result_data_output_dir.filePath(QStringLiteral(u"通道%1粒子数据.csv").arg(channel_num)); if (!particle_data_filename_list.contains(channel_num)) { particle_data_filename_list.insert(channel_num, particle_data_filename); } - if (!ch_particle_data_of_list.contains(channel_num)) { std::shared_ptr out( new std::ofstream(QStrToSysPath(particle_data_filename), std::ios::out | std::ios::app), @@ -428,11 +426,11 @@ std::vector splitFile(const std::string& input_file, size_t chunk_s return a.time < b.time; }); std::string chunk_file = input_file + ".chunk" + std::to_string(chunk_index); - std::ofstream outFile(chunk_file); + std::ofstream out_file(chunk_file); for (const auto& row : rows) { - outFile << row.board_id << "," << row.channel_id << "," << row.address << "," << row.time << "\n"; + out_file << row.board_id << "," << row.channel_id << "," << row.address << "," << row.time << "\n"; } - outFile.close(); + out_file.close(); chunks.push_back(chunk_file); chunk_index++; } @@ -647,8 +645,7 @@ bool AutoFindPeaksTask::processTask() return true; } -void ChannelEnergyScaleFittingTask::SetData( - const FitDataMap& channel_energy_scale_fit_data_map, const QMap& fit_degree_map) +void ChannelEnergyScaleFittingTask::SetData(const FitDataMap& channel_energy_scale_fit_data_map, const QMap& fit_degree_map) { this->_channel_energy_scale_fit_data_map = channel_energy_scale_fit_data_map; this->_fit_degree_map = fit_degree_map; @@ -734,17 +731,85 @@ bool ChannelEnergyScaleFittingTask::processTask() return true; } -bool ApplyEnergyScaleTask::processTask() +bool ApplyEnergyScaleTask::scaleParticleData(EnergyScaleDataModel& energy_scale_data_model, const QString& data_filename, const QString& out_filename) { bool ok = true; + 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)); + out << board_id_str << "," << channel_id_str << "," << energy_str << "," << time_str<< "\n" ; + try { + io::CSVReader< + 4, + 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, board_id_str, channel_id_str, address_str, time_str); + uint board_id; + uint channel_id; + uint address; + unsigned long long time; + while (reader.read_row(board_id, channel_id, address, time)) { + int channel_num = (board_id) * 4 + (channel_id + 1); + const QString& channel_name = QStringLiteral(u"通道%1").arg(channel_num); + auto coeffs = energy_scale_data_model.GetEnergyFitResultCoeffs(channel_name); + double energy = GaussPolyCoe::Predict(coeffs, address); + out << board_id << "," << channel_id << "," << energy << "," << time << "\n"; + } + out.close(); + } catch (const std::exception& e) { + out.close(); + std::remove(QStrToSysPath(out_filename)); + } + return ok; +} +bool ApplyEnergyScaleTask::energyCountProcess() +{ + bool ok = true; + return ok; +} + +bool ApplyEnergyScaleTask::coincidenceProcess() +{ + bool ok = true; + return ok; +} + +bool ApplyEnergyScaleTask::processTask() +{ const QString& project_name = GetProjectName(); MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(project_name); if (project_model == nullptr) { return false; } + EnergyScaleDataModel energy_scale_data_model(project_model->GetEnergyScaleFilename()); + if (!energy_scale_data_model.LoadData()) { + return false; + } + 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()) { + 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()) { + return false; + } + if (!coincidenceProcess()) { + return false; + } const QString& info = QStringLiteral(u"应用能量刻度完成."); LOG_INFO(info); - - return ok; + return true; } diff --git a/src/DataProcessWorkPool.h b/src/DataProcessWorkPool.h index 1871d80..65af2b8 100644 --- a/src/DataProcessWorkPool.h +++ b/src/DataProcessWorkPool.h @@ -8,6 +8,8 @@ #include #include +class EnergyScaleDataModel; + namespace DataProcessWorkPool { class DataProcessTask : public QRunnable @@ -128,6 +130,9 @@ 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 coincidenceProcess(); virtual bool processTask() override; private: QString _project_name; diff --git a/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp b/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp index a66df25..200a0d5 100644 --- a/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp +++ b/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp @@ -347,10 +347,18 @@ void BatchEnergyScaleDialog::applyEnergyScaleFitResultData() } QDir project_dir(project_model->GetProjectDir()); const QString& energy_scale_data_filename = project_dir.filePath(QStringLiteral(u"能量刻度.json")); + if ( QFileInfo(energy_scale_data_filename).exists() ) { + if ( !QFile::remove(energy_scale_data_filename) ) { + LOG_WARN(QStringLiteral(u"应用能量刻度异常,无法清除测量分析[%1]存在的能量刻度数据!").arg(project_model->GetProjectName())); + return; + } + } const QString& energy_scale_result_filename = this->_energy_scale_data_model->GetDataFilename(); if (QFile::copy(energy_scale_result_filename, energy_scale_data_filename)) { project_model->SetEnergyScaleFilename(energy_scale_data_filename); ProjectList::Instance()->ApplyEnergyScale(this->_project_name); + } else { + LOG_WARN(QStringLiteral(u"应用能量刻度异常,无法配置到测量分析[%1]!").arg(project_model->GetProjectName())); } } else { QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"不能应用非完整的能量刻度!")); diff --git a/src/MeasureAnalysisProjectModel.cpp b/src/MeasureAnalysisProjectModel.cpp index 7e06d12..73cb068 100644 --- a/src/MeasureAnalysisProjectModel.cpp +++ b/src/MeasureAnalysisProjectModel.cpp @@ -73,11 +73,6 @@ void MeasureAnalysisProjectModel::SetAllChannelParticleDataFilename(const QStrin this->_all_channel_particle_data_filename = filename; } -void MeasureAnalysisProjectModel::SetSortedParticleDataFilename(const QString& filename) -{ - this->_sorted_particle_data_filename = filename; -} - // void MeasureAnalysisProjectModel::SetChannelParticleDataFilename(uint channel, const QString& filename) // { // this->_channel_particle_data_filename_list[channel] = filename; @@ -173,11 +168,6 @@ const QString& MeasureAnalysisProjectModel::GetAllChannelParticleDataFilename() return this->_all_channel_particle_data_filename; } -const QString& MeasureAnalysisProjectModel::GetSortAllChannelParticleDataFilename() const -{ - return this->_sorted_particle_data_filename; -} - // const QMap& MeasureAnalysisProjectModel::GetChannelParticleDataFilenameList() const // { // return this->_channel_particle_data_filename_list; @@ -307,7 +297,6 @@ bool MeasureAnalysisProjectModel::LoadProjectModel(const QString& project_filena this->_efficiency_scale_filename = ProjectAbsFilename(json_obj["EfficiencyScaleFilename"].toString()); this->_all_channel_particle_data_filename = ProjectAbsFilename(json_obj["AllChannelParticleDataFilename"].toString()); - this->_sorted_particle_data_filename = ProjectAbsFilename(json_obj["SortedParticleDataFilename"].toString()); const auto& address_count_data_filename_list = json_obj["ChannelAddressCountDataFilenameList"].toObject().toVariantMap(); for (auto it = address_count_data_filename_list.constBegin(); it!=address_count_data_filename_list.constEnd(); ++it) { @@ -369,7 +358,6 @@ bool MeasureAnalysisProjectModel::SaveProjectModel() project_json_obj_map["EnergyScaleFilename"] = ProjectRelativeFilename(this->_energy_scale_filename); project_json_obj_map["EfficiencyScaleFilename"] = ProjectRelativeFilename(this->_efficiency_scale_filename); project_json_obj_map["AllChannelParticleDataFilename"] = ProjectRelativeFilename(this->_all_channel_particle_data_filename); - project_json_obj_map["SortedParticleDataFilename"] = ProjectRelativeFilename(this->_sorted_particle_data_filename); QVariantMap channel_address_count_data_filename_list; for (auto it = this->_channel_address_count_data_filename_list.constBegin(); it != this->_channel_address_count_data_filename_list.constEnd(); ++it) { channel_address_count_data_filename_list[QString::number(it.key())] = ProjectRelativeFilename(it.value()); @@ -619,7 +607,7 @@ void MeasureAnalysisProjectModelList::ApplyEnergyScale(const QString &project_na auto pro_model = this->_project_models[project_name]; const QString& energy_scale_filename = pro_model->GetEnergyScaleFilename(); QString status = QStringLiteral(u"未配置"); - if (energy_scale_filename.isEmpty()) { + if (!energy_scale_filename.isEmpty()) { status = QStringLiteral(u"已配置"); auto& node_map = this->_project_node_items[project_name]; const QString& energy_scale_item_name = QStringLiteral(u"能量刻度"); @@ -844,7 +832,7 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProje node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = pro_model->GetSortAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + status = pro_model->GetAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::CountingRateView); item_name = QStringLiteral(u"计数率分析"); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); @@ -865,14 +853,14 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProje node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = pro_model->GetSortAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + status = pro_model->GetAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::ParticleInTimeView); item_name = QStringLiteral(u"粒子入射时间分析"); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = pro_model->GetSortAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + status = pro_model->GetAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::ParticleTimeDiffView); item_name = QStringLiteral(u"粒子时间差分析"); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); diff --git a/src/MeasureAnalysisProjectModel.h b/src/MeasureAnalysisProjectModel.h index 3e903ca..abae6f9 100644 --- a/src/MeasureAnalysisProjectModel.h +++ b/src/MeasureAnalysisProjectModel.h @@ -28,23 +28,16 @@ public: void SetMeasurePresetTime(ulong measure_preset_time); void SetConformTimeWin(uint conform_time_win); void SetIsMeasureComplete(bool is_measure_complete); - void SetMeasureDeviceParamsCfgFilename(const QString& filename); void SetEnergyScaleFilename(const QString& filename); void SetEfficiencyScaleFilename(const QString& filename); - void SetAllChannelParticleDataFilename(const QString& filename); - void SetSortedParticleDataFilename(const QString& filename); // void SetChannelParticleDataFilename(uint channel, const QString& filename); - void SetChannelAddressCountDataFilename(uint channel, const QString& filename); // void SetAllChannelParticleTotalCountDataFilename(const QString& filename); - void SetChannelEnergyCountDataFilename(uint channel, const QString& filename); void SetAllChannelEnergyTotalCountDataFilename(const QString& filename); - void SetTimeWinConformParticleData(uint time_win, uint conform_particle_count, const QString& filename); - void SetAnalysisCustomData(AnalysisType analysis_type, const QString& data_item_name, const QString& data_filename); const QString& GetProjectDir() const; @@ -58,23 +51,16 @@ public: const QString& GetMeasureDeviceParamsCfgFilename() const; const QString& GetEnergyScaleFilename() const; const QString& GetEfficiencyScaleFilename() const; - const QString& GetAllChannelParticleDataFilename() const; - const QString& GetSortAllChannelParticleDataFilename() const; - // const QMap& GetChannelParticleDataFilenameList() const; // const QString& GetChannelParticleDataFilename(uint channel) const; - const QMap& GetChannelAddressCountDataFilenameList() const; const QString GetChannelAddressCountDataFilename(uint channel) const; // const QString& GetAllChannelParticleTotalCountDataFilename() const; - const QMap& GetChannelEnergyCountDataFilenameList() const; const QString GetChannelEnergyCountDataFilename(uint channel) const; const QString& GetAllChannelEnergyTotalCountDataFilename() const; - const QMap GetTimeWinConformParticleDataFilenameList(uint time_win) const; - const QString GetAnalysisCustomData(AnalysisType analysis_type, const QString& data_item_name); private: @@ -85,25 +71,18 @@ private: QString _description_info; ulong _measure_preset_time = 0; uint _conform_time_win = 50; - bool _is_measure_complete = false; - + QString _measure_device_params_cfg_filename; QString _energy_scale_filename; QString _efficiency_scale_filename; - QString _all_channel_particle_data_filename; - QString _sorted_particle_data_filename; // QMap _channel_particle_data_filename_list; - QMap _channel_address_count_data_filename_list; // QString _all_channel_particle_total_count_data_filename; - QMap _channel_energy_count_data_filename_list; QString _all_channel_energy_total_count_data_filename; - QMap > _time_win_conform_particle_data; - QMap > _analysis_custom_data_set; public: