实现多通道能量刻度数据文件生成

This commit is contained in:
徐海 2026-03-18 19:31:24 +08:00
parent 3a5b22be2d
commit bdc88f2230
12 changed files with 396 additions and 137 deletions

View File

@ -58,6 +58,7 @@ void CustomQwtPlot::AddCurve(QwtPlotCurve *curve)
{
if (curve) {
curve->setPen(QPen(getDistinctColorForManyCurves(_curves.count()), 1));
curve->setZ(0);
curve->attach(this);
_curves[curve->title().text()] = curve;
}
@ -85,9 +86,7 @@ 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->setZ(20);
marker->attach(this);
_markers[marker_name][postion] = marker;
}
@ -131,6 +130,7 @@ void CustomQwtPlot::AddZoneItem(QwtPlotZoneItem *zone_item, const QString &zone_
if (zone_item) {
zone_item->setPen(Qt::transparent); // 无边框
zone_item->setBrush(QColor(0, 120, 215, 95)); // 半透明蓝色RGBAA=80 透明度)
zone_item->setZ(10);
zone_item->attach(this);
_zone_items[zone_item_name] = zone_item;
}
@ -276,6 +276,7 @@ CustomQwtPlotXaxisSelector::CustomQwtPlotXaxisSelector(QWidget *canvas)
_overlay->setRenderHint(QwtPlotItem::RenderAntialiased);
_overlay->setPen(QPen(Qt::red, 2));
_overlay->setBrush(QBrush(QColor(0, 120, 210, 50)));
_overlay->setZ(100);
_overlay->attach(plot());
_overlay->setVisible(false);
}

View File

@ -2,7 +2,7 @@
using namespace arma;
std::vector<FindPeaksBySvd::PeakInfo> FindPeaksBySvd::FindPeaks(const arma::mat &spec_data, int step_w)
std::vector<FindPeaksBySvd::PeakInfo> FindPeaksBySvd::FindPeaks(const arma::mat &spec_data, int step_w) throw(std::string)
{
std::vector<FindPeaksBySvd::PeakInfo> peak_info_vec;
try {
@ -131,11 +131,9 @@ std::vector<FindPeaksBySvd::PeakInfo> FindPeaksBySvd::FindPeaks(const arma::mat
}
}
catch(const std::exception& e) {
return peak_info_vec;
throw std::string("Find Peaks Exception:") + std::string(e.what());
throw std::string("Find Peaks Exception, ") + std::string(e.what());
}
catch (...) {
return peak_info_vec;
throw std::string("Find peaks unkonow exception");
}
return peak_info_vec;

View File

@ -17,7 +17,7 @@ public:
double area = 0.0f; // 峰的面积
} 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) throw(std::string);
};

View File

@ -4,8 +4,8 @@ using namespace std;
vector<double> GaussPolyCoe::GaussianElimination(vector<vector<double>> A, vector<double> b)
{
try {
int n = A.size();
for (int i = 0; i < n; ++i) {
// 寻找主元
int maxRow = i;
@ -39,11 +39,16 @@ vector<double> GaussPolyCoe::GaussianElimination(vector<vector<double>> A, vecto
}
}
}
} catch(const std::exception& e) {
throw e;
}
return b;
}
vector<double> GaussPolyCoe::PolynomialFit(const vector<double>& x, const vector<double>& y, int degree)
{
vector<double> coeffs;
try {
int n = x.size();
int m = degree + 1; // 系数个数
@ -64,7 +69,11 @@ vector<double> GaussPolyCoe::PolynomialFit(const vector<double>& x, const vector
}
// 求解线性方程组得到系数
return GaussianElimination(AT_A, AT_b);
coeffs = GaussianElimination(AT_A, AT_b);
} catch(const std::exception& e) {
throw e;
}
return coeffs;
}
double GaussPolyCoe::Predict(const vector<double>& coeffs, double x)

View File

