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();
|
||||
pen.setWidth(2);
|
||||
marker->setLinePen(pen);
|
||||
QwtText label_text = marker->label();
|
||||
label_text.setColor(Qt::black);
|
||||
marker->setLabel(label_text);
|
||||
marker->attach(this);
|
||||
_markers[marker_name][postion] = marker;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ public:
|
|||
void clearSelection();
|
||||
|
||||
signals:
|
||||
void selectionFinished(double minX, double maxX);
|
||||
void selectionFinished(double min_x, double max_x);
|
||||
|
||||
protected:
|
||||
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);
|
||||
double height = peak_region.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);
|
||||
// 筛选有效峰:峰宽>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.height = height;
|
||||
peak_info.pos = spec_data_col0.at(pos);
|
||||
peak_info.fwhm = fwhm;
|
||||
peak_info.area = area;
|
||||
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");
|
||||
}
|
||||
return peak_info_vec;
|
||||
}
|
||||
}
|
||||
|
|
@ -13,11 +13,12 @@ public:
|
|||
double width = 0.0f; // 峰所在数据区域的宽度
|
||||
double height = 0.0f; // 峰所在数据区域的高度
|
||||
double pos = 0.0f; // 峰所在位置
|
||||
double fwhm = 0.0f; // 峰所在位置
|
||||
double fwhm = 0.0f; // 峰的半高宽
|
||||
double area = 0.0f; // 峰的面积
|
||||
} PeakInfo;
|
||||
|
||||
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;
|
||||
}
|
||||
} 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)
|
||||
ret_ok = false;
|
||||
} 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)
|
||||
ret_ok = false;
|
||||
} catch (...) {
|
||||
|
|
@ -303,15 +305,17 @@ bool EveryChannelParticleCountDataTask::processEveryChannelParticleData()
|
|||
// all_channel_out.close();
|
||||
|
||||
} 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)
|
||||
ret_ok = false;
|
||||
} 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)
|
||||
ret_ok = false;
|
||||
} 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)
|
||||
ret_ok = false;
|
||||
}
|
||||
|
|
@ -529,7 +533,8 @@ bool ParticleDataSortTask::processEveryChannelParticleData()
|
|||
}
|
||||
|
||||
} 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)
|
||||
ret_ok = false;
|
||||
} catch (...) {
|
||||
|
|
@ -576,7 +581,7 @@ bool AutoFindPeaksTask::IsValidSetWorkParameters() const
|
|||
|
||||
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::string channel_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 height_str = QString(QStringLiteral(u"峰高")).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) {
|
||||
std::string channel = it.key().toStdString();
|
||||
arma::mat data;
|
||||
const std::string data_filename = QStrToSysPath(it.value().toString());
|
||||
if (!data.load(data_filename, arma::csv_ascii)) {
|
||||
QString error = QString(QStringLiteral(u"%1自动寻峰数据加载异常!")).arg(it.key());
|
||||
LOG_WARN(error);
|
||||
continue;
|
||||
}
|
||||
FindPeaksBySvd peak_svd;
|
||||
std::vector<FindPeaksBySvd::PeakInfo> peak_info_vec = peak_svd.FindPeaks(data, this->_step_win_width);
|
||||
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;
|
||||
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";
|
||||
QStringList ch_count_data_name = this->_data_files_set.keys();
|
||||
std::sort(ch_count_data_name.begin(), ch_count_data_name.end(), [](const QString& a, const QString& b) {
|
||||
int num_a = ExtractNumberFromString(a);
|
||||
int num_b = ExtractNumberFromString(b);
|
||||
return num_a < num_b;
|
||||
});
|
||||
for (const QString& ch_count_data_name : ch_count_data_name) {
|
||||
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();
|
||||
std::string channel = ch_count_data_name.toStdString();
|
||||
arma::mat data;
|
||||
const std::string data_filename = QStrToSysPath(ch_count_data_filename);
|
||||
if (!data.load(data_filename, arma::csv_ascii)) {
|
||||
QString error = QString(QStringLiteral(u"%1自动寻峰数据加载异常!")).arg(ch_count_data_name);
|
||||
LOG_WARN(error);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
const QString& error = QStringLiteral(u"%1自动寻峰异常!").arg(it.key());
|
||||
LOG_WARN(error);
|
||||
FindPeaksBySvd peak_svd;
|
||||
std::vector<FindPeaksBySvd::PeakInfo> peak_info_vec = peak_svd.FindPeaks(data, this->_step_win_width);
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "MainWindow.h"
|
||||
#include "QsLog.h"
|
||||
#include <QTextCodec>
|
||||
#include <QRegularExpression>
|
||||
#include <QDebug>
|
||||
|
||||
// 转换Qt字符串路径为系统编码的C字符串(解决中文路径问题)
|
||||
|
|
@ -22,6 +23,16 @@ static const char* QStrToSysPath(const QString& qstr_path)
|
|||
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) \
|
||||
{ \
|
||||
|
|
|
|||
|
|
@ -1,15 +1,39 @@
|
|||
#include "BatchEneryScaleDialog.h"
|
||||
#include "ui_BatchEneryScaleDialog.h"
|
||||
#include <QDebug>
|
||||
|
||||
BatchEneryScaleDialog::BatchEneryScaleDialog(QWidget *parent)
|
||||
BatchEneryScaleDialog::BatchEneryScaleDialog(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::BatchEneryScaleDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
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()
|
||||
{
|
||||
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>
|
||||
|
||||
class QAbstractTableModel;
|
||||
|
||||
namespace Ui {
|
||||
class BatchEneryScaleDialog;
|
||||
}
|
||||
|
|
@ -15,8 +17,20 @@ public:
|
|||
explicit BatchEneryScaleDialog(QWidget *parent = nullptr);
|
||||
~BatchEneryScaleDialog();
|
||||
|
||||
void SetPeakResultDataModel(QAbstractTableModel *peaks_result_model);
|
||||
|
||||
public slots:
|
||||
void onSelectedScaleRange(double min, double max);
|
||||
|
||||
signals:
|
||||
void close();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *e);
|
||||
|
||||
private:
|
||||
Ui::BatchEneryScaleDialog *ui;
|
||||
QAbstractTableModel* _peaks_result_model;
|
||||
};
|
||||
|
||||
#endif // BATCHENERYSCALEDIALOG_H
|
||||
|
|
|
|||
|
|
@ -6,18 +6,35 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>824</width>
|
||||
<height>409</height>
|
||||
<width>929</width>
|
||||
<height>404</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
<string>多通道能量刻度</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<item>
|
||||
<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>
|
||||
<widget class="QLabel" name="label_channel">
|
||||
<property name="text">
|
||||
|
|
@ -26,7 +43,14 @@
|
|||
</widget>
|
||||
</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>
|
||||
</layout>
|
||||
</item>
|
||||
|
|
@ -40,10 +64,24 @@
|
|||
</widget>
|
||||
</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>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_remove_selected">
|
||||
<property name="text">
|
||||
<string>删除勾选</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
|
|
@ -64,10 +102,26 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_save">
|
||||
<property name="text">
|
||||
<string>保存</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</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>
|
||||
<property name="text">
|
||||
<string>通道</string>
|
||||
|
|
@ -111,6 +165,11 @@
|
|||
<string>分辨率偏差</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>操作</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</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 <QPen>
|
||||
#include <QPushButton>
|
||||
#include <QRegularExpression>
|
||||
#include <QSpinBox>
|
||||
#include <QTableWidget>
|
||||
#include <QVector>
|
||||
|
|
@ -28,16 +27,7 @@
|
|||
#include <QwtText>
|
||||
#include <fstream>
|
||||
#include "BatchEneryScaleDialog.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;
|
||||
};
|
||||
#include "FindPeaksResultDialog.h"
|
||||
|
||||
MeasureAnalysisParticleCountPlotView::MeasureAnalysisParticleCountPlotView(QWidget* parent)
|
||||
: MeasureAnalysisView { parent }
|
||||
|
|
@ -47,11 +37,11 @@ MeasureAnalysisParticleCountPlotView::MeasureAnalysisParticleCountPlotView(QWidg
|
|||
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||
this->_plot = new CustomQwtPlot(this);
|
||||
layout->addWidget(this->_plot);
|
||||
this->_menu = new QMenu(this);
|
||||
|
||||
setupPlot();
|
||||
|
||||
this->_menu = new QMenu(this);
|
||||
setupMenu();
|
||||
setupPeakResultDlg();
|
||||
}
|
||||
|
||||
MeasureAnalysisParticleCountPlotView::~MeasureAnalysisParticleCountPlotView()
|
||||
|
|
@ -69,20 +59,23 @@ void MeasureAnalysisParticleCountPlotView::InitViewWorkspace(const QString& proj
|
|||
return;
|
||||
}
|
||||
QDir project_dir(project_model->GetProjectDir());
|
||||
QString workspace = project_dir.filePath("AddressCountSpectrumView");
|
||||
QString workspace = project_dir.filePath(this->GetViewName());
|
||||
if (QDir(workspace).exists()) {
|
||||
this->_workspace = workspace;
|
||||
} else if (project_dir.mkpath(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)
|
||||
{
|
||||
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) {
|
||||
int num_a = extractNumber(a);
|
||||
int num_b = extractNumber(b);
|
||||
int num_a = ExtractNumberFromString(a);
|
||||
int num_b = ExtractNumberFromString(b);
|
||||
return num_a < num_b;
|
||||
});
|
||||
for (const QString& ch_count_data_name : ch_count_data_name) {
|
||||
|
|
@ -156,6 +149,26 @@ void MeasureAnalysisParticleCountPlotView::setupPlot()
|
|||
_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)
|
||||
{
|
||||
std::string address_str = QString(QStringLiteral(u"道址")).toStdString();
|
||||
|
|
@ -185,72 +198,7 @@ void MeasureAnalysisParticleCountPlotView::loadDataFromFile(const QString& data_
|
|||
_plot->AddCurve(curve);
|
||||
}
|
||||
|
||||
void MeasureAnalysisParticleCountPlotView::loadPeaksResultToTable(QTableWidget* peaks_result_table)
|
||||
{
|
||||
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)
|
||||
void MeasureAnalysisParticleCountPlotView::updatePlotPeakInfo(const QVariantMap &peak_infos)
|
||||
{
|
||||
const QString& channel = peak_infos["channel"].toString();
|
||||
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 peak_width = peak_infos["peak_width"].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_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->setValue(peak_pos, 0.0);
|
||||
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);
|
||||
this->_plot->AddMarker(peak_marker, channel, postion);
|
||||
} else if (!is_checked) {
|
||||
|
|
@ -286,46 +238,15 @@ void MeasureAnalysisParticleCountPlotView::updatePlotPeakInfo(QVariantMap peak_i
|
|||
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)
|
||||
{
|
||||
Q_UNUSED(project_name);
|
||||
if (_find_peaks_result_dlg) {
|
||||
for (const auto& child_obj : _find_peaks_result_dlg->children()) {
|
||||
if ("peaks_result_table" == child_obj->objectName()) {
|
||||
QTableWidget* table = qobject_cast<QTableWidget*>(child_obj);
|
||||
if (table) {
|
||||
loadPeaksResultToTable(table);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this->_plot->CleanMarkers();
|
||||
this->_plot->replot();
|
||||
if (this->_find_peaks_result_dlg) {
|
||||
this->_find_peaks_result_dlg->UpdatePeakResult();
|
||||
_find_peaks_result_dlg->show();
|
||||
}
|
||||
onActionFindPeaksResult();
|
||||
}
|
||||
|
||||
void MeasureAnalysisParticleCountPlotView::onActionCurveShowSetting()
|
||||
|
|
@ -350,8 +271,8 @@ void MeasureAnalysisParticleCountPlotView::onActionCurveShowSetting()
|
|||
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);
|
||||
int num_a = ExtractNumberFromString(a);
|
||||
int num_b = ExtractNumberFromString(b);
|
||||
return num_a < num_b;
|
||||
});
|
||||
for (const QString& ch_name : list_ch_names) {
|
||||
|
|
@ -407,146 +328,9 @@ void MeasureAnalysisParticleCountPlotView::onActionCurveShowSetting()
|
|||
|
||||
void MeasureAnalysisParticleCountPlotView::onActionFindPeaksResult()
|
||||
{
|
||||
if (!_find_peaks_result_dlg) {
|
||||
_find_peaks_result_dlg = new QDialog(this, Qt::Dialog | Qt::WindowCloseButtonHint);
|
||||
_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);
|
||||
if (_find_peaks_result_dlg) {
|
||||
_find_peaks_result_dlg->show();
|
||||
}
|
||||
_find_peaks_result_dlg->show();
|
||||
}
|
||||
|
||||
void MeasureAnalysisParticleCountPlotView::onActionAutoFindPeaks()
|
||||
|
|
@ -594,18 +378,22 @@ void MeasureAnalysisParticleCountPlotView::onActionAutoFindPeaks()
|
|||
|
||||
void MeasureAnalysisParticleCountPlotView::onActionManualFindPeaks()
|
||||
{
|
||||
_data_selector->setEnabled(true);
|
||||
// _data_selector->setEnabled(true);
|
||||
}
|
||||
|
||||
void MeasureAnalysisParticleCountPlotView::onActionEneryScale()
|
||||
{
|
||||
_data_selector->setEnabled(true);
|
||||
if (!_batch_enery_scale_dlg) {
|
||||
_batch_enery_scale_dlg = new BatchEneryScaleDialog(this);
|
||||
_batch_enery_scale_dlg->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
_batch_enery_scale_dlg->setWindowTitle(QString(QStringLiteral(u"多通道能量刻度")));
|
||||
_batch_enery_scale_dlg->SetPeakResultDataModel(_find_peaks_result_dlg->GetPeakResultDataModel());
|
||||
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();
|
||||
_data_selector->setEnabled(true);
|
||||
}
|
||||
|
||||
void MeasureAnalysisParticleCountPlotView::onActionPlotConfigure()
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ class QTableWidget;
|
|||
class QTableWidgetItem;
|
||||
class CustomQwtPlotXaxisSelector;
|
||||
class BatchEneryScaleDialog;
|
||||
class FindPeaksResultDialog;
|
||||
|
||||
class MeasureAnalysisParticleCountPlotView : public MeasureAnalysisView
|
||||
{
|
||||
|
|
@ -27,10 +28,10 @@ public:
|
|||
private:
|
||||
void setupMenu();
|
||||
void setupPlot();
|
||||
void setupPeakResultDlg();
|
||||
void loadDataFromFile(const QString &data_name, const QString& filename);
|
||||
void loadPeaksResultToTable(QTableWidget* peaks_result_table);
|
||||
void updatePlotPeakInfo(QVariantMap peak_infos);
|
||||
void updatePlotPeakInfoByTableItem(QTableWidgetItem* item, bool checked = false, bool show_peak_area = false);
|
||||
void updatePlotPeakInfo(const QVariantMap& peak_infos);
|
||||
|
||||
private slots:
|
||||
void onAutoFindPeaksFinished(const QString& project_name);
|
||||
|
|
@ -48,7 +49,7 @@ private:
|
|||
QMenu* _menu = nullptr;
|
||||
QDialog* _curve_show_setting_dlg = nullptr;
|
||||
QMap<QString, QVariant> _data_files_set_ptr;
|
||||
QDialog* _find_peaks_result_dlg = nullptr;
|
||||
FindPeaksResultDialog* _find_peaks_result_dlg = nullptr;
|
||||
CustomQwtPlotXaxisSelector* _data_selector = nullptr;
|
||||
BatchEneryScaleDialog* _batch_enery_scale_dlg = nullptr;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index)
|
|||
if ( view ) {
|
||||
view->InitViewWorkspace(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->SetViewDescription(view_name);
|
||||
view->SetAnalyzeDataFilename(data_files_set);
|
||||
|
|
@ -120,11 +120,11 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index)
|
|||
view = _item_views[item];
|
||||
} else {
|
||||
view = MeasureAnalysisView::NewAnalyzeView(analysis_type);
|
||||
view->InitViewWorkspace(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->SetViewDescription(view_name);
|
||||
view->InitViewWorkspace(project_name);
|
||||
view->SetAnalyzeDataFilename(data_files_set);
|
||||
}
|
||||
if ( view ) {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ SOURCES += \
|
|||
MeasureAnalysisDataTableView.cpp \
|
||||
MeasureAnalysisHistoryForm.cpp \
|
||||
MeasureAnalysisParticleCountPlotView/BatchEneryScaleDialog.cpp \
|
||||
MeasureAnalysisParticleCountPlotView/FindPeaksResultDialog.cpp \
|
||||
MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp \
|
||||
MeasureAnalysisTreeView.cpp \
|
||||
MeasureAnalysisView.cpp \
|
||||
|
|
@ -68,6 +69,7 @@ HEADERS += \
|
|||
MeasureAnalysisDataTableView.h \
|
||||
MeasureAnalysisHistoryForm.h \
|
||||
MeasureAnalysisParticleCountPlotView/BatchEneryScaleDialog.h \
|
||||
MeasureAnalysisParticleCountPlotView/FindPeaksResultDialog.h \
|
||||
MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.h \
|
||||
MeasureAnalysisTreeView.h \
|
||||
MeasureAnalysisView.h \
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user