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);