@ -14,7 +14,10 @@
#include <QVariant>
#include <QFuture>
#include <QtConcurrent>
#include "DataCalcProcess/MathModelDefine.h"
#include "DataCalcProcess/FindPeaksBySvd.h"
#include "DataCalcProcess/GaussPolyCoe.h"
#include "DataCalcProcess/NolinearLeastSquaresCurveFit.h"
#include <QDebug>
using namespace DataProcessWorkPool;
@ -534,7 +537,7 @@ bool ParticleDataSortTask::processEveryChannelParticleData()
} catch (const std::exception& e) {
const QString& e_what = QString::fromLatin1(e.what());
QString error = QString(QStringLiteral(u"处理%1异常:%2")).arg(all_channel_particle_data_filename).arg(e_what);
QString error = QString(QStringLiteral(u"处理%1异常:%2")).arg(all_channel_particle_data_filename).arg(QString::fromStdString(e.what()));
LOG_ERROR(error)
ret_ok = false;
} catch (...) {
@ -611,8 +614,14 @@ bool AutoFindPeaksTask::processTask()
LOG_WARN(error);
continue;
}
FindPeaksBySvd peak_svd;
std::vector<FindPeaksBySvd::PeakInfo> peak_info_vec = peak_svd.FindPeaks(data, this->_step_win_width);
std::vector<FindPeaksBySvd::PeakInfo> peak_info_vec;
try {
peak_info_vec = FindPeaksBySvd().FindPeaks(data, this->_step_win_width);
} catch (const std::string& e) {
QString error = QString(QStringLiteral(u"%1自动寻峰异常:%2!")).arg(ch_count_data_name).arg(QString::fromStdString(e));
LOG_WARN(error);
continue;
}
if (!peak_info_vec.empty()) {
for(auto peak_info : peak_info_vec) {
int addr = peak_info.pos;
@ -645,3 +654,106 @@ bool AutoFindPeaksTask::processTask()
LOG_INFO(info);
return true;
}
void ChannelEnergyScaleFittingTask::SetData(
const FitDataMap& channel_enery_scale_fit_data_map, const QMap<QString, int>& fit_degree_map)
{
this->_channel_enery_scale_fit_data_map = channel_enery_scale_fit_data_map;
this->_fit_degree_map = fit_degree_map;
}
bool ChannelEnergyScaleFittingTask::IsValidSetWorkParameters() const
{
return (!this->_channel_enery_scale_fit_data_map.isEmpty()) && (!this->_fit_degree_map.isEmpty()) && DataProcessTask::IsValidSetWorkParameters();
}
bool ChannelEnergyScaleFittingTask::processTask()
{
QVariantMap enery_scale_json_obj_map;
for (const QString& channel : this->_channel_enery_scale_fit_data_map.keys()) {
const QMap<int, QList<double> >& enery_scale_fit_data = this->_channel_enery_scale_fit_data_map.value(channel);
if (enery_scale_fit_data.isEmpty()) {
continue;
}
int fit_degree = this->_fit_degree_map.value(channel);
if (fit_degree <= 0) {
continue;
}
std::vector<double> vec_x, vec_y1, vec_y2;
for (const int& addr : enery_scale_fit_data.keys()) {
vec_x.push_back(addr);
vec_y1.push_back(enery_scale_fit_data.value(addr)[0]);
vec_y2.push_back(enery_scale_fit_data.value(addr)[1]);
}
std::vector<double> enery_scale_fit_result_coeffs;
try {
enery_scale_fit_result_coeffs = GaussPolyCoe::PolynomialFit(vec_x, vec_y1, fit_degree);
} catch(const std::exception& e) {
QString error = QString(QStringLiteral(u"%1能量刻度多项式%2次拟合异常:%3!")).arg(channel).arg(fit_degree).arg(QString::fromStdString(e.what()));
LOG_WARN(error);
}
arma::vec fwhm_fit_result_coeffs;
try {
fwhm_fit_result_coeffs = NolinearLeastSquaresCurveFit::Lsqcurvefit(FwhmModel, vec_y1, vec_y2, { 1.0, 1.0 });
} catch(const std::exception& e) {
QString error = QString(QStringLiteral(u"%1分辨率拟合异常:%2!")).arg(channel).arg(QString::fromStdString(e.what()));
LOG_WARN(error);
}
const QString& info = QStringLiteral(u"%1能量刻度拟合完成.").arg(channel);
LOG_INFO(info);
QVariantList enery_scale_fit_coeffs_val;
for (const double& coeff : enery_scale_fit_result_coeffs) {
enery_scale_fit_coeffs_val.append(coeff);
}
QVariantList fwhm_fit_coeffs_val;
for (const double& coeff : fwhm_fit_result_coeffs) {
fwhm_fit_coeffs_val.append(coeff);
}
QVariantList fit_result_data_item;
for (int i = 0; i < vec_x.size(); i++) {
int addr = vec_x[i];
double set_energy = vec_y1[i];
double fit_energy = GaussPolyCoe::Predict(enery_scale_fit_result_coeffs, addr);
double peak_fwhm = vec_y2[i];
double fit_fwhm = FwhmModel(addr, fwhm_fit_result_coeffs);
QVariantList fit_result_item_data;
fit_result_item_data.append(addr);
fit_result_item_data.append(set_energy);
fit_result_item_data.append(fit_energy);
fit_result_item_data.append(set_energy - fit_energy);
fit_result_item_data.append(peak_fwhm);
fit_result_item_data.append(fit_fwhm);
fit_result_item_data.append(peak_fwhm - fit_fwhm);
fit_result_data_item.append(QVariant::fromValue(fit_result_item_data));
}
QVariantMap channel_enery_scale_fit_result_obj_map;
channel_enery_scale_fit_result_obj_map["EneryFitDegree"] = fit_degree;
channel_enery_scale_fit_result_obj_map["EneryFitResultCoeffs"] = QVariant::fromValue(enery_scale_fit_coeffs_val);
channel_enery_scale_fit_result_obj_map["FwhmFitResultCoeffs"] = QVariant::fromValue(fwhm_fit_coeffs_val);
channel_enery_scale_fit_result_obj_map["FitResultData"] = QVariant::fromValue(fit_result_data_item);
enery_scale_json_obj_map.insert(channel, channel_enery_scale_fit_result_obj_map);
}
const QString& project_name = GetProjectName();
MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(project_name);
if (project_model == nullptr) {
return false;
}
QDir project_dir(project_model->GetProjectDir());
const QString& enery_scale_data_filename = project_dir.filePath(QStringLiteral(u"能量刻度.csv"));
QJsonDocument enery_scale_fit_result_doc = QJsonDocument::fromVariant(enery_scale_json_obj_map);;
QFile json_file(enery_scale_data_filename);
if (!json_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QString error = QString(QStringLiteral(u"生成测量分析[%1]能量刻度结果失败!")).arg(project_name);
LOG_WARN(error);
return false;
}
json_file.write(enery_scale_fit_result_doc.toJson());
json_file.close();
project_model->SetEneryScaleFilename(enery_scale_data_filename);
const QString& info = QStringLiteral(u"能量刻度拟合完成.");
LOG_INFO(info);
return true;
}

View File

@ -105,6 +105,19 @@ namespace DataProcessWorkPool
QString _result_dir;
int _step_win_width = 7;
};
class ChannelEnergyScaleFittingTask : public DataProcessTask {
public:
typedef QMap<QString, QMap<int, QList<double> > > FitDataMap;
public:
void SetData(const FitDataMap& channel_enery_scale_fit_data_map, const QMap<QString, int>& fit_degree_map);
virtual bool IsValidSetWorkParameters() const override;
private:
virtual bool processTask() override;
private:
FitDataMap _channel_enery_scale_fit_data_map;
QMap<QString, int> _fit_degree_map;
};
}
#endif // DATAPROCESSWORKPOOL_H

