1、添加能量刻度数据模型;2、优化多通道能量刻度拟合;3、修改错误的变量命名;
This commit is contained in:
parent
bdc88f2230
commit
25cc07917b
|
|
@ -13,7 +13,7 @@ enum class AnalysisType {
|
|||
ChannelEnergyCountData, // 通道能量计数数据
|
||||
CoincidenceParticleEnergyData, // 符合粒子能量数据
|
||||
AddressCountSpectrumView, // 粒子计数谱视图
|
||||
EneryCountSpectrumView, // 能量计数谱视图
|
||||
EnergyCountSpectrumView, // 能量计数谱视图
|
||||
CoincidenceParticleEnergySpectrum2DView, // 符合粒子能量2D视图
|
||||
CoincidenceParticleEnergySpectrum3DView, // 符合粒子能量3D视图
|
||||
CountingRateView, // 计数率视图
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ LIBS += -L$$PWD/armadillo/lib -lliblapack
|
|||
|
||||
SOURCES += \
|
||||
$$PWD/CoincidenceSpectrum.cpp \
|
||||
$$PWD/EneryEfficiencyFit.cpp \
|
||||
$$PWD/EnergyEfficiencyFit.cpp \
|
||||
$$PWD/Poly2FindPeaks.cpp \
|
||||
$$PWD/FindPeaksBySvd.cpp \
|
||||
$$PWD/GaussPolyCoe.cpp \
|
||||
|
|
@ -18,7 +18,7 @@ SOURCES += \
|
|||
HEADERS += \
|
||||
$$PWD/AdaptiveSimpsonIntegrate.h \
|
||||
$$PWD/CoincidenceSpectrumProcess.h \
|
||||
$$PWD/EneryEfficiencyFit.h \
|
||||
$$PWD/EnergyEfficiencyFit.h \
|
||||
$$PWD/Poly2FindPeaks.h \
|
||||
$$PWD/FindPeaksBySvd.h \
|
||||
$$PWD/GaussPolyCoe.h \
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include "EneryEfficiencyFit.h"
|
||||
#include "EnergyEfficiencyFit.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace arma;
|
||||
|
||||
|
||||
// 拟合效率-能量曲线,E 能量数据(keV)eps 效率数据(需>0),拟合系数a0~a5
|
||||
arma::vec EneryEfficiencyFit::SemiEmpiricalFit(const arma::vec &E, const arma::vec &eps, int order)
|
||||
arma::vec EnergyEfficiencyFit::SemiEmpiricalFit(const arma::vec &E, const arma::vec &eps, int order)
|
||||
{
|
||||
// 输入数据有效性检查
|
||||
if (E.n_elem != eps.n_elem) {
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
#ifndef ENERYEFFICIENCYFIT_H
|
||||
#define ENERYEFFICIENCYFIT_H
|
||||
#ifndef ENERGYEFFICIENCYFIT_H
|
||||
#define ENERGYEFFICIENCYFIT_H
|
||||
|
||||
#include <armadillo>
|
||||
|
||||
namespace EneryEfficiencyFit
|
||||
namespace EnergyEfficiencyFit
|
||||
{
|
||||
|
||||
// 拟合效率-能量曲线,E 能量数据(keV)eps 效率数据(需>0),拟合系数a0~a5
|
||||
|
|
@ -11,4 +11,4 @@ arma::vec SemiEmpiricalFit(const arma::vec& E, const arma::vec& eps, int order)
|
|||
|
||||
}
|
||||
|
||||
#endif // ENERYEFFICIENCYFIT_H
|
||||
#endif // ENERGYEFFICIENCYFIT_H
|
||||
|
|
@ -232,7 +232,7 @@ double EfficiencyExperimentalCalc(int N, double A, double P, double t)
|
|||
}
|
||||
|
||||
// 光子能量探测效率
|
||||
double EneryEfficiency(double E, const vec &coeffs)
|
||||
double EnergyEfficiency(double E, const vec &coeffs)
|
||||
{
|
||||
if (E <= 0) {
|
||||
throw std::string("能量数据必须为正数!");
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ arma::vec EstimateElectronPeakModelInitialParams(const arma::vec& x, const arma:
|
|||
double EfficiencyExperimentalCalc(int N, double A, double P, double t);
|
||||
// 光子能量探测效率
|
||||
// ln(ε) = a0 + a1*lnE + a2*(lnE)^2 + a3*(lnE)^3 + ... + ai*(lnE)^i
|
||||
double EneryEfficiency(double E, const arma::vec& coeffs) ;
|
||||
double EnergyEfficiency(double E, const arma::vec& coeffs) ;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -55,12 +55,12 @@ ConformitySpectrum::EventFilter(raw_spec_data, conformity_event_time_win)
|
|||
示例参考TestCase中的TestConformitySpectrumEventFilter。
|
||||
|
||||
6、效率刻度
|
||||
使用EneryEfficiencyFit::SemiEmpiricalFit
|
||||
使用EnergyEfficiencyFit::SemiEmpiricalFit
|
||||
在下式中:E 能量数据(keV)eps 效率数据(需>0),拟合结果系数coeff为a0~...a_order
|
||||
vec coeff = EneryEfficiencyFit::SemiEmpiricalFit(E, eps, order);
|
||||
vec coeff = EnergyEfficiencyFit::SemiEmpiricalFit(E, eps, order);
|
||||
拟合结果返回系数[a0, a1, a2, ...]对应:
|
||||
ln(ε) = a0 + a1*lnE + a2*(lnE)^2 + a3*(lnE)^3 + ... + ai*(lnE)^i
|
||||
示例参考TestCase中的TestEneryEfficiencyFit。
|
||||
示例参考TestCase中的TestEnergyEfficiencyFit。
|
||||
在实际使用时注意,数据要求:一次拟合需至少2个标准源数据点,二次拟合需至少3个标准源数据点,数据点数必须大于多项式阶数,
|
||||
数据点越多拟合越稳定效率值需通过实验计算ε=N/(A*P*t)即,确保准确性:N为净峰计数,A为活度,P为分支比,t为测量时间
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "DataCalcProcess/FindPeaksBySvd.h"
|
||||
#include "DataCalcProcess/GaussPolyCoe.h"
|
||||
#include "DataCalcProcess/NolinearLeastSquaresCurveFit.h"
|
||||
#include "EnergyScaleDataModel.h"
|
||||
#include <QDebug>
|
||||
|
||||
using namespace DataProcessWorkPool;
|
||||
|
|
@ -656,23 +657,31 @@ bool AutoFindPeaksTask::processTask()
|
|||
}
|
||||
|
||||
void ChannelEnergyScaleFittingTask::SetData(
|
||||
const FitDataMap& channel_enery_scale_fit_data_map, const QMap<QString, int>& fit_degree_map)
|
||||
const FitDataMap& channel_energy_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->_channel_energy_scale_fit_data_map = channel_energy_scale_fit_data_map;
|
||||
this->_fit_degree_map = fit_degree_map;
|
||||
}
|
||||
|
||||
void ChannelEnergyScaleFittingTask::SetResultDir(const QString &result_dir)
|
||||
{
|
||||
this->_result_dir = result_dir;
|
||||
}
|
||||
|
||||
bool ChannelEnergyScaleFittingTask::IsValidSetWorkParameters() const
|
||||
{
|
||||
return (!this->_channel_enery_scale_fit_data_map.isEmpty()) && (!this->_fit_degree_map.isEmpty()) && DataProcessTask::IsValidSetWorkParameters();
|
||||
return (!this->_channel_energy_scale_fit_data_map.isEmpty()) && (!this->_fit_degree_map.isEmpty())&& (!this->_result_dir.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()) {
|
||||
QDir result_dir(this->_result_dir);
|
||||
const QString& energy_scale_data_filename = result_dir.filePath(QStringLiteral(u"多通道能量刻度拟合.json"));
|
||||
EnergyScaleDataModel energy_scale_data_model(energy_scale_data_filename);
|
||||
|
||||
for (const QString& channel : this->_channel_energy_scale_fit_data_map.keys()) {
|
||||
const QMap<int, QList<double> >& energy_scale_fit_data = this->_channel_energy_scale_fit_data_map.value(channel);
|
||||
if (energy_scale_fit_data.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
int fit_degree = this->_fit_degree_map.value(channel);
|
||||
|
|
@ -680,14 +689,14 @@ bool ChannelEnergyScaleFittingTask::processTask()
|
|||
continue;
|
||||
}
|
||||
std::vector<double> vec_x, vec_y1, vec_y2;
|
||||
for (const int& addr : enery_scale_fit_data.keys()) {
|
||||
for (const int& addr : energy_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]);
|
||||
vec_y1.push_back(energy_scale_fit_data.value(addr)[0]);
|
||||
vec_y2.push_back(energy_scale_fit_data.value(addr)[1]);
|
||||
}
|
||||
std::vector<double> enery_scale_fit_result_coeffs;
|
||||
std::vector<double> energy_scale_fit_result_coeffs;
|
||||
try {
|
||||
enery_scale_fit_result_coeffs = GaussPolyCoe::PolynomialFit(vec_x, vec_y1, fit_degree);
|
||||
energy_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);
|
||||
|
|
@ -702,57 +711,33 @@ bool ChannelEnergyScaleFittingTask::processTask()
|
|||
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;
|
||||
std::vector<std::vector<double> > fit_result_data;
|
||||
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 fit_energy = GaussPolyCoe::Predict(energy_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));
|
||||
std::vector<double> fit_result_item_data;
|
||||
fit_result_item_data.push_back(addr);
|
||||
fit_result_item_data.push_back(set_energy);
|
||||
fit_result_item_data.push_back(fit_energy);
|
||||
fit_result_item_data.push_back(set_energy - fit_energy);
|
||||
fit_result_item_data.push_back(peak_fwhm);
|
||||
fit_result_item_data.push_back(fit_fwhm);
|
||||
fit_result_item_data.push_back(peak_fwhm - fit_fwhm);
|
||||
fit_result_data.push_back(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);
|
||||
energy_scale_data_model.SetEnergyFitDegree(channel, fit_degree);
|
||||
energy_scale_data_model.SetEnergyFitResultCoeffs(channel, energy_scale_fit_result_coeffs);
|
||||
energy_scale_data_model.SetFwhmFitResultCoeffs(channel, std::vector<double>(fwhm_fit_result_coeffs.begin(), fwhm_fit_result_coeffs.end()));
|
||||
energy_scale_data_model.SetFitData(channel, fit_result_data);
|
||||
}
|
||||
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);
|
||||
|
||||
if (!energy_scale_data_model.SaveData()) {
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -110,12 +110,14 @@ namespace DataProcessWorkPool
|
|||
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);
|
||||
void SetData(const FitDataMap& channel_energy_scale_fit_data_map, const QMap<QString, int>& fit_degree_map);
|
||||
void SetResultDir(const QString& result_dir);
|
||||
virtual bool IsValidSetWorkParameters() const override;
|
||||
private:
|
||||
virtual bool processTask() override;
|
||||
private:
|
||||
FitDataMap _channel_enery_scale_fit_data_map;
|
||||
QString _result_dir;
|
||||
FitDataMap _channel_energy_scale_fit_data_map;
|
||||
QMap<QString, int> _fit_degree_map;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
186
src/EnergyScaleDataModel.cpp
Normal file
186
src/EnergyScaleDataModel.cpp
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
#include "EnergyScaleDataModel.h"
|
||||
#include <QJsonDocument>
|
||||
#include <QFile>
|
||||
#include <QVariant>
|
||||
|
||||
EnergyScaleDataModel::EnergyScaleDataModel(const QString& filename) : _data_filename(filename)
|
||||
{
|
||||
_data_filename = filename;
|
||||
if (!_data_filename.isEmpty()) {
|
||||
LoadData();
|
||||
}
|
||||
}
|
||||
|
||||
EnergyScaleDataModel::~EnergyScaleDataModel()
|
||||
{
|
||||
SaveData();
|
||||
}
|
||||
|
||||
void EnergyScaleDataModel::SetDataFilename(const QString& filename)
|
||||
{
|
||||
_data_filename = filename;
|
||||
if (!_data_filename.isEmpty()) {
|
||||
LoadData();
|
||||
}
|
||||
}
|
||||
|
||||
bool EnergyScaleDataModel::LoadData()
|
||||
{
|
||||
QFile json_file(_data_filename);
|
||||
if (!json_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
return false;
|
||||
}
|
||||
QJsonDocument json_doc = QJsonDocument::fromJson(json_file.readAll());
|
||||
json_file.close();
|
||||
_energy_scale_data_map = json_doc.toVariant().toMap();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EnergyScaleDataModel::SaveData()
|
||||
{
|
||||
QJsonDocument energy_scale_fit_result_doc = QJsonDocument::fromVariant(_energy_scale_data_map);;
|
||||
QFile json_file(_data_filename);
|
||||
if (!json_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
return false;
|
||||
}
|
||||
json_file.write(energy_scale_fit_result_doc.toJson());
|
||||
json_file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EnergyScaleDataModel::IsValid()
|
||||
{
|
||||
bool b_is_valid = true;
|
||||
if (this->_data_filename.isEmpty()) {
|
||||
b_is_valid &= false;
|
||||
}
|
||||
for (const QString& channel_name : _energy_scale_data_map.keys()) {
|
||||
const QVariantMap& energy_scale_ch_data_map = _energy_scale_data_map[channel_name].toMap();
|
||||
b_is_valid &= energy_scale_ch_data_map.contains("EnergyFitDegree");
|
||||
b_is_valid &= energy_scale_ch_data_map.contains("EnergyFitResultCoeffs");
|
||||
b_is_valid &= energy_scale_ch_data_map.contains("FwhmFitResultCoeffs");
|
||||
b_is_valid &= energy_scale_ch_data_map.contains("FitData");
|
||||
}
|
||||
return b_is_valid;
|
||||
}
|
||||
|
||||
void EnergyScaleDataModel::SetEnergyFitDegree(const QString& channel_name, int fit_degree)
|
||||
{
|
||||
if (!_energy_scale_data_map.contains(channel_name)) {
|
||||
_energy_scale_data_map[channel_name] = QVariantMap();
|
||||
}
|
||||
QVariantMap energy_scale_ch_data_map = _energy_scale_data_map[channel_name].toMap();
|
||||
if ( fit_degree == 0) {
|
||||
energy_scale_ch_data_map.remove("EnergyFitDegree");
|
||||
} else {
|
||||
energy_scale_ch_data_map["EnergyFitDegree"] = fit_degree;
|
||||
}
|
||||
_energy_scale_data_map[channel_name] = energy_scale_ch_data_map;
|
||||
}
|
||||
|
||||
int EnergyScaleDataModel::GetEnergyFitDegree(const QString& channel_name)
|
||||
{
|
||||
int fit_degree = 0;
|
||||
if (_energy_scale_data_map.contains(channel_name)) {
|
||||
const QVariantMap& energy_scale_ch_data_map = _energy_scale_data_map[channel_name].toMap();
|
||||
fit_degree = energy_scale_ch_data_map.value("EnergyFitDegree", 0).toInt();
|
||||
}
|
||||
return fit_degree;
|
||||
}
|
||||
|
||||
void EnergyScaleDataModel::SetEnergyFitResultCoeffs(const QString& channel_name, std::vector<double> coeffs)
|
||||
{
|
||||
if (!_energy_scale_data_map.contains(channel_name)) {
|
||||
_energy_scale_data_map[channel_name] = QVariantMap();
|
||||
}
|
||||
QVariantList coeffs_list;
|
||||
for (double coeff : coeffs) {
|
||||
coeffs_list.append(coeff);
|
||||
}
|
||||
QVariantMap energy_scale_ch_data_map = _energy_scale_data_map[channel_name].toMap();
|
||||
if ( coeffs_list.empty() ) {
|
||||
energy_scale_ch_data_map.remove("EnergyFitResultCoeffs");
|
||||
} else {
|
||||
energy_scale_ch_data_map["EnergyFitResultCoeffs"] = coeffs_list;
|
||||
}
|
||||
_energy_scale_data_map[channel_name] = energy_scale_ch_data_map;
|
||||
}
|
||||
|
||||
std::vector<double> EnergyScaleDataModel::GetEnergyFitResultCoeffs(const QString& channel_name)
|
||||
{
|
||||
std::vector<double> coeffs;
|
||||
if (_energy_scale_data_map.contains(channel_name)) {
|
||||
const QVariantMap& energy_scale_ch_data_map = _energy_scale_data_map[channel_name].toMap();
|
||||
QVariantList coeffs_list = energy_scale_ch_data_map.value("EnergyFitResultCoeffs", QVariantList()).toList();
|
||||
for (QVariant coeff : coeffs_list) {
|
||||
coeffs.push_back(coeff.toDouble());
|
||||
}
|
||||
}
|
||||
return coeffs;
|
||||
}
|
||||
|
||||
void EnergyScaleDataModel::SetFwhmFitResultCoeffs(const QString& channel_name, std::vector<double> coeffs)
|
||||
{
|
||||
if (!_energy_scale_data_map.contains(channel_name)) {
|
||||
_energy_scale_data_map[channel_name] = QVariantMap();
|
||||
}
|
||||
QVariantList coeffs_list;
|
||||
for (double coeff : coeffs) {
|
||||
coeffs_list.append(coeff);
|
||||
}
|
||||
QVariantMap energy_scale_ch_data_map = _energy_scale_data_map[channel_name].toMap();
|
||||
if ( coeffs_list.empty() ) {
|
||||
energy_scale_ch_data_map.remove("FwhmFitResultCoeffs");
|
||||
} else {
|
||||
energy_scale_ch_data_map["FwhmFitResultCoeffs"] = coeffs_list;
|
||||
}
|
||||
_energy_scale_data_map[channel_name] = energy_scale_ch_data_map;
|
||||
}
|
||||
|
||||
std::vector<double> EnergyScaleDataModel::GetFwhmFitResultCoeffs(const QString& channel_name)
|
||||
{
|
||||
std::vector<double> coeffs;
|
||||
if (_energy_scale_data_map.contains(channel_name)) {
|
||||
const QVariantMap& energy_scale_ch_data_map = _energy_scale_data_map[channel_name].toMap();
|
||||
QVariantList coeffs_list = energy_scale_ch_data_map.value("FwhmFitResultCoeffs", QVariantList()).toList();
|
||||
for (QVariant coeff : coeffs_list) {
|
||||
coeffs.push_back(coeff.toDouble());
|
||||
}
|
||||
}
|
||||
return coeffs;
|
||||
}
|
||||
|
||||
void EnergyScaleDataModel::SetFitData(const QString& channel_name, const std::vector<std::vector<double> >& fit_data)
|
||||
{
|
||||
if (!_energy_scale_data_map.contains(channel_name)) {
|
||||
_energy_scale_data_map[channel_name] = QVariantMap();
|
||||
}
|
||||
QVariantList fit_data_list;
|
||||
for (std::vector<double> fit : fit_data) {
|
||||
QVariantList fit_list;
|
||||
for (double value : fit) {
|
||||
fit_list.append(value);
|
||||
}
|
||||
fit_data_list.append(QVariant(fit_list));
|
||||
}
|
||||
QVariantMap energy_scale_ch_data_map = _energy_scale_data_map[channel_name].toMap();
|
||||
energy_scale_ch_data_map["FitData"] = fit_data_list;
|
||||
_energy_scale_data_map[channel_name] = energy_scale_ch_data_map;
|
||||
}
|
||||
|
||||
std::vector<std::vector<double> > EnergyScaleDataModel::GetFitData(const QString& channel_name)
|
||||
{
|
||||
std::vector<std::vector<double> > fit_data;
|
||||
if (_energy_scale_data_map.contains(channel_name)) {
|
||||
const QVariantMap& energy_scale_ch_data_map = _energy_scale_data_map[channel_name].toMap();
|
||||
QVariantList fit_data_list = energy_scale_ch_data_map.value("FitData", QVariantList()).toList();
|
||||
for (QVariant fit_list : fit_data_list) {
|
||||
std::vector<double> fit;
|
||||
for (QVariant value : fit_list.toList()) {
|
||||
fit.push_back(value.toDouble());
|
||||
}
|
||||
fit_data.push_back(fit);
|
||||
}
|
||||
}
|
||||
return fit_data;
|
||||
}
|
||||
36
src/EnergyScaleDataModel.h
Normal file
36
src/EnergyScaleDataModel.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef ENERGYSCALEDATAMODEL_H
|
||||
#define ENERGYSCALEDATAMODEL_H
|
||||
|
||||
#include <QString>
|
||||
#include <QVariantMap>
|
||||
|
||||
class EnergyScaleDataModel
|
||||
{
|
||||
public:
|
||||
EnergyScaleDataModel(const QString& filename = QString());
|
||||
~EnergyScaleDataModel();
|
||||
|
||||
void SetDataFilename(const QString& filename);
|
||||
|
||||
bool LoadData();
|
||||
bool SaveData();
|
||||
bool IsValid();
|
||||
|
||||
void SetEnergyFitDegree(const QString& channel_name, int fit_degree);
|
||||
int GetEnergyFitDegree(const QString& channel_name);
|
||||
|
||||
void SetEnergyFitResultCoeffs(const QString& channel_name, std::vector<double> coeffs);
|
||||
std::vector<double> GetEnergyFitResultCoeffs(const QString& channel_name);
|
||||
|
||||
void SetFwhmFitResultCoeffs(const QString& channel_name, std::vector<double> coeffs);
|
||||
std::vector<double> GetFwhmFitResultCoeffs(const QString& channel_name);
|
||||
|
||||
void SetFitData(const QString& channel_name, const std::vector<std::vector<double> >& fit_data);
|
||||
std::vector<std::vector<double> > GetFitData(const QString& channel_name);
|
||||
|
||||
private:
|
||||
QString _data_filename;
|
||||
QVariantMap _energy_scale_data_map;
|
||||
};
|
||||
|
||||
#endif // ENERGYSCALEDATAMODEL_H
|
||||
14
src/EnergyScaleForm.cpp
Normal file
14
src/EnergyScaleForm.cpp
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#include "EnergyScaleForm.h"
|
||||
#include "ui_EnergyScaleForm.h"
|
||||
|
||||
EnergyScaleForm::EnergyScaleForm(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::EnergyScaleForm)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
EnergyScaleForm::~EnergyScaleForm()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
22
src/EnergyScaleForm.h
Normal file
22
src/EnergyScaleForm.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef ENERGYSCALEFORM_H
|
||||
#define ENERGYSCALEFORM_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class EnergyScaleForm;
|
||||
}
|
||||
|
||||
class EnergyScaleForm : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EnergyScaleForm(QWidget *parent = nullptr);
|
||||
~EnergyScaleForm();
|
||||
|
||||
private:
|
||||
Ui::EnergyScaleForm *ui;
|
||||
};
|
||||
|
||||
#endif // ENERGYSCALEFORM_H
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EneryScaleForm</class>
|
||||
<widget class="QWidget" name="EneryScaleForm">
|
||||
<class>EnergyScaleForm</class>
|
||||
<widget class="QWidget" name="EnergyScaleForm">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
#include "EneryScaleForm.h"
|
||||
#include "ui_EneryScaleForm.h"
|
||||
|
||||
EneryScaleForm::EneryScaleForm(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::EneryScaleForm)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
EneryScaleForm::~EneryScaleForm()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
#ifndef ENERYSCALEFORM_H
|
||||
#define ENERYSCALEFORM_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class EneryScaleForm;
|
||||
}
|
||||
|
||||
class EneryScaleForm : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EneryScaleForm(QWidget *parent = nullptr);
|
||||
~EneryScaleForm();
|
||||
|
||||
private:
|
||||
Ui::EneryScaleForm *ui;
|
||||
};
|
||||
|
||||
#endif // ENERYSCALEFORM_H
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
#include "FloatingDockContainer.h"
|
||||
#include "AboutDlg.h"
|
||||
#include "DataProcessWorkPool.h"
|
||||
#include "EneryScaleForm.h"
|
||||
#include "EnergyScaleForm.h"
|
||||
#include "MeasureAnalysisHistoryForm.h"
|
||||
#include "MeasureAnalysisProjectModel.h"
|
||||
#include "MeasureDeviceParamsCfgForm.h"
|
||||
|
|
@ -225,16 +225,16 @@ void MainWindow::initAction()
|
|||
device_cfg_mrg_dlg.setLayout(hlayout);
|
||||
device_cfg_mrg_dlg.exec();
|
||||
});
|
||||
connect(ui->action_enery_scale_mrg, &QAction::triggered, []() {
|
||||
QDialog enery_scale_mrg_dlg;
|
||||
enery_scale_mrg_dlg.setObjectName("EneryScaleFormDlg");
|
||||
enery_scale_mrg_dlg.setWindowTitle(QStringLiteral(u"能量刻度管理"));
|
||||
enery_scale_mrg_dlg.setWindowFlags(enery_scale_mrg_dlg.windowFlags() | Qt::WindowMaximizeButtonHint);
|
||||
EneryScaleForm* enery_scale_mrg_form = new EneryScaleForm(&enery_scale_mrg_dlg);
|
||||
connect(ui->action_energy_scale_mrg, &QAction::triggered, []() {
|
||||
QDialog energy_scale_mrg_dlg;
|
||||
energy_scale_mrg_dlg.setObjectName("EnergyScaleFormDlg");
|
||||
energy_scale_mrg_dlg.setWindowTitle(QStringLiteral(u"能量刻度管理"));
|
||||
energy_scale_mrg_dlg.setWindowFlags(energy_scale_mrg_dlg.windowFlags() | Qt::WindowMaximizeButtonHint);
|
||||
EnergyScaleForm* energy_scale_mrg_form = new EnergyScaleForm(&energy_scale_mrg_dlg);
|
||||
QHBoxLayout* hlayout = new QHBoxLayout;
|
||||
hlayout->addWidget(enery_scale_mrg_form);
|
||||
enery_scale_mrg_dlg.setLayout(hlayout);
|
||||
enery_scale_mrg_dlg.exec();
|
||||
hlayout->addWidget(energy_scale_mrg_form);
|
||||
energy_scale_mrg_dlg.setLayout(hlayout);
|
||||
energy_scale_mrg_dlg.exec();
|
||||
});
|
||||
connect(ui->action_about_info, &QAction::triggered, []() {
|
||||
AboutDlg about_dlg;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
</property>
|
||||
<addaction name="action_device_connect_cfg"/>
|
||||
<addaction name="action_device_config_mrg"/>
|
||||
<addaction name="action_enery_scale_mrg"/>
|
||||
<addaction name="action_energy_scale_mrg"/>
|
||||
<addaction name="action_efficiency_scale_mrg"/>
|
||||
<addaction name="action_roi"/>
|
||||
</widget>
|
||||
|
|
@ -101,7 +101,7 @@
|
|||
<bool>false</bool>
|
||||
</attribute>
|
||||
<addaction name="action_device_config_mrg"/>
|
||||
<addaction name="action_enery_scale_mrg"/>
|
||||
<addaction name="action_energy_scale_mrg"/>
|
||||
<addaction name="action_efficiency_scale_mrg"/>
|
||||
<addaction name="action_roi"/>
|
||||
</widget>
|
||||
|
|
@ -158,7 +158,7 @@
|
|||
<string>设备测量参数配置管理</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_enery_scale_mrg">
|
||||
<action name="action_energy_scale_mrg">
|
||||
<property name="text">
|
||||
<string>能量刻度管理</string>
|
||||
</property>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,393 @@
|
|||
#include "BatchEnergyScaleDialog.h"
|
||||
#include "ui_BatchEnergyScaleDialog.h"
|
||||
#include <QDoubleSpinBox>
|
||||
#include "DataProcessWorkPool.h"
|
||||
#include "GlobalDefine.h"
|
||||
#include "MeasureAnalysisProjectModel.h"
|
||||
#include <QDir>
|
||||
#include <QMessageBox>
|
||||
#include "EnergyScaleDataModel.h"
|
||||
#include <QDebug>
|
||||
|
||||
BatchEnergyScaleDialog::BatchEnergyScaleDialog(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::BatchEnergyScaleDialog)
|
||||
, _energy_scale_data_model(std::make_unique<EnergyScaleDataModel>())
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
this->setWindowTitle(QString(QStringLiteral(u"多通道能量刻度")));
|
||||
this->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
|
||||
this->setWindowModality(Qt::WindowModal);
|
||||
this->setModal(false);
|
||||
|
||||
ui->tablew_process_data->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
ui->tablew_process_data->horizontalHeader()->setSectionResizeMode(
|
||||
ui->tablew_process_data->columnCount() - 1, QHeaderView::ResizeToContents);
|
||||
ui->tablew_process_data->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
|
||||
ui->filter_set_energy_combo_box->addItem(QStringLiteral(u"所有设置能量"));
|
||||
|
||||
auto filterFunc = [this](){
|
||||
ui->tablew_process_data->setCurrentItem(nullptr);
|
||||
auto row_count = ui->tablew_process_data->rowCount();
|
||||
const QString& channel_filter_text = ui->filter_channel_combo_box->currentText();
|
||||
const QString& set_energy_filter_text = ui->filter_set_energy_combo_box->currentText();
|
||||
for (int i = row_count - 1; i >= 0; i--) {
|
||||
const QString& channel = ui->tablew_process_data->item(i, 0)->text();
|
||||
const QString& set_energy = ui->tablew_process_data->item(i, 2)->text();
|
||||
bool is_match_channel = false;
|
||||
if (channel_filter_text != QStringLiteral(u"所有通道")) {
|
||||
is_match_channel = (channel_filter_text == channel) ? false : true;
|
||||
}
|
||||
bool is_match_set_energy = false;
|
||||
if (set_energy_filter_text != QStringLiteral(u"所有设置能量")) {
|
||||
is_match_set_energy = (set_energy_filter_text == set_energy) ? false : true;
|
||||
}
|
||||
bool is_hidden = is_match_channel || is_match_set_energy;
|
||||
ui->tablew_process_data->setRowHidden(i, is_hidden);
|
||||
}
|
||||
};
|
||||
connect(ui->filter_channel_combo_box, &QComboBox::currentTextChanged, filterFunc);
|
||||
connect(ui->filter_set_energy_combo_box, &QComboBox::currentTextChanged, filterFunc);
|
||||
|
||||
connect(ui->btn_all_select, &QPushButton::clicked, [this](){
|
||||
ui->tablew_process_data->setCurrentItem(nullptr);
|
||||
auto row_count = ui->tablew_process_data->rowCount();
|
||||
for (int i = 0; i < row_count; ++i) {
|
||||
if (ui->tablew_process_data->isRowHidden(i)) {
|
||||
continue;
|
||||
}
|
||||
auto item = ui->tablew_process_data->item(i, 0);
|
||||
if (item) {
|
||||
item->setCheckState(Qt::Checked);
|
||||
}
|
||||
}
|
||||
});
|
||||
connect(ui->btn_reserve_select, &QPushButton::clicked, [this](){
|
||||
ui->tablew_process_data->setCurrentItem(nullptr);
|
||||
auto row_count = ui->tablew_process_data->rowCount();
|
||||
for (int i = 0; i < row_count - 1; i++) {
|
||||
if (ui->tablew_process_data->isRowHidden(i)) {
|
||||
continue;
|
||||
}
|
||||
auto item = ui->tablew_process_data->item(i, 0);
|
||||
if (item) {
|
||||
Qt::CheckState check_state = (item->checkState() == Qt::Checked) ? Qt::Unchecked : Qt::Checked;
|
||||
item->setCheckState(check_state);
|
||||
}
|
||||
}
|
||||
});
|
||||
connect(ui->btn_remove_selected, &QPushButton::clicked, [this](){
|
||||
auto row_count = ui->tablew_process_data->rowCount();
|
||||
for (int row = row_count - 1; row >= 0; --row) {
|
||||
QTableWidgetItem* item = ui->tablew_process_data->item(row, 0);
|
||||
if (Qt::Unchecked == item->checkState())
|
||||
continue;
|
||||
QPushButton* btn_remove_row = dynamic_cast<QPushButton*>(ui->tablew_process_data->cellWidget(row, 8));
|
||||
if (btn_remove_row) {
|
||||
ui->tablew_process_data->removeRow(row);
|
||||
btn_remove_row->deleteLater();
|
||||
this->updateSetEnergyFilter();
|
||||
}
|
||||
}
|
||||
if ( row_count > ui->tablew_process_data->rowCount() ) {
|
||||
this->saveEnergyScaleData();
|
||||
}
|
||||
});
|
||||
connect(ui->btn_fit, &QPushButton::clicked, this, &BatchEnergyScaleDialog::onFitBtnClickedProcess);
|
||||
connect(ui->btn_save, &QPushButton::clicked, [this](){
|
||||
this->saveEnergyScaleData();
|
||||
});
|
||||
connect(ui->btn_apply, &QPushButton::clicked, [this](){
|
||||
this->applyEnergyScaleFitResultData();
|
||||
});
|
||||
}
|
||||
|
||||
BatchEnergyScaleDialog::~BatchEnergyScaleDialog()
|
||||
{
|
||||
qDebug() << "~BatchEnergyScaleDialog";
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void BatchEnergyScaleDialog::SetProjectName(const QString &project_name)
|
||||
{
|
||||
this->_project_name = project_name;
|
||||
}
|
||||
|
||||
void BatchEnergyScaleDialog::SetChannelNameList(const QStringList &ch_name_list)
|
||||
{
|
||||
this->_channel_name_list = ch_name_list;
|
||||
ui->filter_channel_combo_box->clear();
|
||||
ui->filter_channel_combo_box->addItem(QString(QStringLiteral(u"所有通道")));
|
||||
ui->filter_channel_combo_box->addItems(ch_name_list);
|
||||
}
|
||||
|
||||
void BatchEnergyScaleDialog::SetPeakResultDataModel(QAbstractTableModel* peaks_result_model)
|
||||
{
|
||||
_peaks_result_model = peaks_result_model;
|
||||
}
|
||||
|
||||
void BatchEnergyScaleDialog::SetViewWorkspace(const QString &workspace)
|
||||
{
|
||||
this->_workspace = workspace;
|
||||
|
||||
QDir workspace_dir(this->_workspace);
|
||||
const QString& energy_scale_data_filename = workspace_dir.filePath(QStringLiteral(u"多通道能量刻度拟合.json"));
|
||||
this->_energy_scale_data_model->SetDataFilename(energy_scale_data_filename);
|
||||
}
|
||||
|
||||
void BatchEnergyScaleDialog::onSelectedScaleRange(double min, double max)
|
||||
{
|
||||
if (!_peaks_result_model) {
|
||||
return;
|
||||
}
|
||||
QDialog set_energy_dlg(this, Qt::Dialog | Qt::WindowCloseButtonHint);
|
||||
set_energy_dlg.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
set_energy_dlg.setFixedSize(300, 100);
|
||||
set_energy_dlg.setSizeGripEnabled(false);
|
||||
set_energy_dlg.setWindowTitle(QString(QStringLiteral(u"设置刻度能量")));
|
||||
|
||||
QLabel* set_energy_label = new QLabel(QString(QStringLiteral(u"刻度能量:")));
|
||||
QDoubleSpinBox* spinbox_set_energy = new QDoubleSpinBox();
|
||||
spinbox_set_energy->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
spinbox_set_energy->setRange(0.0f, std::numeric_limits<double>::max());
|
||||
spinbox_set_energy->setSingleStep(1.0f);
|
||||
spinbox_set_energy->setDecimals(3);
|
||||
QHBoxLayout* layout_input = new QHBoxLayout();
|
||||
layout_input->addWidget(set_energy_label);
|
||||
layout_input->addWidget(spinbox_set_energy);
|
||||
|
||||
QPushButton* btn_ok = new QPushButton(QStringLiteral(u"确认"));
|
||||
connect(btn_ok, &QPushButton::clicked, &set_energy_dlg, &QDialog::accept);
|
||||
QPushButton* btn_cancel = new QPushButton(QStringLiteral(u"取消"));
|
||||
connect(btn_cancel, &QPushButton::clicked, &set_energy_dlg, &QDialog::reject);
|
||||
QHBoxLayout* layout_btns = new QHBoxLayout();
|
||||
layout_btns->addStretch();
|
||||
layout_btns->addWidget(btn_ok);
|
||||
layout_btns->addWidget(btn_cancel);
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(&set_energy_dlg);
|
||||
layout->addLayout(layout_input);
|
||||
layout->addStretch();
|
||||
layout->addLayout(layout_btns);
|
||||
|
||||
if (QDialog::Accepted == set_energy_dlg.exec()) {
|
||||
bool b_has_new_data = false;
|
||||
double set_energy = spinbox_set_energy->value();
|
||||
for (int i = 0; i < _peaks_result_model->rowCount(); i++) {
|
||||
const QString& channel_name = _peaks_result_model->data(_peaks_result_model->index(i, 0)).toString();
|
||||
int peak_pos = _peaks_result_model->data(_peaks_result_model->index(i, 1)).toInt();
|
||||
int peak_fwhm = _peaks_result_model->data(_peaks_result_model->index(i, 6)).toInt();
|
||||
if (min < peak_pos && peak_pos < max ) {
|
||||
int row = ui->tablew_process_data->rowCount();
|
||||
ui->tablew_process_data->insertRow(row);
|
||||
ui->tablew_process_data->setItem(row, 0, new QTableWidgetItem(channel_name));
|
||||
ui->tablew_process_data->item(row, 0)->setCheckState(Qt::Unchecked);
|
||||
ui->tablew_process_data->setItem(row, 1, new QTableWidgetItem(QString::number(peak_pos)));
|
||||
ui->tablew_process_data->setItem(row, 2, new QTableWidgetItem(QString::number(set_energy)));
|
||||
ui->tablew_process_data->setItem(row, 3, new QTableWidgetItem);
|
||||
ui->tablew_process_data->setItem(row, 4, new QTableWidgetItem);
|
||||
ui->tablew_process_data->setItem(row, 5, new QTableWidgetItem(QString::number(peak_fwhm)));
|
||||
ui->tablew_process_data->setItem(row, 6, new QTableWidgetItem);
|
||||
ui->tablew_process_data->setItem(row, 7, new QTableWidgetItem);
|
||||
QTableWidgetItem* item = new QTableWidgetItem;
|
||||
ui->tablew_process_data->setItem(row, 8, item);
|
||||
QPushButton* btn_remove_row = new QPushButton(QStringLiteral(u"删除"));
|
||||
btn_remove_row->setMaximumWidth(35);
|
||||
connect(btn_remove_row, &QPushButton::clicked, [this, item, btn_remove_row]() {
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
int remove_row = item->row();
|
||||
ui->tablew_process_data->removeRow(remove_row);
|
||||
btn_remove_row->deleteLater();
|
||||
this->updateSetEnergyFilter();
|
||||
this->saveEnergyScaleData();
|
||||
});
|
||||
ui->tablew_process_data->setCellWidget(row, 8, btn_remove_row);
|
||||
this->insertSetEnergyValueToFilter(set_energy);
|
||||
b_has_new_data = true;
|
||||
}
|
||||
}
|
||||
if (b_has_new_data) {
|
||||
this->saveEnergyScaleData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BatchEnergyScaleDialog::insertSetEnergyValueToFilter(double energy)
|
||||
{
|
||||
int count = 0;
|
||||
int index = ui->filter_set_energy_combo_box->findText(QString::number(energy));
|
||||
if (index >= 0) {
|
||||
count = ui->filter_set_energy_combo_box->itemData(index).toInt() + 1;
|
||||
ui->filter_set_energy_combo_box->setItemData(index, count);
|
||||
} else {
|
||||
ui->filter_set_energy_combo_box->addItem(QString::number(energy), count);
|
||||
}
|
||||
}
|
||||
|
||||
void BatchEnergyScaleDialog::updateSetEnergyFilter()
|
||||
{
|
||||
int item_count = ui->filter_set_energy_combo_box->count();
|
||||
for (int index = item_count - 1; index > 0; --index) {
|
||||
int count = ui->filter_set_energy_combo_box->itemData(index).toInt();
|
||||
count = count - 1;
|
||||
ui->filter_set_energy_combo_box->setItemData(index, count);
|
||||
if (0 == count) {
|
||||
int current_index = ui->filter_set_energy_combo_box->currentIndex();
|
||||
if (index == current_index) {
|
||||
ui->filter_set_energy_combo_box->setCurrentIndex(0);
|
||||
}
|
||||
ui->filter_set_energy_combo_box->removeItem(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BatchEnergyScaleDialog::LoadEnergyScaleData()
|
||||
{
|
||||
auto row_count = ui->tablew_process_data->rowCount();
|
||||
for (int row = row_count - 1; row >= 0; --row) {
|
||||
QPushButton* btn_remove_row = dynamic_cast<QPushButton*>(ui->tablew_process_data->cellWidget(row, 8));
|
||||
if (btn_remove_row) {
|
||||
ui->tablew_process_data->removeRow(row);
|
||||
btn_remove_row->deleteLater();
|
||||
this->updateSetEnergyFilter();
|
||||
}
|
||||
}
|
||||
if (!this->_energy_scale_data_model->LoadData()) {
|
||||
return;
|
||||
}
|
||||
for (const QString& channel_name : this->_channel_name_list) {
|
||||
std::vector<std::vector<double>> energy_scale_fit_data_list = this->_energy_scale_data_model->GetFitData(channel_name);
|
||||
for (const std::vector<double>& fit_data_item : energy_scale_fit_data_list) {
|
||||
int row = ui->tablew_process_data->rowCount();
|
||||
ui->tablew_process_data->insertRow(row);
|
||||
ui->tablew_process_data->setItem(row, 0, new QTableWidgetItem(channel_name));
|
||||
ui->tablew_process_data->item(row, 0)->setCheckState(Qt::Unchecked);
|
||||
ui->tablew_process_data->setItem(row, 1, new QTableWidgetItem(QString::number(fit_data_item[0])));
|
||||
ui->tablew_process_data->setItem(row, 2, new QTableWidgetItem(QString::number(fit_data_item[1])));
|
||||
ui->tablew_process_data->setItem(row, 3, new QTableWidgetItem(QString::number(fit_data_item[2])));
|
||||
ui->tablew_process_data->setItem(row, 4, new QTableWidgetItem(QString::number(fit_data_item[3])));
|
||||
ui->tablew_process_data->setItem(row, 5, new QTableWidgetItem(QString::number(fit_data_item[4])));
|
||||
ui->tablew_process_data->setItem(row, 6, new QTableWidgetItem(QString::number(fit_data_item[5])));
|
||||
ui->tablew_process_data->setItem(row, 7, new QTableWidgetItem(QString::number(fit_data_item[6])));
|
||||
QTableWidgetItem* item = new QTableWidgetItem;
|
||||
ui->tablew_process_data->setItem(row, 8, item);
|
||||
QPushButton* btn_remove_row = new QPushButton(QStringLiteral(u"删除"));
|
||||
btn_remove_row->setMaximumWidth(35);
|
||||
connect(btn_remove_row, &QPushButton::clicked, [this, item, btn_remove_row]() {
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
int remove_row = item->row();
|
||||
ui->tablew_process_data->removeRow(remove_row);
|
||||
btn_remove_row->deleteLater();
|
||||
this->updateSetEnergyFilter();
|
||||
this->saveEnergyScaleData();
|
||||
});
|
||||
ui->tablew_process_data->setCellWidget(row, 8, btn_remove_row);
|
||||
this->insertSetEnergyValueToFilter(fit_data_item[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BatchEnergyScaleDialog::saveEnergyScaleData()
|
||||
{
|
||||
QMap<QString, std::vector<std::vector<double> > > fit_data;
|
||||
for (int i = 0; i < ui->tablew_process_data->rowCount(); i++) {
|
||||
std::vector<double> fit_data_item;
|
||||
const QString& channel_name = ui->tablew_process_data->item(i, 0)->text();
|
||||
double peak_pos_addr = ui->tablew_process_data->item(i, 1)->text().toDouble();
|
||||
double set_energy = ui->tablew_process_data->item(i, 2)->text().toDouble();
|
||||
double fit_energy = ui->tablew_process_data->item(i, 3)->text().toDouble();
|
||||
double energy_diff = ui->tablew_process_data->item(i, 4)->text().toDouble();
|
||||
double peak_fwhm = ui->tablew_process_data->item(i, 5)->text().toDouble();
|
||||
double fit_fwhm = ui->tablew_process_data->item(i, 6)->text().toDouble();
|
||||
double fwhm_diff = ui->tablew_process_data->item(i, 7)->text().toDouble();
|
||||
fit_data_item.push_back(peak_pos_addr);
|
||||
fit_data_item.push_back(set_energy);
|
||||
fit_data_item.push_back(fit_energy);
|
||||
fit_data_item.push_back(energy_diff);
|
||||
fit_data_item.push_back(peak_fwhm);
|
||||
fit_data_item.push_back(fit_fwhm);
|
||||
fit_data_item.push_back(fwhm_diff);
|
||||
fit_data[channel_name].push_back(fit_data_item);
|
||||
}
|
||||
for (const QString& channel_name : fit_data.keys()) {
|
||||
this->_energy_scale_data_model->SetFitData(channel_name, fit_data[channel_name]);
|
||||
this->_energy_scale_data_model->SetEnergyFitDegree(channel_name, 0);
|
||||
this->_energy_scale_data_model->SetEnergyFitResultCoeffs(channel_name, {});
|
||||
this->_energy_scale_data_model->SetFwhmFitResultCoeffs(channel_name, {});
|
||||
}
|
||||
this->_energy_scale_data_model->SaveData();
|
||||
}
|
||||
|
||||
void BatchEnergyScaleDialog::onFitBtnClickedProcess()
|
||||
{
|
||||
QMap<QString, int> fit_degree_map;
|
||||
DataProcessWorkPool::ChannelEnergyScaleFittingTask::FitDataMap channel_energy_scale_fit_data_map;
|
||||
for (int i = 0; i < ui->tablew_process_data->rowCount(); i++) {
|
||||
const QString& channel_name = ui->tablew_process_data->item(i, 0)->text();
|
||||
int peak_pos = ui->tablew_process_data->item(i, 1)->text().toInt();
|
||||
double energy = ui->tablew_process_data->item(i, 2)->text().toDouble();
|
||||
int peak_fwhm = ui->tablew_process_data->item(i, 5)->text().toInt();
|
||||
channel_energy_scale_fit_data_map[channel_name].insert(peak_pos, QList<double>() << energy << peak_fwhm);
|
||||
fit_degree_map[channel_name] = 1;
|
||||
}
|
||||
QStringList data_except_channel_name_list;
|
||||
for (auto it = channel_energy_scale_fit_data_map.begin(); it != channel_energy_scale_fit_data_map.end(); ++it) {
|
||||
const QString& channel_name = it.key();
|
||||
const QMap<int, QList<double> >& fit_data = it.value();
|
||||
if (fit_data.size() < 2) {
|
||||
data_except_channel_name_list << channel_name;
|
||||
}
|
||||
}
|
||||
if (data_except_channel_name_list.size() > 0) {
|
||||
const QString& warn_msg = QStringLiteral(u"请为以下通道设置拟合数据:%1").arg(data_except_channel_name_list.join(QStringLiteral(u",")));
|
||||
LOG_WARN(warn_msg);
|
||||
QMessageBox::warning(this, QStringLiteral(u"警告"), warn_msg);
|
||||
return;
|
||||
}
|
||||
if (!channel_energy_scale_fit_data_map.empty()) {
|
||||
ui->btn_apply->setEnabled(false);
|
||||
auto channel_erergy_scale_fit_task = new DataProcessWorkPool::ChannelEnergyScaleFittingTask;
|
||||
channel_erergy_scale_fit_task->SetResultDir(this->_workspace);
|
||||
channel_erergy_scale_fit_task->SetData(channel_energy_scale_fit_data_map, fit_degree_map);
|
||||
channel_erergy_scale_fit_task->SetFinishedNotifier(this, "onEnergyScaleFitFinished", this->_project_name);
|
||||
channel_erergy_scale_fit_task->StartTask();
|
||||
}
|
||||
}
|
||||
|
||||
void BatchEnergyScaleDialog::onEnergyScaleFitFinished(const QString &project_name)
|
||||
{
|
||||
Q_UNUSED(project_name);
|
||||
this->LoadEnergyScaleData();
|
||||
}
|
||||
|
||||
void BatchEnergyScaleDialog::applyEnergyScaleFitResultData()
|
||||
{
|
||||
if ( this->_energy_scale_data_model->IsValid() ) {
|
||||
MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(this->_project_name);
|
||||
if (project_model == nullptr) {
|
||||
return;
|
||||
}
|
||||
QDir project_dir(project_model->GetProjectDir());
|
||||
const QString& energy_scale_data_filename = project_dir.filePath(QStringLiteral(u"能量刻度.json"));
|
||||
QDir result_dir(this->_workspace);
|
||||
const QString& energy_scale_result_filename = result_dir.filePath(QStringLiteral(u"多通道能量刻度拟合.json"));
|
||||
if (QFile::copy(energy_scale_result_filename, energy_scale_data_filename)) {
|
||||
project_model->SetEnergyScaleFilename(energy_scale_data_filename);
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void BatchEnergyScaleDialog::energyScaleDataChange()
|
||||
{
|
||||
this->_is_fit_finished = false;
|
||||
ui->btn_apply->setEnabled(false);
|
||||
}
|
||||
|
||||
void BatchEnergyScaleDialog::closeEvent(QCloseEvent *e)
|
||||
{
|
||||
emit close();
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef BATCHENERGYSCALEDIALOG_H
|
||||
#define BATCHENERGYSCALEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QAbstractTableModel;
|
||||
class EnergyScaleDataModel;
|
||||
|
||||
namespace Ui {
|
||||
class BatchEnergyScaleDialog;
|
||||
}
|
||||
|
||||
class BatchEnergyScaleDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BatchEnergyScaleDialog(QWidget *parent = nullptr);
|
||||
~BatchEnergyScaleDialog();
|
||||
|
||||
void SetProjectName(const QString& project_name);
|
||||
void SetChannelNameList(const QStringList& ch_name_list);
|
||||
void SetPeakResultDataModel(QAbstractTableModel *peaks_result_model);
|
||||
void SetViewWorkspace(const QString& workspace);
|
||||
void LoadEnergyScaleData();
|
||||
|
||||
public slots:
|
||||
void onSelectedScaleRange(double min, double max);
|
||||
void onFitBtnClickedProcess();
|
||||
private slots:
|
||||
void onEnergyScaleFitFinished(const QString& project_name);
|
||||
|
||||
private:
|
||||
void insertSetEnergyValueToFilter(double energy);
|
||||
void updateSetEnergyFilter();
|
||||
void saveEnergyScaleData();
|
||||
void applyEnergyScaleFitResultData();
|
||||
void energyScaleDataChange();
|
||||
|
||||
signals:
|
||||
void close();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *e);
|
||||
|
||||
private:
|
||||
Ui::BatchEnergyScaleDialog *ui;
|
||||
QString _project_name;
|
||||
QStringList _channel_name_list;
|
||||
QString _workspace;
|
||||
QAbstractTableModel* _peaks_result_model;
|
||||
bool _is_fit_finished = false;
|
||||
std::unique_ptr<EnergyScaleDataModel> _energy_scale_data_model;
|
||||
};
|
||||
|
||||
#endif // BATCHENERGYSCALEDIALOG_H
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BatchEneryScaleDialog</class>
|
||||
<widget class="QDialog" name="BatchEneryScaleDialog">
|
||||
<class>BatchEnergyScaleDialog</class>
|
||||
<widget class="QDialog" name="BatchEnergyScaleDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
|
|
@ -15,10 +15,7 @@
|
|||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
|
|
@ -36,52 +33,60 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_channel">
|
||||
<widget class="QPushButton" name="btn_remove_selected">
|
||||
<property name="text">
|
||||
<string>筛选通道:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="filter_channel_combo_box">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
<string>删除选择</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_enery">
|
||||
<property name="text">
|
||||
<string>筛选设置能量:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_channel">
|
||||
<property name="text">
|
||||
<string>筛选通道:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="filter_channel_combo_box">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="filter_set_enery_combo_box">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_energy">
|
||||
<property name="text">
|
||||
<string>筛选设置能量:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="filter_set_energy_combo_box">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</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">
|
||||
|
|
@ -89,25 +94,36 @@
|
|||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
<width>13</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_fit">
|
||||
<property name="text">
|
||||
<string>拟合</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_save">
|
||||
<property name="text">
|
||||
<string>保存</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_fit">
|
||||
<property name="text">
|
||||
<string>拟合</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_save">
|
||||
<property name="text">
|
||||
<string>保存</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_apply">
|
||||
<property name="text">
|
||||
<string>应用</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
|
@ -1,333 +0,0 @@
|
|||
#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)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::BatchEneryScaleDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->setWindowTitle(QString(QStringLiteral(u"多通道能量刻度")));
|
||||
this->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
|
||||
this->setWindowModality(Qt::WindowModal);
|
||||
this->setModal(false);
|
||||
|
||||
ui->tablew_process_data->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
ui->tablew_process_data->horizontalHeader()->setSectionResizeMode(
|
||||
ui->tablew_process_data->columnCount() - 1, QHeaderView::ResizeToContents);
|
||||
ui->tablew_process_data->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
|
||||
ui->filter_set_enery_combo_box->addItem(QStringLiteral(u"所有设置能量"));
|
||||
auto filterFunc = [this](){
|
||||
ui->tablew_process_data->setCurrentItem(nullptr);
|
||||
auto row_count = ui->tablew_process_data->rowCount();
|
||||
const QString& channel_filter_text = ui->filter_channel_combo_box->currentText();
|
||||
const QString& set_enery_filter_text = ui->filter_set_enery_combo_box->currentText();
|
||||
for (int i = row_count - 1; i >= 0; i--) {
|
||||
const QString& channel = ui->tablew_process_data->item(i, 0)->text();
|
||||
const QString& set_enery = ui->tablew_process_data->item(i, 2)->text();
|
||||
bool is_match_channel = false;
|
||||
if (channel_filter_text != QStringLiteral(u"所有通道")) {
|
||||
is_match_channel = (channel_filter_text == channel) ? false : true;
|
||||
}
|
||||
bool is_match_set_enery = false;
|
||||
if (set_enery_filter_text != QStringLiteral(u"所有设置能量")) {
|
||||
is_match_set_enery = (set_enery_filter_text == set_enery) ? false : true;
|
||||
}
|
||||
bool is_hidden = is_match_channel || is_match_set_enery;
|
||||
ui->tablew_process_data->setRowHidden(i, is_hidden);
|
||||
}
|
||||
};
|
||||
connect(ui->filter_channel_combo_box, &QComboBox::currentTextChanged, filterFunc);
|
||||
connect(ui->filter_set_enery_combo_box, &QComboBox::currentTextChanged, filterFunc);
|
||||
|
||||
connect(ui->btn_all_select, &QPushButton::clicked, [this](){
|
||||
ui->tablew_process_data->setCurrentItem(nullptr);
|
||||
auto row_count = ui->tablew_process_data->rowCount();
|
||||
for (int i = 0; i < row_count; ++i) {
|
||||
if (ui->tablew_process_data->isRowHidden(i)) {
|
||||
continue;
|
||||
}
|
||||
auto item = ui->tablew_process_data->item(i, 0);
|
||||
if (item) {
|
||||
item->setCheckState(Qt::Checked);
|
||||
}
|
||||
}
|
||||
});
|
||||
connect(ui->btn_reserve_select, &QPushButton::clicked, [this](){
|
||||
ui->tablew_process_data->setCurrentItem(nullptr);
|
||||
auto row_count = ui->tablew_process_data->rowCount();
|
||||
for (int i = 0; i < row_count - 1; i++) {
|
||||
if (ui->tablew_process_data->isRowHidden(i)) {
|
||||
continue;
|
||||
}
|
||||
auto item = ui->tablew_process_data->item(i, 0);
|
||||
if (item) {
|
||||
Qt::CheckState check_state = (item->checkState() == Qt::Checked) ? Qt::Unchecked : Qt::Checked;
|
||||
item->setCheckState(check_state);
|
||||
}
|
||||
}
|
||||
});
|
||||
connect(ui->btn_remove_selected, &QPushButton::clicked, [this](){
|
||||
auto row_count = ui->tablew_process_data->rowCount();
|
||||
for (int row = row_count - 1; row >= 0; --row) {
|
||||
QTableWidgetItem* item = ui->tablew_process_data->item(row, 0);
|
||||
if (Qt::Unchecked == item->checkState())
|
||||
continue;
|
||||
QPushButton* btn_remove_row = dynamic_cast<QPushButton*>(ui->tablew_process_data->cellWidget(row, 8));
|
||||
if (btn_remove_row) {
|
||||
ui->tablew_process_data->removeRow(row);
|
||||
btn_remove_row->deleteLater();
|
||||
this->updateSetEneryFilter();
|
||||
}
|
||||
}
|
||||
});
|
||||
connect(ui->btn_fit, &QPushButton::clicked, this, &BatchEneryScaleDialog::onFitBtnClickedProcess);
|
||||
connect(ui->btn_save, &QPushButton::clicked, [this](){
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void BatchEneryScaleDialog::SetPeakResultDataModel(QAbstractTableModel* peaks_result_model)
|
||||
{
|
||||
_peaks_result_model = peaks_result_model;
|
||||
if (_peaks_result_model) {
|
||||
qDebug() << _peaks_result_model->rowCount();
|
||||
}
|
||||
}
|
||||
|
||||
void BatchEneryScaleDialog::SetViewWorkspace(const QString &workspace)
|
||||
{
|
||||
this->_workspace = workspace;
|
||||
}
|
||||
|
||||
void BatchEneryScaleDialog::onSelectedScaleRange(double min, double max)
|
||||
{
|
||||
if (!_peaks_result_model) {
|
||||
return;
|
||||
}
|
||||
QDialog set_enery_dlg(this, Qt::Dialog | Qt::WindowCloseButtonHint);
|
||||
set_enery_dlg.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
set_enery_dlg.setFixedSize(300, 100);
|
||||
set_enery_dlg.setSizeGripEnabled(false);
|
||||
set_enery_dlg.setWindowTitle(QString(QStringLiteral(u"设置刻度能量")));
|
||||
|
||||
QLabel* set_enery_label = new QLabel(QString(QStringLiteral(u"刻度能量:")));
|
||||
QDoubleSpinBox* spinbox_set_enery = new QDoubleSpinBox();
|
||||
spinbox_set_enery->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
spinbox_set_enery->setRange(0.0f, std::numeric_limits<double>::max());
|
||||
spinbox_set_enery->setSingleStep(1.0f);
|
||||
spinbox_set_enery->setDecimals(3);
|
||||
QHBoxLayout* layout_input = new QHBoxLayout();
|
||||
layout_input->addWidget(set_enery_label);
|
||||
layout_input->addWidget(spinbox_set_enery);
|
||||
|
||||
QPushButton* btn_ok = new QPushButton(QStringLiteral(u"确认"));
|
||||
connect(btn_ok, &QPushButton::clicked, &set_enery_dlg, &QDialog::accept);
|
||||
QPushButton* btn_cancel = new QPushButton(QStringLiteral(u"取消"));
|
||||
connect(btn_cancel, &QPushButton::clicked, &set_enery_dlg, &QDialog::reject);
|
||||
QHBoxLayout* layout_btns = new QHBoxLayout();
|
||||
layout_btns->addStretch();
|
||||
layout_btns->addWidget(btn_ok);
|
||||
layout_btns->addWidget(btn_cancel);
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(&set_enery_dlg);
|
||||
layout->addLayout(layout_input);
|
||||
layout->addStretch();
|
||||
layout->addLayout(layout_btns);
|
||||
|
||||
if (QDialog::Accepted == set_enery_dlg.exec()) {
|
||||
double set_enery = spinbox_set_enery->value();
|
||||
for (int i = 0; i < _peaks_result_model->rowCount(); i++) {
|
||||
const QString& channel_name = _peaks_result_model->data(_peaks_result_model->index(i, 0)).toString();
|
||||
int peak_pos = _peaks_result_model->data(_peaks_result_model->index(i, 1)).toInt();
|
||||
int peak_fwhm = _peaks_result_model->data(_peaks_result_model->index(i, 6)).toInt();
|
||||
if (min < peak_pos && peak_pos < max ) {
|
||||
int row = ui->tablew_process_data->rowCount();
|
||||
ui->tablew_process_data->insertRow(row);
|
||||
ui->tablew_process_data->setItem(row, 0, new QTableWidgetItem(channel_name));
|
||||
ui->tablew_process_data->item(row, 0)->setCheckState(Qt::Unchecked);
|
||||
ui->tablew_process_data->setItem(row, 1, new QTableWidgetItem(QString::number(peak_pos)));
|
||||
ui->tablew_process_data->setItem(row, 2, new QTableWidgetItem(QString::number(set_enery)));
|
||||
ui->tablew_process_data->setItem(row, 3, new QTableWidgetItem);
|
||||
ui->tablew_process_data->setItem(row, 4, new QTableWidgetItem);
|
||||
ui->tablew_process_data->setItem(row, 5, new QTableWidgetItem(QString::number(peak_fwhm)));
|
||||
ui->tablew_process_data->setItem(row, 6, new QTableWidgetItem);
|
||||
ui->tablew_process_data->setItem(row, 7, new QTableWidgetItem);
|
||||
QTableWidgetItem* item = new QTableWidgetItem;
|
||||
ui->tablew_process_data->setItem(row, 8, item);
|
||||
QPushButton* btn_remove_row = new QPushButton(QStringLiteral(u"删除"));
|
||||
btn_remove_row->setMaximumWidth(35);
|
||||
connect(btn_remove_row, &QPushButton::clicked, [this, item, btn_remove_row]() {
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
int remove_row = item->row();
|
||||
ui->tablew_process_data->removeRow(remove_row);
|
||||
btn_remove_row->deleteLater();
|
||||
this->updateSetEneryFilter();
|
||||
});
|
||||
ui->tablew_process_data->setCellWidget(row, 8, btn_remove_row);
|
||||
this->insertSetEneryValueToFilter(set_enery);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BatchEneryScaleDialog::insertSetEneryValueToFilter(double enery)
|
||||
{
|
||||
int count = 0;
|
||||
int index = ui->filter_set_enery_combo_box->findText(QString::number(enery));
|
||||
if (index >= 0) {
|
||||
count = ui->filter_set_enery_combo_box->itemData(index).toInt() + 1;
|
||||
ui->filter_set_enery_combo_box->setItemData(index, count);
|
||||
} else {
|
||||
ui->filter_set_enery_combo_box->addItem(QString::number(enery), count);
|
||||
}
|
||||
}
|
||||
|
||||
void BatchEneryScaleDialog::updateSetEneryFilter()
|
||||
{
|
||||
int item_count = ui->filter_set_enery_combo_box->count();
|
||||
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);
|
||||
if (0 == count) {
|
||||
int current_index = ui->filter_set_enery_combo_box->currentIndex();
|
||||
if (index == current_index) {
|
||||
ui->filter_set_enery_combo_box->setCurrentIndex(0);
|
||||
}
|
||||
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)
|
||||
{
|
||||
emit close();
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
#ifndef BATCHENERYSCALEDIALOG_H
|
||||
#define BATCHENERYSCALEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QAbstractTableModel;
|
||||
|
||||
namespace Ui {
|
||||
class BatchEneryScaleDialog;
|
||||
}
|
||||
|
||||
class BatchEneryScaleDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
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);
|
||||
void updateSetEneryFilter();
|
||||
|
||||
signals:
|
||||
void close();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *e);
|
||||
|
||||
private:
|
||||
Ui::BatchEneryScaleDialog *ui;
|
||||
QString _project_name;
|
||||
QStringList _channel_name_list;
|
||||
QString _workspace;
|
||||
QAbstractTableModel* _peaks_result_model;
|
||||
};
|
||||
|
||||
#endif // BATCHENERYSCALEDIALOG_H
|
||||
|
|
@ -124,6 +124,11 @@ FindPeaksResultDialog::FindPeaksResultDialog(QWidget *parent)
|
|||
layout->addWidget(_peaks_result_table);
|
||||
}
|
||||
|
||||
FindPeaksResultDialog::~FindPeaksResultDialog()
|
||||
{
|
||||
qDebug() << "~FindPeaksResultDialog";
|
||||
}
|
||||
|
||||
void FindPeaksResultDialog::SetPeakResultDataFilename(const QString &data_filename)
|
||||
{
|
||||
this->_peaks_result_data_filename = data_filename;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ class FindPeaksResultDialog : public QDialog
|
|||
Q_OBJECT
|
||||
public:
|
||||
FindPeaksResultDialog(QWidget* parent = nullptr);
|
||||
virtual ~FindPeaksResultDialog();
|
||||
void SetPeakResultDataFilename(const QString& data_filename);
|
||||
void SetChannelNameList(const QStringList& ch_name_list);
|
||||
void UpdatePeakResult();
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
#include <QwtScaleMap>
|
||||
#include <QwtText>
|
||||
#include <fstream>
|
||||
#include "BatchEneryScaleDialog.h"
|
||||
#include "BatchEnergyScaleDialog.h"
|
||||
#include "FindPeaksResultDialog.h"
|
||||
|
||||
MeasureAnalysisParticleCountPlotView::MeasureAnalysisParticleCountPlotView(QWidget* parent)
|
||||
|
|
@ -42,7 +42,7 @@ MeasureAnalysisParticleCountPlotView::MeasureAnalysisParticleCountPlotView(QWidg
|
|||
setupPlot();
|
||||
setupMenu();
|
||||
setupPeakResultDlg();
|
||||
setupEneryScaleDlg();
|
||||
setupEnergyScaleDlg();
|
||||
}
|
||||
|
||||
MeasureAnalysisParticleCountPlotView::~MeasureAnalysisParticleCountPlotView()
|
||||
|
|
@ -72,10 +72,8 @@ void MeasureAnalysisParticleCountPlotView::InitViewWorkspace(const QString& proj
|
|||
_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);
|
||||
|
||||
_batch_energy_scale_dlg->SetProjectName(project_name);
|
||||
_batch_energy_scale_dlg->SetViewWorkspace(workspace);
|
||||
}
|
||||
|
||||
void MeasureAnalysisParticleCountPlotView::SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set)
|
||||
|
|
@ -106,8 +104,11 @@ void MeasureAnalysisParticleCountPlotView::SetAnalyzeDataFilename(const QMap<QSt
|
|||
if (_find_peaks_result_dlg ) {
|
||||
_find_peaks_result_dlg->SetChannelNameList(list_ch_names);
|
||||
}
|
||||
if (_batch_enery_scale_dlg ) {
|
||||
_batch_enery_scale_dlg->SetChannelNameList(list_ch_names);
|
||||
if (_batch_energy_scale_dlg ) {
|
||||
_batch_energy_scale_dlg->SetChannelNameList(list_ch_names);
|
||||
}
|
||||
if (_batch_energy_scale_dlg) {
|
||||
_batch_energy_scale_dlg->LoadEnergyScaleData();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -138,7 +139,7 @@ void MeasureAnalysisParticleCountPlotView::setupMenu()
|
|||
connect(action_auto_find_peaks, &QAction::triggered, this, &MeasureAnalysisParticleCountPlotView::onActionManualFindPeaks);
|
||||
QAction* action_set_energy_scale = this->_menu->addAction(QStringLiteral(u"能量刻度"));
|
||||
action_set_energy_scale->setObjectName("energy_scale");
|
||||
connect(action_set_energy_scale, &QAction::triggered, this, &MeasureAnalysisParticleCountPlotView::onActionEneryScale);
|
||||
connect(action_set_energy_scale, &QAction::triggered, this, &MeasureAnalysisParticleCountPlotView::onActionEnergyScale);
|
||||
QAction* action_plot_config = this->_menu->addAction(QStringLiteral(u"图表配置"));
|
||||
action_plot_config->setObjectName("plot_config");
|
||||
connect(action_plot_config, &QAction::triggered, this, &MeasureAnalysisParticleCountPlotView::onActionPlotConfigure);
|
||||
|
|
@ -183,15 +184,15 @@ void MeasureAnalysisParticleCountPlotView::setupPeakResultDlg()
|
|||
}
|
||||
}
|
||||
|
||||
void MeasureAnalysisParticleCountPlotView::setupEneryScaleDlg()
|
||||
void MeasureAnalysisParticleCountPlotView::setupEnergyScaleDlg()
|
||||
{
|
||||
if (!_batch_enery_scale_dlg) {
|
||||
_batch_enery_scale_dlg = new BatchEneryScaleDialog(this);
|
||||
_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](){
|
||||
if (!_batch_energy_scale_dlg) {
|
||||
_batch_energy_scale_dlg = new BatchEnergyScaleDialog(this);
|
||||
_batch_energy_scale_dlg->SetPeakResultDataModel(_find_peaks_result_dlg->GetPeakResultDataModel());
|
||||
connect(_data_selector, &CustomQwtPlotXaxisSelector::selectionFinished, _batch_energy_scale_dlg, &BatchEnergyScaleDialog::onSelectedScaleRange);
|
||||
connect(_batch_energy_scale_dlg, &BatchEnergyScaleDialog::close, [this](){
|
||||
this->_data_selector->setEnabled(false);
|
||||
disconnect(_data_selector, &CustomQwtPlotXaxisSelector::selectionFinished, _batch_enery_scale_dlg, &BatchEneryScaleDialog::onSelectedScaleRange);
|
||||
disconnect(_data_selector, &CustomQwtPlotXaxisSelector::selectionFinished, _batch_energy_scale_dlg, &BatchEnergyScaleDialog::onSelectedScaleRange);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -422,10 +423,10 @@ void MeasureAnalysisParticleCountPlotView::onActionManualFindPeaks()
|
|||
// _data_selector->setEnabled(true);
|
||||
}
|
||||
|
||||
void MeasureAnalysisParticleCountPlotView::onActionEneryScale()
|
||||
void MeasureAnalysisParticleCountPlotView::onActionEnergyScale()
|
||||
{
|
||||
if (_batch_enery_scale_dlg && _data_selector) {
|
||||
_batch_enery_scale_dlg->show();
|
||||
if (_batch_energy_scale_dlg && _data_selector) {
|
||||
_batch_energy_scale_dlg->show();
|
||||
_data_selector->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class CustomQwtPlot;
|
|||
class QTableWidget;
|
||||
class QTableWidgetItem;
|
||||
class CustomQwtPlotXaxisSelector;
|
||||
class BatchEneryScaleDialog;
|
||||
class BatchEnergyScaleDialog;
|
||||
class FindPeaksResultDialog;
|
||||
|
||||
class MeasureAnalysisParticleCountPlotView : public MeasureAnalysisView
|
||||
|
|
@ -29,7 +29,7 @@ private:
|
|||
void setupMenu();
|
||||
void setupPlot();
|
||||
void setupPeakResultDlg();
|
||||
void setupEneryScaleDlg();
|
||||
void setupEnergyScaleDlg();
|
||||
void loadDataFromFile(const QString &data_name, const QString& filename);
|
||||
void loadPeaksResultToTable(QTableWidget* peaks_result_table);
|
||||
void updatePlotPeakInfo(const QVariantMap& peak_infos);
|
||||
|
|
@ -41,7 +41,7 @@ private slots:
|
|||
void onActionFindPeaksResult();
|
||||
void onActionAutoFindPeaks();
|
||||
void onActionManualFindPeaks();
|
||||
void onActionEneryScale();
|
||||
void onActionEnergyScale();
|
||||
void onActionPlotConfigure();
|
||||
|
||||
private:
|
||||
|
|
@ -52,7 +52,7 @@ private:
|
|||
QMap<QString, QVariant> _data_files_set_ptr;
|
||||
FindPeaksResultDialog* _find_peaks_result_dlg = nullptr;
|
||||
CustomQwtPlotXaxisSelector* _data_selector = nullptr;
|
||||
BatchEneryScaleDialog* _batch_enery_scale_dlg = nullptr;
|
||||
BatchEnergyScaleDialog* _batch_energy_scale_dlg = nullptr;
|
||||
};
|
||||
|
||||
#endif // MEASUREANALYSISPARTICLECOUNTPLOTVIEW_H
|
||||
|
|
|
|||
|
|
@ -57,9 +57,9 @@ void MeasureAnalysisProjectModel::SetMeasureDeviceParamsCfgFilename(const QStrin
|
|||
this->_measure_device_params_cfg_filename = filename;
|
||||
}
|
||||
|
||||
void MeasureAnalysisProjectModel::SetEneryScaleFilename(const QString& filename)
|
||||
void MeasureAnalysisProjectModel::SetEnergyScaleFilename(const QString& filename)
|
||||
{
|
||||
this->_enery_scale_filename = filename;
|
||||
this->_energy_scale_filename = filename;
|
||||
}
|
||||
|
||||
void MeasureAnalysisProjectModel::SetEfficiencyScaleFilename(const QString& filename)
|
||||
|
|
@ -92,14 +92,14 @@ void MeasureAnalysisProjectModel::SetChannelAddressCountDataFilename(uint channe
|
|||
// this->_all_channel_particle_total_count_data_filename = filename;
|
||||
// }
|
||||
|
||||
void MeasureAnalysisProjectModel::SetChannelEneryCountDataFilename(uint channel, const QString& filename)
|
||||
void MeasureAnalysisProjectModel::SetChannelEnergyCountDataFilename(uint channel, const QString& filename)
|
||||
{
|
||||
this->_channel_enery_count_data_filename_list[channel] = filename;
|
||||
this->_channel_energy_count_data_filename_list[channel] = filename;
|
||||
}
|
||||
|
||||
void MeasureAnalysisProjectModel::SetAllChannelEneryTotalCountDataFilename(const QString& filename)
|
||||
void MeasureAnalysisProjectModel::SetAllChannelEnergyTotalCountDataFilename(const QString& filename)
|
||||
{
|
||||
this->_all_channel_enery_total_count_data_filename = filename;
|
||||
this->_all_channel_energy_total_count_data_filename = filename;
|
||||
}
|
||||
|
||||
void MeasureAnalysisProjectModel::SetTimeWinConformParticleData(uint time_win, uint conform_particle_count, const QString& filename)
|
||||
|
|
@ -157,9 +157,9 @@ const QString& MeasureAnalysisProjectModel::GetMeasureDeviceParamsCfgFilename()
|
|||
return this->_measure_device_params_cfg_filename;
|
||||
}
|
||||
|
||||
const QString& MeasureAnalysisProjectModel::GetEneryScaleFilename() const
|
||||
const QString& MeasureAnalysisProjectModel::GetEnergyScaleFilename() const
|
||||
{
|
||||
return this->_enery_scale_filename;
|
||||
return this->_energy_scale_filename;
|
||||
}
|
||||
|
||||
const QString& MeasureAnalysisProjectModel::GetEfficiencyScaleFilename() const
|
||||
|
|
@ -206,23 +206,23 @@ const QString MeasureAnalysisProjectModel::GetChannelAddressCountDataFilename(ui
|
|||
// return this->_all_channel_particle_total_count_data_filename;
|
||||
// }
|
||||
|
||||
const QMap<uint, QString>& MeasureAnalysisProjectModel::GetChannelEneryCountDataFilenameList() const
|
||||
const QMap<uint, QString>& MeasureAnalysisProjectModel::GetChannelEnergyCountDataFilenameList() const
|
||||
{
|
||||
return this->_channel_enery_count_data_filename_list;
|
||||
return this->_channel_energy_count_data_filename_list;
|
||||
}
|
||||
|
||||
const QString MeasureAnalysisProjectModel::GetChannelEneryCountDataFilename(uint channel) const
|
||||
const QString MeasureAnalysisProjectModel::GetChannelEnergyCountDataFilename(uint channel) const
|
||||
{
|
||||
QString file_name;
|
||||
if ( this->_channel_enery_count_data_filename_list.contains(channel) ) {
|
||||
file_name = this->_channel_enery_count_data_filename_list[channel];
|
||||
if ( this->_channel_energy_count_data_filename_list.contains(channel) ) {
|
||||
file_name = this->_channel_energy_count_data_filename_list[channel];
|
||||
}
|
||||
return file_name;
|
||||
}
|
||||
|
||||
const QString& MeasureAnalysisProjectModel::GetAllChannelEneryTotalCountDataFilename() const
|
||||
const QString& MeasureAnalysisProjectModel::GetAllChannelEnergyTotalCountDataFilename() const
|
||||
{
|
||||
return this->_all_channel_enery_total_count_data_filename;
|
||||
return this->_all_channel_energy_total_count_data_filename;
|
||||
}
|
||||
|
||||
const QMap<uint, QString> MeasureAnalysisProjectModel::GetTimeWinConformParticleDataFilenameList(uint time_win) const
|
||||
|
|
@ -302,7 +302,7 @@ bool MeasureAnalysisProjectModel::LoadProjectModel(const QString& project_filena
|
|||
};
|
||||
|
||||
this->_measure_device_params_cfg_filename = ProjectAbsFilename(json_obj["MeasureDeviceParamsCfgFilename"].toString());
|
||||
this->_enery_scale_filename = ProjectAbsFilename(json_obj["EneryScaleFilename"].toString());
|
||||
this->_energy_scale_filename = ProjectAbsFilename(json_obj["EnergyScaleFilename"].toString());
|
||||
this->_efficiency_scale_filename = ProjectAbsFilename(json_obj["EfficiencyScaleFilename"].toString());
|
||||
|
||||
this->_all_channel_particle_data_filename = ProjectAbsFilename(json_obj["AllChannelParticleDataFilename"].toString());
|
||||
|
|
@ -314,13 +314,13 @@ bool MeasureAnalysisProjectModel::LoadProjectModel(const QString& project_filena
|
|||
this->_channel_address_count_data_filename_list[channel_num] = ProjectAbsFilename(it.value().toString());
|
||||
}
|
||||
|
||||
const auto& enery_count_data_filename_list = json_obj["ChannelEneryCountDataFilenameList"].toObject().toVariantMap();
|
||||
for (auto it = enery_count_data_filename_list.constBegin(); it!=enery_count_data_filename_list.constEnd(); ++it) {
|
||||
const auto& energy_count_data_filename_list = json_obj["ChannelEnergyCountDataFilenameList"].toObject().toVariantMap();
|
||||
for (auto it = energy_count_data_filename_list.constBegin(); it!=energy_count_data_filename_list.constEnd(); ++it) {
|
||||
uint channel_num = it.key().toUInt();
|
||||
this->_channel_enery_count_data_filename_list[channel_num] = ProjectAbsFilename(it.value().toString());
|
||||
this->_channel_energy_count_data_filename_list[channel_num] = ProjectAbsFilename(it.value().toString());
|
||||
}
|
||||
|
||||
this->_all_channel_enery_total_count_data_filename = ProjectAbsFilename(json_obj["AllChannelEneryTotalCountDataFilename"].toString());
|
||||
this->_all_channel_energy_total_count_data_filename = ProjectAbsFilename(json_obj["AllChannelEnergyTotalCountDataFilename"].toString());
|
||||
|
||||
const auto& time_win_conform_particle_data = json_obj["TimeWinConformParticleData"].toObject().toVariantMap();
|
||||
for (auto it = time_win_conform_particle_data.constBegin(); it!=time_win_conform_particle_data.constEnd(); ++it) {
|
||||
|
|
@ -365,7 +365,7 @@ bool MeasureAnalysisProjectModel::SaveProjectModel()
|
|||
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["EnergyScaleFilename"] = ProjectRelativeFilename(this->_energy_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);
|
||||
|
|
@ -374,12 +374,12 @@ bool MeasureAnalysisProjectModel::SaveProjectModel()
|
|||
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());
|
||||
QVariantMap channel_energy_count_data_filename_list;
|
||||
for (auto it = this->_channel_energy_count_data_filename_list.constBegin(); it != this->_channel_energy_count_data_filename_list.constEnd(); ++it) {
|
||||
channel_energy_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);
|
||||
project_json_obj_map["ChannelEnergyCountDataFilenameList"] = channel_energy_count_data_filename_list;
|
||||
project_json_obj_map["AllChannelEnergyTotalCountDataFilename"] = ProjectRelativeFilename(this->_all_channel_energy_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;
|
||||
|
|
@ -673,7 +673,7 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProje
|
|||
node_map[item_name] = node_item;
|
||||
}
|
||||
|
||||
status = pro_model->GetEneryScaleFilename().isEmpty() ? QStringLiteral(u"未配置") : QStringLiteral(u"已配置");
|
||||
status = pro_model->GetEnergyScaleFilename().isEmpty() ? QStringLiteral(u"未配置") : QStringLiteral(u"已配置");
|
||||
analys_type = QVariant::fromValue(AnalysisType::EnergyScale);
|
||||
item_name = QStringLiteral(u"能量刻度");
|
||||
QStandardItem* node_item = AddChildNode(measure_ctrl_item, item_name, status, analys_type, true);
|
||||
|
|
@ -718,18 +718,18 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProje
|
|||
}
|
||||
|
||||
item_name = QStringLiteral(u"能量计数");
|
||||
status = pro_model->GetAllChannelEneryTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效");
|
||||
status = pro_model->GetAllChannelEnergyTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效");
|
||||
analys_type = QVariant::fromValue(AnalysisType::EnergyCountData);
|
||||
node_item = AddChildNode(analysis_data_item, item_name, status, analys_type, true);
|
||||
node_item->setData(project_name, ProjectName);
|
||||
node_map[item_name] = node_item;
|
||||
QStandardItem* enery_count_item = node_item;
|
||||
const auto& ch_enery_count_data_filename_list = pro_model->GetChannelEneryCountDataFilenameList();
|
||||
for (auto it = ch_enery_count_data_filename_list.begin(); it != ch_enery_count_data_filename_list.end(); ++it) {
|
||||
QStandardItem* energy_count_item = node_item;
|
||||
const auto& ch_energy_count_data_filename_list = pro_model->GetChannelEnergyCountDataFilenameList();
|
||||
for (auto it = ch_energy_count_data_filename_list.begin(); it != ch_energy_count_data_filename_list.end(); ++it) {
|
||||
uint ch_num = it.key();
|
||||
QString item_name = QStringLiteral(u"通道%1能量计数").arg(ch_num);
|
||||
const QVariant& analys_type = QVariant::fromValue(AnalysisType::EnergyCountData);
|
||||
QStandardItem* node_item = AddChildNode(enery_count_item, item_name, status, analys_type, true);
|
||||
QStandardItem* node_item = AddChildNode(energy_count_item, item_name, status, analys_type, true);
|
||||
node_item->setData(project_name, ProjectName);
|
||||
node_item->setData(ch_num, ChannelNum);
|
||||
node_map[item_name] = node_item;
|
||||
|
|
@ -756,15 +756,15 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProje
|
|||
node_item->setData(project_name, ProjectName);
|
||||
node_map[item_name] = node_item;
|
||||
|
||||
status = pro_model->GetChannelEneryCountDataFilenameList().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效");
|
||||
analys_type = QVariant::fromValue(AnalysisType::EneryCountSpectrumView);
|
||||
status = pro_model->GetChannelEnergyCountDataFilenameList().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效");
|
||||
analys_type = QVariant::fromValue(AnalysisType::EnergyCountSpectrumView);
|
||||
item_name = QStringLiteral(u"通道能量计数谱");
|
||||
node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true);
|
||||
node_item->setData(project_name, ProjectName);
|
||||
node_map[item_name] = node_item;
|
||||
|
||||
status = pro_model->GetAllChannelEneryTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效");
|
||||
analys_type = QVariant::fromValue(AnalysisType::EneryCountSpectrumView);
|
||||
status = pro_model->GetAllChannelEnergyTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效");
|
||||
analys_type = QVariant::fromValue(AnalysisType::EnergyCountSpectrumView);
|
||||
item_name = QStringLiteral(u"能量计数谱");
|
||||
node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true);
|
||||
node_item->setData(project_name, ProjectName);
|
||||
|
|
@ -777,14 +777,14 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProje
|
|||
node_item->setData(project_name, ProjectName);
|
||||
node_map[item_name] = node_item;
|
||||
|
||||
status = pro_model->GetAllChannelEneryTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效");
|
||||
status = pro_model->GetAllChannelEnergyTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效");
|
||||
analys_type = QVariant::fromValue(AnalysisType::EnergyPeakFitView);
|
||||
item_name = QStringLiteral(u"峰拟合分析");
|
||||
node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true);
|
||||
node_item->setData(project_name, ProjectName);
|
||||
node_map[item_name] = node_item;
|
||||
|
||||
status = pro_model->GetAllChannelEneryTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效");
|
||||
status = pro_model->GetAllChannelEnergyTotalCountDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效");
|
||||
analys_type = QVariant::fromValue(AnalysisType::NuclideAnalysisView);
|
||||
item_name = QStringLiteral(u"核素分析");
|
||||
node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true);
|
||||
|
|
@ -844,7 +844,7 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProje
|
|||
LOG_WARN(QStringLiteral(u"测量分析项目\"%1\"测量设备参数未配置!").arg(project_name));
|
||||
}
|
||||
}
|
||||
if (pro_model->GetEneryScaleFilename().isEmpty()) {
|
||||
if (pro_model->GetEnergyScaleFilename().isEmpty()) {
|
||||
LOG_WARN(QStringLiteral(u"测量分析项目\"%1\"能量刻度未配置!").arg(project_name));
|
||||
}
|
||||
if (pro_model->GetEfficiencyScaleFilename().isEmpty()) {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public:
|
|||
void SetIsMeasureComplete(bool is_measure_complete);
|
||||
|
||||
void SetMeasureDeviceParamsCfgFilename(const QString& filename);
|
||||
void SetEneryScaleFilename(const QString& filename);
|
||||
void SetEnergyScaleFilename(const QString& filename);
|
||||
void SetEfficiencyScaleFilename(const QString& filename);
|
||||
|
||||
void SetAllChannelParticleDataFilename(const QString& filename);
|
||||
|
|
@ -40,8 +40,8 @@ public:
|
|||
void SetChannelAddressCountDataFilename(uint channel, const QString& filename);
|
||||
// void SetAllChannelParticleTotalCountDataFilename(const QString& filename);
|
||||
|
||||
void SetChannelEneryCountDataFilename(uint channel, const QString& filename);
|
||||
void SetAllChannelEneryTotalCountDataFilename(const QString& filename);
|
||||
void SetChannelEnergyCountDataFilename(uint channel, const QString& filename);
|
||||
void SetAllChannelEnergyTotalCountDataFilename(const QString& filename);
|
||||
|
||||
void SetTimeWinConformParticleData(uint time_win, uint conform_particle_count, const QString& filename);
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ public:
|
|||
uint GetConformTimeWin() const;
|
||||
bool GetIsMeasureComplete() const;
|
||||
const QString& GetMeasureDeviceParamsCfgFilename() const;
|
||||
const QString& GetEneryScaleFilename() const;
|
||||
const QString& GetEnergyScaleFilename() const;
|
||||
const QString& GetEfficiencyScaleFilename() const;
|
||||
|
||||
const QString& GetAllChannelParticleDataFilename() const;
|
||||
|
|
@ -69,9 +69,9 @@ public:
|
|||
const QString GetChannelAddressCountDataFilename(uint channel) const;
|
||||
// const QString& GetAllChannelParticleTotalCountDataFilename() const;
|
||||
|
||||
const QMap<uint, QString>& GetChannelEneryCountDataFilenameList() const;
|
||||
const QString GetChannelEneryCountDataFilename(uint channel) const;
|
||||
const QString& GetAllChannelEneryTotalCountDataFilename() const;
|
||||
const QMap<uint, QString>& GetChannelEnergyCountDataFilenameList() const;
|
||||
const QString GetChannelEnergyCountDataFilename(uint channel) const;
|
||||
const QString& GetAllChannelEnergyTotalCountDataFilename() const;
|
||||
|
||||
const QMap<uint, QString> GetTimeWinConformParticleDataFilenameList(uint time_win) const;
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ private:
|
|||
bool _is_measure_complete = false;
|
||||
|
||||
QString _measure_device_params_cfg_filename;
|
||||
QString _enery_scale_filename;
|
||||
QString _energy_scale_filename;
|
||||
QString _efficiency_scale_filename;
|
||||
|
||||
QString _all_channel_particle_data_filename;
|
||||
|
|
@ -99,8 +99,8 @@ private:
|
|||
QMap<uint, QString> _channel_address_count_data_filename_list;
|
||||
// QString _all_channel_particle_total_count_data_filename;
|
||||
|
||||
QMap<uint, QString> _channel_enery_count_data_filename_list;
|
||||
QString _all_channel_enery_total_count_data_filename;
|
||||
QMap<uint, QString> _channel_energy_count_data_filename_list;
|
||||
QString _all_channel_energy_total_count_data_filename;
|
||||
|
||||
QMap<uint, QMap<uint, QString> > _time_win_conform_particle_data;
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ MeasureAnalysisView *MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type)
|
|||
new_view = new MeasureAnalysisParticleCountPlotView;
|
||||
new_view->setDeleteOnClose(false);
|
||||
} break;
|
||||
case AnalysisType::EneryCountSpectrumView: {
|
||||
case AnalysisType::EnergyCountSpectrumView: {
|
||||
// new_view = new MeasureAnalysisParticleCountPlotView;
|
||||
// new_view->setDeleteOnClose(false);
|
||||
} break;
|
||||
|
|
|
|||
|
|
@ -430,7 +430,7 @@
|
|||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_enery_scale">
|
||||
<widget class="QLabel" name="label_energy_scale">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
|
|
@ -455,7 +455,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_enery_scale"/>
|
||||
<widget class="QComboBox" name="comboBox_energy_scale"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ int main(int argc, char *argv[])
|
|||
// 设置样式
|
||||
// app.setStyle(QStyleFactory::create("Fusion"));
|
||||
app.setWindowIcon(QIcon(":/logo/256.png"));
|
||||
app.setQuitOnLastWindowClosed(false);
|
||||
app.setQuitOnLastWindowClosed(true);
|
||||
|
||||
// 在应用程序可执行文件所在目录检查并创建Projects目录
|
||||
QString projects_dir_path = QDir(app.applicationDirPath()).filePath("Projects");
|
||||
|
|
|
|||
14
src/src.pro
14
src/src.pro
|
|
@ -40,11 +40,12 @@ SOURCES += \
|
|||
AboutDlg.cpp \
|
||||
CustomQwtPlot.cpp \
|
||||
DataProcessWorkPool.cpp \
|
||||
EneryScaleForm.cpp \
|
||||
EnergyScaleDataModel.cpp \
|
||||
EnergyScaleForm.cpp \
|
||||
MainWindow.cpp \
|
||||
MeasureAnalysisDataTableView.cpp \
|
||||
MeasureAnalysisHistoryForm.cpp \
|
||||
MeasureAnalysisParticleCountPlotView/BatchEneryScaleDialog.cpp \
|
||||
MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.cpp \
|
||||
MeasureAnalysisParticleCountPlotView/FindPeaksResultDialog.cpp \
|
||||
MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.cpp \
|
||||
MeasureAnalysisTreeView.cpp \
|
||||
|
|
@ -63,12 +64,13 @@ HEADERS += \
|
|||
AnalysisTypeDefine.h \
|
||||
CustomQwtPlot.h \
|
||||
DataProcessWorkPool.h \
|
||||
EneryScaleForm.h \
|
||||
EnergyScaleDataModel.h \
|
||||
EnergyScaleForm.h \
|
||||
GlobalDefine.h \
|
||||
MainWindow.h \
|
||||
MeasureAnalysisDataTableView.h \
|
||||
MeasureAnalysisHistoryForm.h \
|
||||
MeasureAnalysisParticleCountPlotView/BatchEneryScaleDialog.h \
|
||||
MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.h \
|
||||
MeasureAnalysisParticleCountPlotView/FindPeaksResultDialog.h \
|
||||
MeasureAnalysisParticleCountPlotView/MeasureAnalysisParticleCountPlotView.h \
|
||||
MeasureAnalysisTreeView.h \
|
||||
|
|
@ -84,10 +86,10 @@ HEADERS += \
|
|||
|
||||
FORMS += \
|
||||
AboutDlg.ui \
|
||||
MeasureAnalysisParticleCountPlotView/BatchEneryScaleDialog.ui \
|
||||
EneryScaleForm.ui \
|
||||
EnergyScaleForm.ui \
|
||||
MainWindow.ui \
|
||||
MeasureAnalysisHistoryForm.ui \
|
||||
MeasureAnalysisParticleCountPlotView/BatchEnergyScaleDialog.ui \
|
||||
MeasureDeviceParamsCfgForm.ui \
|
||||
NewMeasureAnalysisDlg.ui
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user