From e7f7e31d85615208671cf8c9f7daf58a1a4312dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B5=B7?= Date: Tue, 19 May 2026 14:34:22 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E6=B7=BB=E5=8A=A0=E5=8F=8D=E7=AC=A6?= =?UTF-8?q?=E5=90=88=E8=B0=B1=E6=95=B0=E6=8D=AE=E6=9F=A5=E7=9C=8B=E5=92=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=8D=E7=AC=A6=E5=90=88=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=9B=202=E3=80=81=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=B7=B2=E7=9F=A5BUG=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/AnalysisTypeDefine.h | 1 + .../AntiConformEnergySpectrumView.cpp | 41 ++----- src/MeasureAnalysisProjectModel.cpp | 105 ++++++++++++++++-- src/MeasureAnalysisTreeView.cpp | 12 ++ src/MeasureAnalysisView.cpp | 4 + 5 files changed, 119 insertions(+), 44 deletions(-) diff --git a/src/AnalysisTypeDefine.h b/src/AnalysisTypeDefine.h index c65e637..b6fc83c 100644 --- a/src/AnalysisTypeDefine.h +++ b/src/AnalysisTypeDefine.h @@ -13,6 +13,7 @@ enum class AnalysisType { EnergyCountData, // 能量计数数据 ChannelEnergyCountData, // 通道能量计数数据 CoincidenceParticleEnergyData, // 符合粒子能量数据 + AntiCoincidenceParticleEnergyData, // 反符合粒子能量数据 AddressCountSpectrumView, // 粒子计数谱视图 EnergyCountSpectrumView, // 能量计数谱视图 CoincidenceParticleEnergySpectrum2DView, // 符合粒子能量2D视图 diff --git a/src/AntiConformEnergySpectrumView/AntiConformEnergySpectrumView.cpp b/src/AntiConformEnergySpectrumView/AntiConformEnergySpectrumView.cpp index 48198d4..87f68a9 100644 --- a/src/AntiConformEnergySpectrumView/AntiConformEnergySpectrumView.cpp +++ b/src/AntiConformEnergySpectrumView/AntiConformEnergySpectrumView.cpp @@ -16,13 +16,6 @@ #include #include -struct SpectrumData { - int board_id; - int channel_id; - double energy; - uint64_t timestamp; -}; - AntiConformEnergySpectrumView::AntiConformEnergySpectrumView(QWidget* parent) : MeasureAnalysisView(parent) { @@ -92,57 +85,37 @@ void AntiConformEnergySpectrumView::loadAndProcess() return; } - std::vector rawData; - io::CSVReader<4> in(QStrToSysPath(_data_filename)); + io::CSVReader<5> in(QStrToSysPath(_data_filename)); in.read_header(io::ignore_extra_column, + QString(QStringLiteral(u"时间窗口")).toStdString(), QString(QStringLiteral(u"板卡号")).toStdString(), QString(QStringLiteral(u"通道号")).toStdString(), QString(QStringLiteral(u"能量(KeV)")).toStdString(), QString(QStringLiteral(u"时间计数")).toStdString()); - int board, channel; - double energy; - unsigned long long time_count; - while (in.read_row(board, channel, energy, time_count)) { - SpectrumData sd; - sd.board_id = board; - sd.channel_id = channel; - sd.energy = energy; - sd.timestamp = time_count; - rawData.push_back(sd); - } - - if (rawData.empty()) { - QMetaObject::invokeMethod(this, [this]() { - _busy_indicator->Stop(); - }, Qt::QueuedConnection); - return; - } - const int STEP = 1; std::map hist; - for (const auto& spdt : rawData) { - int idx = static_cast(spdt.energy) / STEP; + int time_win, board, channel; + double energy; + unsigned long long time_count; + while (in.read_row(time_win, board, channel, energy, time_count)) { + int idx = static_cast(energy) / STEP; hist[idx] += 1.0; } - QVector vx, vy; for (const auto& pair : hist) { vx.push_back(pair.first * STEP); vy.push_back(pair.second); } - if (vx.isEmpty()) { QMetaObject::invokeMethod(this, [this]() { _busy_indicator->Stop(); }, Qt::QueuedConnection); return; } - double dmaxx = *std::max_element(vx.begin(), vx.end()); double dmaxy = *std::max_element(vy.begin(), vy.end()); - QMetaObject::invokeMethod(this, [this, vx, vy, dmaxx, dmaxy]() { _curve->setSamples(vx, vy); _plot->SetAxisInitRange(QwtPlot::xBottom, 0.0f, dmaxx); diff --git a/src/MeasureAnalysisProjectModel.cpp b/src/MeasureAnalysisProjectModel.cpp index 36164a1..29f67b2 100644 --- a/src/MeasureAnalysisProjectModel.cpp +++ b/src/MeasureAnalysisProjectModel.cpp @@ -861,6 +861,15 @@ void MeasureAnalysisProjectModelList::onChannelAddressCountProcessFinished(bool this->SetNodeStatus(adrr_count_spec_item, status, status_ok); } pro_model->SaveProjectModel(); + + if ( !pro_model->GetEnergyScaleFilename().isEmpty() ) { + 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(); + } } } @@ -962,7 +971,24 @@ void MeasureAnalysisProjectModelList::onCoincidenceProcessFinished(bool ok, cons 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]; + // const QString& item_name = QStringLiteral(u"符合事件时间分析[%1ns]").arg(conform_time_win);; + // if (node_map.contains(item_name)) { + // auto item = node_map[item_name]; + // this->SetNodeStatus(item, status, status_ok); + // } + pro_model->SaveProjectModel(); + + if ( !pro_model->GetEnergyScaleFilename().isEmpty() ) { + auto coincidence_process_task = new DataProcessWorkPool::EnergyScaleCoincidenceDataTask; + coincidence_process_task->SetFinishedNotifier(this, "onEnergyScaleCoincidenceDataFinished", project_name); + coincidence_process_task->StartTask(); + auto anti_coincidence_process_task = new DataProcessWorkPool::EnergyScaleaAntiCoincidenceDataTask; + anti_coincidence_process_task->SetFinishedNotifier(this, "onEnergyScaleAntiCoincidenceDataFinished", project_name); + anti_coincidence_process_task->StartTask(); + } } } @@ -1007,18 +1033,28 @@ void MeasureAnalysisProjectModelList::onEnergyScaleCoincidenceDataFinished(bool if (!conform_energy_data_filename_list.isEmpty()) { 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); + auto item = node_map[item_name]; + this->SetNodeStatus(item, status, status_ok); + } + item_name = QStringLiteral(u"符合事件时间分析[%1ns]").arg(conform_time_win);; + if (node_map.contains(item_name)) { + auto item = node_map[item_name]; + this->SetNodeStatus(item, status, status_ok); + } + item_name = QStringLiteral(u"符合事件时间分析[%1ns]").arg(conform_time_win);; + if (node_map.contains(item_name)) { + auto item = node_map[item_name]; + this->SetNodeStatus(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); + auto item = node_map[item_name]; + this->SetNodeStatus(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); + auto item = node_map[item_name]; + this->SetNodeStatus(item, status, status_ok); } } } @@ -1037,14 +1073,41 @@ void MeasureAnalysisProjectModelList::onEnergyScaleAntiCoincidenceDataFinished(b auto pro_model = this->_project_models[project_name]; auto& node_map = this->_project_node_items[project_name]; const auto& anti_conform_energy_data = pro_model->GetAntiConformEnergyData(); + + bool status_ok = false; + QString status = QStringLiteral(u"无效"); + if ( anti_conform_energy_data.size() ) { + status_ok = true; + status = QStringLiteral(u"有效"); + } + QString item_name = QStringLiteral(u"反符合粒子能量数据"); + QStandardItem* anti_conform_energy_data_group_item = nullptr; + if (node_map.contains(item_name)) { + anti_conform_energy_data_group_item = node_map[item_name]; + this->SetNodeStatus(anti_conform_energy_data_group_item, status, status_ok); + } for (const auto& time_win : anti_conform_energy_data.keys()) { - bool status_ok = false; - QString status = QStringLiteral(u"无效"); + status_ok = false; + status = QStringLiteral(u"无效"); const QString& data_filename = anti_conform_energy_data.value(time_win); if ( (!data_filename.isEmpty()) && QFile::exists(data_filename) ) { status_ok = true; status = QStringLiteral(u"有效"); } + if (anti_conform_energy_data_group_item) { + QString item_name = QStringLiteral(u"反符合能谱数据[%1ns]").arg(time_win); + if (node_map.contains(item_name)) { + auto anti_conform_erergy_spec_item = node_map[item_name]; + this->SetNodeStatus(anti_conform_erergy_spec_item, status, status_ok); + } else { + const QVariant& analys_type = QVariant::fromValue(AnalysisType::AntiCoincidenceParticleEnergyData); + QStandardItem* node_item = AddChildNode(anti_conform_energy_data_group_item, item_name, status, analys_type, true, status_ok); + node_item->setData(project_name, ProjectName); + QVariant conform_info(time_win); + node_item->setData(conform_info, ConformInfo); + node_map[item_name] = node_item; + } + } QString item_name = QStringLiteral(u"反符合能谱[%1ns]").arg(time_win); if (node_map.contains(item_name)) { auto anti_conform_erergy_spec_item = node_map[item_name]; @@ -1181,7 +1244,7 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProje int order = it.key(); status_ok = !it.value().isEmpty(); status = status_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); - QString item_name = QStringLiteral(u"%1个粒子符合[%2ns]").arg(order).arg(conform_time_win); + QString item_name = QStringLiteral(u"%1个粒子符合能谱[%2ns]").arg(order).arg(conform_time_win); const QVariant& analys_type = QVariant::fromValue(AnalysisType::CoincidenceParticleEnergyData); QStandardItem* node_item = AddChildNode(conform_energy_data_group_item, item_name, status, analys_type, true, status_ok); node_item->setData(project_name, ProjectName); @@ -1191,6 +1254,28 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProje } } + status_ok = !pro_model->GetAntiConformEnergyData(conform_time_win).isEmpty(); + status = status_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); + item_name = QStringLiteral(u"反符合粒子能量数据"); + analys_type = QVariant::fromValue(AnalysisType::None); + QStandardItem* anti_conform_energy_data_group_item = AddChildNode(analysis_data_item, item_name, status, analys_type, true, status_ok); + anti_conform_energy_data_group_item->setData(project_name, ProjectName); + node_map[item_name] = anti_conform_energy_data_group_item; + + auto time_win_anit_confirm_file_name_set = pro_model->GetAntiConformEnergyData(); + for (int conform_time_win : time_win_anit_confirm_file_name_set.keys()) { + const auto& anti_conform_energy_data_filename = pro_model->GetAntiConformEnergyData(conform_time_win); + status_ok = !anti_conform_energy_data_filename.isEmpty(); + status = status_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); + QString item_name = QStringLiteral(u"反符合能谱数据[%1ns]").arg(conform_time_win); + const QVariant& analys_type = QVariant::fromValue(AnalysisType::AntiCoincidenceParticleEnergyData); + QStandardItem* node_item = AddChildNode(anti_conform_energy_data_group_item, item_name, status, analys_type, true, status_ok); + node_item->setData(project_name, ProjectName); + QVariant conform_info(conform_time_win); + node_item->setData(conform_info, ConformInfo); + node_map[item_name] = node_item; + } + // 交互分析 item_name = QStringLiteral(u"交互分析"); QStandardItem* interactive_analysis_item = AddChildNode(project_item, item_name, QString(), QVariant(), true, true); @@ -1257,7 +1342,7 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProje status_ok = !pro_model->GetTimeWinConformEnergyDataFilenameList(conform_time_win).isEmpty(); status = status_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效"); analys_type = QVariant::fromValue(AnalysisType::CoincidenceEventTimeView); - item_name = QStringLiteral(u"符合事件时间分析"); + item_name = QStringLiteral(u"符合事件时间分析[%1ns]").arg(conform_time_win); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true, status_ok); node_item->setData(project_name, ProjectName); node_map[item_name] = node_item; diff --git a/src/MeasureAnalysisTreeView.cpp b/src/MeasureAnalysisTreeView.cpp index d4a9084..80ac6e9 100644 --- a/src/MeasureAnalysisTreeView.cpp +++ b/src/MeasureAnalysisTreeView.cpp @@ -155,6 +155,18 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index) } } } break; + case AnalysisType::AntiCoincidenceParticleEnergyData: { + QVariant conform_info_v = _model->GetNodeUserData(item, ProjectList::ConformInfo); + if (conform_info_v.isValid()) { + int conform_time_win = conform_info_v.toInt(); + MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name); + if (project_model) { + auto file_name = project_model->GetAntiConformEnergyData(conform_time_win); + const QString& data_name = QStringLiteral(u"反符合粒子能量数据[%1ns]").arg(conform_time_win); + data_files_set[data_name] = QString(file_name); + } + } + } break; case AnalysisType::CoincidenceParticleEnergyData: { QVariant conform_info_v = _model->GetNodeUserData(item, ProjectList::ConformInfo); if (conform_info_v.isValid()) { diff --git a/src/MeasureAnalysisView.cpp b/src/MeasureAnalysisView.cpp index b31a05e..f8cdf07 100644 --- a/src/MeasureAnalysisView.cpp +++ b/src/MeasureAnalysisView.cpp @@ -59,6 +59,10 @@ MeasureAnalysisView* MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type) new_view = new MeasureAnalysisDataTableView; new_view->setDeleteOnClose(true); } break; + case AnalysisType::AntiCoincidenceParticleEnergyData: { + new_view = new MeasureAnalysisDataTableView; + new_view->setDeleteOnClose(true); + } break; case AnalysisType::AddressCountSpectrumView: { new_view = new ParticleCountPlotView; new_view->setDeleteOnClose(false);