View File

@ -1,6 +1,13 @@
#include "BatchEneryScaleDialog.h"
#include "ui_BatchEneryScaleDialog.h"
#include <QDoubleSpinBox>
#include "DataProcessWorkPool.h"
#include "GlobalDefine.h"
#include "MeasureAnalysisProjectModel.h"
#include <QDir>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMessageBox>
#include <QDebug>
BatchEneryScaleDialog::BatchEneryScaleDialog(QWidget* parent)
@ -13,7 +20,7 @@ BatchEneryScaleDialog::BatchEneryScaleDialog(QWidget* parent)
this->setWindowModality(Qt::WindowModal);
this->setModal(false);
ui->tablew_process_data->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
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);
@ -79,13 +86,11 @@ BatchEneryScaleDialog::BatchEneryScaleDialog(QWidget* parent)
if (btn_remove_row) {
ui->tablew_process_data->removeRow(row);
btn_remove_row->deleteLater();
}
}
this->updateSetEneryFilter();
}
}
});
connect(ui->btn_fit, &QPushButton::clicked, [this](){
});
connect(ui->btn_fit, &QPushButton::clicked, this, &BatchEneryScaleDialog::onFitBtnClickedProcess);
connect(ui->btn_save, &QPushButton::clicked, [this](){
});
@ -96,8 +101,14 @@ BatchEneryScaleDialog::~BatchEneryScaleDialog()
delete ui;
}
void BatchEneryScaleDialog::SetProjectName(const QString &project_name)
{
this->_project_name = project_name;
}
void BatchEneryScaleDialog::SetChannelNameList(const QStringList &ch_name_list)
{
this->_channel_name_list = ch_name_list;
ui->filter_channel_combo_box->clear();
ui->filter_channel_combo_box->addItem(QString(QStringLiteral(u"所有通道")));
ui->filter_channel_combo_box->addItems(ch_name_list);
@ -111,6 +122,11 @@ void BatchEneryScaleDialog::SetPeakResultDataModel(QAbstractTableModel* peaks_re
}
}
void BatchEneryScaleDialog::SetViewWorkspace(const QString &workspace)
{
this->_workspace = workspace;
}
void BatchEneryScaleDialog::onSelectedScaleRange(double min, double max)
{
if (!_peaks_result_model) {
@ -152,9 +168,7 @@ void BatchEneryScaleDialog::onSelectedScaleRange(double min, double max)
const QString& channel_name = _peaks_result_model->data(_peaks_result_model->index(i, 0)).toString();
int peak_pos = _peaks_result_model->data(_peaks_result_model->index(i, 1)).toInt();
int peak_fwhm = _peaks_result_model->data(_peaks_result_model->index(i, 6)).toInt();
if (min < peak_pos && peak_pos > max ) {
continue;
}
if (min < peak_pos && peak_pos < max ) {
int row = ui->tablew_process_data->rowCount();
ui->tablew_process_data->insertRow(row);
ui->tablew_process_data->setItem(row, 0, new QTableWidgetItem(channel_name));
@ -181,6 +195,7 @@ void BatchEneryScaleDialog::onSelectedScaleRange(double min, double max)
this->insertSetEneryValueToFilter(set_enery);
}
}
}
}
void BatchEneryScaleDialog::insertSetEneryValueToFilter(double enery)
@ -198,7 +213,7 @@ void BatchEneryScaleDialog::insertSetEneryValueToFilter(double enery)
void BatchEneryScaleDialog::updateSetEneryFilter()
{
int item_count = ui->filter_set_enery_combo_box->count();
for (int index = item_count - 1; index >= 1; --index) {
for (int index = item_count - 1; index > 0; --index) {
int count = ui->filter_set_enery_combo_box->itemData(index).toInt();
count = count - 1;
ui->filter_set_enery_combo_box->setItemData(index, count);
@ -210,7 +225,106 @@ void BatchEneryScaleDialog::updateSetEneryFilter()
ui->filter_set_enery_combo_box->removeItem(index);
}
}
}
bool BatchEneryScaleDialog::LoadEneryScaleData(const QString &project_name)
{
MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(project_name);
if (project_model) {
const QString& enery_scale_data_filename = project_model->GetEneryScaleFilename();
QFile json_file(enery_scale_data_filename);
if (json_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QJsonDocument json_doc = QJsonDocument::fromJson(json_file.readAll());
json_file.close();
const QVariantMap& enery_scale_data_map = json_doc.toVariant().toMap();
if (!enery_scale_data_map.isEmpty()) {
auto row_count = ui->tablew_process_data->rowCount();
for (int row = row_count - 1; row >= 0; --row) {
QPushButton* btn_remove_row = dynamic_cast<QPushButton*>(ui->tablew_process_data->cellWidget(row, 8));
if (btn_remove_row) {
ui->tablew_process_data->removeRow(row);
btn_remove_row->deleteLater();
this->updateSetEneryFilter();
}
}
for (const QString& channel_name : this->_channel_name_list) {
if (enery_scale_data_map.contains(channel_name)) {
const QVariantMap& channel_enery_scale_data_map = enery_scale_data_map[channel_name].toMap();
if (channel_enery_scale_data_map.contains("FitResultData")) {
const QVariantList& fit_result_data_item_list = channel_enery_scale_data_map["FitResultData"].toList();
for (const QVariant& fit_result_data_item : fit_result_data_item_list) {
const QVariantList& fit_result_data_map = fit_result_data_item.toList();
int row = ui->tablew_process_data->rowCount();
ui->tablew_process_data->insertRow(row);
ui->tablew_process_data->setItem(row, 0, new QTableWidgetItem(channel_name));
ui->tablew_process_data->item(row, 0)->setCheckState(Qt::Unchecked);
ui->tablew_process_data->setItem(row, 1, new QTableWidgetItem(fit_result_data_map[0].toString()));
ui->tablew_process_data->setItem(row, 2, new QTableWidgetItem(fit_result_data_map[1].toString()));
ui->tablew_process_data->setItem(row, 3, new QTableWidgetItem(fit_result_data_map[2].toString()));
ui->tablew_process_data->setItem(row, 4, new QTableWidgetItem(fit_result_data_map[3].toString()));
ui->tablew_process_data->setItem(row, 5, new QTableWidgetItem(fit_result_data_map[4].toString()));
ui->tablew_process_data->setItem(row, 6, new QTableWidgetItem(fit_result_data_map[5].toString()));
ui->tablew_process_data->setItem(row, 7, new QTableWidgetItem(fit_result_data_map[6].toString()));
QTableWidgetItem* item = new QTableWidgetItem;
ui->tablew_process_data->setItem(row, 8, item);
QPushButton* btn_remove_row = new QPushButton(QStringLiteral(u"删除"));
btn_remove_row->setMaximumWidth(35);
connect(btn_remove_row, &QPushButton::clicked, [this, item, btn_remove_row]() {
item->setCheckState(Qt::Unchecked);
int remove_row = item->row();
ui->tablew_process_data->removeRow(remove_row);
btn_remove_row->deleteLater();
this->updateSetEneryFilter();
});
ui->tablew_process_data->setCellWidget(row, 8, btn_remove_row);
this->insertSetEneryValueToFilter(fit_result_data_map[1].toDouble());
}
}
}
}
return true;
}
}
}
}
void BatchEneryScaleDialog::onFitBtnClickedProcess()
{
QMap<QString, int> fit_degree_map;
DataProcessWorkPool::ChannelEnergyScaleFittingTask::FitDataMap channel_enery_scale_fit_data_map;
for (int i = 0; i < ui->tablew_process_data->rowCount(); i++) {
const QString& channel_name = ui->tablew_process_data->item(i, 0)->text();
int peak_pos = ui->tablew_process_data->item(i, 1)->text().toInt();
double enery = ui->tablew_process_data->item(i, 2)->text().toDouble();
int peak_fwhm = ui->tablew_process_data->item(i, 5)->text().toInt();
channel_enery_scale_fit_data_map[channel_name].insert(peak_pos, QList<double>() << enery << peak_fwhm);
fit_degree_map[channel_name] = 1;
}
QStringList data_except_channel_name_list;
for (auto it = channel_enery_scale_fit_data_map.begin(); it != channel_enery_scale_fit_data_map.end(); ++it) {
const QString& channel_name = it.key();
const QMap<int, QList<double> >& fit_data = it.value();
if (fit_data.size() < 2) {
data_except_channel_name_list << channel_name;
}
}
if (data_except_channel_name_list.size() > 0) {
const QString& warn_msg = QStringLiteral(u"请为以下通道设置拟合数据:%1").arg(data_except_channel_name_list.join(QStringLiteral(u",")));
LOG_WARN(warn_msg);
QMessageBox::warning(this, QStringLiteral(u"警告"), warn_msg);
return;
}
if (!channel_enery_scale_fit_data_map.empty()) {
auto auto_find_peaks_task = new DataProcessWorkPool::ChannelEnergyScaleFittingTask;
auto_find_peaks_task->SetData(channel_enery_scale_fit_data_map, fit_degree_map);
auto_find_peaks_task->SetFinishedNotifier(this, "onEneryScaleFitFinished", this->_project_name);
auto_find_peaks_task->StartTask();
}
}
void BatchEneryScaleDialog::onEneryScaleFitFinished(const QString &project_name)
{
this->LoadEneryScaleData(project_name);
}
void BatchEneryScaleDialog::closeEvent(QCloseEvent *e)

