From 1ba84d36ee35042b5cff194962a0d6e815cb0612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B5=B7?= Date: Fri, 20 Mar 2026 15:45:18 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=A4=84=E7=90=86=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/DataProcessWorkPool.cpp | 108 ++++++++-------- src/DataProcessWorkPool.h | 12 ++ src/MainWindow.cpp | 22 +--- .../BatchEnergyScaleDialog.cpp | 7 +- .../BatchEnergyScaleDialog.h | 4 +- .../MeasureAnalysisParticleCountPlotView.cpp | 6 +- .../MeasureAnalysisParticleCountPlotView.h | 5 +- src/MeasureAnalysisProjectModel.cpp | 75 ++++++++++- src/MeasureAnalysisProjectModel.h | 7 +- src/MeasureAnalysisTreeView.cpp | 1 + src/NewMeasureAnalysisDlg.cpp | 122 ++++++++++++------ src/NewMeasureAnalysisDlg.h | 2 + src/NewMeasureAnalysisDlg.ui | 28 +++- 13 files changed, 275 insertions(+), 124 deletions(-) diff --git a/src/DataProcessWorkPool.cpp b/src/DataProcessWorkPool.cpp index c967239..1f04f85 100644 --- a/src/DataProcessWorkPool.cpp +++ b/src/DataProcessWorkPool.cpp @@ -62,16 +62,24 @@ void DataProcessTask::run() if (!IsValidSetWorkParameters()) { return; } - - if (!processTask()) { - return; - } - + bool task_ok = processTask(); if ((GetFinishedNotifier() != nullptr) && (GetFinishedNotifierProcess() != nullptr)) { - QMetaObject::invokeMethod(_finished_notifier, _finished_notifier_process, Qt::QueuedConnection, Q_ARG(QString, _project_name)); + QMetaObject::invokeMethod( + _finished_notifier, + _finished_notifier_process, + Qt::QueuedConnection, + Q_ARG(bool, task_ok), + Q_ARG(QString, _project_name), + Q_ARG(QVariant, _task_result_data) + ); } } +void DataProcessTask::updateTaskResultData(const QVariant &task_result_data) +{ + this->_task_result_data = task_result_data; +} + void ParticleDataTask::SetAllChannelParticleDataFilename(const QString& all_channel_particle_data_filename) { this->_all_channel_particle_data_filename = all_channel_particle_data_filename; @@ -336,7 +344,8 @@ bool EveryChannelParticleCountDataTask::processEveryChannelParticleData() // 更新项目模型中的所有通道粒子总计数数据文件名 // project_model->SetAllChannelParticleTotalCountDataFilename(all_channel_total_count_filename); } - + const QString& info = QStringLiteral(u"所有通道粒子计数处理完成."); + LOG_INFO(info); return ret_ok; } @@ -389,17 +398,16 @@ std::vector splitFile(const std::string& input_file, size_t chunk_s > reader(input_file); reader.read_header(io::ignore_extra_column, board_id_str, channel_id_str, address_str, time_str); - int chunkIndex = 0; + int chunk_index = 0; while (true) { std::vector rows; - size_t currentSize = 0; + size_t current_size = 0; uint board_id; uint channel_id; uint address; unsigned long long time; - while (reader.read_row(board_id, channel_id, address, time)) { CsvRow row; row.board_id = board_id; @@ -408,63 +416,56 @@ std::vector splitFile(const std::string& input_file, size_t chunk_s row.time = time; // Estimate row size - currentSize += std::to_string(board_id).size() + std::to_string(channel_id).size() + std::to_string(address).size() + std::to_string(time).size() + 4; // +4 for commas - - if (currentSize > chunk_size && !rows.empty()) { + current_size += std::to_string(board_id).size() + std::to_string(channel_id).size() + std::to_string(address).size() + std::to_string(time).size() + 4; + if (current_size > chunk_size && !rows.empty()) { break; } - rows.push_back(row); } - if (rows.empty()) break; - std::sort(rows.begin(), rows.end(), [](const CsvRow& a, const CsvRow& b) { return a.time < b.time; }); - - std::string chunkFile = input_file + ".chunk" + std::to_string(chunkIndex); - std::ofstream outFile(chunkFile); + std::string chunk_file = input_file + ".chunk" + std::to_string(chunk_index); + std::ofstream outFile(chunk_file); for (const auto& row : rows) { outFile << row.board_id << "," << row.channel_id << "," << row.address << "," << row.time << "\n"; } outFile.close(); - - chunks.push_back(chunkFile); - chunkIndex++; + chunks.push_back(chunk_file); + chunk_index++; } } catch (const std::exception& e) { throw(e); } - return chunks; } void mergeChunks(const std::vector& chunks, const std::string& output_file) { - std::vector>> chunkReaders; - std::priority_queue minHeap; + std::vector>> chunk_readers; + std::priority_queue min_heap; for (const auto& chunk : chunks) { auto reader = std::make_unique>(chunk); - chunkReaders.push_back(std::move(reader)); + chunk_readers.push_back(std::move(reader)); } - for (size_t i = 0; i < chunkReaders.size(); i++) { + for (size_t i = 0; i < chunk_readers.size(); i++) { uint board_id; uint channel_id; uint address; unsigned long long time; - if (chunkReaders[i]->read_row(board_id, channel_id, address, time)) { + if (chunk_readers[i]->read_row(board_id, channel_id, address, time)) { CsvRow row; row.board_id = board_id; row.channel_id = channel_id; row.address = address; row.time = time; row.chunk_index = i; - minHeap.push(row); + min_heap.push(row); } } @@ -475,35 +476,33 @@ void mergeChunks(const std::vector& chunks, const std::string& outp std::ofstream outFile(output_file); outFile << board_id_str << "," << channel_id_str << "," << address_str << "," << time_str << "\n"; - while (!minHeap.empty()) { - CsvRow current = minHeap.top(); - minHeap.pop(); + while (!min_heap.empty()) { + CsvRow current = min_heap.top(); + min_heap.pop(); outFile << current.board_id << "," << current.channel_id << "," << current.address << "," << current.time << "\n"; size_t chunk_index = current.chunk_index; - if (chunkReaders[chunk_index]) { + if (chunk_readers[chunk_index]) { uint board_id; uint channel_id; uint address; unsigned long long time; - if (chunkReaders[chunk_index]->read_row(board_id, channel_id, address, time)) { + if (chunk_readers[chunk_index]->read_row(board_id, channel_id, address, time)) { CsvRow row; row.board_id = board_id; row.channel_id = channel_id; row.address = address; row.time = time; row.chunk_index = chunk_index; - minHeap.push(row); + min_heap.push(row); } else { - chunkReaders[chunk_index].reset(); + chunk_readers[chunk_index].reset(); } } } - outFile.close(); - for (const auto& chunk : chunks) { std::remove(chunk.c_str()); } @@ -517,7 +516,7 @@ bool ParticleDataSortTask::processEveryChannelParticleData() sorted_result_output_dir.mkpath(sorted_result_dir); const QString& all_channel_particle_data_filename = GetAllChannelParticleDataFilename(); - QString sorted_output_filename = sorted_result_output_dir.filePath(QStringLiteral(u"粒子数据[已排序].csv")); + QString sorted_output_filename = sorted_result_output_dir.filePath(QStringLiteral(u"粒子数据.csv")); try { const size_t CHUNK_SIZE = 100 * 1024 * 1024; // 100MB chunks @@ -538,7 +537,7 @@ bool ParticleDataSortTask::processEveryChannelParticleData() } catch (const std::exception& e) { const QString& e_what = QString::fromLatin1(e.what()); - QString error = QString(QStringLiteral(u"处理%1异常:%2")).arg(all_channel_particle_data_filename).arg(QString::fromStdString(e.what())); + QString error = QString(QStringLiteral(u"处理%1异常:%2")).arg(all_channel_particle_data_filename).arg(e_what); LOG_ERROR(error) ret_ok = false; } catch (...) { @@ -546,15 +545,7 @@ bool ParticleDataSortTask::processEveryChannelParticleData() LOG_ERROR(error) ret_ok = false; } - - const QString& project_name = GetProjectName(); - MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(project_name); - if (project_model == nullptr) { - ret_ok = false; - } else { - project_model->SetSortedParticleDataFilename(sorted_output_filename); - } - + this->updateTaskResultData(QVariant(sorted_output_filename)); return ret_ok; } @@ -639,7 +630,7 @@ bool AutoFindPeaksTask::processTask() const QString& error = QStringLiteral(u"%1自动寻峰异常!").arg(ch_count_data_name); LOG_WARN(error); } - const QString& info = QStringLiteral(u"%1自动寻峰完成").arg(ch_count_data_name); + const QString& info = QStringLiteral(u"%1自动寻峰完成.").arg(ch_count_data_name); LOG_INFO(info); } } @@ -651,7 +642,7 @@ bool AutoFindPeaksTask::processTask() } else { project_model->SetAnalysisCustomData(this->_analysis_type, QString("AutoFindPeaksResult"), result_filename); } - const QString& info = QStringLiteral(u"自动寻峰完成"); + const QString& info = QStringLiteral(u"自动寻峰完成."); LOG_INFO(info); return true; } @@ -742,3 +733,18 @@ bool ChannelEnergyScaleFittingTask::processTask() LOG_INFO(info); return true; } + +bool ApplyEnergyScaleTask::processTask() +{ + bool ok = true; + + const QString& project_name = GetProjectName(); + MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(project_name); + if (project_model == nullptr) { + return false; + } + const QString& info = QStringLiteral(u"应用能量刻度完成."); + LOG_INFO(info); + + return ok; +} diff --git a/src/DataProcessWorkPool.h b/src/DataProcessWorkPool.h index b66c296..1871d80 100644 --- a/src/DataProcessWorkPool.h +++ b/src/DataProcessWorkPool.h @@ -23,6 +23,9 @@ namespace DataProcessWorkPool virtual void run() override final; + protected: + void updateTaskResultData(const QVariant& task_result_data); + private: virtual bool processTask() = 0; @@ -30,6 +33,7 @@ namespace DataProcessWorkPool QObject* _finished_notifier { nullptr }; const char* _finished_notifier_process { nullptr }; QString _project_name; + QVariant _task_result_data; }; class ParticleDataTask : public DataProcessTask @@ -120,6 +124,14 @@ namespace DataProcessWorkPool FitDataMap _channel_energy_scale_fit_data_map; QMap _fit_degree_map; }; + + class ApplyEnergyScaleTask : public DataProcessTask + { + private: + virtual bool processTask() override; + private: + QString _project_name; + }; } #endif // DATAPROCESSWORKPOOL_H diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 14e267f..7e1c88e 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -151,32 +151,18 @@ void MainWindow::initAction() { auto new_measurement_analysis_handler = [this]() { NewMeasureAnalysisDlg new_measure_analysis_dlg; - // new_measure_analysis_dlg.exec(); if (QDialog::Accepted == new_measure_analysis_dlg.exec()) { ProjectList* project_list_model = ProjectList::Instance(); auto project_model = project_list_model->GetCurrentProjectModel(); - if (project_model->GetIsMeasureComplete()) { - const QString& project_name = project_model->GetProjectName(); - - // const QString& result_data_dir = QDir(project_model->GetProjectDir()).filePath("EveryChannelParticleData"); - // auto separate_task = new DataProcessWorkPool::EveryChannelParticleDataSeparateTask; - // separate_task->SetAllChannelParticleDataFilename(project_model->GetAllChannelParticleDataFilename()); - // separate_task->SetResultDataDir(result_data_dir); - // separate_task->SetFinishedNotifier(this->_tree_measure_analysis, "onFinishedSeparateEveryChannelParticleData", project_name); - // separate_task->StartTask(); - - // auto separate_task = new DataProcessWorkPool::ParticleDataSortTask; - // separate_task->SetAllChannelParticleDataFilename(project_model->GetAllChannelParticleDataFilename()); - // separate_task->SetSortedResultDir(project_model->GetProjectDir()); - // separate_task->StartTask(); - + const QString& all_channel_particle_data_filename = project_model->GetAllChannelParticleDataFilename(); + if (!all_channel_particle_data_filename.isEmpty()) { const QString& all_ch_count_dir = project_model->GetProjectDir(); const QString& every_ch_count_dir = QDir(project_model->GetProjectDir()).filePath(QStringLiteral(u"通道道址计数")); auto count_task = new DataProcessWorkPool::EveryChannelParticleCountDataTask; - count_task->SetAllChannelParticleDataFilename(project_model->GetAllChannelParticleDataFilename()); + count_task->SetAllChannelParticleDataFilename(all_channel_particle_data_filename); count_task->SetAllChannelCountResultDir(all_ch_count_dir); count_task->SetEveryChannelCountResultDir(every_ch_count_dir); - count_task->SetFinishedNotifier(project_list_model, "onChannelAddressCountProcessFinished", project_name); + count_task->SetFinishedNotifier(project_list_model, "onChannelAddressCountProcessFinished", project_model->GetProjectName()); count_task->StartTask(); } } diff --git a/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp b/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp index 5d358d2..a66df25 100644 --- a/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp +++ b/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp @@ -318,9 +318,13 @@ void BatchEnergyScaleDialog::onFitBtnClickedProcess() } } -void BatchEnergyScaleDialog::onEnergyScaleFitFinished(const QString &project_name) +void BatchEnergyScaleDialog::onEnergyScaleFitFinished(bool ok, const QString &project_name, const QVariant& data) { Q_UNUSED(project_name); + Q_UNUSED(data); + if ( !ok ) + return; + QDir result_dir(this->_workspace); const QString& result_filename = result_dir.filePath(QStringLiteral(u"多通道能量刻度拟合结果.json")); EnergyScaleDataModel result_model(result_filename); @@ -346,6 +350,7 @@ void BatchEnergyScaleDialog::applyEnergyScaleFitResultData() 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 { QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"不能应用非完整的能量刻度!")); diff --git a/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.h b/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.h index 5dc6dbc..ef61475 100644 --- a/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.h +++ b/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.h @@ -28,7 +28,7 @@ public slots: void onSelectedScaleRange(double min, double max); void onFitBtnClickedProcess(); private slots: - void onEnergyScaleFitFinished(const QString& project_name); + void onEnergyScaleFitFinished(bool ok, const QString& project_name, const QVariant &data); private: void insertSetEnergyValueToFilter(double energy); @@ -37,7 +37,7 @@ private: void energyScaleDataChanged(const QStringList& channel_name_list); signals: - void applyEnergyScale(); + void applyEnergyScale(const QString& project_name); void close(); protected: diff --git a/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp b/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp index 22cb2fb..a53c5e6 100644 --- a/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp +++ b/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp @@ -280,9 +280,13 @@ void MeasureAnalysisParticleCountPlotView::updatePlotPeakInfo(const QVariantMap this->_plot->replot(); } -void MeasureAnalysisParticleCountPlotView::onAutoFindPeaksFinished(const QString& project_name) +void MeasureAnalysisParticleCountPlotView::onAutoFindPeaksFinished(bool ok, const QString &project_name, const QVariant& data) { Q_UNUSED(project_name); + Q_UNUSED(data); + if ( !ok ) + return; + this->_plot->CleanMarkers(); this->_plot->replot(); if (this->_find_peaks_result_dlg) { diff --git a/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.h b/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.h index 563c28b..54d4a17 100644 --- a/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.h +++ b/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.h @@ -35,7 +35,7 @@ private: void updatePlotPeakInfo(const QVariantMap& peak_infos); private slots: - void onAutoFindPeaksFinished(const QString& project_name); + void onAutoFindPeaksFinished(bool ok, const QString &project_name, const QVariant& data); private slots: void onActionCurveShowSetting(); void onActionFindPeaksResult(); @@ -44,6 +44,9 @@ private slots: void onActionEnergyScale(); void onActionPlotConfigure(); +signals: + void applyEnergyScale(); + private: QString _workspace; CustomQwtPlot* _plot = nullptr; diff --git a/src/MeasureAnalysisProjectModel.cpp b/src/MeasureAnalysisProjectModel.cpp index 6c6cb00..7e06d12 100644 --- a/src/MeasureAnalysisProjectModel.cpp +++ b/src/MeasureAnalysisProjectModel.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "DataProcessWorkPool.h" MeasureAnalysisProjectModel::~MeasureAnalysisProjectModel() @@ -430,15 +431,17 @@ MeasureAnalysisProjectModelList::~MeasureAnalysisProjectModelList() } } -bool MeasureAnalysisProjectModelList::AddProjectModel(MeasureAnalysisProjectModel* model) +bool MeasureAnalysisProjectModelList::AddProjectModel(MeasureAnalysisProjectModel* model, bool save) { bool ok = true; const QString& project_name = model->GetProjectName(); if (!_project_models.contains(project_name)) { _project_models[project_name] = model; intiProjectNodeStruce(model); - SetCurrentProjectModel(project_name); - model->SaveProjectModel(); + if (save) { + this->SetCurrentProjectModel(project_name); + model->SaveProjectModel(); + } } else { delete model; ok &= false; @@ -610,8 +613,34 @@ QString MeasureAnalysisProjectModelList::GetNodeStatus(QStandardItem* item) cons return status_item ? status_item->text() : QString(); } -void MeasureAnalysisProjectModelList::onChannelAddressCountProcessFinished(const QString& project_name) +void MeasureAnalysisProjectModelList::ApplyEnergyScale(const QString &project_name) { + if (this->_project_models.contains(project_name)) { + 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()) { + status = QStringLiteral(u"已配置"); + auto& node_map = this->_project_node_items[project_name]; + const QString& energy_scale_item_name = QStringLiteral(u"能量刻度"); + if (node_map.contains(energy_scale_item_name)) { + auto energy_scale_item = node_map[energy_scale_item_name]; + this->SetNodeStatus(energy_scale_item, status); + } + pro_model->SaveProjectModel(); + + auto apply_erergy_scale_fit_task = new DataProcessWorkPool::ApplyEnergyScaleTask; + apply_erergy_scale_fit_task->SetFinishedNotifier(this, "onApplyEnergyScaleProcessFinished", project_name); + apply_erergy_scale_fit_task->StartTask(); + } + } +} + +void MeasureAnalysisProjectModelList::onChannelAddressCountProcessFinished(bool ok, const QString& project_name, const QVariant &data) +{ + Q_UNUSED(data); + if ( !ok ) + return; if (this->_project_models.contains(project_name)) { auto pro_model = this->_project_models[project_name]; const QMap& filename_list = pro_model->GetChannelAddressCountDataFilenameList(); @@ -648,6 +677,44 @@ void MeasureAnalysisProjectModelList::onChannelAddressCountProcessFinished(const } } +void MeasureAnalysisProjectModelList::onApplyEnergyScaleProcessFinished(bool ok, const QString& project_name, const QVariant &data) +{ + Q_UNUSED(data); + if ( !ok ) + return; + if (this->_project_models.contains(project_name)) { + auto pro_model = this->_project_models[project_name]; + auto& node_map = this->_project_node_items[project_name]; + QString status = QStringLiteral(u"无效"); + + const QString& energy_total_count_filename = pro_model->GetAllChannelEnergyTotalCountDataFilename(); + if (!energy_total_count_filename.isEmpty()) { + status = QStringLiteral(u"有效"); + const QString& energy_total_count_item_name = QStringLiteral(u"能量计数"); + if (node_map.contains(energy_total_count_item_name)) { + auto energy_total_count_item = node_map[energy_total_count_item_name]; + this->SetNodeStatus(energy_total_count_item, status); + const QMap& channel_energy_count_filename_list = pro_model->GetChannelEnergyCountDataFilenameList(); + for (auto it = channel_energy_count_filename_list.constBegin(); it != channel_energy_count_filename_list.constEnd(); ++it) { + uint ch_num = it.key(); + QString item_name = QStringLiteral(u"通道%1能量计数").arg(ch_num); + const QVariant& analys_type = QVariant::fromValue(AnalysisType::EnergyCountData); + QStandardItem* node_item = AddChildNode(energy_total_count_item, item_name, status, analys_type, true); + node_item->setData(project_name, ProjectName); + node_item->setData(ch_num, ChannelNum); + node_map[item_name] = node_item; + } + const QString& adrr_count_spec_item_name = QStringLiteral(u"能量计数谱"); + if (node_map.contains(adrr_count_spec_item_name)) { + auto adrr_count_spec_item = node_map[adrr_count_spec_item_name]; + this->SetNodeStatus(adrr_count_spec_item, status); + } + } + } + pro_model->SaveProjectModel(); + } +} + void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProjectModel* pro_model) { if (!pro_model) { diff --git a/src/MeasureAnalysisProjectModel.h b/src/MeasureAnalysisProjectModel.h index b0ed29d..3e903ca 100644 --- a/src/MeasureAnalysisProjectModel.h +++ b/src/MeasureAnalysisProjectModel.h @@ -131,7 +131,7 @@ public: static MeasureAnalysisProjectModelList* Instance(); virtual ~MeasureAnalysisProjectModelList(); - bool AddProjectModel(MeasureAnalysisProjectModel* model); + bool AddProjectModel(MeasureAnalysisProjectModel* model, bool save = true); bool RmProjectModel(const QString& project_name); MeasureAnalysisProjectModel* GetProjectModel(const QString& project_name); @@ -152,8 +152,11 @@ public: void SetNodeStatus(QStandardItem* item, const QString& status); QString GetNodeStatus(QStandardItem* item) const; + void ApplyEnergyScale(const QString& project_name); + private slots: - void onChannelAddressCountProcessFinished(const QString& project_name); + void onChannelAddressCountProcessFinished(bool ok, const QString& project_name, const QVariant& data); + void onApplyEnergyScaleProcessFinished(bool ok, const QString& project_name, const QVariant &data); private: void intiProjectNodeStruce(MeasureAnalysisProjectModel *pro_model); diff --git a/src/MeasureAnalysisTreeView.cpp b/src/MeasureAnalysisTreeView.cpp index 3213a68..fc4eb7c 100644 --- a/src/MeasureAnalysisTreeView.cpp +++ b/src/MeasureAnalysisTreeView.cpp @@ -126,6 +126,7 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index) view->SetViewDescription(view_name); view->InitViewWorkspace(project_name); view->SetAnalyzeDataFilename(data_files_set); + } if ( view ) { _item_views[item] = view; diff --git a/src/NewMeasureAnalysisDlg.cpp b/src/NewMeasureAnalysisDlg.cpp index 840c4fe..0af1e74 100644 --- a/src/NewMeasureAnalysisDlg.cpp +++ b/src/NewMeasureAnalysisDlg.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "DataProcessWorkPool.h" NewMeasureAnalysisDlg::NewMeasureAnalysisDlg(QWidget *parent) : QDialog(parent) @@ -21,6 +22,8 @@ NewMeasureAnalysisDlg::~NewMeasureAnalysisDlg() void NewMeasureAnalysisDlg::initialization() { + ui->progressBar->setVisible(false); + QRegExp rx(R"(^[^\\/:*?"<>|]+$)"); QValidator *validator = new QRegExpValidator(rx, this); ui->lineEdit_name->setValidator(validator); @@ -102,6 +105,63 @@ void NewMeasureAnalysisDlg::initialization() connect(ui->btn_cancel, &QPushButton::clicked, this, &NewMeasureAnalysisDlg::reject); } +void NewMeasureAnalysisDlg::newProject(const QString& particle_data_filename) +{ + const QString& project_name = ui->lineEdit_name->text(); + QString projects_dir_path = QDir(qApp->applicationDirPath()).filePath("Projects"); + QDir projects_dir(projects_dir_path); + QString project_dir_path = projects_dir.filePath(project_name); + + bool is_std_source = ui->checkBox_is_std_source->isChecked(); + ulong measure_preset_time = ui->spinBox_measure_preset_time->value(); + uint conform_time_win = ui->spinBox_conform_time->value(); + QString description_info = ui->plainTextEdit_description->toPlainText(); + MeasureAnalysisProjectModel::SpectrumType spec_type = MeasureAnalysisProjectModel::SpectrumType::None; + if (ui->rbtn_sample_spec->isChecked()) { + spec_type = MeasureAnalysisProjectModel::SpectrumType::Sample; + } else if (ui->rbtn_background_spec->isChecked()) { + spec_type = MeasureAnalysisProjectModel::SpectrumType::Background; + } + bool is_measure_complete = true; + MeasureAnalysisProjectModel* model = new MeasureAnalysisProjectModel; + model->SetProjectDir(project_dir_path); + model->SetProjectName(project_name); + model->SetSpectrumType(spec_type); + model->SetIsStdSource(is_std_source); + model->SetMeasurePresetTime(measure_preset_time); + model->SetConformTimeWin(conform_time_win); + model->SetDescriptionInfo(description_info); + model->SetAllChannelParticleDataFilename(particle_data_filename); + model->SetIsMeasureComplete(is_measure_complete); + ProjectList::Instance()->AddProjectModel(model); + NewMeasureAnalysisDlg::accept(); +} + +void NewMeasureAnalysisDlg::onNewProjectFromFileFinished(bool ok, const QString& project_name, const QVariant &data) +{ + QString projects_dir_path = QDir(qApp->applicationDirPath()).filePath("Projects"); + QDir projects_dir(projects_dir_path); + QString project_dir_path = projects_dir.filePath(project_name); + QDir project_dir(project_dir_path); + if (ok) { + QString all_channel_particle_data_filename = data.toString(); + QFileInfo data_file_info(all_channel_particle_data_filename); + if ( data_file_info.exists(all_channel_particle_data_filename) ) { + this->newProject(all_channel_particle_data_filename); + } + } else { + project_dir.removeRecursively(); + + ui->stackedWidget->setEnabled(false); + ui->btn_previous_step->setEnabled(false); + ui->btn_next_step->setEnabled(false); + ui->btn_ok->setEnabled(false); + + const QString& data_file_path = ui->lineEdit_filename->property("data_file_path").toString(); + QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"粒子数据%1异常,创建测量分析项目失败!").arg(data_file_path)); + } +} + void NewMeasureAnalysisDlg::on_btn_ok_clicked() { const QString& project_name = ui->lineEdit_name->text(); @@ -112,56 +172,36 @@ void NewMeasureAnalysisDlg::on_btn_ok_clicked() QString projects_dir_path = QDir(qApp->applicationDirPath()).filePath("Projects"); QDir projects_dir(projects_dir_path); QString project_dir_path = projects_dir.filePath(project_name); - QDir project_dir(project_dir_path); + QDir project_dir(project_dir_path); if (project_dir.exists()) { QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"测量分析名称已存在,请重新输入!")); return; } - MeasureAnalysisProjectModel::SpectrumType spec_type = MeasureAnalysisProjectModel::SpectrumType::None; - if (ui->rbtn_sample_spec->isChecked()) { - spec_type = MeasureAnalysisProjectModel::SpectrumType::Sample; - } else if (ui->rbtn_background_spec->isChecked()) { - spec_type = MeasureAnalysisProjectModel::SpectrumType::Background; - } - bool is_std_source = ui->checkBox_is_std_source->isChecked(); - ulong measure_preset_time = ui->spinBox_measure_preset_time->value(); - uint conform_time_win = ui->spinBox_conform_time->value(); - QString description_info = ui->plainTextEdit_description->toPlainText(); - bool is_measure_complete = false; - - QString data_file_path; - if (ui->checkBox_file_data->isChecked()) { - data_file_path = ui->lineEdit_filename->property("data_file_path").toString(); + 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"请选择粒子数据文件!")); return; } - } - - project_dir.mkpath(project_dir_path); - // 拷贝粒子数据文件到项目目录 - QFileInfo data_file_info(data_file_path); - QString all_channel_particle_data_filename = project_dir.filePath(data_file_info.fileName()); - if (!QFile::copy(data_file_path, all_channel_particle_data_filename)) { - QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"载入粒子数据文件到项目目录失败!")); - project_dir.removeRecursively(); - return; + auto separate_task = new DataProcessWorkPool::ParticleDataSortTask; + separate_task->SetAllChannelParticleDataFilename(data_file_path); + separate_task->SetSortedResultDir(project_dir_path); + separate_task->SetFinishedNotifier(this, "onNewProjectFromFileFinished", project_name); + separate_task->StartTask(); + ui->progressBar->setVisible(true); } else { - is_measure_complete = true; + this->newProject(); } + ui->stackedWidget->setEnabled(false); + ui->btn_previous_step->setEnabled(false); + ui->btn_next_step->setEnabled(false); + ui->btn_ok->setEnabled(false); - MeasureAnalysisProjectModel* model = new MeasureAnalysisProjectModel; - model->SetProjectDir(project_dir_path); - model->SetProjectName(project_name); - model->SetSpectrumType(spec_type); - model->SetIsStdSource(is_std_source); - model->SetMeasurePresetTime(measure_preset_time); - model->SetConformTimeWin(conform_time_win); - model->SetDescriptionInfo(description_info); - model->SetAllChannelParticleDataFilename(all_channel_particle_data_filename); - model->SetIsMeasureComplete(is_measure_complete); - - ProjectList::Instance()->AddProjectModel(model); - - NewMeasureAnalysisDlg::accept(); + // const QString& result_data_dir = QDir(project_model->GetProjectDir()).filePath("EveryChannelParticleData"); + // auto separate_task = new DataProcessWorkPool::EveryChannelParticleDataSeparateTask; + // separate_task->SetAllChannelParticleDataFilename(project_model->GetAllChannelParticleDataFilename()); + // separate_task->SetResultDataDir(result_data_dir); + // separate_task->SetFinishedNotifier(this->_tree_measure_analysis, "onFinishedSeparateEveryChannelParticleData", project_name); + // separate_task->StartTask(); } diff --git a/src/NewMeasureAnalysisDlg.h b/src/NewMeasureAnalysisDlg.h index 10863ac..2dc2d22 100644 --- a/src/NewMeasureAnalysisDlg.h +++ b/src/NewMeasureAnalysisDlg.h @@ -17,8 +17,10 @@ public: private: void initialization(); + void newProject(const QString &particle_data_filename = QString()); private slots: + void onNewProjectFromFileFinished(bool ok, const QString& project_name, const QVariant &data); void on_btn_ok_clicked(); private: diff --git a/src/NewMeasureAnalysisDlg.ui b/src/NewMeasureAnalysisDlg.ui index c13789f..35d724a 100644 --- a/src/NewMeasureAnalysisDlg.ui +++ b/src/NewMeasureAnalysisDlg.ui @@ -6,8 +6,8 @@ 0 0 - 534 - 279 + 550 + 278 @@ -542,14 +542,36 @@ + + + + + 200 + 0 + + + + 24 + + + false + + + false + + + Qt::Horizontal + + QSizePolicy::Expanding + - 40 + 1 20 From af36a5a21c3dbedd991e0d112db0675ab9b10731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B5=B7?= Date: Fri, 20 Mar 2026 15:45:18 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=A4=84=E7=90=86=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/DataProcessWorkPool.cpp | 108 ++++++++-------- src/DataProcessWorkPool.h | 12 ++ src/MainWindow.cpp | 22 +--- .../BatchEnergyScaleDialog.cpp | 7 +- .../BatchEnergyScaleDialog.h | 4 +- .../MeasureAnalysisParticleCountPlotView.cpp | 6 +- .../MeasureAnalysisParticleCountPlotView.h | 5 +- src/MeasureAnalysisProjectModel.cpp | 75 ++++++++++- src/MeasureAnalysisProjectModel.h | 7 +- src/MeasureAnalysisTreeView.cpp | 1 + src/NewMeasureAnalysisDlg.cpp | 122 ++++++++++++------ src/NewMeasureAnalysisDlg.h | 2 + src/NewMeasureAnalysisDlg.ui | 28 +++- 13 files changed, 275 insertions(+), 124 deletions(-) diff --git a/src/DataProcessWorkPool.cpp b/src/DataProcessWorkPool.cpp index c967239..1f04f85 100644 --- a/src/DataProcessWorkPool.cpp +++ b/src/DataProcessWorkPool.cpp @@ -62,16 +62,24 @@ void DataProcessTask::run() if (!IsValidSetWorkParameters()) { return; } - - if (!processTask()) { - return; - } - + bool task_ok = processTask(); if ((GetFinishedNotifier() != nullptr) && (GetFinishedNotifierProcess() != nullptr)) { - QMetaObject::invokeMethod(_finished_notifier, _finished_notifier_process, Qt::QueuedConnection, Q_ARG(QString, _project_name)); + QMetaObject::invokeMethod( + _finished_notifier, + _finished_notifier_process, + Qt::QueuedConnection, + Q_ARG(bool, task_ok), + Q_ARG(QString, _project_name), + Q_ARG(QVariant, _task_result_data) + ); } } +void DataProcessTask::updateTaskResultData(const QVariant &task_result_data) +{ + this->_task_result_data = task_result_data; +} + void ParticleDataTask::SetAllChannelParticleDataFilename(const QString& all_channel_particle_data_filename) { this->_all_channel_particle_data_filename = all_channel_particle_data_filename; @@ -336,7 +344,8 @@ bool EveryChannelParticleCountDataTask::processEveryChannelParticleData() // 更新项目模型中的所有通道粒子总计数数据文件名 // project_model->SetAllChannelParticleTotalCountDataFilename(all_channel_total_count_filename); } - + const QString& info = QStringLiteral(u"所有通道粒子计数处理完成."); + LOG_INFO(info); return ret_ok; } @@ -389,17 +398,16 @@ std::vector splitFile(const std::string& input_file, size_t chunk_s > reader(input_file); reader.read_header(io::ignore_extra_column, board_id_str, channel_id_str, address_str, time_str); - int chunkIndex = 0; + int chunk_index = 0; while (true) { std::vector rows; - size_t currentSize = 0; + size_t current_size = 0; uint board_id; uint channel_id; uint address; unsigned long long time; - while (reader.read_row(board_id, channel_id, address, time)) { CsvRow row; row.board_id = board_id; @@ -408,63 +416,56 @@ std::vector splitFile(const std::string& input_file, size_t chunk_s row.time = time; // Estimate row size - currentSize += std::to_string(board_id).size() + std::to_string(channel_id).size() + std::to_string(address).size() + std::to_string(time).size() + 4; // +4 for commas - - if (currentSize > chunk_size && !rows.empty()) { + current_size += std::to_string(board_id).size() + std::to_string(channel_id).size() + std::to_string(address).size() + std::to_string(time).size() + 4; + if (current_size > chunk_size && !rows.empty()) { break; } - rows.push_back(row); } - if (rows.empty()) break; - std::sort(rows.begin(), rows.end(), [](const CsvRow& a, const CsvRow& b) { return a.time < b.time; }); - - std::string chunkFile = input_file + ".chunk" + std::to_string(chunkIndex); - std::ofstream outFile(chunkFile); + std::string chunk_file = input_file + ".chunk" + std::to_string(chunk_index); + std::ofstream outFile(chunk_file); for (const auto& row : rows) { outFile << row.board_id << "," << row.channel_id << "," << row.address << "," << row.time << "\n"; } outFile.close(); - - chunks.push_back(chunkFile); - chunkIndex++; + chunks.push_back(chunk_file); + chunk_index++; } } catch (const std::exception& e) { throw(e); } - return chunks; } void mergeChunks(const std::vector& chunks, const std::string& output_file) { - std::vector>> chunkReaders; - std::priority_queue minHeap; + std::vector>> chunk_readers; + std::priority_queue min_heap; for (const auto& chunk : chunks) { auto reader = std::make_unique>(chunk); - chunkReaders.push_back(std::move(reader)); + chunk_readers.push_back(std::move(reader)); } - for (size_t i = 0; i < chunkReaders.size(); i++) { + for (size_t i = 0; i < chunk_readers.size(); i++) { uint board_id; uint channel_id; uint address; unsigned long long time; - if (chunkReaders[i]->read_row(board_id, channel_id, address, time)) { + if (chunk_readers[i]->read_row(board_id, channel_id, address, time)) { CsvRow row; row.board_id = board_id; row.channel_id = channel_id; row.address = address; row.time = time; row.chunk_index = i; - minHeap.push(row); + min_heap.push(row); } } @@ -475,35 +476,33 @@ void mergeChunks(const std::vector& chunks, const std::string& outp std::ofstream outFile(output_file); outFile << board_id_str << "," << channel_id_str << "," << address_str << "," << time_str << "\n"; - while (!minHeap.empty()) { - CsvRow current = minHeap.top(); - minHeap.pop(); + while (!min_heap.empty()) { + CsvRow current = min_heap.top(); + min_heap.pop(); outFile << current.board_id << "," << current.channel_id << "," << current.address << "," << current.time << "\n"; size_t chunk_index = current.chunk_index; - if (chunkReaders[chunk_index]) { + if (chunk_readers[chunk_index]) { uint board_id; uint channel_id; uint address; unsigned long long time; - if (chunkReaders[chunk_index]->read_row(board_id, channel_id, address, time)) { + if (chunk_readers[chunk_index]->read_row(board_id, channel_id, address, time)) { CsvRow row; row.board_id = board_id; row.channel_id = channel_id; row.address = address; row.time = time; row.chunk_index = chunk_index; - minHeap.push(row); + min_heap.push(row); } else { - chunkReaders[chunk_index].reset(); + chunk_readers[chunk_index].reset(); } } } - outFile.close(); - for (const auto& chunk : chunks) { std::remove(chunk.c_str()); } @@ -517,7 +516,7 @@ bool ParticleDataSortTask::processEveryChannelParticleData() sorted_result_output_dir.mkpath(sorted_result_dir); const QString& all_channel_particle_data_filename = GetAllChannelParticleDataFilename(); - QString sorted_output_filename = sorted_result_output_dir.filePath(QStringLiteral(u"粒子数据[已排序].csv")); + QString sorted_output_filename = sorted_result_output_dir.filePath(QStringLiteral(u"粒子数据.csv")); try { const size_t CHUNK_SIZE = 100 * 1024 * 1024; // 100MB chunks @@ -538,7 +537,7 @@ bool ParticleDataSortTask::processEveryChannelParticleData() } catch (const std::exception& e) { const QString& e_what = QString::fromLatin1(e.what()); - QString error = QString(QStringLiteral(u"处理%1异常:%2")).arg(all_channel_particle_data_filename).arg(QString::fromStdString(e.what())); + QString error = QString(QStringLiteral(u"处理%1异常:%2")).arg(all_channel_particle_data_filename).arg(e_what); LOG_ERROR(error) ret_ok = false; } catch (...) { @@ -546,15 +545,7 @@ bool ParticleDataSortTask::processEveryChannelParticleData() LOG_ERROR(error) ret_ok = false; } - - const QString& project_name = GetProjectName(); - MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(project_name); - if (project_model == nullptr) { - ret_ok = false; - } else { - project_model->SetSortedParticleDataFilename(sorted_output_filename); - } - + this->updateTaskResultData(QVariant(sorted_output_filename)); return ret_ok; } @@ -639,7 +630,7 @@ bool AutoFindPeaksTask::processTask() const QString& error = QStringLiteral(u"%1自动寻峰异常!").arg(ch_count_data_name); LOG_WARN(error); } - const QString& info = QStringLiteral(u"%1自动寻峰完成").arg(ch_count_data_name); + const QString& info = QStringLiteral(u"%1自动寻峰完成.").arg(ch_count_data_name); LOG_INFO(info); } } @@ -651,7 +642,7 @@ bool AutoFindPeaksTask::processTask() } else { project_model->SetAnalysisCustomData(this->_analysis_type, QString("AutoFindPeaksResult"), result_filename); } - const QString& info = QStringLiteral(u"自动寻峰完成"); + const QString& info = QStringLiteral(u"自动寻峰完成."); LOG_INFO(info); return true; } @@ -742,3 +733,18 @@ bool ChannelEnergyScaleFittingTask::processTask() LOG_INFO(info); return true; } + +bool ApplyEnergyScaleTask::processTask() +{ + bool ok = true; + + const QString& project_name = GetProjectName(); + MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(project_name); + if (project_model == nullptr) { + return false; + } + const QString& info = QStringLiteral(u"应用能量刻度完成."); + LOG_INFO(info); + + return ok; +} diff --git a/src/DataProcessWorkPool.h b/src/DataProcessWorkPool.h index b66c296..1871d80 100644 --- a/src/DataProcessWorkPool.h +++ b/src/DataProcessWorkPool.h @@ -23,6 +23,9 @@ namespace DataProcessWorkPool virtual void run() override final; + protected: + void updateTaskResultData(const QVariant& task_result_data); + private: virtual bool processTask() = 0; @@ -30,6 +33,7 @@ namespace DataProcessWorkPool QObject* _finished_notifier { nullptr }; const char* _finished_notifier_process { nullptr }; QString _project_name; + QVariant _task_result_data; }; class ParticleDataTask : public DataProcessTask @@ -120,6 +124,14 @@ namespace DataProcessWorkPool FitDataMap _channel_energy_scale_fit_data_map; QMap _fit_degree_map; }; + + class ApplyEnergyScaleTask : public DataProcessTask + { + private: + virtual bool processTask() override; + private: + QString _project_name; + }; } #endif // DATAPROCESSWORKPOOL_H diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 14e267f..7e1c88e 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -151,32 +151,18 @@ void MainWindow::initAction() { auto new_measurement_analysis_handler = [this]() { NewMeasureAnalysisDlg new_measure_analysis_dlg; - // new_measure_analysis_dlg.exec(); if (QDialog::Accepted == new_measure_analysis_dlg.exec()) { ProjectList* project_list_model = ProjectList::Instance(); auto project_model = project_list_model->GetCurrentProjectModel(); - if (project_model->GetIsMeasureComplete()) { - const QString& project_name = project_model->GetProjectName(); - - // const QString& result_data_dir = QDir(project_model->GetProjectDir()).filePath("EveryChannelParticleData"); - // auto separate_task = new DataProcessWorkPool::EveryChannelParticleDataSeparateTask; - // separate_task->SetAllChannelParticleDataFilename(project_model->GetAllChannelParticleDataFilename()); - // separate_task->SetResultDataDir(result_data_dir); - // separate_task->SetFinishedNotifier(this->_tree_measure_analysis, "onFinishedSeparateEveryChannelParticleData", project_name); - // separate_task->StartTask(); - - // auto separate_task = new DataProcessWorkPool::ParticleDataSortTask; - // separate_task->SetAllChannelParticleDataFilename(project_model->GetAllChannelParticleDataFilename()); - // separate_task->SetSortedResultDir(project_model->GetProjectDir()); - // separate_task->StartTask(); - + const QString& all_channel_particle_data_filename = project_model->GetAllChannelParticleDataFilename(); + if (!all_channel_particle_data_filename.isEmpty()) { const QString& all_ch_count_dir = project_model->GetProjectDir(); const QString& every_ch_count_dir = QDir(project_model->GetProjectDir()).filePath(QStringLiteral(u"通道道址计数")); auto count_task = new DataProcessWorkPool::EveryChannelParticleCountDataTask; - count_task->SetAllChannelParticleDataFilename(project_model->GetAllChannelParticleDataFilename()); + count_task->SetAllChannelParticleDataFilename(all_channel_particle_data_filename); count_task->SetAllChannelCountResultDir(all_ch_count_dir); count_task->SetEveryChannelCountResultDir(every_ch_count_dir); - count_task->SetFinishedNotifier(project_list_model, "onChannelAddressCountProcessFinished", project_name); + count_task->SetFinishedNotifier(project_list_model, "onChannelAddressCountProcessFinished", project_model->GetProjectName()); count_task->StartTask(); } } diff --git a/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp b/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp index 5d358d2..a66df25 100644 --- a/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp +++ b/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp @@ -318,9 +318,13 @@ void BatchEnergyScaleDialog::onFitBtnClickedProcess() } } -void BatchEnergyScaleDialog::onEnergyScaleFitFinished(const QString &project_name) +void BatchEnergyScaleDialog::onEnergyScaleFitFinished(bool ok, const QString &project_name, const QVariant& data) { Q_UNUSED(project_name); + Q_UNUSED(data); + if ( !ok ) + return; + QDir result_dir(this->_workspace); const QString& result_filename = result_dir.filePath(QStringLiteral(u"多通道能量刻度拟合结果.json")); EnergyScaleDataModel result_model(result_filename); @@ -346,6 +350,7 @@ void BatchEnergyScaleDialog::applyEnergyScaleFitResultData() 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 { QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"不能应用非完整的能量刻度!")); diff --git a/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.h b/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.h index 5dc6dbc..ef61475 100644 --- a/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.h +++ b/src/MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.h @@ -28,7 +28,7 @@ public slots: void onSelectedScaleRange(double min, double max); void onFitBtnClickedProcess(); private slots: - void onEnergyScaleFitFinished(const QString& project_name); + void onEnergyScaleFitFinished(bool ok, const QString& project_name, const QVariant &data); private: void insertSetEnergyValueToFilter(double energy); @@ -37,7 +37,7 @@ private: void energyScaleDataChanged(const QStringList& channel_name_list); signals: - void applyEnergyScale(); + void applyEnergyScale(const QString& project_name); void close(); protected: diff --git a/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp b/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp index 22cb2fb..a53c5e6 100644 --- a/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp +++ b/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp @@ -280,9 +280,13 @@ void MeasureAnalysisParticleCountPlotView::updatePlotPeakInfo(const QVariantMap this->_plot->replot(); } -void MeasureAnalysisParticleCountPlotView::onAutoFindPeaksFinished(const QString& project_name) +void MeasureAnalysisParticleCountPlotView::onAutoFindPeaksFinished(bool ok, const QString &project_name, const QVariant& data) { Q_UNUSED(project_name); + Q_UNUSED(data); + if ( !ok ) + return; + this->_plot->CleanMarkers(); this->_plot->replot(); if (this->_find_peaks_result_dlg) { diff --git a/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.h b/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.h index 563c28b..54d4a17 100644 --- a/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.h +++ b/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.h @@ -35,7 +35,7 @@ private: void updatePlotPeakInfo(const QVariantMap& peak_infos); private slots: - void onAutoFindPeaksFinished(const QString& project_name); + void onAutoFindPeaksFinished(bool ok, const QString &project_name, const QVariant& data); private slots: void onActionCurveShowSetting(); void onActionFindPeaksResult(); @@ -44,6 +44,9 @@ private slots: void onActionEnergyScale(); void onActionPlotConfigure(); +signals: + void applyEnergyScale(); + private: QString _workspace; CustomQwtPlot* _plot = nullptr; diff --git a/src/MeasureAnalysisProjectModel.cpp b/src/MeasureAnalysisProjectModel.cpp index 6c6cb00..7e06d12 100644 --- a/src/MeasureAnalysisProjectModel.cpp +++ b/src/MeasureAnalysisProjectModel.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "DataProcessWorkPool.h" MeasureAnalysisProjectModel::~MeasureAnalysisProjectModel() @@ -430,15 +431,17 @@ MeasureAnalysisProjectModelList::~MeasureAnalysisProjectModelList() } } -bool MeasureAnalysisProjectModelList::AddProjectModel(MeasureAnalysisProjectModel* model) +bool MeasureAnalysisProjectModelList::AddProjectModel(MeasureAnalysisProjectModel* model, bool save) { bool ok = true; const QString& project_name = model->GetProjectName(); if (!_project_models.contains(project_name)) { _project_models[project_name] = model; intiProjectNodeStruce(model); - SetCurrentProjectModel(project_name); - model->SaveProjectModel(); + if (save) { + this->SetCurrentProjectModel(project_name); + model->SaveProjectModel(); + } } else { delete model; ok &= false; @@ -610,8 +613,34 @@ QString MeasureAnalysisProjectModelList::GetNodeStatus(QStandardItem* item) cons return status_item ? status_item->text() : QString(); } -void MeasureAnalysisProjectModelList::onChannelAddressCountProcessFinished(const QString& project_name) +void MeasureAnalysisProjectModelList::ApplyEnergyScale(const QString &project_name) { + if (this->_project_models.contains(project_name)) { + 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()) { + status = QStringLiteral(u"已配置"); + auto& node_map = this->_project_node_items[project_name]; + const QString& energy_scale_item_name = QStringLiteral(u"能量刻度"); + if (node_map.contains(energy_scale_item_name)) { + auto energy_scale_item = node_map[energy_scale_item_name]; + this->SetNodeStatus(energy_scale_item, status); + } + pro_model->SaveProjectModel(); + + auto apply_erergy_scale_fit_task = new DataProcessWorkPool::ApplyEnergyScaleTask; + apply_erergy_scale_fit_task->SetFinishedNotifier(this, "onApplyEnergyScaleProcessFinished", project_name); + apply_erergy_scale_fit_task->StartTask(); + } + } +} + +void MeasureAnalysisProjectModelList::onChannelAddressCountProcessFinished(bool ok, const QString& project_name, const QVariant &data) +{ + Q_UNUSED(data); + if ( !ok ) + return; if (this->_project_models.contains(project_name)) { auto pro_model = this->_project_models[project_name]; const QMap& filename_list = pro_model->GetChannelAddressCountDataFilenameList(); @@ -648,6 +677,44 @@ void MeasureAnalysisProjectModelList::onChannelAddressCountProcessFinished(const } } +void MeasureAnalysisProjectModelList::onApplyEnergyScaleProcessFinished(bool ok, const QString& project_name, const QVariant &data) +{ + Q_UNUSED(data); + if ( !ok ) + return; + if (this->_project_models.contains(project_name)) { + auto pro_model = this->_project_models[project_name]; + auto& node_map = this->_project_node_items[project_name]; + QString status = QStringLiteral(u"无效"); + + const QString& energy_total_count_filename = pro_model->GetAllChannelEnergyTotalCountDataFilename(); + if (!energy_total_count_filename.isEmpty()) { + status = QStringLiteral(u"有效"); + const QString& energy_total_count_item_name = QStringLiteral(u"能量计数"); + if (node_map.contains(energy_total_count_item_name)) { + auto energy_total_count_item = node_map[energy_total_count_item_name]; + this->SetNodeStatus(energy_total_count_item, status); + const QMap& channel_energy_count_filename_list = pro_model->GetChannelEnergyCountDataFilenameList(); + for (auto it = channel_energy_count_filename_list.constBegin(); it != channel_energy_count_filename_list.constEnd(); ++it) { + uint ch_num = it.key(); + QString item_name = QStringLiteral(u"通道%1能量计数").arg(ch_num); + const QVariant& analys_type = QVariant::fromValue(AnalysisType::EnergyCountData); + QStandardItem* node_item = AddChildNode(energy_total_count_item, item_name, status, analys_type, true); + node_item->setData(project_name, ProjectName); + node_item->setData(ch_num, ChannelNum); + node_map[item_name] = node_item; + } + const QString& adrr_count_spec_item_name = QStringLiteral(u"能量计数谱"); + if (node_map.contains(adrr_count_spec_item_name)) { + auto adrr_count_spec_item = node_map[adrr_count_spec_item_name]; + this->SetNodeStatus(adrr_count_spec_item, status); + } + } + } + pro_model->SaveProjectModel(); + } +} + void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProjectModel* pro_model) { if (!pro_model) { diff --git a/src/MeasureAnalysisProjectModel.h b/src/MeasureAnalysisProjectModel.h index b0ed29d..3e903ca 100644 --- a/src/MeasureAnalysisProjectModel.h +++ b/src/MeasureAnalysisProjectModel.h @@ -131,7 +131,7 @@ public: static MeasureAnalysisProjectModelList* Instance(); virtual ~MeasureAnalysisProjectModelList(); - bool AddProjectModel(MeasureAnalysisProjectModel* model); + bool AddProjectModel(MeasureAnalysisProjectModel* model, bool save = true); bool RmProjectModel(const QString& project_name); MeasureAnalysisProjectModel* GetProjectModel(const QString& project_name); @@ -152,8 +152,11 @@ public: void SetNodeStatus(QStandardItem* item, const QString& status); QString GetNodeStatus(QStandardItem* item) const; + void ApplyEnergyScale(const QString& project_name); + private slots: - void onChannelAddressCountProcessFinished(const QString& project_name); + void onChannelAddressCountProcessFinished(bool ok, const QString& project_name, const QVariant& data); + void onApplyEnergyScaleProcessFinished(bool ok, const QString& project_name, const QVariant &data); private: void intiProjectNodeStruce(MeasureAnalysisProjectModel *pro_model); diff --git a/src/MeasureAnalysisTreeView.cpp b/src/MeasureAnalysisTreeView.cpp index 3213a68..fc4eb7c 100644 --- a/src/MeasureAnalysisTreeView.cpp +++ b/src/MeasureAnalysisTreeView.cpp @@ -126,6 +126,7 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index) view->SetViewDescription(view_name); view->InitViewWorkspace(project_name); view->SetAnalyzeDataFilename(data_files_set); + } if ( view ) { _item_views[item] = view; diff --git a/src/NewMeasureAnalysisDlg.cpp b/src/NewMeasureAnalysisDlg.cpp index 840c4fe..0af1e74 100644 --- a/src/NewMeasureAnalysisDlg.cpp +++ b/src/NewMeasureAnalysisDlg.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "DataProcessWorkPool.h" NewMeasureAnalysisDlg::NewMeasureAnalysisDlg(QWidget *parent) : QDialog(parent) @@ -21,6 +22,8 @@ NewMeasureAnalysisDlg::~NewMeasureAnalysisDlg() void NewMeasureAnalysisDlg::initialization() { + ui->progressBar->setVisible(false); + QRegExp rx(R"(^[^\\/:*?"<>|]+$)"); QValidator *validator = new QRegExpValidator(rx, this); ui->lineEdit_name->setValidator(validator); @@ -102,6 +105,63 @@ void NewMeasureAnalysisDlg::initialization() connect(ui->btn_cancel, &QPushButton::clicked, this, &NewMeasureAnalysisDlg::reject); } +void NewMeasureAnalysisDlg::newProject(const QString& particle_data_filename) +{ + const QString& project_name = ui->lineEdit_name->text(); + QString projects_dir_path = QDir(qApp->applicationDirPath()).filePath("Projects"); + QDir projects_dir(projects_dir_path); + QString project_dir_path = projects_dir.filePath(project_name); + + bool is_std_source = ui->checkBox_is_std_source->isChecked(); + ulong measure_preset_time = ui->spinBox_measure_preset_time->value(); + uint conform_time_win = ui->spinBox_conform_time->value(); + QString description_info = ui->plainTextEdit_description->toPlainText(); + MeasureAnalysisProjectModel::SpectrumType spec_type = MeasureAnalysisProjectModel::SpectrumType::None; + if (ui->rbtn_sample_spec->isChecked()) { + spec_type = MeasureAnalysisProjectModel::SpectrumType::Sample; + } else if (ui->rbtn_background_spec->isChecked()) { + spec_type = MeasureAnalysisProjectModel::SpectrumType::Background; + } + bool is_measure_complete = true; + MeasureAnalysisProjectModel* model = new MeasureAnalysisProjectModel; + model->SetProjectDir(project_dir_path); + model->SetProjectName(project_name); + model->SetSpectrumType(spec_type); + model->SetIsStdSource(is_std_source); + model->SetMeasurePresetTime(measure_preset_time); + model->SetConformTimeWin(conform_time_win); + model->SetDescriptionInfo(description_info); + model->SetAllChannelParticleDataFilename(particle_data_filename); + model->SetIsMeasureComplete(is_measure_complete); + ProjectList::Instance()->AddProjectModel(model); + NewMeasureAnalysisDlg::accept(); +} + +void NewMeasureAnalysisDlg::onNewProjectFromFileFinished(bool ok, const QString& project_name, const QVariant &data) +{ + QString projects_dir_path = QDir(qApp->applicationDirPath()).filePath("Projects"); + QDir projects_dir(projects_dir_path); + QString project_dir_path = projects_dir.filePath(project_name); + QDir project_dir(project_dir_path); + if (ok) { + QString all_channel_particle_data_filename = data.toString(); + QFileInfo data_file_info(all_channel_particle_data_filename); + if ( data_file_info.exists(all_channel_particle_data_filename) ) { + this->newProject(all_channel_particle_data_filename); + } + } else { + project_dir.removeRecursively(); + + ui->stackedWidget->setEnabled(false); + ui->btn_previous_step->setEnabled(false); + ui->btn_next_step->setEnabled(false); + ui->btn_ok->setEnabled(false); + + const QString& data_file_path = ui->lineEdit_filename->property("data_file_path").toString(); + QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"粒子数据%1异常,创建测量分析项目失败!").arg(data_file_path)); + } +} + void NewMeasureAnalysisDlg::on_btn_ok_clicked() { const QString& project_name = ui->lineEdit_name->text(); @@ -112,56 +172,36 @@ void NewMeasureAnalysisDlg::on_btn_ok_clicked() QString projects_dir_path = QDir(qApp->applicationDirPath()).filePath("Projects"); QDir projects_dir(projects_dir_path); QString project_dir_path = projects_dir.filePath(project_name); - QDir project_dir(project_dir_path); + QDir project_dir(project_dir_path); if (project_dir.exists()) { QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"测量分析名称已存在,请重新输入!")); return; } - MeasureAnalysisProjectModel::SpectrumType spec_type = MeasureAnalysisProjectModel::SpectrumType::None; - if (ui->rbtn_sample_spec->isChecked()) { - spec_type = MeasureAnalysisProjectModel::SpectrumType::Sample; - } else if (ui->rbtn_background_spec->isChecked()) { - spec_type = MeasureAnalysisProjectModel::SpectrumType::Background; - } - bool is_std_source = ui->checkBox_is_std_source->isChecked(); - ulong measure_preset_time = ui->spinBox_measure_preset_time->value(); - uint conform_time_win = ui->spinBox_conform_time->value(); - QString description_info = ui->plainTextEdit_description->toPlainText(); - bool is_measure_complete = false; - - QString data_file_path; - if (ui->checkBox_file_data->isChecked()) { - data_file_path = ui->lineEdit_filename->property("data_file_path").toString(); + 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"请选择粒子数据文件!")); return; } - } - - project_dir.mkpath(project_dir_path); - // 拷贝粒子数据文件到项目目录 - QFileInfo data_file_info(data_file_path); - QString all_channel_particle_data_filename = project_dir.filePath(data_file_info.fileName()); - if (!QFile::copy(data_file_path, all_channel_particle_data_filename)) { - QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"载入粒子数据文件到项目目录失败!")); - project_dir.removeRecursively(); - return; + auto separate_task = new DataProcessWorkPool::ParticleDataSortTask; + separate_task->SetAllChannelParticleDataFilename(data_file_path); + separate_task->SetSortedResultDir(project_dir_path); + separate_task->SetFinishedNotifier(this, "onNewProjectFromFileFinished", project_name); + separate_task->StartTask(); + ui->progressBar->setVisible(true); } else { - is_measure_complete = true; + this->newProject(); } + ui->stackedWidget->setEnabled(false); + ui->btn_previous_step->setEnabled(false); + ui->btn_next_step->setEnabled(false); + ui->btn_ok->setEnabled(false); - MeasureAnalysisProjectModel* model = new MeasureAnalysisProjectModel; - model->SetProjectDir(project_dir_path); - model->SetProjectName(project_name); - model->SetSpectrumType(spec_type); - model->SetIsStdSource(is_std_source); - model->SetMeasurePresetTime(measure_preset_time); - model->SetConformTimeWin(conform_time_win); - model->SetDescriptionInfo(description_info); - model->SetAllChannelParticleDataFilename(all_channel_particle_data_filename); - model->SetIsMeasureComplete(is_measure_complete); - - ProjectList::Instance()->AddProjectModel(model); - - NewMeasureAnalysisDlg::accept(); + // const QString& result_data_dir = QDir(project_model->GetProjectDir()).filePath("EveryChannelParticleData"); + // auto separate_task = new DataProcessWorkPool::EveryChannelParticleDataSeparateTask; + // separate_task->SetAllChannelParticleDataFilename(project_model->GetAllChannelParticleDataFilename()); + // separate_task->SetResultDataDir(result_data_dir); + // separate_task->SetFinishedNotifier(this->_tree_measure_analysis, "onFinishedSeparateEveryChannelParticleData", project_name); + // separate_task->StartTask(); } diff --git a/src/NewMeasureAnalysisDlg.h b/src/NewMeasureAnalysisDlg.h index 10863ac..2dc2d22 100644 --- a/src/NewMeasureAnalysisDlg.h +++ b/src/NewMeasureAnalysisDlg.h @@ -17,8 +17,10 @@ public: private: void initialization(); + void newProject(const QString &particle_data_filename = QString()); private slots: + void onNewProjectFromFileFinished(bool ok, const QString& project_name, const QVariant &data); void on_btn_ok_clicked(); private: diff --git a/src/NewMeasureAnalysisDlg.ui b/src/NewMeasureAnalysisDlg.ui index c13789f..35d724a 100644 --- a/src/NewMeasureAnalysisDlg.ui +++ b/src/NewMeasureAnalysisDlg.ui @@ -6,8 +6,8 @@ 0 0 - 534 - 279 + 550 + 278 @@ -542,14 +542,36 @@ + + + + + 200 + 0 + + + + 24 + + + false + + + false + + + Qt::Horizontal + + QSizePolicy::Expanding + - 40 + 1 20 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 3/9] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=83=BD=E8=B0=B1?= =?UTF-8?q?=E6=95=B0=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: 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 4/9] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=83=BD=E9=87=8F?= =?UTF-8?q?=E8=AE=A1=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; From adbca70bda412668f9a0362bc6d2c303eba0c64b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B5=B7?= Date: Tue, 24 Mar 2026 10:30:26 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=B2=92=E5=AD=90?= =?UTF-8?q?=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/AnalysisTypeDefine.h | 2 +- src/DataProcessWorkPool.cpp | 134 +++++++++++++----- src/DataProcessWorkPool.h | 28 +++- src/MainWindow.cpp | 15 +- .../FindPeaksResultDialog.cpp | 20 ++- src/MeasureAnalysisProjectModel.cpp | 33 ++++- src/MeasureAnalysisProjectModel.h | 7 +- src/MeasureAnalysisView.cpp | 4 +- src/NewMeasureAnalysisDlg.cpp | 2 +- 9 files changed, 188 insertions(+), 57 deletions(-) diff --git a/src/AnalysisTypeDefine.h b/src/AnalysisTypeDefine.h index 067195a..6318f4e 100644 --- a/src/AnalysisTypeDefine.h +++ b/src/AnalysisTypeDefine.h @@ -19,7 +19,7 @@ enum class AnalysisType { CountingRateView, // 计数率视图 EnergyPeakFitView, // 能量峰拟合视图 NuclideAnalysisView, // 核分析视图 - ParticleInTimeView, // 粒子在时间视图 + ParticleInTimeView, // 粒子射入时间视图 ParticleTimeDiffView, // 粒子时间差视图 CoincidenceEventTimeView, // 符合事件时间视图 CoincidenceParticleEnergySpectrumView, // 符合粒子能量谱视图 diff --git a/src/DataProcessWorkPool.cpp b/src/DataProcessWorkPool.cpp index 841bb7c..c76baf7 100644 --- a/src/DataProcessWorkPool.cpp +++ b/src/DataProcessWorkPool.cpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include "DataCalcProcess/MathModelDefine.h" #include "DataCalcProcess/FindPeaksBySvd.h" #include "DataCalcProcess/GaussPolyCoe.h" @@ -536,17 +538,62 @@ bool ParticleDataSortTask::processEveryChannelParticleData() } catch (const std::exception& e) { const QString& e_what = QString::fromLatin1(e.what()); QString error = QString(QStringLiteral(u"处理%1异常:%2")).arg(all_channel_particle_data_filename).arg(e_what); - LOG_ERROR(error) + LOG_ERROR(error); ret_ok = false; } catch (...) { QString error = QString(QStringLiteral(u"处理%1未知异常.")).arg(all_channel_particle_data_filename); - LOG_ERROR(error) + LOG_ERROR(error); ret_ok = false; } this->updateTaskResultData(QVariant(sorted_output_filename)); return ret_ok; } +bool ParticleDataSortByMinimysTask::processEveryChannelParticleData() +{ + bool ret_ok = true; + const QString& sorted_result_dir = GetSortedResultDir(); + QDir sorted_result_output_dir(sorted_result_dir); + sorted_result_output_dir.mkpath(sorted_result_dir); + + const QString& data_filename = GetAllChannelParticleDataFilename(); + QString output_filename = sorted_result_output_dir.filePath(QStringLiteral(u"粒子数据.csv")); + QString minimsys = QDir(qApp->applicationDirPath()).filePath(QString("minimsys")); + QString bash = QDir(minimsys).filePath(QString("bash")); + QString head = QDir(minimsys).filePath(QString("head")); + QString tail = QDir(minimsys).filePath(QString("tail")); + QString sort = QDir(minimsys).filePath(QString("sort")); + QString cmd = QString("(%1 -n 1 %4 && %2 -n +2 %4 | %3 -t ',' -k4 -n --parallel=8 -S 4G) > %5").arg(head).arg(tail).arg(sort).arg(data_filename).arg(output_filename); + QProcess proc; + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + env.clear(); + env.insert("PATH", minimsys); + proc.setProcessEnvironment(env); + proc.setWorkingDirectory(minimsys); + proc.start(bash, { "-c", cmd }); + proc.waitForFinished(-1); + if (proc.exitCode() != 0) { + QString process_error = QString(proc.readAllStandardError()); + QString error = QStringLiteral(u"处理%1异常:%2").arg(data_filename).arg(process_error); + LOG_ERROR(error); + ret_ok = false; + } + this->updateTaskResultData(QVariant(output_filename)); + return ret_ok; +} + +bool CoincidenceEventAnalysisTask::processTask() +{ + const QString& project_name = GetProjectName(); + MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(project_name); + if (project_model == nullptr) { + return false; + } + const QString& info = QStringLiteral(u"粒子符合事件数据处理完成."); + LOG_INFO(info); + return true; +} + void AutoFindPeaksTask::SetAnalysisType(AnalysisType analysis_type) { this->_analysis_type = analysis_type; @@ -731,12 +778,23 @@ bool ChannelEnergyScaleFittingTask::processTask() return true; } -bool ApplyEnergyScaleTask::scaleParticleData(MeasureAnalysisProjectModel* project_model, EnergyScaleDataModel& energy_scale_data_model) +bool EnergyScaleParticleDataTask::processTask() { - bool ok = true; + 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 ok &= false; + return false; } const QString& energy_spectrum_filename = QDir(project_model->GetProjectDir()).filePath(QStringLiteral(u"能谱数据.csv")); std::string board_id_str = QString(QStringLiteral(u"板卡号")).toStdString(); @@ -763,35 +821,49 @@ bool ApplyEnergyScaleTask::scaleParticleData(MeasureAnalysisProjectModel* projec 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"; + if (!coeffs.empty()) { + 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(energy_spectrum_filename)); - ok &= false; const QString& e_what = QString::fromStdString(e.what()); LOG_WARN(QStringLiteral(u"能谱数据异常:%1").arg(e_what)); + return false; } - return ok; + const QString& info = QStringLiteral(u"能谱数据处理完成."); + LOG_INFO(info); + return true; } -bool ApplyEnergyScaleTask::energyCountProcess(MeasureAnalysisProjectModel* project_model, EnergyScaleDataModel& energy_scale_data_model) +bool EnergyCountProcessTask::processTask() { - bool ok = true; + 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 QMap& ch_addr_count_filename_list = project_model->GetChannelAddressCountDataFilenameList(); if (ch_addr_count_filename_list.isEmpty()) { LOG_WARN(QStringLiteral(u"能量计数统计需要的通道道址计数文件异常!")); - return ok &= false; + return 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; + return false; } - QMap every_ch_energy_count_filename_list; - for (const int& channel_num : ch_addr_count_filename_list.keys()) { + for (const uint& 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(); @@ -813,11 +885,13 @@ bool ApplyEnergyScaleTask::energyCountProcess(MeasureAnalysisProjectModel* proje 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"; + if (!coeffs.empty()) { + double energy = GaussPolyCoe::Predict(coeffs, address); + out << energy << "," << count << "\n"; + } } out.close(); - every_ch_energy_count_filename_list[channel_num] = out_filename; + project_model->SetChannelEnergyCountDataFilename(channel_num, out_filename); } catch (const std::exception& e) { out.close(); std::remove(QStrToSysPath(out_filename)); @@ -825,16 +899,12 @@ bool ApplyEnergyScaleTask::energyCountProcess(MeasureAnalysisProjectModel* proje LOG_WARN(QStringLiteral(u"%1能量计数异常:%2").arg(channel_name).arg(e_what)); } } - return ok; + const QString& info = QStringLiteral(u"能量计数处理完成."); + LOG_INFO(info); + return true; } -bool ApplyEnergyScaleTask::coincidenceProcess() -{ - bool ok = true; - return ok; -} - -bool ApplyEnergyScaleTask::processTask() +bool EnergyScaleCoincidenceEventDataTask::processTask() { const QString& project_name = GetProjectName(); MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(project_name); @@ -848,16 +918,8 @@ bool ApplyEnergyScaleTask::processTask() if (!energy_scale_data_model.IsValid()) { return false; } - if (!scaleParticleData(project_model, energy_scale_data_model)) { - return false; - } - if (!energyCountProcess(project_model, energy_scale_data_model)) { - return false; - } - if (!coincidenceProcess()) { - return false; - } - const QString& info = QStringLiteral(u"应用能量刻度完成."); + const QString& info = QStringLiteral(u"符合能谱数据处理完成."); LOG_INFO(info); return true; } + diff --git a/src/DataProcessWorkPool.h b/src/DataProcessWorkPool.h index 24d20f1..e0aadfd 100644 --- a/src/DataProcessWorkPool.h +++ b/src/DataProcessWorkPool.h @@ -97,6 +97,17 @@ namespace DataProcessWorkPool QString _sorted_result_dir; }; + class ParticleDataSortByMinimysTask : public ParticleDataSortTask + { + virtual bool processEveryChannelParticleData() override; + }; + + class CoincidenceEventAnalysisTask : public DataProcessTask + { + private: + virtual bool processTask() override; + }; + class AutoFindPeaksTask : public DataProcessTask { public: void SetAnalysisType(AnalysisType analysis_type); @@ -128,15 +139,22 @@ namespace DataProcessWorkPool QMap _fit_degree_map; }; - class ApplyEnergyScaleTask : public DataProcessTask + class EnergyScaleParticleDataTask : public DataProcessTask { private: - 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; + }; + + class EnergyCountProcessTask : public DataProcessTask + { private: - QString _project_name; + virtual bool processTask() override; + }; + + class EnergyScaleCoincidenceEventDataTask : public DataProcessTask + { + private: + virtual bool processTask() override; }; } diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 9bccdaf..5051976 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -243,10 +243,13 @@ void MainWindow::initAction() for (auto it = dock_widget_list.constBegin(); it != dock_widget_list.constEnd(); ++it) { CDockWidget* dock_widget = *it; if (dock_widget) { - if ( dock_widget->widget() == view ) { - dock_widget->toggleView(); - dock_widget->raise(); - view_exist = true; + MeasureAnalysisView* dock_view = dynamic_cast(dock_widget->widget()); + if ( dock_view ) { + if (dock_view->GetViewName() == view->GetViewName()) { + dock_widget->toggleView(); + dock_widget->raise(); + view_exist = true; + } } } } @@ -265,6 +268,10 @@ void MainWindow::initAction() } auto central_area = _dock_manager->centralWidget()->dockAreaWidget(); _dock_manager->addDockWidget(ads::DockWidgetArea::CenterDockWidgetArea, dock_widget, central_area); + } else { + if ( view->IsDeleteOnClose() ) { + delete view; + } } } }); diff --git a/src/MeasureAnalysisParticleCountPlotView/FindPeaksResultDialog.cpp b/src/MeasureAnalysisParticleCountPlotView/FindPeaksResultDialog.cpp index 123eeff..cec4c04 100644 --- a/src/MeasureAnalysisParticleCountPlotView/FindPeaksResultDialog.cpp +++ b/src/MeasureAnalysisParticleCountPlotView/FindPeaksResultDialog.cpp @@ -114,8 +114,20 @@ FindPeaksResultDialog::FindPeaksResultDialog(QWidget *parent) connect(_peaks_result_table, &QTableWidget::currentItemChanged, [this](QTableWidgetItem* current, QTableWidgetItem* previous) { bool is_watch_item_changed = _peaks_result_table->property("WatchItemChanged").toBool(); if (is_watch_item_changed) { - emit peakInfoChanged(peakInfo(previous, false, false)); - emit peakInfoChanged(peakInfo(current, true, true)); + int previous_row = -1; + if (previous ) { + previous_row = previous->row(); + } + int current_row = -1; + if (current) { + current_row = current->row(); + } + if ((previous_row >= 0) && (previous_row != current_row) ) { + emit peakInfoChanged(peakInfo(previous, false, false)); + } + if (current_row >= 0) { + emit peakInfoChanged(peakInfo(current, true, true)); + } } }); @@ -200,9 +212,9 @@ void FindPeaksResultDialog::UpdatePeakResult() QPushButton* btn_remove_row = new QPushButton(QStringLiteral(u"删除")); btn_remove_row->setMaximumWidth(35); connect(btn_remove_row, &QPushButton::clicked, [this, item, btn_remove_row]() { - item->setCheckState(Qt::Unchecked); - emit peakInfoChanged(peakInfo(item, false, false)); int remove_row = item->row(); + this->_peaks_result_table->item(remove_row, 0)->setCheckState(Qt::Unchecked); + emit peakInfoChanged(peakInfo(item, false, false)); this->_peaks_result_table->removeRow(remove_row); btn_remove_row->deleteLater(); }); diff --git a/src/MeasureAnalysisProjectModel.cpp b/src/MeasureAnalysisProjectModel.cpp index 73cb068..c18c0b8 100644 --- a/src/MeasureAnalysisProjectModel.cpp +++ b/src/MeasureAnalysisProjectModel.cpp @@ -103,6 +103,11 @@ void MeasureAnalysisProjectModel::SetTimeWinConformParticleData(uint time_win, u this->_time_win_conform_particle_data[time_win][conform_particle_count] = filename; } +void MeasureAnalysisProjectModel::SetTimeWinConformEnergyData(uint time_win, uint conform_particle_count, const QString& filename) +{ + this->_time_win_conform_energy_data[time_win][conform_particle_count] = filename; +} + void MeasureAnalysisProjectModel::SetAnalysisCustomData(AnalysisType analysis_type, const QString &data_item_name, const QString &data_filename) { this->_analysis_custom_data_set[analysis_type][data_item_name] = data_filename; @@ -225,6 +230,15 @@ const QMap MeasureAnalysisProjectModel::GetTimeWinConformParticle return conform_particle_data; } +const QMap MeasureAnalysisProjectModel::GetTimeWinConformEnergyDataFilenameList(uint time_win) const +{ + QMap conform_energy_data; + if ( this->_time_win_conform_energy_data.contains(time_win) ) { + conform_energy_data = this->_time_win_conform_energy_data[time_win]; + } + return conform_energy_data; +} + const QString MeasureAnalysisProjectModel::GetAnalysisCustomData(AnalysisType analysis_type, const QString &data_item_name) { return this->_analysis_custom_data_set.value(analysis_type).value(data_item_name); @@ -617,9 +631,12 @@ void MeasureAnalysisProjectModelList::ApplyEnergyScale(const QString &project_na } pro_model->SaveProjectModel(); - auto apply_erergy_scale_fit_task = new DataProcessWorkPool::ApplyEnergyScaleTask; - apply_erergy_scale_fit_task->SetFinishedNotifier(this, "onApplyEnergyScaleProcessFinished", project_name); + auto apply_erergy_scale_fit_task = new DataProcessWorkPool::EnergyScaleParticleDataTask; + apply_erergy_scale_fit_task->SetFinishedNotifier(this, "onEnergyScaleParticleDataFinished", project_name); apply_erergy_scale_fit_task->StartTask(); + auto energy_count_process_task = new DataProcessWorkPool::EnergyCountProcessTask; + energy_count_process_task->SetFinishedNotifier(this, "onEnergyCountProcessFinished", project_name); + energy_count_process_task->StartTask(); } } } @@ -665,7 +682,12 @@ void MeasureAnalysisProjectModelList::onChannelAddressCountProcessFinished(bool } } -void MeasureAnalysisProjectModelList::onApplyEnergyScaleProcessFinished(bool ok, const QString& project_name, const QVariant &data) +void MeasureAnalysisProjectModelList::onEnergyScaleParticleDataFinished(bool ok, const QString &project_name, const QVariant &data) +{ + +} + +void MeasureAnalysisProjectModelList::onEnergyCountProcessFinished(bool ok, const QString &project_name, const QVariant &data) { Q_UNUSED(data); if ( !ok ) @@ -703,6 +725,11 @@ void MeasureAnalysisProjectModelList::onApplyEnergyScaleProcessFinished(bool ok, } } +void MeasureAnalysisProjectModelList::onCoincidenceProcessFinished(bool ok, const QString &project_name, const QVariant &data) +{ + +} + void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProjectModel* pro_model) { if (!pro_model) { diff --git a/src/MeasureAnalysisProjectModel.h b/src/MeasureAnalysisProjectModel.h index abae6f9..53325bc 100644 --- a/src/MeasureAnalysisProjectModel.h +++ b/src/MeasureAnalysisProjectModel.h @@ -38,6 +38,7 @@ public: 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 SetTimeWinConformEnergyData(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; @@ -61,6 +62,7 @@ public: const QString GetChannelEnergyCountDataFilename(uint channel) const; const QString& GetAllChannelEnergyTotalCountDataFilename() const; const QMap GetTimeWinConformParticleDataFilenameList(uint time_win) const; + const QMap GetTimeWinConformEnergyDataFilenameList(uint time_win) const; const QString GetAnalysisCustomData(AnalysisType analysis_type, const QString& data_item_name); private: @@ -83,6 +85,7 @@ private: QMap _channel_energy_count_data_filename_list; QString _all_channel_energy_total_count_data_filename; QMap > _time_win_conform_particle_data; + QMap > _time_win_conform_energy_data; QMap > _analysis_custom_data_set; public: @@ -135,7 +138,9 @@ public: private slots: void onChannelAddressCountProcessFinished(bool ok, const QString& project_name, const QVariant& data); - void onApplyEnergyScaleProcessFinished(bool ok, const QString& project_name, const QVariant &data); + void onEnergyScaleParticleDataFinished(bool ok, const QString& project_name, const QVariant& data); + void onEnergyCountProcessFinished(bool ok, const QString& project_name, const QVariant& data); + void onCoincidenceProcessFinished(bool ok, const QString& project_name, const QVariant& data); private: void intiProjectNodeStruce(MeasureAnalysisProjectModel *pro_model); diff --git a/src/MeasureAnalysisView.cpp b/src/MeasureAnalysisView.cpp index f851757..0f52878 100644 --- a/src/MeasureAnalysisView.cpp +++ b/src/MeasureAnalysisView.cpp @@ -72,8 +72,8 @@ MeasureAnalysisView *MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type) // new_view->setDeleteOnClose(false); } break; case AnalysisType::ParticleInTimeView: { - // new_view = new MeasureAnalysisDataTableView; - // new_view->setDeleteOnClose(false); + new_view = new MeasureAnalysisDataTableView; + new_view->setDeleteOnClose(false); } break; case AnalysisType::ParticleTimeDiffView: { // new_view = new MeasureAnalysisParticleCountPlotView; diff --git a/src/NewMeasureAnalysisDlg.cpp b/src/NewMeasureAnalysisDlg.cpp index 7b39e66..d99be93 100644 --- a/src/NewMeasureAnalysisDlg.cpp +++ b/src/NewMeasureAnalysisDlg.cpp @@ -200,7 +200,7 @@ void NewMeasureAnalysisDlg::on_btn_ok_clicked() QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"请选择粒子数据文件!")); return; } - auto separate_task = new DataProcessWorkPool::ParticleDataSortTask; + auto separate_task = new DataProcessWorkPool::ParticleDataSortByMinimysTask; separate_task->SetAllChannelParticleDataFilename(data_file_path); separate_task->SetSortedResultDir(project_dir_path); separate_task->SetFinishedNotifier(this, "onNewProjectFromFileFinished", project_name); From 114e6843e35479997c58320ead037bf525b9fea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B5=B7?= Date: Tue, 24 Mar 2026 10:56:14 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=A4=9A=E9=80=9A?= =?UTF-8?q?=E9=81=93=E8=83=BD=E9=87=8F=E5=88=BB=E5=BA=A6=E5=B3=B0=E9=80=89?= =?UTF-8?q?=E6=8B=A9bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MeasureAnalysisParticleCountPlotView.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp b/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp index 452d213..0e6cb19 100644 --- a/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp +++ b/src/MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp @@ -192,7 +192,6 @@ void MeasureAnalysisParticleCountPlotView::setupEnergyScaleDlg() connect(_data_selector, &CustomQwtPlotXaxisSelector::selectionFinished, _batch_energy_scale_dlg, &BatchEnergyScaleDialog::onSelectedScaleRange); connect(_batch_energy_scale_dlg, &BatchEnergyScaleDialog::close, [this](){ this->_data_selector->setEnabled(false); - disconnect(_data_selector, &CustomQwtPlotXaxisSelector::selectionFinished, _batch_energy_scale_dlg, &BatchEnergyScaleDialog::onSelectedScaleRange); }); } } From ee794cfccc69156e2805c6281b90ee7e48102bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B5=B7?= Date: Tue, 24 Mar 2026 13:58:48 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B5=8B=E9=87=8F?= =?UTF-8?q?=E5=88=86=E6=9E=90=E6=A0=91=E5=88=86=E6=9E=90=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MeasureAnalysisProjectModel.cpp | 312 ++++++++++++++++++++-------- src/MeasureAnalysisProjectModel.h | 12 +- 2 files changed, 236 insertions(+), 88 deletions(-) diff --git a/src/MeasureAnalysisProjectModel.cpp b/src/MeasureAnalysisProjectModel.cpp index c18c0b8..6d1d01b 100644 --- a/src/MeasureAnalysisProjectModel.cpp +++ b/src/MeasureAnalysisProjectModel.cpp @@ -98,6 +98,11 @@ void MeasureAnalysisProjectModel::SetAllChannelEnergyTotalCountDataFilename(cons this->_all_channel_energy_total_count_data_filename = filename; } +void MeasureAnalysisProjectModel::SetParticleEnergyDataFilename(const QString &filename) +{ + this->_particle_energy_data_filename = filename; +} + void MeasureAnalysisProjectModel::SetTimeWinConformParticleData(uint time_win, uint conform_particle_count, const QString& filename) { this->_time_win_conform_particle_data[time_win][conform_particle_count] = filename; @@ -221,6 +226,11 @@ const QString& MeasureAnalysisProjectModel::GetAllChannelEnergyTotalCountDataFil return this->_all_channel_energy_total_count_data_filename; } +const QString MeasureAnalysisProjectModel::GetParticleEnergyDataFilename() const +{ + return this->_particle_energy_data_filename; +} + const QMap MeasureAnalysisProjectModel::GetTimeWinConformParticleDataFilenameList(uint time_win) const { QMap conform_particle_data; @@ -309,23 +319,19 @@ bool MeasureAnalysisProjectModel::LoadProjectModel(const QString& project_filena this->_measure_device_params_cfg_filename = ProjectAbsFilename(json_obj["MeasureDeviceParamsCfgFilename"].toString()); this->_energy_scale_filename = ProjectAbsFilename(json_obj["EnergyScaleFilename"].toString()); this->_efficiency_scale_filename = ProjectAbsFilename(json_obj["EfficiencyScaleFilename"].toString()); - this->_all_channel_particle_data_filename = ProjectAbsFilename(json_obj["AllChannelParticleDataFilename"].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) { uint channel_num = it.key().toUInt(); this->_channel_address_count_data_filename_list[channel_num] = ProjectAbsFilename(it.value().toString()); } - const auto& energy_count_data_filename_list = json_obj["ChannelEnergyCountDataFilenameList"].toObject().toVariantMap(); for (auto it = energy_count_data_filename_list.constBegin(); it!=energy_count_data_filename_list.constEnd(); ++it) { uint channel_num = it.key().toUInt(); this->_channel_energy_count_data_filename_list[channel_num] = ProjectAbsFilename(it.value().toString()); } - this->_all_channel_energy_total_count_data_filename = ProjectAbsFilename(json_obj["AllChannelEnergyTotalCountDataFilename"].toString()); - + this->_particle_energy_data_filename = ProjectAbsFilename(json_obj["ParticleEnergyDataFilename"].toString()); const auto& time_win_conform_particle_data = json_obj["TimeWinConformParticleData"].toObject().toVariantMap(); for (auto it = time_win_conform_particle_data.constBegin(); it!=time_win_conform_particle_data.constEnd(); ++it) { uint time_win = it.key().toUInt(); @@ -337,7 +343,6 @@ bool MeasureAnalysisProjectModel::LoadProjectModel(const QString& project_filena // } this->_time_win_conform_particle_data[time_win] = conform_particle_data; } - return true; } @@ -391,6 +396,7 @@ bool MeasureAnalysisProjectModel::SaveProjectModel() } time_win_conform_particle_data[QString::number(it.key())] = conform_particle_data; } + project_json_obj_map["ParticleEnergyDataFilename"] = ProjectRelativeFilename(this->_particle_energy_data_filename); project_json_obj_map["TimeWinConformParticleData"] = time_win_conform_particle_data; // 将项目模型保存到json文件 @@ -536,8 +542,8 @@ QStandardItem* MeasureAnalysisProjectModelList::GetItemFromIndex(const QModelInd } QStandardItem* MeasureAnalysisProjectModelList::AddChildNode( - QStandardItem* parent_item, const QString& node_name, const QString& status, - const QVariant& user_data, bool is_fixed) + QStandardItem* parent_item, const QString& node_name, const QString& status_text, + const QVariant& user_data, bool is_fixed, bool state_ok) { if (!parent_item) return nullptr; @@ -545,9 +551,15 @@ QStandardItem* MeasureAnalysisProjectModelList::AddChildNode( QStandardItem* name_item = new QStandardItem(node_name); name_item->setData(user_data, NodeType); name_item->setData(is_fixed, Fixed); - - QStandardItem* status_item = new QStandardItem(status); - + QStandardItem* status_item = new QStandardItem(status_text); + status_item->setData(state_ok, Qt::UserRole); + if (state_ok) { + name_item->setForeground(Qt::black); + status_item->setForeground(Qt::black); + } else { + name_item->setForeground(Qt::gray); + status_item->setForeground(Qt::gray); + } QList row_items; row_items << name_item << status_item; parent_item->appendRow(row_items); @@ -593,7 +605,7 @@ QVariant MeasureAnalysisProjectModelList::GetNodeUserData(QStandardItem* item, U return (item && item->column() == NameColumn) ? item->data(data_type) : QVariant(); } -void MeasureAnalysisProjectModelList::SetNodeStatus(QStandardItem* item, const QString& status) +void MeasureAnalysisProjectModelList::SetNodeStatus(QStandardItem* item, const QString& status, bool state_ok) { if (!item || item->column() != NameColumn) return; @@ -602,17 +614,25 @@ void MeasureAnalysisProjectModelList::SetNodeStatus(QStandardItem* item, const Q : invisibleRootItem()->child(item->row(), StatusColumn); if (status_item) { status_item->setText(status); + status_item->setData(state_ok, Qt::UserRole); + if (state_ok) { + status_item->setForeground(Qt::black); + } else { + status_item->setForeground(Qt::gray); + } } } -QString MeasureAnalysisProjectModelList::GetNodeStatus(QStandardItem* item) const +bool MeasureAnalysisProjectModelList::GetNodeStatus(QStandardItem* item) const { if (!item || item->column() != NameColumn) - return QString(); + return false; QStandardItem* status_item = item->parent() ? item->parent()->child(item->row(), StatusColumn) : invisibleRootItem()->child(item->row(), StatusColumn); - return status_item ? status_item->text() : QString(); + if ( !status_item ) + return false; + return status_item->data(Qt::UserRole).toBool(); } void MeasureAnalysisProjectModelList::ApplyEnergyScale(const QString &project_name) @@ -649,18 +669,15 @@ void MeasureAnalysisProjectModelList::onChannelAddressCountProcessFinished(bool if (this->_project_models.contains(project_name)) { auto pro_model = this->_project_models[project_name]; const QMap& filename_list = pro_model->GetChannelAddressCountDataFilenameList(); - QString status = QStringLiteral(u"无效"); if (!filename_list.isEmpty()) { status = QStringLiteral(u"有效"); } - auto& node_map = this->_project_node_items[project_name]; const QString& adrr_count_item_name = QStringLiteral(u"道址计数"); if (node_map.contains(adrr_count_item_name)) { auto adrr_count_item = node_map[adrr_count_item_name]; this->SetNodeStatus(adrr_count_item, status); - for (auto it = filename_list.begin(); it != filename_list.end(); ++it) { uint ch_num = it.key(); QString item_name = QStringLiteral(u"通道%1道址计数").arg(ch_num); @@ -671,23 +688,16 @@ void MeasureAnalysisProjectModelList::onChannelAddressCountProcessFinished(bool node_map[item_name] = node_item; } } - const QString& adrr_count_spec_item_name = QStringLiteral(u"道址计数谱"); if (node_map.contains(adrr_count_spec_item_name)) { auto adrr_count_spec_item = node_map[adrr_count_spec_item_name]; this->SetNodeStatus(adrr_count_spec_item, status); } - pro_model->SaveProjectModel(); } } void MeasureAnalysisProjectModelList::onEnergyScaleParticleDataFinished(bool ok, const QString &project_name, const QVariant &data) -{ - -} - -void MeasureAnalysisProjectModelList::onEnergyCountProcessFinished(bool ok, const QString &project_name, const QVariant &data) { Q_UNUSED(data); if ( !ok ) @@ -725,9 +735,121 @@ void MeasureAnalysisProjectModelList::onEnergyCountProcessFinished(bool ok, cons } } +void MeasureAnalysisProjectModelList::onEnergyCountProcessFinished(bool ok, const QString &project_name, const QVariant &data) +{ + Q_UNUSED(data); + if ( !ok ) + return; + if (this->_project_models.contains(project_name)) { + auto pro_model = this->_project_models[project_name]; + auto& node_map = this->_project_node_items[project_name]; + bool status_ok = false; + QString status = QStringLiteral(u"无效"); + const QString& energy_total_count_filename = pro_model->GetAllChannelEnergyTotalCountDataFilename(); + if (!energy_total_count_filename.isEmpty()) { + status_ok = true; + status = QStringLiteral(u"有效"); + const QString& energy_total_count_item_name = QStringLiteral(u"能量计数"); + if (node_map.contains(energy_total_count_item_name)) { + auto energy_total_count_item = node_map[energy_total_count_item_name]; + this->SetNodeStatus(energy_total_count_item, status, status_ok); + const QMap& channel_energy_count_filename_list = pro_model->GetChannelEnergyCountDataFilenameList(); + for (auto it = channel_energy_count_filename_list.constBegin(); it != channel_energy_count_filename_list.constEnd(); ++it) { + uint ch_num = it.key(); + QString item_name = QStringLiteral(u"通道%1能量计数").arg(ch_num); + if ( !node_map.contains(item_name) ) { + const QVariant& analys_type = QVariant::fromValue(AnalysisType::EnergyCountData); + QStandardItem* node_item = AddChildNode(energy_total_count_item, item_name, status, analys_type, true, status_ok); + node_item->setData(project_name, ProjectName); + node_item->setData(ch_num, ChannelNum); + node_map[item_name] = node_item; + } else { + auto ch_energy_count_item = node_map[item_name]; + this->SetNodeStatus(ch_energy_count_item, status, status_ok); + } + } + const auto& ch_energy_count_data_list = pro_model->GetChannelEnergyCountDataFilenameList(); + if (!ch_energy_count_data_list.isEmpty()) { + const QString& adrr_count_spec_item_name = QStringLiteral(u"能量计数谱"); + if (node_map.contains(adrr_count_spec_item_name)) { + auto adrr_count_spec_item = node_map[adrr_count_spec_item_name]; + this->SetNodeStatus(adrr_count_spec_item, status); + } + } + } + } + const QString& particle_energy_data_filename = pro_model->GetParticleEnergyDataFilename(); + if (!particle_energy_data_filename.isEmpty()) { + status_ok = true; + status = QStringLiteral(u"有效"); + const QString& count_rate_analysis_item_name = QStringLiteral(u"计数率分析"); + if (node_map.contains(count_rate_analysis_item_name)) { + auto energy_total_count_spec_item = node_map[count_rate_analysis_item_name]; + this->SetNodeStatus(energy_total_count_spec_item, status, status_ok); + } + const QString& peak_fit_analysis_item_name = QStringLiteral(u"峰拟合分析"); + if (node_map.contains(peak_fit_analysis_item_name)) { + auto energy_total_count_spec_item = node_map[peak_fit_analysis_item_name]; + this->SetNodeStatus(energy_total_count_spec_item, status, status_ok); + } + const QString& nuclide_analysis_item_name = QStringLiteral(u"核素分析"); + if (node_map.contains(nuclide_analysis_item_name)) { + auto energy_total_count_spec_item = node_map[nuclide_analysis_item_name]; + this->SetNodeStatus(energy_total_count_spec_item, status, status_ok); + } + const QString& particle_in_time_analysis_item_name = QStringLiteral(u"粒子入射时间分析"); + if (node_map.contains(particle_in_time_analysis_item_name)) { + auto energy_total_count_spec_item = node_map[particle_in_time_analysis_item_name]; + this->SetNodeStatus(energy_total_count_spec_item, status, status_ok); + } + } + pro_model->SaveProjectModel(); + } +} + void MeasureAnalysisProjectModelList::onCoincidenceProcessFinished(bool ok, const QString &project_name, const QVariant &data) { - + Q_UNUSED(data); + if ( !ok ) + return; + if (this->_project_models.contains(project_name)) { + auto pro_model = this->_project_models[project_name]; + auto& node_map = this->_project_node_items[project_name]; + bool status_ok = false; + QString status = QStringLiteral(u"无效"); + uint conform_time_win = pro_model->GetConformTimeWin(); + const auto& Conform_energy_data_filename_list = pro_model->GetTimeWinConformEnergyDataFilenameList(conform_time_win); + if (!Conform_energy_data_filename_list.isEmpty()) { + status_ok = true; + status = QStringLiteral(u"有效"); + QString item_name = QStringLiteral(u"符合事件时间分析"); + if (node_map.contains(item_name)) { + auto energy_total_count_item = node_map[item_name]; + this->SetNodeStatus(energy_total_count_item, status, status_ok); + } + item_name = QStringLiteral(u"符合能谱[%1ns]").arg(conform_time_win); + if (node_map.contains(item_name)) { + auto energy_total_count_spec_item = node_map[item_name]; + this->SetNodeStatus(energy_total_count_spec_item, status, status_ok); + } + item_name = QStringLiteral(u"反符合能谱[%1ns]").arg(conform_time_win); + if (node_map.contains(item_name)) { + auto energy_total_count_spec_item = node_map[item_name]; + this->SetNodeStatus(energy_total_count_spec_item, status, status_ok); + } + item_name = QStringLiteral(u"二维符合能谱[%1ns]").arg(conform_time_win); + if (node_map.contains(item_name)) { + auto energy_total_count_spec_item = node_map[item_name]; + this->SetNodeStatus(energy_total_count_spec_item, status, status_ok); + } + item_name = QStringLiteral(u"三维符合能谱[%1ns]").arg(conform_time_win); + if (node_map.contains(item_name)) { + auto energy_total_count_spec_item = node_map[item_name]; + this->SetNodeStatus(energy_total_count_spec_item, status, status_ok); + } + } + pro_model->SaveProjectModel(); + } } void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProjectModel* pro_model) @@ -742,57 +864,60 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProje const QString& project_name = pro_model->GetProjectName(); QString status = pro_model->GetIsMeasureComplete() ? QStringLiteral(u"测量完成") : QStringLiteral(u"未测量"); QVariant analys_type = QVariant::fromValue(AnalysisType::Project); - QStandardItem* project_item = AddChildNode(root_item, project_name, status, analys_type, false); + QStandardItem* project_item = AddChildNode(root_item, project_name, status, analys_type, false, true); project_item->setData(project_name, ProjectName); node_map[project_name] = project_item; // 测量控制 QString item_name = QStringLiteral(u"测量控制"); - QStandardItem* measure_ctrl_item = AddChildNode(project_item, item_name, QString(), QVariant(), true); + QStandardItem* measure_ctrl_item = AddChildNode(project_item, item_name, QString(), QVariant(), true, true); measure_ctrl_item->setData(project_name, ProjectName); node_map[item_name] = measure_ctrl_item; - if (!pro_model->GetIsMeasureComplete()) { - const QString& measure_device_params_cfg_filename = pro_model->GetMeasureDeviceParamsCfgFilename(); - status = measure_device_params_cfg_filename.isEmpty() ? QStringLiteral(u"未配置") : QStringLiteral(u"已配置"); - analys_type = QVariant::fromValue(AnalysisType::DeviceParamsCfg); - item_name = QStringLiteral(u"设备配置参数"); - QStandardItem* node_item = AddChildNode(measure_ctrl_item, item_name, status, analys_type, true); - node_item->setData(project_name, ProjectName); - node_map[item_name] = node_item; - } - - status = pro_model->GetEnergyScaleFilename().isEmpty() ? QStringLiteral(u"未配置") : QStringLiteral(u"已配置"); - analys_type = QVariant::fromValue(AnalysisType::EnergyScale); - item_name = QStringLiteral(u"能量刻度"); - QStandardItem* node_item = AddChildNode(measure_ctrl_item, item_name, status, analys_type, true); + const QString& measure_device_params_cfg_filename = pro_model->GetMeasureDeviceParamsCfgFilename(); + bool state_ok = !measure_device_params_cfg_filename.isEmpty(); + status = state_ok ? QStringLiteral(u"已配置") : QStringLiteral(u"未配置"); + analys_type = QVariant::fromValue(AnalysisType::DeviceParamsCfg); + item_name = QStringLiteral(u"设备配置参数"); + QStandardItem* node_item = AddChildNode(measure_ctrl_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = pro_model->GetEfficiencyScaleFilename().isEmpty() ? QStringLiteral(u"未配置") : QStringLiteral(u"已配置"); + state_ok = !pro_model->GetEnergyScaleFilename().isEmpty(); + status = state_ok ? QStringLiteral(u"已配置") : QStringLiteral(u"未配置"); + analys_type = QVariant::fromValue(AnalysisType::EnergyScale); + item_name = QStringLiteral(u"能量刻度"); + node_item = AddChildNode(measure_ctrl_item, item_name, status, analys_type, true, state_ok); + node_item->setData(project_name, ProjectName); + node_map[item_name] = node_item; + + state_ok = !pro_model->GetEfficiencyScaleFilename().isEmpty(); + status = state_ok ? QStringLiteral(u"已配置") : QStringLiteral(u"未配置"); analys_type = QVariant::fromValue(AnalysisType::EfficiencyScale); item_name = QStringLiteral(u"效率刻度"); - node_item = AddChildNode(measure_ctrl_item, item_name, status, analys_type, true); + node_item = AddChildNode(measure_ctrl_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; // 分析数据 item_name = QStringLiteral(u"分析数据"); - QStandardItem* analysis_data_item = AddChildNode(project_item, item_name, QString(), QVariant(), true); + QStandardItem* analysis_data_item = AddChildNode(project_item, item_name, QString(), QVariant(), true, true); analysis_data_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = pro_model->GetAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + state_ok = !pro_model->GetAllChannelParticleDataFilename().isEmpty(); + status = state_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); analys_type = QVariant::fromValue(AnalysisType::ParticleData); item_name = QStringLiteral(u"测量粒子数据"); - node_item = AddChildNode(analysis_data_item, item_name, status, analys_type, true); + node_item = AddChildNode(analysis_data_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - item_name = QStringLiteral(u"道址计数"); const auto& ch_addr_count_data_filename_list = pro_model->GetChannelAddressCountDataFilenameList(); - status = ch_addr_count_data_filename_list.isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); - node_item = AddChildNode(analysis_data_item, item_name, status, QVariant(), true); + state_ok = !ch_addr_count_data_filename_list.isEmpty(); + status = state_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); + item_name = QStringLiteral(u"道址计数"); + node_item = AddChildNode(analysis_data_item, item_name, status, QVariant(), true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; QStandardItem* adrr_count_item = node_item; @@ -800,128 +925,147 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProje uint ch_num = it.key(); QString item_name = QStringLiteral(u"通道%1道址计数").arg(ch_num); const QVariant& analys_type = QVariant::fromValue(AnalysisType::AddressCountData); - QStandardItem* node_item = AddChildNode(adrr_count_item, item_name, status, analys_type, true); + QStandardItem* node_item = AddChildNode(adrr_count_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_item->setData(ch_num, ChannelNum); node_map[item_name] = node_item; } + state_ok = !pro_model->GetParticleEnergyDataFilename().isEmpty(); + status = state_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); + analys_type = QVariant::fromValue(AnalysisType::CoincidenceParticleEnergyData); + item_name = QStringLiteral(u"粒子能量数据"); + node_item = AddChildNode(analysis_data_item, item_name, status, analys_type, true, state_ok); + node_item->setData(project_name, ProjectName); + node_map[item_name] = node_item; + + state_ok = !pro_model->GetAllChannelEnergyTotalCountDataFilename().isEmpty(); + status = state_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); item_name = QStringLiteral(u"能量计数"); - status = pro_model->GetAllChannelEnergyTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); analys_type = QVariant::fromValue(AnalysisType::EnergyCountData); - node_item = AddChildNode(analysis_data_item, item_name, status, analys_type, true); + node_item = AddChildNode(analysis_data_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; QStandardItem* energy_count_item = node_item; const auto& ch_energy_count_data_filename_list = pro_model->GetChannelEnergyCountDataFilenameList(); + state_ok = !ch_energy_count_data_filename_list.isEmpty(); for (auto it = ch_energy_count_data_filename_list.begin(); it != ch_energy_count_data_filename_list.end(); ++it) { uint ch_num = it.key(); QString item_name = QStringLiteral(u"通道%1能量计数").arg(ch_num); const QVariant& analys_type = QVariant::fromValue(AnalysisType::EnergyCountData); - QStandardItem* node_item = AddChildNode(energy_count_item, item_name, status, analys_type, true); + QStandardItem* node_item = AddChildNode(energy_count_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_item->setData(ch_num, ChannelNum); node_map[item_name] = node_item; } uint conform_time_win = pro_model->GetConformTimeWin(); - status = pro_model->GetTimeWinConformParticleDataFilenameList(conform_time_win).isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + state_ok = !pro_model->GetTimeWinConformParticleDataFilenameList(conform_time_win).isEmpty(); + status = state_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); analys_type = QVariant::fromValue(AnalysisType::CoincidenceParticleEnergyData); item_name = QStringLiteral(u"符合粒子数据[%1ns]").arg(conform_time_win); - node_item = AddChildNode(analysis_data_item, item_name, status, analys_type, true); + node_item = AddChildNode(analysis_data_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; // 交互分析 item_name = QStringLiteral(u"交互分析"); - QStandardItem* interactive_analysis_item = AddChildNode(project_item, item_name, QString(), QVariant(), true); + QStandardItem* interactive_analysis_item = AddChildNode(project_item, item_name, QString(), QVariant(), true, true); interactive_analysis_item->setData(project_name, ProjectName); node_map[item_name] = interactive_analysis_item; - status = pro_model->GetChannelAddressCountDataFilenameList().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + state_ok = !pro_model->GetChannelAddressCountDataFilenameList().isEmpty(); + status = state_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); analys_type = QVariant::fromValue(AnalysisType::AddressCountSpectrumView); item_name = QStringLiteral(u"道址计数谱"); - node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); + node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = pro_model->GetChannelEnergyCountDataFilenameList().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); - analys_type = QVariant::fromValue(AnalysisType::EnergyCountSpectrumView); - 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->GetAllChannelEnergyTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + state_ok = !pro_model->GetAllChannelEnergyTotalCountDataFilename().isEmpty(); + state_ok &= pro_model->GetChannelEnergyCountDataFilenameList().isEmpty(); + status = state_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); analys_type = QVariant::fromValue(AnalysisType::EnergyCountSpectrumView); item_name = QStringLiteral(u"能量计数谱"); - node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); + node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = pro_model->GetAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + state_ok = !pro_model->GetParticleEnergyDataFilename().isEmpty(); + status = state_ok ? 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); + node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = pro_model->GetAllChannelEnergyTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + state_ok = !pro_model->GetParticleEnergyDataFilename().isEmpty(); + status = state_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); analys_type = QVariant::fromValue(AnalysisType::EnergyPeakFitView); item_name = QStringLiteral(u"峰拟合分析"); - node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); + node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = pro_model->GetAllChannelEnergyTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + state_ok = !pro_model->GetParticleEnergyDataFilename().isEmpty(); + status = state_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); analys_type = QVariant::fromValue(AnalysisType::NuclideAnalysisView); item_name = QStringLiteral(u"核素分析"); - node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); + node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = pro_model->GetAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + state_ok = !pro_model->GetParticleEnergyDataFilename().isEmpty(); + status = state_ok ? 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 = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = pro_model->GetAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + state_ok = !pro_model->GetAllChannelParticleDataFilename().isEmpty(); + status = state_ok ? 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); + node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; - status = pro_model->GetTimeWinConformParticleDataFilenameList(conform_time_win).isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); + state_ok = !pro_model->GetTimeWinConformEnergyDataFilenameList(conform_time_win).isEmpty(); + status = state_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); analys_type = QVariant::fromValue(AnalysisType::CoincidenceEventTimeView); item_name = QStringLiteral(u"符合事件时间分析"); - node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); + node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; + state_ok = !pro_model->GetTimeWinConformEnergyDataFilenameList(conform_time_win).isEmpty(); + status = state_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); analys_type = QVariant::fromValue(AnalysisType::CoincidenceParticleEnergySpectrumView); item_name = QStringLiteral(u"符合能谱[%1ns]").arg(conform_time_win); - node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); + node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; analys_type = QVariant::fromValue(AnalysisType::AntiCoincidenceSpectrumView); item_name = QStringLiteral(u"反符合能谱[%1ns]").arg(conform_time_win); - node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); + node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; + state_ok = !pro_model->GetTimeWinConformEnergyDataFilenameList(conform_time_win).isEmpty(); + status = state_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); analys_type = QVariant::fromValue(AnalysisType::CoincidenceParticleEnergySpectrum2DView); item_name = QStringLiteral(u"二维符合能谱[%1ns]").arg(conform_time_win); - node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); + node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; + state_ok = !pro_model->GetTimeWinConformEnergyDataFilenameList(conform_time_win).isEmpty(); + status = state_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); analys_type = QVariant::fromValue(AnalysisType::CoincidenceParticleEnergySpectrum3DView); item_name = QStringLiteral(u"三维符合能谱[%1ns]").arg(conform_time_win); - node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); + node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; diff --git a/src/MeasureAnalysisProjectModel.h b/src/MeasureAnalysisProjectModel.h index 53325bc..74801ab 100644 --- a/src/MeasureAnalysisProjectModel.h +++ b/src/MeasureAnalysisProjectModel.h @@ -37,6 +37,7 @@ public: // void SetAllChannelParticleTotalCountDataFilename(const QString& filename); void SetChannelEnergyCountDataFilename(uint channel, const QString& filename); void SetAllChannelEnergyTotalCountDataFilename(const QString& filename); + void SetParticleEnergyDataFilename(const QString& filename); void SetTimeWinConformParticleData(uint time_win, uint conform_particle_count, const QString& filename); void SetTimeWinConformEnergyData(uint time_win, uint conform_particle_count, const QString& filename); void SetAnalysisCustomData(AnalysisType analysis_type, const QString& data_item_name, const QString& data_filename); @@ -61,6 +62,7 @@ public: const QMap& GetChannelEnergyCountDataFilenameList() const; const QString GetChannelEnergyCountDataFilename(uint channel) const; const QString& GetAllChannelEnergyTotalCountDataFilename() const; + const QString GetParticleEnergyDataFilename() const; const QMap GetTimeWinConformParticleDataFilenameList(uint time_win) const; const QMap GetTimeWinConformEnergyDataFilenameList(uint time_win) const; const QString GetAnalysisCustomData(AnalysisType analysis_type, const QString& data_item_name); @@ -84,6 +86,7 @@ private: // QString _all_channel_particle_total_count_data_filename; QMap _channel_energy_count_data_filename_list; QString _all_channel_energy_total_count_data_filename; + QString _particle_energy_data_filename; QMap > _time_win_conform_particle_data; QMap > _time_win_conform_energy_data; QMap > _analysis_custom_data_set; @@ -125,14 +128,15 @@ public: QStandardItem* GetItemFromIndex(const QModelIndex &index) const; QStandardItem* AddChildNode(QStandardItem *parent_item, const QString &node_name, - const QString &status = QString(), + const QString &status_text = QString(), const QVariant &user_data = QVariant(), - bool is_fixed = false); + bool is_fixed = false, + bool state_ok = false); bool RemoveNode(QStandardItem *item); void SetNodeUserData(QStandardItem* item, const QVariant& data); QVariant GetNodeUserData(QStandardItem* item, UserDataType data_type = NodeType) const; - void SetNodeStatus(QStandardItem* item, const QString& status); - QString GetNodeStatus(QStandardItem* item) const; + void SetNodeStatus(QStandardItem* item, const QString& status, bool state_ok = false); + bool GetNodeStatus(QStandardItem* item) const; void ApplyEnergyScale(const QString& project_name); From 3e18a7dea072be0da61d18eefdd6b2d382c7dd9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B5=B7?= Date: Tue, 24 Mar 2026 14:18:44 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=B2=92=E5=AD=90?= =?UTF-8?q?=E8=83=BD=E9=87=8F=E6=95=B0=E6=8D=AE=E8=A7=86=E5=9B=BE=E6=98=BE?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/AnalysisTypeDefine.h | 1 + src/MeasureAnalysisProjectModel.cpp | 2 +- src/MeasureAnalysisTreeView.cpp | 20 ++++++++++++++++++++ src/MeasureAnalysisView.cpp | 4 ++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/AnalysisTypeDefine.h b/src/AnalysisTypeDefine.h index 6318f4e..c65e637 100644 --- a/src/AnalysisTypeDefine.h +++ b/src/AnalysisTypeDefine.h @@ -9,6 +9,7 @@ enum class AnalysisType { EfficiencyScale, // 效率刻度 ParticleData, // 粒子数据 AddressCountData, // 粒子道址计数数据 + ParticleEnergyData, // 粒子数据 EnergyCountData, // 能量计数数据 ChannelEnergyCountData, // 通道能量计数数据 CoincidenceParticleEnergyData, // 符合粒子能量数据 diff --git a/src/MeasureAnalysisProjectModel.cpp b/src/MeasureAnalysisProjectModel.cpp index 6d1d01b..c85a11b 100644 --- a/src/MeasureAnalysisProjectModel.cpp +++ b/src/MeasureAnalysisProjectModel.cpp @@ -933,7 +933,7 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProje state_ok = !pro_model->GetParticleEnergyDataFilename().isEmpty(); status = state_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); - analys_type = QVariant::fromValue(AnalysisType::CoincidenceParticleEnergyData); + analys_type = QVariant::fromValue(AnalysisType::ParticleEnergyData); item_name = QStringLiteral(u"粒子能量数据"); node_item = AddChildNode(analysis_data_item, item_name, status, analys_type, true, state_ok); node_item->setData(project_name, ProjectName); diff --git a/src/MeasureAnalysisTreeView.cpp b/src/MeasureAnalysisTreeView.cpp index 90d04d5..5a148a9 100644 --- a/src/MeasureAnalysisTreeView.cpp +++ b/src/MeasureAnalysisTreeView.cpp @@ -102,6 +102,26 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index) } } } break; + case AnalysisType::ParticleEnergyData: { + MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name); + if (project_model) { + auto file_name = project_model->GetParticleEnergyDataFilename(); + if ( !file_name.isEmpty() ) { + QMap data_files_set; + data_files_set[QStringLiteral(u"粒子能量数据")] = file_name; + MeasureAnalysisView* view = MeasureAnalysisView::NewAnalyzeView(analysis_type); + if ( view ) { + view->SetProjectName(project_name); + const auto& view_name = QStringLiteral(u"%1[%2]").arg(item_text).arg(project_name); + view->SetViewName(view_name); + view->SetViewDescription(view_name); + view->InitViewWorkspace(project_name); + view->SetAnalyzeDataFilename(data_files_set); + emit currentItemView(view); + } + } + } + } break; case AnalysisType::AddressCountSpectrumView: { MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name); if (project_model) { diff --git a/src/MeasureAnalysisView.cpp b/src/MeasureAnalysisView.cpp index 0f52878..cf72a82 100644 --- a/src/MeasureAnalysisView.cpp +++ b/src/MeasureAnalysisView.cpp @@ -27,6 +27,10 @@ MeasureAnalysisView *MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type) new_view = new MeasureAnalysisDataTableView; new_view->setDeleteOnClose(true); } break; + case AnalysisType::ParticleEnergyData: { + new_view = new MeasureAnalysisDataTableView; + new_view->setDeleteOnClose(true); + } break; case AnalysisType::AddressCountData: { new_view = new MeasureAnalysisDataTableView; new_view->setDeleteOnClose(true); From 3d7b185afdae189d73982af4bb6bda04a8823be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B5=B7?= Date: Tue, 24 Mar 2026 15:01:17 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MainWindow.cpp | 16 +++- src/MeasureAnalysisTreeView.cpp | 161 ++++++++++++++------------------ src/MeasureAnalysisTreeView.h | 1 + 3 files changed, 83 insertions(+), 95 deletions(-) diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 5051976..8c9f8ad 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -258,7 +258,17 @@ void MainWindow::initAction() dock_widget->setWidget(view); dock_widget->setMinimumSizeHintMode(ads::CDockWidget::MinimumSizeHintFromDockWidget); if (view->IsDeleteOnClose()) { - dock_widget->setFeatures(dock_widget->features() | ads::CDockWidget::DockWidgetDeleteOnClose); + // dock_widget->setFeatures(dock_widget->features() | ads::CDockWidget::DockWidgetDeleteOnClose); + dock_widget->setFeatures(dock_widget->features() | ads::CDockWidget::CustomCloseHandling); + connect(dock_widget, &CDockWidget::closeRequested, [this, dock_widget, view](){ + MeasureAnalysisView* dock_view = dynamic_cast(dock_widget->widget()); + if ( dock_view ) { + const QString& view_name = view->GetViewName(); + if (dock_view->GetViewName() == view_name) { + _tree_measure_analysis->RemoveItemView(view_name); + } + } + }); } if ( view->GetViewType() == MeasureAnalysisView::DataTable ) { _menu_view_data_table_list->addAction(dock_widget->toggleViewAction()); @@ -268,10 +278,6 @@ void MainWindow::initAction() } auto central_area = _dock_manager->centralWidget()->dockAreaWidget(); _dock_manager->addDockWidget(ads::DockWidgetArea::CenterDockWidgetArea, dock_widget, central_area); - } else { - if ( view->IsDeleteOnClose() ) { - delete view; - } } } }); diff --git a/src/MeasureAnalysisTreeView.cpp b/src/MeasureAnalysisTreeView.cpp index 5a148a9..00e4b5d 100644 --- a/src/MeasureAnalysisTreeView.cpp +++ b/src/MeasureAnalysisTreeView.cpp @@ -27,6 +27,20 @@ MeasureAnalysisTreeView::MeasureAnalysisTreeView(QWidget* parent) connect(this, &QTreeView::doubleClicked, this, &MeasureAnalysisTreeView::onNodeDoubleClicked); } +void MeasureAnalysisTreeView::RemoveItemView(const QString &item_name) +{ + for (auto it = _item_views.constBegin(); it!=_item_views.constEnd(); ++it ) { + MeasureAnalysisView* view = it.value(); + if (view) { + if ( view->GetViewName() == item_name ) { + emit removeItemView(view); + _item_views.remove(it.key()); + return; + } + } + } +} + void MeasureAnalysisTreeView::onCustomContextMenuRequested(const QPoint& pos) { QModelIndex index = indexAt(pos); @@ -56,106 +70,73 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index) if (!analysis_type_data.isValid()) return; AnalysisType analysis_type = analysis_type_data.value(); - - switch(analysis_type) { - case AnalysisType::ParticleData: { - MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name); - if (project_model) { - auto file_name = project_model->GetAllChannelParticleDataFilename(); - if ( !file_name.isEmpty() ) { - QMap data_files_set; - data_files_set[QStringLiteral(u"粒子数据")] = file_name; - MeasureAnalysisView* view = MeasureAnalysisView::NewAnalyzeView(analysis_type); - if ( view ) { - view->SetProjectName(project_name); - const auto& view_name = QStringLiteral(u"%1[%2]").arg(item_text).arg(project_name); - view->SetViewName(view_name); - view->SetViewDescription(view_name); - view->InitViewWorkspace(project_name); - view->SetAnalyzeDataFilename(data_files_set); - emit currentItemView(view); - } - } - } - } break; - case AnalysisType::AddressCountData: { - QVariant ch_num_data = _model->GetNodeUserData(item, ProjectList::ChannelNum); - if (ch_num_data.isValid()) { - int ch_num = ch_num_data.toInt(); + QMap data_files_set; + MeasureAnalysisView* view = nullptr; + if ( _item_views.contains(item) ) { + view = _item_views[item]; + } else { + switch(analysis_type) { + case AnalysisType::ParticleData: { MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name); if (project_model) { - auto file_name = project_model->GetChannelAddressCountDataFilename(ch_num); + auto file_name = project_model->GetAllChannelParticleDataFilename(); if ( !file_name.isEmpty() ) { - QMap data_files_set; - data_files_set[QStringLiteral(u"通道%1道址计数").arg(ch_num)] = file_name; - MeasureAnalysisView* view = MeasureAnalysisView::NewAnalyzeView(analysis_type); - if ( view ) { - view->SetProjectName(project_name); - const auto& view_name = QStringLiteral(u"%1[%2]").arg(item_text).arg(project_name); - view->SetViewName(view_name); - view->SetViewDescription(view_name); - view->InitViewWorkspace(project_name); - view->SetAnalyzeDataFilename(data_files_set); - emit currentItemView(view); - } + data_files_set[QStringLiteral(u"粒子数据")] = file_name; } } - } - } break; - case AnalysisType::ParticleEnergyData: { - MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name); - if (project_model) { - auto file_name = project_model->GetParticleEnergyDataFilename(); - if ( !file_name.isEmpty() ) { - QMap data_files_set; - data_files_set[QStringLiteral(u"粒子能量数据")] = file_name; - MeasureAnalysisView* view = MeasureAnalysisView::NewAnalyzeView(analysis_type); - if ( view ) { - view->SetProjectName(project_name); - const auto& view_name = QStringLiteral(u"%1[%2]").arg(item_text).arg(project_name); - view->SetViewName(view_name); - view->SetViewDescription(view_name); - view->InitViewWorkspace(project_name); - view->SetAnalyzeDataFilename(data_files_set); - emit currentItemView(view); - } - } - } - } break; - case AnalysisType::AddressCountSpectrumView: { - MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name); - if (project_model) { - auto file_name_list = project_model->GetChannelAddressCountDataFilenameList(); - if ( !file_name_list.isEmpty() ) { - QMap data_files_set; - auto ch_num_list = file_name_list.keys(); - for(auto ch_num : ch_num_list) { - auto file_name = file_name_list[ch_num]; + } break; + case AnalysisType::AddressCountData: { + QVariant ch_num_data = _model->GetNodeUserData(item, ProjectList::ChannelNum); + if (ch_num_data.isValid()) { + int ch_num = ch_num_data.toInt(); + MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name); + if (project_model) { + auto file_name = project_model->GetChannelAddressCountDataFilename(ch_num); if ( !file_name.isEmpty() ) { - data_files_set[QStringLiteral(u"通道%1").arg(ch_num)] = file_name; + data_files_set[QStringLiteral(u"通道%1道址计数").arg(ch_num)] = file_name; } } - MeasureAnalysisView* view = nullptr; - if ( _item_views.contains(item) ) { - view = _item_views[item]; - } else { - view = MeasureAnalysisView::NewAnalyzeView(analysis_type); - view->SetProjectName(project_name); - const auto& view_name = QStringLiteral(u"%1[%2]").arg(item_text).arg(project_name); - view->SetViewName(view_name); - view->SetViewDescription(view_name); - view->InitViewWorkspace(project_name); - view->SetAnalyzeDataFilename(data_files_set); - - } - if ( view ) { - _item_views[item] = view; - emit currentItemView(view); + } + } break; + case AnalysisType::ParticleEnergyData: { + MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name); + if (project_model) { + auto file_name = project_model->GetParticleEnergyDataFilename(); + if ( !file_name.isEmpty() ) { + data_files_set[QStringLiteral(u"粒子能量数据")] = file_name; } } + } break; + case AnalysisType::AddressCountSpectrumView: { + MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name); + if (project_model) { + auto file_name_list = project_model->GetChannelAddressCountDataFilenameList(); + if ( !file_name_list.isEmpty() ) { + auto ch_num_list = file_name_list.keys(); + for(auto ch_num : ch_num_list) { + auto file_name = file_name_list[ch_num]; + if ( !file_name.isEmpty() ) { + data_files_set[QStringLiteral(u"通道%1").arg(ch_num)] = file_name; + } + } + } + } + } break; + default: + break; } - } break; - default: - break; + if (!data_files_set.isEmpty()) { + view = MeasureAnalysisView::NewAnalyzeView(analysis_type); + view->SetProjectName(project_name); + const auto& view_name = QStringLiteral(u"%1[%2]").arg(item_text).arg(project_name); + view->SetViewName(view_name); + view->SetViewDescription(view_name); + view->InitViewWorkspace(project_name); + view->SetAnalyzeDataFilename(data_files_set); + } + } + if ( view ) { + _item_views[item] = view; + emit currentItemView(view); } } diff --git a/src/MeasureAnalysisTreeView.h b/src/MeasureAnalysisTreeView.h index 84841c7..a918ac8 100644 --- a/src/MeasureAnalysisTreeView.h +++ b/src/MeasureAnalysisTreeView.h @@ -13,6 +13,7 @@ class MeasureAnalysisTreeView : public QTreeView Q_OBJECT public: explicit MeasureAnalysisTreeView(QWidget *parent = nullptr); + void RemoveItemView(const QString& item_name); private slots: void onCustomContextMenuRequested(const QPoint &pos);