#include "BatchEnergyScaleDialog.h" #include "ui_BatchEnergyScaleDialog.h" #include #include "DataProcessWorkPool.h" #include "GlobalDefine.h" #include "MeasureAnalysisProjectModel.h" #include #include #include "EnergyScaleDataModel.h" #include BatchEnergyScaleDialog::BatchEnergyScaleDialog(QWidget* parent) : QDialog(parent) , ui(new Ui::BatchEnergyScaleDialog) , _energy_scale_data_model(std::make_unique()) { ui->setupUi(this); this->setWindowTitle(QString(QStringLiteral(u"多通道能量刻度"))); this->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); this->setWindowModality(Qt::WindowModal); this->setModal(false); ui->tablew_process_data->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); ui->tablew_process_data->horizontalHeader()->setSectionResizeMode( ui->tablew_process_data->columnCount() - 1, QHeaderView::ResizeToContents); ui->tablew_process_data->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter); ui->filter_set_energy_combo_box->addItem(QStringLiteral(u"所有设置能量")); auto filterFunc = [this](){ ui->tablew_process_data->setCurrentItem(nullptr); auto row_count = ui->tablew_process_data->rowCount(); const QString& channel_filter_text = ui->filter_channel_combo_box->currentText(); const QString& set_energy_filter_text = ui->filter_set_energy_combo_box->currentText(); for (int i = row_count - 1; i >= 0; i--) { const QString& channel = ui->tablew_process_data->item(i, 0)->text(); const QString& set_energy = ui->tablew_process_data->item(i, 2)->text(); bool is_match_channel = false; if (channel_filter_text != QStringLiteral(u"所有通道")) { is_match_channel = (channel_filter_text == channel) ? false : true; } bool is_match_set_energy = false; if (set_energy_filter_text != QStringLiteral(u"所有设置能量")) { is_match_set_energy = (set_energy_filter_text == set_energy) ? false : true; } bool is_hidden = is_match_channel || is_match_set_energy; ui->tablew_process_data->setRowHidden(i, is_hidden); } }; connect(ui->filter_channel_combo_box, &QComboBox::currentTextChanged, filterFunc); connect(ui->filter_set_energy_combo_box, &QComboBox::currentTextChanged, filterFunc); connect(ui->btn_all_select, &QPushButton::clicked, [this](){ ui->tablew_process_data->setCurrentItem(nullptr); auto row_count = ui->tablew_process_data->rowCount(); for (int i = 0; i < row_count; ++i) { if (ui->tablew_process_data->isRowHidden(i)) { continue; } auto item = ui->tablew_process_data->item(i, 0); if (item) { item->setCheckState(Qt::Checked); } } }); connect(ui->btn_reserve_select, &QPushButton::clicked, [this](){ ui->tablew_process_data->setCurrentItem(nullptr); auto row_count = ui->tablew_process_data->rowCount(); for (int i = 0; i < row_count - 1; i++) { if (ui->tablew_process_data->isRowHidden(i)) { continue; } auto item = ui->tablew_process_data->item(i, 0); if (item) { Qt::CheckState check_state = (item->checkState() == Qt::Checked) ? Qt::Unchecked : Qt::Checked; item->setCheckState(check_state); } } }); connect(ui->btn_remove_selected, &QPushButton::clicked, [this](){ auto row_count = ui->tablew_process_data->rowCount(); for (int row = row_count - 1; row >= 0; --row) { QTableWidgetItem* item = ui->tablew_process_data->item(row, 0); if (Qt::Unchecked == item->checkState()) continue; QPushButton* btn_remove_row = dynamic_cast(ui->tablew_process_data->cellWidget(row, 8)); if (btn_remove_row) { ui->tablew_process_data->removeRow(row); btn_remove_row->deleteLater(); this->updateSetEnergyFilter(); } } if ( row_count > ui->tablew_process_data->rowCount() ) { this->saveEnergyScaleData(); } }); connect(ui->btn_fit, &QPushButton::clicked, this, &BatchEnergyScaleDialog::onFitBtnClickedProcess); connect(ui->btn_save, &QPushButton::clicked, [this](){ this->saveEnergyScaleData(); }); connect(ui->btn_apply, &QPushButton::clicked, [this](){ this->applyEnergyScaleFitResultData(); }); } BatchEnergyScaleDialog::~BatchEnergyScaleDialog() { qDebug() << "~BatchEnergyScaleDialog"; delete ui; } void BatchEnergyScaleDialog::SetProjectName(const QString &project_name) { this->_project_name = project_name; } void BatchEnergyScaleDialog::SetChannelNameList(const QStringList &ch_name_list) { this->_channel_name_list = ch_name_list; ui->filter_channel_combo_box->clear(); ui->filter_channel_combo_box->addItem(QString(QStringLiteral(u"所有通道"))); ui->filter_channel_combo_box->addItems(ch_name_list); } void BatchEnergyScaleDialog::SetPeakResultDataModel(QAbstractTableModel* peaks_result_model) { _peaks_result_model = peaks_result_model; } void BatchEnergyScaleDialog::SetViewWorkspace(const QString &workspace) { this->_workspace = workspace; QDir workspace_dir(this->_workspace); const QString& energy_scale_data_filename = workspace_dir.filePath(QStringLiteral(u"多通道能量刻度拟合.json")); this->_energy_scale_data_model->SetDataFilename(energy_scale_data_filename); } void BatchEnergyScaleDialog::onSelectedScaleRange(double min, double max) { if (!_peaks_result_model) { return; } QDialog set_energy_dlg(this, Qt::Dialog | Qt::WindowCloseButtonHint); set_energy_dlg.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); set_energy_dlg.setFixedSize(300, 100); set_energy_dlg.setSizeGripEnabled(false); set_energy_dlg.setWindowTitle(QString(QStringLiteral(u"设置刻度能量"))); QLabel* set_energy_label = new QLabel(QString(QStringLiteral(u"刻度能量:"))); QDoubleSpinBox* spinbox_set_energy = new QDoubleSpinBox(); spinbox_set_energy->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); spinbox_set_energy->setRange(0.0f, std::numeric_limits::max()); spinbox_set_energy->setSingleStep(1.0f); spinbox_set_energy->setDecimals(3); QHBoxLayout* layout_input = new QHBoxLayout(); layout_input->addWidget(set_energy_label); layout_input->addWidget(spinbox_set_energy); QPushButton* btn_ok = new QPushButton(QStringLiteral(u"确认")); connect(btn_ok, &QPushButton::clicked, &set_energy_dlg, &QDialog::accept); QPushButton* btn_cancel = new QPushButton(QStringLiteral(u"取消")); connect(btn_cancel, &QPushButton::clicked, &set_energy_dlg, &QDialog::reject); QHBoxLayout* layout_btns = new QHBoxLayout(); layout_btns->addStretch(); layout_btns->addWidget(btn_ok); layout_btns->addWidget(btn_cancel); QVBoxLayout* layout = new QVBoxLayout(&set_energy_dlg); layout->addLayout(layout_input); layout->addStretch(); layout->addLayout(layout_btns); if (QDialog::Accepted == set_energy_dlg.exec()) { bool b_has_new_data = false; double set_energy = spinbox_set_energy->value(); for (int i = 0; i < _peaks_result_model->rowCount(); i++) { const QString& channel_name = _peaks_result_model->data(_peaks_result_model->index(i, 0)).toString(); int peak_pos = _peaks_result_model->data(_peaks_result_model->index(i, 1)).toInt(); int peak_fwhm = _peaks_result_model->data(_peaks_result_model->index(i, 6)).toInt(); if (min < peak_pos && peak_pos < max ) { int row = ui->tablew_process_data->rowCount(); ui->tablew_process_data->insertRow(row); ui->tablew_process_data->setItem(row, 0, new QTableWidgetItem(channel_name)); ui->tablew_process_data->item(row, 0)->setCheckState(Qt::Unchecked); ui->tablew_process_data->setItem(row, 1, new QTableWidgetItem(QString::number(peak_pos))); ui->tablew_process_data->setItem(row, 2, new QTableWidgetItem(QString::number(set_energy))); ui->tablew_process_data->setItem(row, 3, new QTableWidgetItem); ui->tablew_process_data->setItem(row, 4, new QTableWidgetItem); ui->tablew_process_data->setItem(row, 5, new QTableWidgetItem(QString::number(peak_fwhm))); ui->tablew_process_data->setItem(row, 6, new QTableWidgetItem); ui->tablew_process_data->setItem(row, 7, new QTableWidgetItem); QTableWidgetItem* item = new QTableWidgetItem; ui->tablew_process_data->setItem(row, 8, item); 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); int remove_row = item->row(); ui->tablew_process_data->removeRow(remove_row); btn_remove_row->deleteLater(); this->updateSetEnergyFilter(); this->saveEnergyScaleData(); }); ui->tablew_process_data->setCellWidget(row, 8, btn_remove_row); this->insertSetEnergyValueToFilter(set_energy); b_has_new_data = true; } } if (b_has_new_data) { this->saveEnergyScaleData(); } } } void BatchEnergyScaleDialog::insertSetEnergyValueToFilter(double energy) { int count = 0; int index = ui->filter_set_energy_combo_box->findText(QString::number(energy)); if (index >= 0) { count = ui->filter_set_energy_combo_box->itemData(index).toInt() + 1; ui->filter_set_energy_combo_box->setItemData(index, count); } else { ui->filter_set_energy_combo_box->addItem(QString::number(energy), count); } } void BatchEnergyScaleDialog::updateSetEnergyFilter() { int item_count = ui->filter_set_energy_combo_box->count(); for (int index = item_count - 1; index > 0; --index) { int count = ui->filter_set_energy_combo_box->itemData(index).toInt(); count = count - 1; ui->filter_set_energy_combo_box->setItemData(index, count); if (0 == count) { int current_index = ui->filter_set_energy_combo_box->currentIndex(); if (index == current_index) { ui->filter_set_energy_combo_box->setCurrentIndex(0); } ui->filter_set_energy_combo_box->removeItem(index); } } } void BatchEnergyScaleDialog::LoadEnergyScaleData() { auto row_count = ui->tablew_process_data->rowCount(); for (int row = row_count - 1; row >= 0; --row) { QPushButton* btn_remove_row = dynamic_cast(ui->tablew_process_data->cellWidget(row, 8)); if (btn_remove_row) { ui->tablew_process_data->removeRow(row); btn_remove_row->deleteLater(); this->updateSetEnergyFilter(); } } if (!this->_energy_scale_data_model->LoadData()) { return; } for (const QString& channel_name : this->_channel_name_list) { std::vector> energy_scale_fit_data_list = this->_energy_scale_data_model->GetFitData(channel_name); for (const std::vector& fit_data_item : energy_scale_fit_data_list) { int row = ui->tablew_process_data->rowCount(); ui->tablew_process_data->insertRow(row); ui->tablew_process_data->setItem(row, 0, new QTableWidgetItem(channel_name)); ui->tablew_process_data->item(row, 0)->setCheckState(Qt::Unchecked); ui->tablew_process_data->setItem(row, 1, new QTableWidgetItem(QString::number(fit_data_item[0]))); ui->tablew_process_data->setItem(row, 2, new QTableWidgetItem(QString::number(fit_data_item[1]))); ui->tablew_process_data->setItem(row, 3, new QTableWidgetItem(QString::number(fit_data_item[2]))); ui->tablew_process_data->setItem(row, 4, new QTableWidgetItem(QString::number(fit_data_item[3]))); ui->tablew_process_data->setItem(row, 5, new QTableWidgetItem(QString::number(fit_data_item[4]))); ui->tablew_process_data->setItem(row, 6, new QTableWidgetItem(QString::number(fit_data_item[5]))); ui->tablew_process_data->setItem(row, 7, new QTableWidgetItem(QString::number(fit_data_item[6]))); QTableWidgetItem* item = new QTableWidgetItem; ui->tablew_process_data->setItem(row, 8, item); 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); int remove_row = item->row(); ui->tablew_process_data->removeRow(remove_row); btn_remove_row->deleteLater(); this->updateSetEnergyFilter(); this->saveEnergyScaleData(); }); ui->tablew_process_data->setCellWidget(row, 8, btn_remove_row); this->insertSetEnergyValueToFilter(fit_data_item[1]); } } } void BatchEnergyScaleDialog::saveEnergyScaleData() { QMap > > fit_data; for (int i = 0; i < ui->tablew_process_data->rowCount(); i++) { std::vector fit_data_item; const QString& channel_name = ui->tablew_process_data->item(i, 0)->text(); double peak_pos_addr = ui->tablew_process_data->item(i, 1)->text().toDouble(); double set_energy = ui->tablew_process_data->item(i, 2)->text().toDouble(); double fit_energy = ui->tablew_process_data->item(i, 3)->text().toDouble(); double energy_diff = ui->tablew_process_data->item(i, 4)->text().toDouble(); double peak_fwhm = ui->tablew_process_data->item(i, 5)->text().toDouble(); double fit_fwhm = ui->tablew_process_data->item(i, 6)->text().toDouble(); double fwhm_diff = ui->tablew_process_data->item(i, 7)->text().toDouble(); fit_data_item.push_back(peak_pos_addr); fit_data_item.push_back(set_energy); fit_data_item.push_back(fit_energy); fit_data_item.push_back(energy_diff); fit_data_item.push_back(peak_fwhm); fit_data_item.push_back(fit_fwhm); fit_data_item.push_back(fwhm_diff); fit_data[channel_name].push_back(fit_data_item); } for (const QString& channel_name : fit_data.keys()) { this->_energy_scale_data_model->SetFitData(channel_name, fit_data[channel_name]); this->_energy_scale_data_model->SetEnergyFitDegree(channel_name, 0); this->_energy_scale_data_model->SetEnergyFitResultCoeffs(channel_name, {}); this->_energy_scale_data_model->SetFwhmFitResultCoeffs(channel_name, {}); } this->_energy_scale_data_model->SaveData(); } void BatchEnergyScaleDialog::onFitBtnClickedProcess() { QMap fit_degree_map; DataProcessWorkPool::ChannelEnergyScaleFittingTask::FitDataMap channel_energy_scale_fit_data_map; for (int i = 0; i < ui->tablew_process_data->rowCount(); i++) { const QString& channel_name = ui->tablew_process_data->item(i, 0)->text(); int peak_pos = ui->tablew_process_data->item(i, 1)->text().toInt(); double energy = ui->tablew_process_data->item(i, 2)->text().toDouble(); int peak_fwhm = ui->tablew_process_data->item(i, 5)->text().toInt(); channel_energy_scale_fit_data_map[channel_name].insert(peak_pos, QList() << energy << peak_fwhm); fit_degree_map[channel_name] = 1; } QStringList data_except_channel_name_list; for (auto it = channel_energy_scale_fit_data_map.begin(); it != channel_energy_scale_fit_data_map.end(); ++it) { const QString& channel_name = it.key(); const QMap >& fit_data = it.value(); if (fit_data.size() < 2) { data_except_channel_name_list << channel_name; } } if (data_except_channel_name_list.size() > 0) { const QString& warn_msg = QStringLiteral(u"请为以下通道设置拟合数据:%1").arg(data_except_channel_name_list.join(QStringLiteral(u","))); LOG_WARN(warn_msg); QMessageBox::warning(this, QStringLiteral(u"警告"), warn_msg); return; } if (!channel_energy_scale_fit_data_map.empty()) { ui->btn_apply->setEnabled(false); auto channel_erergy_scale_fit_task = new DataProcessWorkPool::ChannelEnergyScaleFittingTask; channel_erergy_scale_fit_task->SetResultDir(this->_workspace); channel_erergy_scale_fit_task->SetData(channel_energy_scale_fit_data_map, fit_degree_map); channel_erergy_scale_fit_task->SetFinishedNotifier(this, "onEnergyScaleFitFinished", this->_project_name); channel_erergy_scale_fit_task->StartTask(); } } void BatchEnergyScaleDialog::onEnergyScaleFitFinished(const QString &project_name) { Q_UNUSED(project_name); this->LoadEnergyScaleData(); } void BatchEnergyScaleDialog::applyEnergyScaleFitResultData() { if ( this->_energy_scale_data_model->IsValid() ) { MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(this->_project_name); if (project_model == nullptr) { return; } QDir project_dir(project_model->GetProjectDir()); const QString& energy_scale_data_filename = project_dir.filePath(QStringLiteral(u"能量刻度.json")); QDir result_dir(this->_workspace); const QString& energy_scale_result_filename = result_dir.filePath(QStringLiteral(u"多通道能量刻度拟合.json")); if (QFile::copy(energy_scale_result_filename, energy_scale_data_filename)) { project_model->SetEnergyScaleFilename(energy_scale_data_filename); } } else { } } void BatchEnergyScaleDialog::energyScaleDataChange() { this->_is_fit_finished = false; ui->btn_apply->setEnabled(false); } void BatchEnergyScaleDialog::closeEvent(QCloseEvent *e) { emit close(); }