View File

@ -17,11 +17,17 @@ public:
explicit BatchEneryScaleDialog(QWidget *parent = nullptr);
~BatchEneryScaleDialog();
void SetProjectName(const QString& project_name);
void SetChannelNameList(const QStringList& ch_name_list);
void SetPeakResultDataModel(QAbstractTableModel *peaks_result_model);
void SetViewWorkspace(const QString& workspace);
bool LoadEneryScaleData(const QString& project_name);
public slots:
void onSelectedScaleRange(double min, double max);
void onFitBtnClickedProcess();
private slots:
void onEneryScaleFitFinished(const QString& project_name);
private:
void insertSetEneryValueToFilter(double enery);
@ -35,6 +41,9 @@ protected:
private:
Ui::BatchEneryScaleDialog *ui;
QString _project_name;
QStringList _channel_name_list;
QString _workspace;
QAbstractTableModel* _peaks_result_model;
};

View File

@ -107,7 +107,8 @@ FindPeaksResultDialog::FindPeaksResultDialog(QWidget *parent)
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));
bool b_show_peak = (item->checkState() == Qt::Checked);
emit peakInfoChanged(peakInfo(item, b_show_peak, false));
}
});
connect(_peaks_result_table, &QTableWidget::currentItemChanged, [this](QTableWidgetItem* current, QTableWidgetItem* previous) {
@ -228,7 +229,7 @@ void FindPeaksResultDialog::saveCurrentPeakResult()
<< fwhm_str << "," << area_str << "\n";
auto row_count = _peaks_result_table->rowCount();
for (int i = 0; i < row_count - 1; i++) {
for (int i = 0; i < row_count; 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();
@ -269,6 +270,6 @@ QVariantMap FindPeaksResultDialog::peakInfo(QTableWidgetItem *item, bool show_pe
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;
peak_infos["show_peak_area"] = show_peak_area && show_peak;
return peak_infos;
}

View File

@ -48,6 +48,7 @@ MeasureAnalysisParticleCountPlotView::MeasureAnalysisParticleCountPlotView(QWidg
MeasureAnalysisParticleCountPlotView::~MeasureAnalysisParticleCountPlotView()
{
LOG_DEBUG(QStringLiteral(u"%1析构.").arg(this->GetViewName()));
}
void MeasureAnalysisParticleCountPlotView::InitViewWorkspace(const QString& project_name)
@ -59,6 +60,7 @@ void MeasureAnalysisParticleCountPlotView::InitViewWorkspace(const QString& proj
if (!project_model) {
return;
}
QDir project_dir(project_model->GetProjectDir());
QString workspace = project_dir.filePath(this->GetViewName());
if (QDir(workspace).exists()) {
@ -66,9 +68,14 @@ void MeasureAnalysisParticleCountPlotView::InitViewWorkspace(const QString& proj
} else if (project_dir.mkpath(workspace)) {
this->_workspace = workspace;
}
const QString& peaks_result_filename = QDir(this->_workspace).filePath(QStringLiteral(u"自动寻峰结果.csv"));
const QString& peaks_result_filename = QDir(workspace).filePath(QStringLiteral(u"自动寻峰结果.csv"));
_find_peaks_result_dlg->SetPeakResultDataFilename(peaks_result_filename);
_find_peaks_result_dlg->UpdatePeakResult();
_batch_enery_scale_dlg->SetProjectName(project_name);
_batch_enery_scale_dlg->SetViewWorkspace(workspace);
_batch_enery_scale_dlg->LoadEneryScaleData(project_name);
}
void MeasureAnalysisParticleCountPlotView::SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set)
@ -233,19 +240,33 @@ void MeasureAnalysisParticleCountPlotView::updatePlotPeakInfo(const QVariantMap
const QString& postion = QString::number(peak_pos);
QwtPlotMarker* peak_marker = this->_plot->GetMarker(channel, postion);
if ((!peak_marker) && is_checked) {
if (is_checked) {
if (!peak_marker) {
peak_marker = new QwtPlotMarker();
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\nFWHM:%6\n峰面积:%7\n")
const QString& peak_info_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(peak_info_text);
this->_plot->AddMarker(peak_marker, channel, postion);
} else if (!is_checked) {
}
QwtText label_text = peak_marker->label();
if (is_show_peak_area) {
label_text.setColor(Qt::black);
peak_marker->setZ(peak_marker->z() + 1);
} else {
label_text.setColor(Qt::transparent);
peak_marker->setZ(peak_marker->z() - 1);
}
peak_marker->setLabel(label_text);
} else {
if (peak_marker) {
this->_plot->RemoveMarker(channel, postion);
}
}
QwtPlotZoneItem* peak_area_zone_item = this->_plot->GetZoneItem(channel);
if (!peak_area_zone_item && is_show_peak_area) {
peak_area_zone_item = new QwtPlotZoneItem;

View File

@ -244,53 +244,43 @@ bool MeasureAnalysisProjectModel::LoadProjectModel(const QString& project_filena
this->_project_filename = project_filename;
// 从json文件加载项目模型
QFile json_file(this->_project_filename);
if (!json_file.open(QIODevice::ReadOnly | QIODevice::Text))
{
if (!json_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return false;
}
QJsonDocument json_doc = QJsonDocument::fromJson(json_file.readAll());
json_file.close();
if (json_doc.isNull())
{
if (json_doc.isNull()) {
return false;
}
if (!json_doc.isObject())
{
if (!json_doc.isObject()) {
return false;
}
QJsonObject json_obj = json_doc.object();
if (!json_obj.contains("ProjectName"))
{
if (!json_obj.contains("ProjectName")) {
return false;
}
this->_project_name = json_obj["ProjectName"].toString();
if (!json_obj.contains("SpectrumType"))
{
if (!json_obj.contains("SpectrumType")) {
return false;
}
this->_spec_type = (SpectrumType)json_obj["SpectrumType"].toInt();
if (!json_obj.contains("IsStandardSource"))
{
if (!json_obj.contains("IsStandardSource")) {
return false;
}
this->_is_std_source = json_obj["IsStandardSource"].toBool();
if (!json_obj.contains("DescriptionInfo"))
{
if (!json_obj.contains("DescriptionInfo")) {
return false;
}
this->_description_info = json_obj["DescriptionInfo"].toString();
if (!json_obj.contains("MeasurePresetTime"))
{
if (!json_obj.contains("MeasurePresetTime")) {
return false;
}
this->_measure_preset_time = json_obj["MeasurePresetTime"].toInt();
if (!json_obj.contains("IsMeasureComplete"))
{
if (!json_obj.contains("IsMeasureComplete")) {
return false;
}
this->_is_measure_complete = json_obj["IsMeasureComplete"].toBool();
if (!json_obj.contains("ConformTimeWin"))
{
if (!json_obj.contains("ConformTimeWin")) {
return false;
}
this->_conform_time_win = json_obj["ConformTimeWin"].toInt();
@ -349,7 +339,7 @@ bool MeasureAnalysisProjectModel::LoadProjectModel(const QString& project_filena
bool MeasureAnalysisProjectModel::SaveProjectModel()
{
auto ProjectRelativeFilename = [this](const QString& abs_filename){
auto ProjectRelativeFilename = [this](const QString& abs_filename) {
QString project_relative_filename;
if ( !abs_filename.isEmpty() ) {
QFileInfo file_info(abs_filename);
@ -362,9 +352,7 @@ bool MeasureAnalysisProjectModel::SaveProjectModel()
}
return project_relative_filename;
};
if (this->_project_filename.isEmpty())
{
if (this->_project_filename.isEmpty()) {
this->_project_filename = QDir(this->_project_dir).filePath(this->_project_name + QString(".msproject"));;
}
// 将项目模型转换为json对象
@ -376,28 +364,22 @@ bool MeasureAnalysisProjectModel::SaveProjectModel()
project_json_obj_map["MeasurePresetTime"] = int(this->_measure_preset_time);
project_json_obj_map["IsMeasureComplete"] = this->_is_measure_complete;
project_json_obj_map["ConformTimeWin"] = this->_conform_time_win;
project_json_obj_map["MeasureDeviceParamsCfgFilename"] = ProjectRelativeFilename(this->_measure_device_params_cfg_filename);
project_json_obj_map["EneryScaleFilename"] = ProjectRelativeFilename(this->_enery_scale_filename);
project_json_obj_map["EfficiencyScaleFilename"] = ProjectRelativeFilename(this->_efficiency_scale_filename);
project_json_obj_map["AllChannelParticleDataFilename"] = ProjectRelativeFilename(this->_all_channel_particle_data_filename);
project_json_obj_map["SortedParticleDataFilename"] = ProjectRelativeFilename(this->_sorted_particle_data_filename);
QVariantMap channel_address_count_data_filename_list;
for (auto it = this->_channel_address_count_data_filename_list.constBegin(); it != this->_channel_address_count_data_filename_list.constEnd(); ++it) {
channel_address_count_data_filename_list[QString::number(it.key())] = ProjectRelativeFilename(it.value());
}
project_json_obj_map["ChannelAddressCountDataFilenameList"] = channel_address_count_data_filename_list;
QVariantMap channel_enery_count_data_filename_list;
for (auto it = this->_channel_enery_count_data_filename_list.constBegin(); it != this->_channel_enery_count_data_filename_list.constEnd(); ++it) {
channel_enery_count_data_filename_list[QString::number(it.key())] = ProjectRelativeFilename(it.value());
}
project_json_obj_map["ChannelEneryCountDataFilenameList"] = channel_enery_count_data_filename_list;
project_json_obj_map["AllChannelEneryTotalCountDataFilename"] = ProjectRelativeFilename(this->_all_channel_enery_total_count_data_filename);
QVariantMap time_win_conform_particle_data;
for (auto it = this->_time_win_conform_particle_data.constBegin(); it != this->_time_win_conform_particle_data.constEnd(); ++it) {
QVariantMap conform_particle_data;
@ -411,8 +393,7 @@ bool MeasureAnalysisProjectModel::SaveProjectModel()
// 将项目模型保存到json文件
QJsonDocument json_doc = QJsonDocument::fromVariant(project_json_obj_map);
QFile json_file(this->_project_filename);
if (!json_file.open(QIODevice::WriteOnly | QIODevice::Text))
{
if (!json_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
return false;
}
json_file.write(json_doc.toJson());

View File

@ -67,11 +67,11 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index)
data_files_set[QStringLiteral(u"粒子数据")] = file_name;
MeasureAnalysisView* view = MeasureAnalysisView::NewAnalyzeView(analysis_type);
if ( view ) {
view->InitViewWorkspace(project_name);
view->SetProjectName(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);
emit currentItemView(view);
}
@ -90,11 +90,11 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index)
data_files_set[QStringLiteral(u"通道%1道址计数").arg(ch_num)] = file_name;
MeasureAnalysisView* view = MeasureAnalysisView::NewAnalyzeView(analysis_type);
if ( view ) {
view->InitViewWorkspace(project_name);
view->SetProjectName(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);
emit currentItemView(view);
}