394 lines
18 KiB
C++
394 lines
18 KiB
C++
#include "BatchEnergyScaleDialog.h"
|
|
#include "ui_BatchEnergyScaleDialog.h"
|
|
#include <QDoubleSpinBox>
|
|
#include "DataProcessWorkPool.h"
|
|
#include "GlobalDefine.h"
|
|
#include "MeasureAnalysisProjectModel.h"
|
|
#include <QDir>
|
|
#include <QMessageBox>
|
|
#include "EnergyScaleDataModel.h"
|
|
#include <QDebug>
|
|
|
|
BatchEnergyScaleDialog::BatchEnergyScaleDialog(QWidget* parent)
|
|
: QDialog(parent)
|
|
, ui(new Ui::BatchEnergyScaleDialog)
|
|
, _energy_scale_data_model(std::make_unique<EnergyScaleDataModel>())
|
|
{
|
|
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<QPushButton*>(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<double>::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<QPushButton*>(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<std::vector<double>> energy_scale_fit_data_list = this->_energy_scale_data_model->GetFitData(channel_name);
|
|
for (const std::vector<double>& 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<QString, std::vector<std::vector<double> > > fit_data;
|
|
for (int i = 0; i < ui->tablew_process_data->rowCount(); i++) {
|
|
std::vector<double> 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<QString, int> 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<double>() << 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<int, QList<double> >& 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();
|
|
}
|