1、调整代码结构;2、添加多通道能量刻度;
This commit is contained in:
parent
0564843147
commit
bfd9485c8b
|
|
@ -85,6 +85,9 @@ void CustomQwtPlot::AddMarker(QwtPlotMarker *marker, const QString &marker_name,
|
||||||
QPen pen = curve->pen();
|
QPen pen = curve->pen();
|
||||||
pen.setWidth(2);
|
pen.setWidth(2);
|
||||||
marker->setLinePen(pen);
|
marker->setLinePen(pen);
|
||||||
|
QwtText label_text = marker->label();
|
||||||
|
label_text.setColor(Qt::black);
|
||||||
|
marker->setLabel(label_text);
|
||||||
marker->attach(this);
|
marker->attach(this);
|
||||||
_markers[marker_name][postion] = marker;
|
_markers[marker_name][postion] = marker;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ public:
|
||||||
void clearSelection();
|
void clearSelection();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void selectionFinished(double minX, double maxX);
|
void selectionFinished(double min_x, double max_x);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void move(const QPoint& pos) override;
|
virtual void move(const QPoint& pos) override;
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,31 @@ std::vector<FindPeaksBySvd::PeakInfo> FindPeaksBySvd::FindPeaks(const arma::mat
|
||||||
vec peak_region = spec_data_col1.subvec(Lc, Rc);
|
vec peak_region = spec_data_col1.subvec(Lc, Rc);
|
||||||
double height = peak_region.max();
|
double height = peak_region.max();
|
||||||
uword HWP_idx = peak_region.index_max(); // 峰值位置
|
uword HWP_idx = peak_region.index_max(); // 峰值位置
|
||||||
|
// 计算半高宽(FWHM)
|
||||||
|
double half_height = height / 2.0;
|
||||||
|
int left_half = 0, right_half = peak_region.n_elem - 1;
|
||||||
|
// 找到左侧半高位置
|
||||||
|
for (int i = HWP_idx; i >= 0; i--) {
|
||||||
|
if (peak_region(i) <= half_height) {
|
||||||
|
left_half = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 找到右侧半高位置
|
||||||
|
for (int i = HWP_idx; i < peak_region.n_elem; i++) {
|
||||||
|
if (peak_region(i) <= half_height) {
|
||||||
|
right_half = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 计算半高宽(转换为原始坐标)
|
||||||
|
double fwhm = (right_half - left_half + 1);
|
||||||
|
// 计算峰面积(使用梯形法则)
|
||||||
|
double area = 0.0;
|
||||||
|
for (int i = 0; i < peak_region.n_elem - 1; i++) {
|
||||||
|
// 梯形面积 = (上底 + 下底) * 高 / 2
|
||||||
|
area += (peak_region(i) + peak_region(i + 1)) / 2.0;
|
||||||
|
}
|
||||||
// 峰中心
|
// 峰中心
|
||||||
int pl = round((Lc + Rc) / 2.0);
|
int pl = round((Lc + Rc) / 2.0);
|
||||||
// 筛选有效峰:峰宽>2且中心DistV>0
|
// 筛选有效峰:峰宽>2且中心DistV>0
|
||||||
|
|
@ -98,6 +123,8 @@ std::vector<FindPeaksBySvd::PeakInfo> FindPeaksBySvd::FindPeaks(const arma::mat
|
||||||
peak_info.width = spec_data_col0.at(width);
|
peak_info.width = spec_data_col0.at(width);
|
||||||
peak_info.height = height;
|
peak_info.height = height;
|
||||||
peak_info.pos = spec_data_col0.at(pos);
|
peak_info.pos = spec_data_col0.at(pos);
|
||||||
|
peak_info.fwhm = fwhm;
|
||||||
|
peak_info.area = area;
|
||||||
peak_info_vec.push_back(peak_info);
|
peak_info_vec.push_back(peak_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -112,4 +139,4 @@ std::vector<FindPeaksBySvd::PeakInfo> FindPeaksBySvd::FindPeaks(const arma::mat
|
||||||
throw std::string("Find peaks unkonow exception");
|
throw std::string("Find peaks unkonow exception");
|
||||||
}
|
}
|
||||||
return peak_info_vec;
|
return peak_info_vec;
|
||||||
}
|
}
|
||||||
|
|
@ -13,11 +13,12 @@ public:
|
||||||
double width = 0.0f; // 峰所在数据区域的宽度
|
double width = 0.0f; // 峰所在数据区域的宽度
|
||||||
double height = 0.0f; // 峰所在数据区域的高度
|
double height = 0.0f; // 峰所在数据区域的高度
|
||||||
double pos = 0.0f; // 峰所在位置
|
double pos = 0.0f; // 峰所在位置
|
||||||
double fwhm = 0.0f; // 峰所在位置
|
double fwhm = 0.0f; // 峰的半高宽
|
||||||
|
double area = 0.0f; // 峰的面积
|
||||||
} PeakInfo;
|
} PeakInfo;
|
||||||
|
|
||||||
std::vector<FindPeaksBySvd::PeakInfo> FindPeaks(const arma::mat& spec_data, int step_w = 7);
|
std::vector<FindPeaksBySvd::PeakInfo> FindPeaks(const arma::mat& spec_data, int step_w = 7);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FINDPEAKSBYSVD_H
|
#endif // FINDPEAKSBYSVD_H
|
||||||
|
|
@ -154,11 +154,13 @@ bool EveryChannelParticleDataSeparateTask::processEveryChannelParticleData()
|
||||||
*ch_particle_data_of << board_id << "," << channel_id << "," << address << "," << time << std::endl;
|
*ch_particle_data_of << board_id << "," << channel_id << "," << address << "," << time << std::endl;
|
||||||
}
|
}
|
||||||
} catch (const std::runtime_error& e) {
|
} catch (const std::runtime_error& e) {
|
||||||
QString error = QString(QStringLiteral(u"处理%1发生运行时异常:%2")).arg(all_channel_particle_data_filename).arg(e.what());
|
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;
|
ret_ok = false;
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
QString error = QString(QStringLiteral(u"处理%1异常:%2")).arg(all_channel_particle_data_filename).arg(e.what());
|
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;
|
ret_ok = false;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
@ -303,15 +305,17 @@ bool EveryChannelParticleCountDataTask::processEveryChannelParticleData()
|
||||||
// all_channel_out.close();
|
// all_channel_out.close();
|
||||||
|
|
||||||
} catch (const std::runtime_error& e) {
|
} catch (const std::runtime_error& e) {
|
||||||
QString error = QString(QStringLiteral(u"处理%1发生运行时异常:%2")).arg(all_channel_particle_data_filename).arg(e.what());
|
const QString& e_what = QString::fromLatin1(e.what());
|
||||||
|
QString error = QStringLiteral(u"处理%1发生运行时异常:%2").arg(all_channel_particle_data_filename).arg(e_what);
|
||||||
LOG_ERROR(error)
|
LOG_ERROR(error)
|
||||||
ret_ok = false;
|
ret_ok = false;
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
QString error = QString(QStringLiteral(u"处理%1异常:%2")).arg(all_channel_particle_data_filename).arg(e.what());
|
const QString& e_what = QString::fromLatin1(e.what());
|
||||||
|
QString error = QStringLiteral(u"处理%1异常:%2").arg(all_channel_particle_data_filename).arg(e_what);
|
||||||
LOG_ERROR(error)
|
LOG_ERROR(error)
|
||||||
ret_ok = false;
|
ret_ok = false;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
QString error = QString(QStringLiteral(u"处理%1未知异常.").arg(all_channel_particle_data_filename));
|
QString error = QStringLiteral(u"处理%1未知异常.").arg(all_channel_particle_data_filename);
|
||||||
LOG_ERROR(error)
|
LOG_ERROR(error)
|
||||||
ret_ok = false;
|
ret_ok = false;
|
||||||
}
|
}
|
||||||
|
|
@ -529,7 +533,8 @@ bool ParticleDataSortTask::processEveryChannelParticleData()
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
QString error = QString(QStringLiteral(u"处理%1异常:%2")).arg(all_channel_particle_data_filename).arg(e.what());
|
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;
|
ret_ok = false;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
@ -576,7 +581,7 @@ bool AutoFindPeaksTask::IsValidSetWorkParameters() const
|
||||||
|
|
||||||
bool AutoFindPeaksTask::processTask()
|
bool AutoFindPeaksTask::processTask()
|
||||||
{
|
{
|
||||||
QString result_filename = QDir(this->_result_dir).filePath("AutoFindPeaksResult.csv");
|
QString result_filename = QDir(this->_result_dir).filePath(QStringLiteral(u"自动寻峰结果.csv"));
|
||||||
std::ofstream out_file(QStrToSysPath(result_filename));
|
std::ofstream out_file(QStrToSysPath(result_filename));
|
||||||
std::string channel_str = QString(QStringLiteral(u"通道")).toStdString();
|
std::string channel_str = QString(QStringLiteral(u"通道")).toStdString();
|
||||||
std::string addr_str = QString(QStringLiteral(u"峰位")).toStdString();
|
std::string addr_str = QString(QStringLiteral(u"峰位")).toStdString();
|
||||||
|
|
@ -585,38 +590,48 @@ bool AutoFindPeaksTask::processTask()
|
||||||
std::string width_str = QString(QStringLiteral(u"峰宽")).toStdString();
|
std::string width_str = QString(QStringLiteral(u"峰宽")).toStdString();
|
||||||
std::string height_str = QString(QStringLiteral(u"峰高")).toStdString();
|
std::string height_str = QString(QStringLiteral(u"峰高")).toStdString();
|
||||||
std::string fwhm_str = QString(QStringLiteral(u"FWHM")).toStdString();
|
std::string fwhm_str = QString(QStringLiteral(u"FWHM")).toStdString();
|
||||||
out_file << channel_str << "," << addr_str << "," << left_addr_str << "," << lright_addr_str << "," << width_str << "," << height_str << "," << fwhm_str << "\n";
|
std::string area_str = QString(QStringLiteral(u"峰面积")).toStdString();
|
||||||
|
out_file << channel_str << "," << addr_str << "," << left_addr_str << "," << lright_addr_str
|
||||||
|
<< "," << width_str << "," << height_str << "," << fwhm_str << "," << area_str << "\n";
|
||||||
|
|
||||||
for (auto it = this->_data_files_set.begin(); it != this->_data_files_set.end(); ++it) {
|
QStringList ch_count_data_name = this->_data_files_set.keys();
|
||||||
std::string channel = it.key().toStdString();
|
std::sort(ch_count_data_name.begin(), ch_count_data_name.end(), [](const QString& a, const QString& b) {
|
||||||
arma::mat data;
|
int num_a = ExtractNumberFromString(a);
|
||||||
const std::string data_filename = QStrToSysPath(it.value().toString());
|
int num_b = ExtractNumberFromString(b);
|
||||||
if (!data.load(data_filename, arma::csv_ascii)) {
|
return num_a < num_b;
|
||||||
QString error = QString(QStringLiteral(u"%1自动寻峰数据加载异常!")).arg(it.key());
|
});
|
||||||
LOG_WARN(error);
|
for (const QString& ch_count_data_name : ch_count_data_name) {
|
||||||
continue;
|
if (ch_count_data_name.contains(ch_count_data_name)) {
|
||||||
}
|
const QString& ch_count_data_filename = this->_data_files_set.value(ch_count_data_name).toString();
|
||||||
FindPeaksBySvd peak_svd;
|
std::string channel = ch_count_data_name.toStdString();
|
||||||
std::vector<FindPeaksBySvd::PeakInfo> peak_info_vec = peak_svd.FindPeaks(data, this->_step_win_width);
|
arma::mat data;
|
||||||
if (!peak_info_vec.empty()) {
|
const std::string data_filename = QStrToSysPath(ch_count_data_filename);
|
||||||
for(auto peak_info : peak_info_vec) {
|
if (!data.load(data_filename, arma::csv_ascii)) {
|
||||||
int addr = peak_info.pos;
|
QString error = QString(QStringLiteral(u"%1自动寻峰数据加载异常!")).arg(ch_count_data_name);
|
||||||
int left = peak_info.left;
|
LOG_WARN(error);
|
||||||
int right = peak_info.left + peak_info.width;
|
continue;
|
||||||
int width = peak_info.width;
|
|
||||||
int height = peak_info.height;
|
|
||||||
int fwhm = peak_info.fwhm;
|
|
||||||
out_file << channel << "," << addr << "," << left << "," << right << "," << width << "," << height << "," << fwhm << "\n";
|
|
||||||
double p_right(peak_info.left + peak_info.width);
|
|
||||||
qDebug() << QString::fromStdString(channel) << "," << peak_info.pos << "," << peak_info.left << "," << p_right << "," << peak_info.width << "," << peak_info.height << "," << peak_info.fwhm << "\n";
|
|
||||||
}
|
}
|
||||||
} else {
|
FindPeaksBySvd peak_svd;
|
||||||
const QString& error = QStringLiteral(u"%1自动寻峰异常!").arg(it.key());
|
std::vector<FindPeaksBySvd::PeakInfo> peak_info_vec = peak_svd.FindPeaks(data, this->_step_win_width);
|
||||||
LOG_WARN(error);
|
if (!peak_info_vec.empty()) {
|
||||||
|
for(auto peak_info : peak_info_vec) {
|
||||||
|
int addr = peak_info.pos;
|
||||||
|
int left = peak_info.left;
|
||||||
|
int right = peak_info.left + peak_info.width;
|
||||||
|
int width = peak_info.width;
|
||||||
|
int height = peak_info.height;
|
||||||
|
int fwhm = peak_info.fwhm;
|
||||||
|
double area = peak_info.area;
|
||||||
|
out_file << channel << "," << addr << "," << left << "," << right << ","
|
||||||
|
<< width << "," << height << "," << fwhm << "," << area << "\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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);
|
||||||
|
LOG_INFO(info);
|
||||||
}
|
}
|
||||||
const QString& info = QStringLiteral(u"%1自动寻峰完成").arg(it.key());
|
|
||||||
LOG_INFO(info);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString& project_name = GetProjectName();
|
const QString& project_name = GetProjectName();
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "QsLog.h"
|
#include "QsLog.h"
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
|
#include <QRegularExpression>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
// 转换Qt字符串路径为系统编码的C字符串(解决中文路径问题)
|
// 转换Qt字符串路径为系统编码的C字符串(解决中文路径问题)
|
||||||
|
|
@ -22,6 +23,16 @@ static const char* QStrToSysPath(const QString& qstr_path)
|
||||||
return sys_path.c_str();
|
return sys_path.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ExtractNumberFromString(const QString& str) {
|
||||||
|
int ret_num = -1;
|
||||||
|
QRegularExpression regex("\\d+");
|
||||||
|
QRegularExpressionMatch match = regex.match(str);
|
||||||
|
if (match.hasMatch()) {
|
||||||
|
ret_num = match.captured().toInt();
|
||||||
|
}
|
||||||
|
return ret_num;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#define STATUS_BAR_MSG(msg) \
|
#define STATUS_BAR_MSG(msg) \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,39 @@
|
||||||
#include "BatchEneryScaleDialog.h"
|
#include "BatchEneryScaleDialog.h"
|
||||||
#include "ui_BatchEneryScaleDialog.h"
|
#include "ui_BatchEneryScaleDialog.h"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
BatchEneryScaleDialog::BatchEneryScaleDialog(QWidget *parent)
|
BatchEneryScaleDialog::BatchEneryScaleDialog(QWidget* parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
, ui(new Ui::BatchEneryScaleDialog)
|
, ui(new Ui::BatchEneryScaleDialog)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
this->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
BatchEneryScaleDialog::~BatchEneryScaleDialog()
|
BatchEneryScaleDialog::~BatchEneryScaleDialog()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BatchEneryScaleDialog::SetPeakResultDataModel(QAbstractTableModel* peaks_result_model)
|
||||||
|
{
|
||||||
|
_peaks_result_model = peaks_result_model;
|
||||||
|
qDebug() << _peaks_result_model->rowCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BatchEneryScaleDialog::onSelectedScaleRange(double min, double max)
|
||||||
|
{
|
||||||
|
qDebug() << min << ", " << max;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BatchEneryScaleDialog::closeEvent(QCloseEvent *e)
|
||||||
|
{
|
||||||
|
emit close();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
|
class QAbstractTableModel;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class BatchEneryScaleDialog;
|
class BatchEneryScaleDialog;
|
||||||
}
|
}
|
||||||
|
|
@ -15,8 +17,20 @@ public:
|
||||||
explicit BatchEneryScaleDialog(QWidget *parent = nullptr);
|
explicit BatchEneryScaleDialog(QWidget *parent = nullptr);
|
||||||
~BatchEneryScaleDialog();
|
~BatchEneryScaleDialog();
|
||||||
|
|
||||||
|
void SetPeakResultDataModel(QAbstractTableModel *peaks_result_model);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void onSelectedScaleRange(double min, double max);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void close();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void closeEvent(QCloseEvent *e);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::BatchEneryScaleDialog *ui;
|
Ui::BatchEneryScaleDialog *ui;
|
||||||
|
QAbstractTableModel* _peaks_result_model;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BATCHENERYSCALEDIALOG_H
|
#endif // BATCHENERYSCALEDIALOG_H
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,35 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>824</width>
|
<width>929</width>
|
||||||
<height>409</height>
|
<height>404</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Dialog</string>
|
<string>多通道能量刻度</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>16</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_all_select">
|
||||||
|
<property name="text">
|
||||||
|
<string>全选</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_reserve_select">
|
||||||
|
<property name="text">
|
||||||
|
<string>反选</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_channel">
|
<widget class="QLabel" name="label_channel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
|
@ -26,7 +43,14 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="comboBox_channel"/>
|
<widget class="QComboBox" name="comboBox_channel">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>75</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
|
@ -40,10 +64,24 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="comboBox_enery"/>
|
<widget class="QComboBox" name="comboBox_enery">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>125</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_remove_selected">
|
||||||
|
<property name="text">
|
||||||
|
<string>删除勾选</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|
@ -64,10 +102,26 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_save">
|
||||||
|
<property name="text">
|
||||||
|
<string>保存</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTableWidget" name="tableWidget_process_data">
|
<widget class="QTableWidget" name="tablew_process_data">
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::SingleSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectRows</enum>
|
||||||
|
</property>
|
||||||
<column>
|
<column>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>通道</string>
|
<string>通道</string>
|
||||||
|
|
@ -111,6 +165,11 @@
|
||||||
<string>分辨率偏差</string>
|
<string>分辨率偏差</string>
|
||||||
</property>
|
</property>
|
||||||
</column>
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>操作</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,272 @@
|
||||||
|
#include "FindPeaksResultDialog.h"
|
||||||
|
#include "GlobalDefine.h"
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QTableWidget>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include "csv.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
FindPeaksResultDialog::FindPeaksResultDialog(QWidget *parent)
|
||||||
|
{
|
||||||
|
this->setWindowTitle(QString(QStringLiteral(u"寻峰结果")));
|
||||||
|
this->setWindowModality(Qt::WindowModal);
|
||||||
|
this->setModal(false);
|
||||||
|
|
||||||
|
QPushButton* btn_all_select = new QPushButton(QString(QStringLiteral(u"全选")));
|
||||||
|
QPushButton* btn_reserve_select = new QPushButton(QString(QStringLiteral(u"反选")));
|
||||||
|
QLabel* filter_channel_label = new QLabel(QString(QStringLiteral(u"筛选通道:")));
|
||||||
|
_filter_channel_combo_box = new QComboBox();
|
||||||
|
_filter_channel_combo_box->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||||
|
_filter_channel_combo_box->setMinimumWidth(75);
|
||||||
|
_filter_channel_combo_box->addItem(QString(QStringLiteral(u"所有通道")));
|
||||||
|
_filter_channel_combo_box->setMaxVisibleItems(10);
|
||||||
|
_filter_channel_combo_box->view()->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||||
|
QPushButton* btn_save = new QPushButton(QString(QStringLiteral(u"保存")));
|
||||||
|
QHBoxLayout* top_layout = new QHBoxLayout();
|
||||||
|
top_layout->addWidget(btn_all_select);
|
||||||
|
top_layout->addWidget(btn_reserve_select);
|
||||||
|
top_layout->addSpacing(10);
|
||||||
|
top_layout->addWidget(filter_channel_label);
|
||||||
|
top_layout->addWidget(_filter_channel_combo_box);
|
||||||
|
top_layout->addStretch();
|
||||||
|
top_layout->addWidget(btn_save);
|
||||||
|
|
||||||
|
const QString& channel_col_name = QString(QStringLiteral(u"通道"));
|
||||||
|
const QString& peak_pos_col_name = QString(QStringLiteral(u"峰位"));
|
||||||
|
const QString& left_bound_col_name = QString(QStringLiteral(u"左边界"));
|
||||||
|
const QString& right_bound_col_name = QString(QStringLiteral(u"右边界"));
|
||||||
|
const QString& peak_width_col_name = QString(QStringLiteral(u"峰宽"));
|
||||||
|
const QString& peak_height_col_name = QString(QStringLiteral(u"峰高"));
|
||||||
|
const QString& peak_fwhm_col_name = QString(QStringLiteral(u"FWHM"));
|
||||||
|
const QString& peak_area_col_name = QString(QStringLiteral(u"峰面积"));
|
||||||
|
const QString& operation_col_name = QString(QStringLiteral(u"操作"));
|
||||||
|
_peaks_result_table = new QTableWidget();
|
||||||
|
_peaks_result_table->setObjectName("peaks_result_table");
|
||||||
|
_peaks_result_table->setColumnCount(9);
|
||||||
|
_peaks_result_table->setHorizontalHeaderLabels({ channel_col_name, peak_pos_col_name, left_bound_col_name, right_bound_col_name,
|
||||||
|
peak_width_col_name, peak_height_col_name, peak_fwhm_col_name, peak_area_col_name, operation_col_name });
|
||||||
|
_peaks_result_table->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||||
|
_peaks_result_table->horizontalHeader()->setSectionResizeMode(_peaks_result_table->columnCount() - 1, QHeaderView::ResizeToContents);
|
||||||
|
_peaks_result_table->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||||
|
_peaks_result_table->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
_peaks_result_table->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
_peaks_result_table->setEditTriggers(QTableWidget::NoEditTriggers);
|
||||||
|
|
||||||
|
connect(_filter_channel_combo_box, &QComboBox::currentTextChanged, [this](const QString& text) {
|
||||||
|
_peaks_result_table->setCurrentItem(nullptr);
|
||||||
|
auto row_count = _peaks_result_table->rowCount();
|
||||||
|
if (text == QString(QStringLiteral(u"所有通道"))) {
|
||||||
|
for (int i = 0; i < row_count - 1; i++) {
|
||||||
|
_peaks_result_table->setRowHidden(i, false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = row_count - 1; i >= 0; i--) {
|
||||||
|
const QString& channel = _peaks_result_table->item(i, 0)->text();
|
||||||
|
bool is_hidden = text == channel ? false : true;
|
||||||
|
_peaks_result_table->setRowHidden(i, is_hidden);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(btn_all_select, &QPushButton::clicked, [this]() {
|
||||||
|
_peaks_result_table->setCurrentItem(nullptr);
|
||||||
|
auto row_count = _peaks_result_table->rowCount();
|
||||||
|
for (int i = 0; i < row_count - 1; i++) {
|
||||||
|
if (_peaks_result_table->isRowHidden(i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto item = _peaks_result_table->item(i, 0);
|
||||||
|
if (item) {
|
||||||
|
item->setCheckState(Qt::Checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(btn_reserve_select, &QPushButton::clicked, [this]() {
|
||||||
|
_peaks_result_table->setCurrentItem(nullptr);
|
||||||
|
auto row_count = _peaks_result_table->rowCount();
|
||||||
|
for (int i = 0; i < row_count - 1; i++) {
|
||||||
|
if (_peaks_result_table->isRowHidden(i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto item = _peaks_result_table->item(i, 0);
|
||||||
|
if (item) {
|
||||||
|
Qt::CheckState check_state = (item->checkState() == Qt::Checked) ? Qt::Unchecked : Qt::Checked;
|
||||||
|
item->setCheckState(check_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(btn_save, &QPushButton::clicked, [this]() {
|
||||||
|
saveCurrentPeakResult();
|
||||||
|
});
|
||||||
|
connect(_peaks_result_table, &QTableWidget::itemChanged, [this](QTableWidgetItem* item) {
|
||||||
|
bool is_watch_item_changed = _peaks_result_table->property("WatchItemChanged").toBool();
|
||||||
|
if (is_watch_item_changed && bool(item->column() == 0)) {
|
||||||
|
emit peakInfoChanged(peakInfo(item, true, false));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||||
|
layout->addLayout(top_layout);
|
||||||
|
layout->addWidget(_peaks_result_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindPeaksResultDialog::SetPeakResultDataFilename(const QString &data_filename)
|
||||||
|
{
|
||||||
|
this->_peaks_result_data_filename = data_filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindPeaksResultDialog::SetChannelNameList(const QStringList &ch_name_list)
|
||||||
|
{
|
||||||
|
_filter_channel_combo_box->clear();
|
||||||
|
_filter_channel_combo_box->addItem(QString(QStringLiteral(u"所有通道")));
|
||||||
|
_filter_channel_combo_box->addItems(ch_name_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindPeaksResultDialog::UpdatePeakResult()
|
||||||
|
{
|
||||||
|
if (!QFileInfo(_peaks_result_data_filename).exists())
|
||||||
|
return;
|
||||||
|
|
||||||
|
_peaks_result_table->setCurrentItem(nullptr);
|
||||||
|
_peaks_result_table->setProperty("WatchItemChanged", false);
|
||||||
|
|
||||||
|
auto row_count = _peaks_result_table->rowCount();
|
||||||
|
for (int i = row_count - 1; i >= 0; i--) {
|
||||||
|
_peaks_result_table->removeRow(i);
|
||||||
|
}
|
||||||
|
const QString& channel_col_name = QString(QStringLiteral(u"通道"));
|
||||||
|
const QString& peak_pos_col_name = QString(QStringLiteral(u"峰位"));
|
||||||
|
const QString& left_bound_col_name = QString(QStringLiteral(u"左边界"));
|
||||||
|
const QString& right_bound_col_name = QString(QStringLiteral(u"右边界"));
|
||||||
|
const QString& peak_width_col_name = QString(QStringLiteral(u"峰宽"));
|
||||||
|
const QString& peak_height_col_name = QString(QStringLiteral(u"峰高"));
|
||||||
|
const QString& peak_fwhm_col_name = QString(QStringLiteral(u"FWHM"));
|
||||||
|
const QString& peak_area_col_name = QString(QStringLiteral(u"峰面积"));
|
||||||
|
io::CSVReader<
|
||||||
|
8,
|
||||||
|
io::trim_chars<' ', '\t'>,
|
||||||
|
io::double_quote_escape<',', '"'>,
|
||||||
|
io::throw_on_overflow,
|
||||||
|
io::empty_line_comment>
|
||||||
|
reader(QStrToSysPath(_peaks_result_data_filename));
|
||||||
|
reader.read_header(
|
||||||
|
io::ignore_extra_column,
|
||||||
|
channel_col_name.toStdString(),
|
||||||
|
peak_pos_col_name.toStdString(),
|
||||||
|
left_bound_col_name.toStdString(),
|
||||||
|
right_bound_col_name.toStdString(),
|
||||||
|
peak_width_col_name.toStdString(),
|
||||||
|
peak_height_col_name.toStdString(),
|
||||||
|
peak_fwhm_col_name.toStdString(),
|
||||||
|
peak_area_col_name.toStdString());
|
||||||
|
std::string ch_name;
|
||||||
|
int peak_pos;
|
||||||
|
int left_bound, right_bound, peak_width, peak_height, peak_fwhm;
|
||||||
|
double peak_area;
|
||||||
|
while (reader.read_row(ch_name, peak_pos, left_bound, right_bound, peak_width, peak_height, peak_fwhm, peak_area)) {
|
||||||
|
if (!ch_name.empty()) {
|
||||||
|
int row = _peaks_result_table->rowCount();
|
||||||
|
_peaks_result_table->insertRow(row);
|
||||||
|
_peaks_result_table->setItem(row, 0, new QTableWidgetItem(QString::fromStdString(ch_name)));
|
||||||
|
_peaks_result_table->item(row, 0)->setCheckState(Qt::Unchecked);
|
||||||
|
_peaks_result_table->setItem(row, 1, new QTableWidgetItem(QString::number(peak_pos)));
|
||||||
|
_peaks_result_table->setItem(row, 2, new QTableWidgetItem(QString::number(left_bound)));
|
||||||
|
_peaks_result_table->setItem(row, 3, new QTableWidgetItem(QString::number(right_bound)));
|
||||||
|
_peaks_result_table->setItem(row, 4, new QTableWidgetItem(QString::number(peak_width)));
|
||||||
|
_peaks_result_table->setItem(row, 5, new QTableWidgetItem(QString::number(peak_height)));
|
||||||
|
_peaks_result_table->setItem(row, 6, new QTableWidgetItem(QString::number(peak_fwhm)));
|
||||||
|
_peaks_result_table->setItem(row, 7, new QTableWidgetItem(QString::number(peak_area)));
|
||||||
|
QTableWidgetItem* item = new QTableWidgetItem;
|
||||||
|
_peaks_result_table->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);
|
||||||
|
emit peakInfoChanged(peakInfo(item, false, false));
|
||||||
|
int remove_row = item->row();
|
||||||
|
this->_peaks_result_table->removeRow(remove_row);
|
||||||
|
btn_remove_row->deleteLater();
|
||||||
|
});
|
||||||
|
_peaks_result_table->setCellWidget(row, 8, btn_remove_row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_peaks_result_table->setProperty("WatchItemChanged", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractTableModel* FindPeaksResultDialog::GetPeakResultDataModel() const
|
||||||
|
{
|
||||||
|
QAbstractTableModel* peaks_result_model = dynamic_cast<QAbstractTableModel*>(_peaks_result_table->model());
|
||||||
|
return peaks_result_model;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindPeaksResultDialog::saveCurrentPeakResult()
|
||||||
|
{
|
||||||
|
std::ofstream out_file(QStrToSysPath(_peaks_result_data_filename));
|
||||||
|
std::string channel_str = QString(QStringLiteral(u"通道")).toStdString();
|
||||||
|
std::string addr_str = QString(QStringLiteral(u"峰位")).toStdString();
|
||||||
|
std::string left_addr_str = QString(QStringLiteral(u"左边界")).toStdString();
|
||||||
|
std::string lright_addr_str = QString(QStringLiteral(u"右边界")).toStdString();
|
||||||
|
std::string width_str = QString(QStringLiteral(u"峰宽")).toStdString();
|
||||||
|
std::string height_str = QString(QStringLiteral(u"峰高")).toStdString();
|
||||||
|
std::string fwhm_str = QString(QStringLiteral(u"FWHM")).toStdString();
|
||||||
|
std::string area_str = QString(QStringLiteral(u"峰面积")).toStdString();
|
||||||
|
out_file << channel_str << "," << addr_str << "," << left_addr_str << ","
|
||||||
|
<< lright_addr_str << "," << width_str << "," << height_str << ","
|
||||||
|
<< fwhm_str << "," << area_str << "\n";
|
||||||
|
|
||||||
|
auto row_count = _peaks_result_table->rowCount();
|
||||||
|
for (int i = 0; i < row_count - 1; i++) {
|
||||||
|
std::string channel = _peaks_result_table->item(i, 0)->text().toStdString();
|
||||||
|
int peak_pos = _peaks_result_table->item(i, 1)->text().toInt();
|
||||||
|
int left_bound = _peaks_result_table->item(i, 2)->text().toInt();
|
||||||
|
int right_bound = _peaks_result_table->item(i, 3)->text().toInt();
|
||||||
|
int peak_width = _peaks_result_table->item(i, 4)->text().toInt();
|
||||||
|
int peak_height = _peaks_result_table->item(i, 5)->text().toInt();
|
||||||
|
int peak_fwhm = _peaks_result_table->item(i, 6)->text().toInt();
|
||||||
|
double peak_area = _peaks_result_table->item(i, 7)->text().toDouble();
|
||||||
|
out_file << channel << "," << peak_pos << "," << left_bound << "," << right_bound << ","
|
||||||
|
<< peak_width << "," << peak_height << "," << peak_fwhm<< "," << peak_area << "\n";
|
||||||
|
}
|
||||||
|
LOG_INFO(QStringLiteral(u"保存峰信息完成."));
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantMap FindPeaksResultDialog::peakInfo(QTableWidgetItem *item, bool show_peak, bool show_peak_area)
|
||||||
|
{
|
||||||
|
QVariantMap peak_infos;
|
||||||
|
if (!item) {
|
||||||
|
return peak_infos;
|
||||||
|
}
|
||||||
|
int row = item->row();
|
||||||
|
bool is_checked = bool(_peaks_result_table->item(row, 0)->checkState() == Qt::Checked);
|
||||||
|
const QString& channel = _peaks_result_table->item(row, 0)->text();
|
||||||
|
int peak_pos = _peaks_result_table->item(row, 1)->text().toInt();
|
||||||
|
int left_bound = _peaks_result_table->item(row, 2)->text().toInt();
|
||||||
|
int right_bound = _peaks_result_table->item(row, 3)->text().toInt();
|
||||||
|
int peak_width = _peaks_result_table->item(row, 4)->text().toInt();
|
||||||
|
int peak_height = _peaks_result_table->item(row, 5)->text().toInt();
|
||||||
|
int peak_fwhm = _peaks_result_table->item(row, 6)->text().toInt();
|
||||||
|
double peak_area = _peaks_result_table->item(row, 7)->text().toDouble();
|
||||||
|
|
||||||
|
peak_infos["channel"] = channel;
|
||||||
|
peak_infos["peak_pos"] = peak_pos;
|
||||||
|
peak_infos["left_bound"] = left_bound;
|
||||||
|
peak_infos["right_bound"] = right_bound;
|
||||||
|
peak_infos["peak_width"] = peak_width;
|
||||||
|
peak_infos["peak_height"] = peak_height;
|
||||||
|
peak_infos["peak_fwhm"] = peak_fwhm;
|
||||||
|
peak_infos["peak_area"] = peak_area;
|
||||||
|
peak_infos["checked"] = is_checked || show_peak;
|
||||||
|
peak_infos["show_peak_area"] = show_peak_area || show_peak;
|
||||||
|
return peak_infos;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef FINDPEAKSRESULTDIALOG_H
|
||||||
|
#define FINDPEAKSRESULTDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QVariantMap>
|
||||||
|
|
||||||
|
class QTableWidget;
|
||||||
|
class QTableWidgetItem;
|
||||||
|
class QAbstractTableModel;
|
||||||
|
class QComboBox;
|
||||||
|
|
||||||
|
class FindPeaksResultDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
FindPeaksResultDialog(QWidget* parent = nullptr);
|
||||||
|
void SetPeakResultDataFilename(const QString& data_filename);
|
||||||
|
void SetChannelNameList(const QStringList& ch_name_list);
|
||||||
|
void UpdatePeakResult();
|
||||||
|
QAbstractTableModel *GetPeakResultDataModel() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void saveCurrentPeakResult();
|
||||||
|
QVariantMap peakInfo(QTableWidgetItem* item, bool show_peak, bool show_peak_area);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void peakInfoChanged(QVariantMap peak_infos);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QComboBox* _filter_channel_combo_box = nullptr;
|
||||||
|
QTableWidget* _peaks_result_table = nullptr;
|
||||||
|
QString _peaks_result_data_filename;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FINDPEAKSRESULTDIALOG_H
|
||||||
|
|
@ -15,7 +15,6 @@
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QPen>
|
#include <QPen>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QRegularExpression>
|
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
#include <QTableWidget>
|
#include <QTableWidget>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
@ -28,16 +27,7 @@
|
||||||
#include <QwtText>
|
#include <QwtText>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "BatchEneryScaleDialog.h"
|
#include "BatchEneryScaleDialog.h"
|
||||||
|
#include "FindPeaksResultDialog.h"
|
||||||
static auto extractNumber = [](const QString& str) {
|
|
||||||
int ret_num = 0;
|
|
||||||
QRegularExpression regex("\\d+");
|
|
||||||
QRegularExpressionMatch match = regex.match(str);
|
|
||||||
if (match.hasMatch()) {
|
|
||||||
ret_num = match.captured().toInt();
|
|
||||||
}
|
|
||||||
return ret_num;
|
|
||||||
};
|
|
||||||
|
|
||||||
MeasureAnalysisParticleCountPlotView::MeasureAnalysisParticleCountPlotView(QWidget* parent)
|
MeasureAnalysisParticleCountPlotView::MeasureAnalysisParticleCountPlotView(QWidget* parent)
|
||||||
: MeasureAnalysisView { parent }
|
: MeasureAnalysisView { parent }
|
||||||
|
|
@ -47,11 +37,11 @@ MeasureAnalysisParticleCountPlotView::MeasureAnalysisParticleCountPlotView(QWidg
|
||||||
QHBoxLayout* layout = new QHBoxLayout(this);
|
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||||
this->_plot = new CustomQwtPlot(this);
|
this->_plot = new CustomQwtPlot(this);
|
||||||
layout->addWidget(this->_plot);
|
layout->addWidget(this->_plot);
|
||||||
|
this->_menu = new QMenu(this);
|
||||||
|
|
||||||
setupPlot();
|
setupPlot();
|
||||||
|
|
||||||
this->_menu = new QMenu(this);
|
|
||||||
setupMenu();
|
setupMenu();
|
||||||
|
setupPeakResultDlg();
|
||||||
}
|
}
|
||||||
|
|
||||||
MeasureAnalysisParticleCountPlotView::~MeasureAnalysisParticleCountPlotView()
|
MeasureAnalysisParticleCountPlotView::~MeasureAnalysisParticleCountPlotView()
|
||||||
|
|
@ -69,20 +59,23 @@ void MeasureAnalysisParticleCountPlotView::InitViewWorkspace(const QString& proj
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QDir project_dir(project_model->GetProjectDir());
|
QDir project_dir(project_model->GetProjectDir());
|
||||||
QString workspace = project_dir.filePath("AddressCountSpectrumView");
|
QString workspace = project_dir.filePath(this->GetViewName());
|
||||||
if (QDir(workspace).exists()) {
|
if (QDir(workspace).exists()) {
|
||||||
this->_workspace = workspace;
|
this->_workspace = workspace;
|
||||||
} else if (project_dir.mkpath(workspace)) {
|
} else if (project_dir.mkpath(workspace)) {
|
||||||
this->_workspace = workspace;
|
this->_workspace = workspace;
|
||||||
}
|
}
|
||||||
|
const QString& peaks_result_filename = QDir(this->_workspace).filePath(QStringLiteral(u"自动寻峰结果.csv"));
|
||||||
|
_find_peaks_result_dlg->SetPeakResultDataFilename(peaks_result_filename);
|
||||||
|
_find_peaks_result_dlg->UpdatePeakResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeasureAnalysisParticleCountPlotView::SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set)
|
void MeasureAnalysisParticleCountPlotView::SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set)
|
||||||
{
|
{
|
||||||
QStringList ch_count_data_name = data_files_set.keys();
|
QStringList ch_count_data_name = data_files_set.keys();
|
||||||
std::sort(ch_count_data_name.begin(), ch_count_data_name.end(), [](const QString& a, const QString& b) {
|
std::sort(ch_count_data_name.begin(), ch_count_data_name.end(), [](const QString& a, const QString& b) {
|
||||||
int num_a = extractNumber(a);
|
int num_a = ExtractNumberFromString(a);
|
||||||
int num_b = extractNumber(b);
|
int num_b = ExtractNumberFromString(b);
|
||||||
return num_a < num_b;
|
return num_a < num_b;
|
||||||
});
|
});
|
||||||
for (const QString& ch_count_data_name : ch_count_data_name) {
|
for (const QString& ch_count_data_name : ch_count_data_name) {
|
||||||
|
|
@ -156,6 +149,26 @@ void MeasureAnalysisParticleCountPlotView::setupPlot()
|
||||||
_data_selector->setEnabled(false);
|
_data_selector->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MeasureAnalysisParticleCountPlotView::setupPeakResultDlg()
|
||||||
|
{
|
||||||
|
if (!_find_peaks_result_dlg) {
|
||||||
|
_find_peaks_result_dlg = new FindPeaksResultDialog(this);
|
||||||
|
QStringList list_ch_names;
|
||||||
|
for (QwtPlotCurve* curve : this->_plot->GetCurveList()) {
|
||||||
|
list_ch_names.append(curve->title().text());
|
||||||
|
}
|
||||||
|
std::sort(list_ch_names.begin(), list_ch_names.end(), [](const QString& a, const QString& b) {
|
||||||
|
int num_a = ExtractNumberFromString(a);
|
||||||
|
int num_b = ExtractNumberFromString(b);
|
||||||
|
return num_a < num_b;
|
||||||
|
});
|
||||||
|
_find_peaks_result_dlg->SetChannelNameList(list_ch_names);
|
||||||
|
connect(_find_peaks_result_dlg, &FindPeaksResultDialog::peakInfoChanged, [this](QVariantMap peak_infos){
|
||||||
|
this->updatePlotPeakInfo(peak_infos);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MeasureAnalysisParticleCountPlotView::loadDataFromFile(const QString& data_name, const QString& filename)
|
void MeasureAnalysisParticleCountPlotView::loadDataFromFile(const QString& data_name, const QString& filename)
|
||||||
{
|
{
|
||||||
std::string address_str = QString(QStringLiteral(u"道址")).toStdString();
|
std::string address_str = QString(QStringLiteral(u"道址")).toStdString();
|
||||||
|
|
@ -185,72 +198,7 @@ void MeasureAnalysisParticleCountPlotView::loadDataFromFile(const QString& data_
|
||||||
_plot->AddCurve(curve);
|
_plot->AddCurve(curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeasureAnalysisParticleCountPlotView::loadPeaksResultToTable(QTableWidget* peaks_result_table)
|
void MeasureAnalysisParticleCountPlotView::updatePlotPeakInfo(const QVariantMap &peak_infos)
|
||||||
{
|
|
||||||
this->_plot->CleanMarkers();
|
|
||||||
this->_plot->replot();
|
|
||||||
if (!peaks_result_table)
|
|
||||||
return;
|
|
||||||
peaks_result_table->setCurrentItem(nullptr);
|
|
||||||
peaks_result_table->setProperty("WatchItemChanged", false);
|
|
||||||
|
|
||||||
auto row_count = peaks_result_table->rowCount();
|
|
||||||
for (int i = row_count - 1; i >= 0; i--) {
|
|
||||||
peaks_result_table->removeRow(i);
|
|
||||||
}
|
|
||||||
const QString& channel_col_name = QString(QStringLiteral(u"通道"));
|
|
||||||
const QString& peak_pos_col_name = QString(QStringLiteral(u"峰位"));
|
|
||||||
const QString& left_bound_col_name = QString(QStringLiteral(u"左边界"));
|
|
||||||
const QString& right_bound_col_name = QString(QStringLiteral(u"右边界"));
|
|
||||||
const QString& peak_width_col_name = QString(QStringLiteral(u"峰宽"));
|
|
||||||
const QString& peak_height_col_name = QString(QStringLiteral(u"峰高"));
|
|
||||||
const QString& peaks_result_filename = QDir(this->_workspace).filePath("AutoFindPeaksResult.csv");
|
|
||||||
io::CSVReader<
|
|
||||||
6,
|
|
||||||
io::trim_chars<' ', '\t'>,
|
|
||||||
io::double_quote_escape<',', '"'>,
|
|
||||||
io::throw_on_overflow,
|
|
||||||
io::empty_line_comment>
|
|
||||||
reader(QStrToSysPath(peaks_result_filename));
|
|
||||||
reader.read_header(
|
|
||||||
io::ignore_extra_column,
|
|
||||||
channel_col_name.toStdString(),
|
|
||||||
peak_pos_col_name.toStdString(),
|
|
||||||
left_bound_col_name.toStdString(),
|
|
||||||
right_bound_col_name.toStdString(),
|
|
||||||
peak_width_col_name.toStdString(),
|
|
||||||
peak_height_col_name.toStdString());
|
|
||||||
std::string ch_name;
|
|
||||||
int peak_pos;
|
|
||||||
int left_bound, right_bound, peak_width, peak_height;
|
|
||||||
while (reader.read_row(ch_name, peak_pos, left_bound, right_bound, peak_width, peak_height)) {
|
|
||||||
if (!ch_name.empty()) {
|
|
||||||
int row = peaks_result_table->rowCount();
|
|
||||||
peaks_result_table->insertRow(row);
|
|
||||||
peaks_result_table->setItem(row, 0, new QTableWidgetItem(QString::fromStdString(ch_name)));
|
|
||||||
peaks_result_table->item(row, 0)->setCheckState(Qt::Unchecked);
|
|
||||||
peaks_result_table->setItem(row, 1, new QTableWidgetItem(QString::number(peak_pos)));
|
|
||||||
peaks_result_table->setItem(row, 2, new QTableWidgetItem(QString::number(left_bound)));
|
|
||||||
peaks_result_table->setItem(row, 3, new QTableWidgetItem(QString::number(right_bound)));
|
|
||||||
peaks_result_table->setItem(row, 4, new QTableWidgetItem(QString::number(peak_width)));
|
|
||||||
peaks_result_table->setItem(row, 5, new QTableWidgetItem(QString::number(peak_height)));
|
|
||||||
QTableWidgetItem* item = new QTableWidgetItem;
|
|
||||||
peaks_result_table->setItem(row, 6, item);
|
|
||||||
QPushButton* btn_remove_row = new QPushButton(QStringLiteral(u"删除"));
|
|
||||||
connect(btn_remove_row, &QPushButton::clicked, [this, peaks_result_table, item, btn_remove_row]() {
|
|
||||||
item->setCheckState(Qt::Unchecked);
|
|
||||||
this->updatePlotPeakInfoByTableItem(item, false);
|
|
||||||
int remove_row = item->row();
|
|
||||||
peaks_result_table->removeRow(remove_row);
|
|
||||||
btn_remove_row->deleteLater();
|
|
||||||
});
|
|
||||||
peaks_result_table->setCellWidget(row, 6, btn_remove_row);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
peaks_result_table->setProperty("WatchItemChanged", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MeasureAnalysisParticleCountPlotView::updatePlotPeakInfo(QVariantMap peak_infos)
|
|
||||||
{
|
{
|
||||||
const QString& channel = peak_infos["channel"].toString();
|
const QString& channel = peak_infos["channel"].toString();
|
||||||
int peak_pos = peak_infos["peak_pos"].toInt();
|
int peak_pos = peak_infos["peak_pos"].toInt();
|
||||||
|
|
@ -258,6 +206,8 @@ void MeasureAnalysisParticleCountPlotView::updatePlotPeakInfo(QVariantMap peak_i
|
||||||
int right_bound = peak_infos["right_bound"].toInt();
|
int right_bound = peak_infos["right_bound"].toInt();
|
||||||
int peak_width = peak_infos["peak_width"].toInt();
|
int peak_width = peak_infos["peak_width"].toInt();
|
||||||
int peak_height = peak_infos["peak_height"].toInt();
|
int peak_height = peak_infos["peak_height"].toInt();
|
||||||
|
int peak_fwhm = peak_infos["peak_fwhm"].toInt();
|
||||||
|
double peak_area = peak_infos["peak_area"].toDouble();
|
||||||
bool is_checked = peak_infos["checked"].toBool();
|
bool is_checked = peak_infos["checked"].toBool();
|
||||||
bool is_show_peak_area = peak_infos["show_peak_area"].toBool();
|
bool is_show_peak_area = peak_infos["show_peak_area"].toBool();
|
||||||
|
|
||||||
|
|
@ -268,7 +218,9 @@ void MeasureAnalysisParticleCountPlotView::updatePlotPeakInfo(QVariantMap peak_i
|
||||||
peak_marker->setLineStyle(QwtPlotMarker::VLine);
|
peak_marker->setLineStyle(QwtPlotMarker::VLine);
|
||||||
peak_marker->setValue(peak_pos, 0.0);
|
peak_marker->setValue(peak_pos, 0.0);
|
||||||
peak_marker->setLabelAlignment(Qt::AlignTop | Qt::AlignRight);
|
peak_marker->setLabelAlignment(Qt::AlignTop | Qt::AlignRight);
|
||||||
const QString& label_text = QStringLiteral(u"峰位:%1\n峰宽:%2\n左界:%3\n右界:%4\n峰高:%5\n").arg(peak_pos).arg(peak_width).arg(left_bound).arg(right_bound).arg(peak_height);
|
const QString& label_text = QStringLiteral(u"峰位:%1\n峰宽:%2\n左界:%3\n右界:%4\n峰高:%5\nFWHM:%6\n峰面积:%7\n")
|
||||||
|
.arg(peak_pos).arg(peak_width).arg(left_bound).arg(right_bound)
|
||||||
|
.arg(peak_height).arg(peak_fwhm).arg(peak_area);
|
||||||
peak_marker->setLabel(label_text);
|
peak_marker->setLabel(label_text);
|
||||||
this->_plot->AddMarker(peak_marker, channel, postion);
|
this->_plot->AddMarker(peak_marker, channel, postion);
|
||||||
} else if (!is_checked) {
|
} else if (!is_checked) {
|
||||||
|
|
@ -286,46 +238,15 @@ void MeasureAnalysisParticleCountPlotView::updatePlotPeakInfo(QVariantMap peak_i
|
||||||
this->_plot->replot();
|
this->_plot->replot();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeasureAnalysisParticleCountPlotView::updatePlotPeakInfoByTableItem(QTableWidgetItem* item, bool checked, bool show_peak_area)
|
|
||||||
{
|
|
||||||
if (item) {
|
|
||||||
auto peaks_result_table = item->tableWidget();
|
|
||||||
int row = item->row();
|
|
||||||
bool is_checked = bool(peaks_result_table->item(row, 0)->checkState() == Qt::Checked);
|
|
||||||
const QString& channel = peaks_result_table->item(row, 0)->text();
|
|
||||||
int peak_pos = peaks_result_table->item(row, 1)->text().toInt();
|
|
||||||
int left_bound = peaks_result_table->item(row, 2)->text().toInt();
|
|
||||||
int right_bound = peaks_result_table->item(row, 3)->text().toInt();
|
|
||||||
int peak_width = peaks_result_table->item(row, 4)->text().toInt();
|
|
||||||
int peak_height = peaks_result_table->item(row, 5)->text().toInt();
|
|
||||||
QVariantMap peak_infos;
|
|
||||||
peak_infos["channel"] = channel;
|
|
||||||
peak_infos["peak_pos"] = peak_pos;
|
|
||||||
peak_infos["left_bound"] = left_bound;
|
|
||||||
peak_infos["right_bound"] = right_bound;
|
|
||||||
peak_infos["peak_width"] = peak_width;
|
|
||||||
peak_infos["peak_height"] = peak_height;
|
|
||||||
peak_infos["checked"] = is_checked || checked;
|
|
||||||
peak_infos["show_peak_area"] = show_peak_area || checked;
|
|
||||||
this->updatePlotPeakInfo(peak_infos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MeasureAnalysisParticleCountPlotView::onAutoFindPeaksFinished(const QString& project_name)
|
void MeasureAnalysisParticleCountPlotView::onAutoFindPeaksFinished(const QString& project_name)
|
||||||
{
|
{
|
||||||
Q_UNUSED(project_name);
|
Q_UNUSED(project_name);
|
||||||
if (_find_peaks_result_dlg) {
|
this->_plot->CleanMarkers();
|
||||||
for (const auto& child_obj : _find_peaks_result_dlg->children()) {
|
this->_plot->replot();
|
||||||
if ("peaks_result_table" == child_obj->objectName()) {
|
if (this->_find_peaks_result_dlg) {
|
||||||
QTableWidget* table = qobject_cast<QTableWidget*>(child_obj);
|
this->_find_peaks_result_dlg->UpdatePeakResult();
|
||||||
if (table) {
|
_find_peaks_result_dlg->show();
|
||||||
loadPeaksResultToTable(table);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
onActionFindPeaksResult();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeasureAnalysisParticleCountPlotView::onActionCurveShowSetting()
|
void MeasureAnalysisParticleCountPlotView::onActionCurveShowSetting()
|
||||||
|
|
@ -350,8 +271,8 @@ void MeasureAnalysisParticleCountPlotView::onActionCurveShowSetting()
|
||||||
list_ch_names.append(curve->title().text());
|
list_ch_names.append(curve->title().text());
|
||||||
}
|
}
|
||||||
std::sort(list_ch_names.begin(), list_ch_names.end(), [](const QString& a, const QString& b) {
|
std::sort(list_ch_names.begin(), list_ch_names.end(), [](const QString& a, const QString& b) {
|
||||||
int num_a = extractNumber(a);
|
int num_a = ExtractNumberFromString(a);
|
||||||
int num_b = extractNumber(b);
|
int num_b = ExtractNumberFromString(b);
|
||||||
return num_a < num_b;
|
return num_a < num_b;
|
||||||
});
|
});
|
||||||
for (const QString& ch_name : list_ch_names) {
|
for (const QString& ch_name : list_ch_names) {
|
||||||
|
|
@ -407,146 +328,9 @@ void MeasureAnalysisParticleCountPlotView::onActionCurveShowSetting()
|
||||||
|
|
||||||
void MeasureAnalysisParticleCountPlotView::onActionFindPeaksResult()
|
void MeasureAnalysisParticleCountPlotView::onActionFindPeaksResult()
|
||||||
{
|
{
|
||||||
if (!_find_peaks_result_dlg) {
|
if (_find_peaks_result_dlg) {
|
||||||
_find_peaks_result_dlg = new QDialog(this, Qt::Dialog | Qt::WindowCloseButtonHint);
|
_find_peaks_result_dlg->show();
|
||||||
_find_peaks_result_dlg->setWindowTitle(QString(QStringLiteral(u"寻峰结果")));
|
|
||||||
_find_peaks_result_dlg->setWindowModality(Qt::WindowModal);
|
|
||||||
_find_peaks_result_dlg->setModal(false);
|
|
||||||
|
|
||||||
QPushButton* btn_all_select = new QPushButton(QString(QStringLiteral(u"全选")));
|
|
||||||
QPushButton* btn_reserve_select = new QPushButton(QString(QStringLiteral(u"反选")));
|
|
||||||
QLabel* filter_channel_label = new QLabel(QString(QStringLiteral(u"筛选通道:")));
|
|
||||||
QComboBox* filter_channel_combo_box = new QComboBox();
|
|
||||||
filter_channel_combo_box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|
||||||
filter_channel_combo_box->addItem(QString(QStringLiteral(u"所有通道")));
|
|
||||||
QStringList list_ch_names;
|
|
||||||
for (QwtPlotCurve* curve : this->_plot->GetCurveList()) {
|
|
||||||
list_ch_names.append(curve->title().text());
|
|
||||||
}
|
|
||||||
std::sort(list_ch_names.begin(), list_ch_names.end(), [](const QString& a, const QString& b) {
|
|
||||||
int num_a = extractNumber(a);
|
|
||||||
int num_b = extractNumber(b);
|
|
||||||
return num_a < num_b;
|
|
||||||
});
|
|
||||||
filter_channel_combo_box->addItems(list_ch_names);
|
|
||||||
filter_channel_combo_box->setMaxVisibleItems(10);
|
|
||||||
filter_channel_combo_box->view()->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
|
||||||
QPushButton* btn_save = new QPushButton(QString(QStringLiteral(u"保存")));
|
|
||||||
QHBoxLayout* top_layout = new QHBoxLayout();
|
|
||||||
top_layout->addWidget(btn_all_select);
|
|
||||||
top_layout->addWidget(btn_reserve_select);
|
|
||||||
top_layout->addSpacing(10);
|
|
||||||
top_layout->addWidget(filter_channel_label);
|
|
||||||
top_layout->addWidget(filter_channel_combo_box);
|
|
||||||
top_layout->addSpacing(10);
|
|
||||||
top_layout->addWidget(btn_save);
|
|
||||||
|
|
||||||
const QString& channel_col_name = QString(QStringLiteral(u"通道"));
|
|
||||||
const QString& peak_pos_col_name = QString(QStringLiteral(u"峰位"));
|
|
||||||
const QString& left_bound_col_name = QString(QStringLiteral(u"左边界"));
|
|
||||||
const QString& right_bound_col_name = QString(QStringLiteral(u"右边界"));
|
|
||||||
const QString& peak_width_col_name = QString(QStringLiteral(u"峰宽"));
|
|
||||||
const QString& peak_height_col_name = QString(QStringLiteral(u"峰高"));
|
|
||||||
const QString& operation_col_name = QString(QStringLiteral(u"操作"));
|
|
||||||
QTableWidget* peaks_result_table = new QTableWidget();
|
|
||||||
peaks_result_table->setObjectName("peaks_result_table");
|
|
||||||
peaks_result_table->setColumnCount(7);
|
|
||||||
peaks_result_table->setHorizontalHeaderLabels({ channel_col_name, peak_pos_col_name, left_bound_col_name, right_bound_col_name,
|
|
||||||
peak_width_col_name, peak_height_col_name, operation_col_name });
|
|
||||||
peaks_result_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
|
||||||
peaks_result_table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
|
||||||
peaks_result_table->horizontalHeader()->setSectionResizeMode(peaks_result_table->columnCount() - 1, QHeaderView::ResizeToContents);
|
|
||||||
peaks_result_table->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
|
||||||
peaks_result_table->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
||||||
peaks_result_table->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
||||||
peaks_result_table->setEditTriggers(QTableWidget::NoEditTriggers);
|
|
||||||
this->loadPeaksResultToTable(peaks_result_table);
|
|
||||||
|
|
||||||
connect(filter_channel_combo_box, &QComboBox::currentTextChanged, [this, peaks_result_table](const QString& text) {
|
|
||||||
peaks_result_table->setCurrentItem(nullptr);
|
|
||||||
auto row_count = peaks_result_table->rowCount();
|
|
||||||
if (text == QString(QStringLiteral(u"所有通道"))) {
|
|
||||||
for (int i = 0; i < row_count - 1; i++) {
|
|
||||||
peaks_result_table->setRowHidden(i, false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = row_count - 1; i >= 0; i--) {
|
|
||||||
const QString& channel = peaks_result_table->item(i, 0)->text();
|
|
||||||
bool is_hidden = text == channel ? false : true;
|
|
||||||
peaks_result_table->setRowHidden(i, is_hidden);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(btn_all_select, &QPushButton::clicked, [peaks_result_table]() {
|
|
||||||
peaks_result_table->setCurrentItem(nullptr);
|
|
||||||
auto row_count = peaks_result_table->rowCount();
|
|
||||||
for (int i = 0; i < row_count - 1; i++) {
|
|
||||||
if (peaks_result_table->isRowHidden(i)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto item = peaks_result_table->item(i, 0);
|
|
||||||
if (item) {
|
|
||||||
item->setCheckState(Qt::Checked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(btn_reserve_select, &QPushButton::clicked, [peaks_result_table]() {
|
|
||||||
peaks_result_table->setCurrentItem(nullptr);
|
|
||||||
auto row_count = peaks_result_table->rowCount();
|
|
||||||
for (int i = 0; i < row_count - 1; i++) {
|
|
||||||
if (peaks_result_table->isRowHidden(i)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto item = peaks_result_table->item(i, 0);
|
|
||||||
if (item) {
|
|
||||||
Qt::CheckState check_state = (item->checkState() == Qt::Checked) ? Qt::Unchecked : Qt::Checked;
|
|
||||||
item->setCheckState(check_state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(btn_save, &QPushButton::clicked, [peaks_result_table, this]() {
|
|
||||||
const QString& peaks_result_filename = QDir(this->_workspace).filePath("AutoFindPeaksResult.csv");
|
|
||||||
std::ofstream out_file(QStrToSysPath(peaks_result_filename));
|
|
||||||
|
|
||||||
std::string channel_str = QString(QStringLiteral(u"通道")).toStdString();
|
|
||||||
std::string addr_str = QString(QStringLiteral(u"峰位")).toStdString();
|
|
||||||
std::string left_addr_str = QString(QStringLiteral(u"左边界")).toStdString();
|
|
||||||
std::string lright_addr_str = QString(QStringLiteral(u"右边界")).toStdString();
|
|
||||||
std::string width_str = QString(QStringLiteral(u"峰宽")).toStdString();
|
|
||||||
std::string height_str = QString(QStringLiteral(u"峰高")).toStdString();
|
|
||||||
out_file << channel_str << "," << addr_str << "," << left_addr_str << "," << lright_addr_str << "," << width_str << "," << height_str << "\n";
|
|
||||||
|
|
||||||
auto row_count = peaks_result_table->rowCount();
|
|
||||||
for (int i = 0; i < row_count - 1; i++) {
|
|
||||||
std::string channel = peaks_result_table->item(i, 0)->text().toStdString();
|
|
||||||
int peak_pos = peaks_result_table->item(i, 1)->text().toInt();
|
|
||||||
int left_bound = peaks_result_table->item(i, 2)->text().toInt();
|
|
||||||
int right_bound = peaks_result_table->item(i, 3)->text().toInt();
|
|
||||||
int peak_width = peaks_result_table->item(i, 4)->text().toInt();
|
|
||||||
int peak_height = peaks_result_table->item(i, 5)->text().toInt();
|
|
||||||
out_file << channel << "," << peak_pos << "," << left_bound << "," << right_bound << "," << peak_width << "," << peak_height << "\n";
|
|
||||||
}
|
|
||||||
LOG_INFO(QStringLiteral(u"保存峰信息完成."));
|
|
||||||
});
|
|
||||||
connect(peaks_result_table, &QTableWidget::itemChanged, [this, peaks_result_table](QTableWidgetItem* item) {
|
|
||||||
bool is_watch_item_changed = peaks_result_table->property("WatchItemChanged").toBool();
|
|
||||||
if (is_watch_item_changed && bool(item->column() == 0)) {
|
|
||||||
this->updatePlotPeakInfoByTableItem(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(peaks_result_table, &QTableWidget::currentItemChanged, [this, peaks_result_table](QTableWidgetItem* current, QTableWidgetItem* previous) {
|
|
||||||
bool is_watch_item_changed = peaks_result_table->property("WatchItemChanged").toBool();
|
|
||||||
if (is_watch_item_changed) {
|
|
||||||
this->updatePlotPeakInfoByTableItem(previous, false, false);
|
|
||||||
this->updatePlotPeakInfoByTableItem(current, true, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
QVBoxLayout* layout = new QVBoxLayout(_find_peaks_result_dlg);
|
|
||||||
layout->addLayout(top_layout);
|
|
||||||
layout->addWidget(peaks_result_table);
|
|
||||||
}
|
}
|
||||||
_find_peaks_result_dlg->show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeasureAnalysisParticleCountPlotView::onActionAutoFindPeaks()
|
void MeasureAnalysisParticleCountPlotView::onActionAutoFindPeaks()
|
||||||
|
|
@ -594,18 +378,22 @@ void MeasureAnalysisParticleCountPlotView::onActionAutoFindPeaks()
|
||||||
|
|
||||||
void MeasureAnalysisParticleCountPlotView::onActionManualFindPeaks()
|
void MeasureAnalysisParticleCountPlotView::onActionManualFindPeaks()
|
||||||
{
|
{
|
||||||
_data_selector->setEnabled(true);
|
// _data_selector->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeasureAnalysisParticleCountPlotView::onActionEneryScale()
|
void MeasureAnalysisParticleCountPlotView::onActionEneryScale()
|
||||||
{
|
{
|
||||||
_data_selector->setEnabled(true);
|
|
||||||
if (!_batch_enery_scale_dlg) {
|
if (!_batch_enery_scale_dlg) {
|
||||||
_batch_enery_scale_dlg = new BatchEneryScaleDialog(this);
|
_batch_enery_scale_dlg = new BatchEneryScaleDialog(this);
|
||||||
_batch_enery_scale_dlg->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
_batch_enery_scale_dlg->SetPeakResultDataModel(_find_peaks_result_dlg->GetPeakResultDataModel());
|
||||||
_batch_enery_scale_dlg->setWindowTitle(QString(QStringLiteral(u"多通道能量刻度")));
|
connect(_data_selector, &CustomQwtPlotXaxisSelector::selectionFinished, _batch_enery_scale_dlg, &BatchEneryScaleDialog::onSelectedScaleRange);
|
||||||
|
connect(_batch_enery_scale_dlg, &BatchEneryScaleDialog::close, [this](){
|
||||||
|
this->_data_selector->setEnabled(false);
|
||||||
|
disconnect(_data_selector, &CustomQwtPlotXaxisSelector::selectionFinished, _batch_enery_scale_dlg, &BatchEneryScaleDialog::onSelectedScaleRange);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
_batch_enery_scale_dlg->show();
|
_batch_enery_scale_dlg->show();
|
||||||
|
_data_selector->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeasureAnalysisParticleCountPlotView::onActionPlotConfigure()
|
void MeasureAnalysisParticleCountPlotView::onActionPlotConfigure()
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ class QTableWidget;
|
||||||
class QTableWidgetItem;
|
class QTableWidgetItem;
|
||||||
class CustomQwtPlotXaxisSelector;
|
class CustomQwtPlotXaxisSelector;
|
||||||
class BatchEneryScaleDialog;
|
class BatchEneryScaleDialog;
|
||||||
|
class FindPeaksResultDialog;
|
||||||
|
|
||||||
class MeasureAnalysisParticleCountPlotView : public MeasureAnalysisView
|
class MeasureAnalysisParticleCountPlotView : public MeasureAnalysisView
|
||||||
{
|
{
|
||||||
|
|
@ -27,10 +28,10 @@ public:
|
||||||
private:
|
private:
|
||||||
void setupMenu();
|
void setupMenu();
|
||||||
void setupPlot();
|
void setupPlot();
|
||||||
|
void setupPeakResultDlg();
|
||||||
void loadDataFromFile(const QString &data_name, const QString& filename);
|
void loadDataFromFile(const QString &data_name, const QString& filename);
|
||||||
void loadPeaksResultToTable(QTableWidget* peaks_result_table);
|
void loadPeaksResultToTable(QTableWidget* peaks_result_table);
|
||||||
void updatePlotPeakInfo(QVariantMap peak_infos);
|
void updatePlotPeakInfo(const QVariantMap& peak_infos);
|
||||||
void updatePlotPeakInfoByTableItem(QTableWidgetItem* item, bool checked = false, bool show_peak_area = false);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onAutoFindPeaksFinished(const QString& project_name);
|
void onAutoFindPeaksFinished(const QString& project_name);
|
||||||
|
|
@ -48,7 +49,7 @@ private:
|
||||||
QMenu* _menu = nullptr;
|
QMenu* _menu = nullptr;
|
||||||
QDialog* _curve_show_setting_dlg = nullptr;
|
QDialog* _curve_show_setting_dlg = nullptr;
|
||||||
QMap<QString, QVariant> _data_files_set_ptr;
|
QMap<QString, QVariant> _data_files_set_ptr;
|
||||||
QDialog* _find_peaks_result_dlg = nullptr;
|
FindPeaksResultDialog* _find_peaks_result_dlg = nullptr;
|
||||||
CustomQwtPlotXaxisSelector* _data_selector = nullptr;
|
CustomQwtPlotXaxisSelector* _data_selector = nullptr;
|
||||||
BatchEneryScaleDialog* _batch_enery_scale_dlg = nullptr;
|
BatchEneryScaleDialog* _batch_enery_scale_dlg = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index)
|
||||||
if ( view ) {
|
if ( view ) {
|
||||||
view->InitViewWorkspace(project_name);
|
view->InitViewWorkspace(project_name);
|
||||||
view->SetProjectName(project_name);
|
view->SetProjectName(project_name);
|
||||||
const auto& view_name = QStringLiteral(u"%1 [%2]").arg(item_text).arg(project_name);
|
const auto& view_name = QStringLiteral(u"%1[%2]").arg(item_text).arg(project_name);
|
||||||
view->SetViewName(view_name);
|
view->SetViewName(view_name);
|
||||||
view->SetViewDescription(view_name);
|
view->SetViewDescription(view_name);
|
||||||
view->SetAnalyzeDataFilename(data_files_set);
|
view->SetAnalyzeDataFilename(data_files_set);
|
||||||
|
|
@ -120,11 +120,11 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index)
|
||||||
view = _item_views[item];
|
view = _item_views[item];
|
||||||
} else {
|
} else {
|
||||||
view = MeasureAnalysisView::NewAnalyzeView(analysis_type);
|
view = MeasureAnalysisView::NewAnalyzeView(analysis_type);
|
||||||
view->InitViewWorkspace(project_name);
|
|
||||||
view->SetProjectName(project_name);
|
view->SetProjectName(project_name);
|
||||||
const auto& view_name = QStringLiteral(u"%1 [%2]").arg(item_text).arg(project_name);
|
const auto& view_name = QStringLiteral(u"%1[%2]").arg(item_text).arg(project_name);
|
||||||
view->SetViewName(view_name);
|
view->SetViewName(view_name);
|
||||||
view->SetViewDescription(view_name);
|
view->SetViewDescription(view_name);
|
||||||
|
view->InitViewWorkspace(project_name);
|
||||||
view->SetAnalyzeDataFilename(data_files_set);
|
view->SetAnalyzeDataFilename(data_files_set);
|
||||||
}
|
}
|
||||||
if ( view ) {
|
if ( view ) {
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ SOURCES += \
|
||||||
MeasureAnalysisDataTableView.cpp \
|
MeasureAnalysisDataTableView.cpp \
|
||||||
MeasureAnalysisHistoryForm.cpp \
|
MeasureAnalysisHistoryForm.cpp \
|
||||||
MeasureAnalysisParticleCountPlotView/BatchEneryScaleDialog.cpp \
|
MeasureAnalysisParticleCountPlotView/BatchEneryScaleDialog.cpp \
|
||||||
|
MeasureAnalysisParticleCountPlotView/FindPeaksResultDialog.cpp \
|
||||||
MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp \
|
MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp \
|
||||||
MeasureAnalysisTreeView.cpp \
|
MeasureAnalysisTreeView.cpp \
|
||||||
MeasureAnalysisView.cpp \
|
MeasureAnalysisView.cpp \
|
||||||
|
|
@ -68,6 +69,7 @@ HEADERS += \
|
||||||
MeasureAnalysisDataTableView.h \
|
MeasureAnalysisDataTableView.h \
|
||||||
MeasureAnalysisHistoryForm.h \
|
MeasureAnalysisHistoryForm.h \
|
||||||
MeasureAnalysisParticleCountPlotView/BatchEneryScaleDialog.h \
|
MeasureAnalysisParticleCountPlotView/BatchEneryScaleDialog.h \
|
||||||
|
MeasureAnalysisParticleCountPlotView/FindPeaksResultDialog.h \
|
||||||
MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.h \
|
MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.h \
|
||||||
MeasureAnalysisTreeView.h \
|
MeasureAnalysisTreeView.h \
|
||||||
MeasureAnalysisView.h \
|
MeasureAnalysisView.h \
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user