完成能谱数据生成任务

This commit is contained in:
徐海 2026-03-20 19:12:27 +08:00
parent dbb0bc7cd2
commit 2c38e2414a
7 changed files with 99 additions and 51 deletions

View File

@ -1,4 +1,4 @@
#include "GaussPolyCoe.h" #include "GaussPolyCoe.h"
using namespace std; using namespace std;
@ -78,10 +78,11 @@ vector<double> GaussPolyCoe::PolynomialFit(const vector<double>& x, const vector
double GaussPolyCoe::Predict(const vector<double>& coeffs, double x) double GaussPolyCoe::Predict(const vector<double>& coeffs, double x)
{ {
double result = 0.0; double result = 0.0f;
for (int i = 0; i < coeffs.size(); ++i) { for (int i = 0; i < coeffs.size(); ++i) {
result += coeffs[i] * pow(x, i); result += coeffs[i] * pow(x, i);
} }
result = round(result * 1000) / 1000.0f;
return result; return result;
} }

View File

@ -43,7 +43,9 @@ double FwhmModel(double E, const vec& p)
{ {
double k = p(0); double k = p(0);
double c = p(1); double c = p(1);
return k * sqrt(E) + c; double fwhm = k * sqrt(E) + c;
fwhm = round(fwhm * 1000) / 1000.0f;
return fwhm;
} }
// 高斯模型: y = A * exp(-pow(x - mu, 2) / (2 * pow(sigma, 2))) // 高斯模型: y = A * exp(-pow(x - mu, 2) / (2 * pow(sigma, 2)))

View File

@ -147,14 +147,12 @@ bool EveryChannelParticleDataSeparateTask::processEveryChannelParticleData()
uint address; uint address;
unsigned long long time; unsigned long long time;
while (reader.read_row(board_id, channel_id, address, time)) { while (reader.read_row(board_id, channel_id, address, time)) {
// 板卡和通道号计算,通道号 = 板卡号 * 4 + 通道号 // 板卡和通道号计算,通道号 = 板卡号 * 4 + 通道号
int channel_num = (board_id) * 4 + (channel_id + 1); int channel_num = (board_id) * 4 + (channel_id + 1);
QString particle_data_filename = result_data_output_dir.filePath(QStringLiteral(u"通道%1粒子数据.csv").arg(channel_num)); QString particle_data_filename = result_data_output_dir.filePath(QStringLiteral(u"通道%1粒子数据.csv").arg(channel_num));
if (!particle_data_filename_list.contains(channel_num)) { if (!particle_data_filename_list.contains(channel_num)) {
particle_data_filename_list.insert(channel_num, particle_data_filename); particle_data_filename_list.insert(channel_num, particle_data_filename);
} }
if (!ch_particle_data_of_list.contains(channel_num)) { if (!ch_particle_data_of_list.contains(channel_num)) {
std::shared_ptr<std::ofstream> out( std::shared_ptr<std::ofstream> out(
new std::ofstream(QStrToSysPath(particle_data_filename), std::ios::out | std::ios::app), new std::ofstream(QStrToSysPath(particle_data_filename), std::ios::out | std::ios::app),
@ -428,11 +426,11 @@ std::vector<std::string> splitFile(const std::string& input_file, size_t chunk_s
return a.time < b.time; return a.time < b.time;
}); });
std::string chunk_file = input_file + ".chunk" + std::to_string(chunk_index); std::string chunk_file = input_file + ".chunk" + std::to_string(chunk_index);
std::ofstream outFile(chunk_file); std::ofstream out_file(chunk_file);
for (const auto& row : rows) { for (const auto& row : rows) {
outFile << row.board_id << "," << row.channel_id << "," << row.address << "," << row.time << "\n"; out_file << row.board_id << "," << row.channel_id << "," << row.address << "," << row.time << "\n";
} }
outFile.close(); out_file.close();
chunks.push_back(chunk_file); chunks.push_back(chunk_file);
chunk_index++; chunk_index++;
} }
@ -647,8 +645,7 @@ bool AutoFindPeaksTask::processTask()
return true; return true;
} }
void ChannelEnergyScaleFittingTask::SetData( void ChannelEnergyScaleFittingTask::SetData(const FitDataMap& channel_energy_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_energy_scale_fit_data_map = channel_energy_scale_fit_data_map; this->_channel_energy_scale_fit_data_map = channel_energy_scale_fit_data_map;
this->_fit_degree_map = fit_degree_map; this->_fit_degree_map = fit_degree_map;
@ -734,17 +731,85 @@ bool ChannelEnergyScaleFittingTask::processTask()
return true; return true;
} }
bool ApplyEnergyScaleTask::processTask() bool ApplyEnergyScaleTask::scaleParticleData(EnergyScaleDataModel& energy_scale_data_model, const QString& data_filename, const QString& out_filename)
{ {
bool ok = true; bool ok = true;
std::string board_id_str = QString(QStringLiteral(u"板卡号")).toStdString();
std::string channel_id_str = QString(QStringLiteral(u"通道号")).toStdString();
std::string address_str = QString(QStringLiteral(u"道址")).toStdString();
std::string energy_str = QString(QStringLiteral(u"能量(KeV)")).toStdString();
std::string time_str = QString(QStringLiteral(u"时间计数")).toStdString();
std::ofstream out(QStrToSysPath(out_filename));
out << board_id_str << "," << channel_id_str << "," << energy_str << "," << time_str<< "\n" ;
try {
io::CSVReader<
4,
io::trim_chars<' ', '\t'>,
io::double_quote_escape<',', '"'>,
io::throw_on_overflow,
io::empty_line_comment>
reader(QStrToSysPath(data_filename));
reader.read_header(io::ignore_extra_column, board_id_str, channel_id_str, address_str, time_str);
uint board_id;
uint channel_id;
uint address;
unsigned long long time;
while (reader.read_row(board_id, channel_id, address, time)) {
int channel_num = (board_id) * 4 + (channel_id + 1);
const QString& channel_name = QStringLiteral(u"通道%1").arg(channel_num);
auto coeffs = energy_scale_data_model.GetEnergyFitResultCoeffs(channel_name);
double energy = GaussPolyCoe::Predict(coeffs, address);
out << board_id << "," << channel_id << "," << energy << "," << time << "\n";
}
out.close();
} catch (const std::exception& e) {
out.close();
std::remove(QStrToSysPath(out_filename));
}
return ok;
}
bool ApplyEnergyScaleTask::energyCountProcess()
{
bool ok = true;
return ok;
}
bool ApplyEnergyScaleTask::coincidenceProcess()
{
bool ok = true;
return ok;
}
bool ApplyEnergyScaleTask::processTask()
{
const QString& project_name = GetProjectName(); const QString& project_name = GetProjectName();
MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(project_name); MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(project_name);
if (project_model == nullptr) { if (project_model == nullptr) {
return false; return false;
} }
EnergyScaleDataModel energy_scale_data_model(project_model->GetEnergyScaleFilename());
if (!energy_scale_data_model.LoadData()) {
return false;
}
if (!energy_scale_data_model.IsValid()) {
return false;
}
const QString& all_channel_particle_data_filename = project_model->GetAllChannelParticleDataFilename();
if (all_channel_particle_data_filename.isEmpty()) {
return false;
}
const QString& energy_spectrum_filename = QDir(project_model->GetProjectDir()).filePath(QStringLiteral(u"能谱数据.csv"));
if (!scaleParticleData(energy_scale_data_model, all_channel_particle_data_filename, energy_spectrum_filename)) {
return false;
}
if (!energyCountProcess()) {
return false;
}
if (!coincidenceProcess()) {
return false;
}
const QString& info = QStringLiteral(u"应用能量刻度完成."); const QString& info = QStringLiteral(u"应用能量刻度完成.");
LOG_INFO(info); LOG_INFO(info);
return true;
return ok;
} }

View File

@ -8,6 +8,8 @@
#include <QMap> #include <QMap>
#include <QVariant> #include <QVariant>
class EnergyScaleDataModel;
namespace DataProcessWorkPool namespace DataProcessWorkPool
{ {
class DataProcessTask : public QRunnable class DataProcessTask : public QRunnable
@ -128,6 +130,9 @@ namespace DataProcessWorkPool
class ApplyEnergyScaleTask : public DataProcessTask class ApplyEnergyScaleTask : public DataProcessTask
{ {
private: private:
bool scaleParticleData(EnergyScaleDataModel &energy_scale_data_model, const QString& data_filename, const QString& out_filename);
bool energyCountProcess();
bool coincidenceProcess();
virtual bool processTask() override; virtual bool processTask() override;
private: private:
QString _project_name; QString _project_name;

View File

@ -347,10 +347,18 @@ void BatchEnergyScaleDialog::applyEnergyScaleFitResultData()
} }
QDir project_dir(project_model->GetProjectDir()); QDir project_dir(project_model->GetProjectDir());
const QString& energy_scale_data_filename = project_dir.filePath(QStringLiteral(u"能量刻度.json")); const QString& energy_scale_data_filename = project_dir.filePath(QStringLiteral(u"能量刻度.json"));
if ( QFileInfo(energy_scale_data_filename).exists() ) {
if ( !QFile::remove(energy_scale_data_filename) ) {
LOG_WARN(QStringLiteral(u"应用能量刻度异常,无法清除测量分析[%1]存在的能量刻度数据!").arg(project_model->GetProjectName()));
return;
}
}
const QString& energy_scale_result_filename = this->_energy_scale_data_model->GetDataFilename(); const QString& energy_scale_result_filename = this->_energy_scale_data_model->GetDataFilename();
if (QFile::copy(energy_scale_result_filename, energy_scale_data_filename)) { if (QFile::copy(energy_scale_result_filename, energy_scale_data_filename)) {
project_model->SetEnergyScaleFilename(energy_scale_data_filename); project_model->SetEnergyScaleFilename(energy_scale_data_filename);
ProjectList::Instance()->ApplyEnergyScale(this->_project_name); ProjectList::Instance()->ApplyEnergyScale(this->_project_name);
} else {
LOG_WARN(QStringLiteral(u"应用能量刻度异常,无法配置到测量分析[%1]!").arg(project_model->GetProjectName()));
} }
} else { } else {
QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"不能应用非完整的能量刻度!")); QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"不能应用非完整的能量刻度!"));

View File

@ -73,11 +73,6 @@ void MeasureAnalysisProjectModel::SetAllChannelParticleDataFilename(const QStrin
this->_all_channel_particle_data_filename = filename; this->_all_channel_particle_data_filename = filename;
} }
void MeasureAnalysisProjectModel::SetSortedParticleDataFilename(const QString& filename)
{
this->_sorted_particle_data_filename = filename;
}
// void MeasureAnalysisProjectModel::SetChannelParticleDataFilename(uint channel, const QString& filename) // void MeasureAnalysisProjectModel::SetChannelParticleDataFilename(uint channel, const QString& filename)
// { // {
// this->_channel_particle_data_filename_list[channel] = filename; // this->_channel_particle_data_filename_list[channel] = filename;
@ -173,11 +168,6 @@ const QString& MeasureAnalysisProjectModel::GetAllChannelParticleDataFilename()
return this->_all_channel_particle_data_filename; return this->_all_channel_particle_data_filename;
} }
const QString& MeasureAnalysisProjectModel::GetSortAllChannelParticleDataFilename() const
{
return this->_sorted_particle_data_filename;
}
// const QMap<uint, QString>& MeasureAnalysisProjectModel::GetChannelParticleDataFilenameList() const // const QMap<uint, QString>& MeasureAnalysisProjectModel::GetChannelParticleDataFilenameList() const
// { // {
// return this->_channel_particle_data_filename_list; // return this->_channel_particle_data_filename_list;
@ -307,7 +297,6 @@ bool MeasureAnalysisProjectModel::LoadProjectModel(const QString& project_filena
this->_efficiency_scale_filename = ProjectAbsFilename(json_obj["EfficiencyScaleFilename"].toString()); this->_efficiency_scale_filename = ProjectAbsFilename(json_obj["EfficiencyScaleFilename"].toString());
this->_all_channel_particle_data_filename = ProjectAbsFilename(json_obj["AllChannelParticleDataFilename"].toString()); this->_all_channel_particle_data_filename = ProjectAbsFilename(json_obj["AllChannelParticleDataFilename"].toString());
this->_sorted_particle_data_filename = ProjectAbsFilename(json_obj["SortedParticleDataFilename"].toString());
const auto& address_count_data_filename_list = json_obj["ChannelAddressCountDataFilenameList"].toObject().toVariantMap(); const auto& address_count_data_filename_list = json_obj["ChannelAddressCountDataFilenameList"].toObject().toVariantMap();
for (auto it = address_count_data_filename_list.constBegin(); it!=address_count_data_filename_list.constEnd(); ++it) { for (auto it = address_count_data_filename_list.constBegin(); it!=address_count_data_filename_list.constEnd(); ++it) {
@ -369,7 +358,6 @@ bool MeasureAnalysisProjectModel::SaveProjectModel()
project_json_obj_map["EnergyScaleFilename"] = ProjectRelativeFilename(this->_energy_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["EfficiencyScaleFilename"] = ProjectRelativeFilename(this->_efficiency_scale_filename);
project_json_obj_map["AllChannelParticleDataFilename"] = ProjectRelativeFilename(this->_all_channel_particle_data_filename); project_json_obj_map["AllChannelParticleDataFilename"] = ProjectRelativeFilename(this->_all_channel_particle_data_filename);
project_json_obj_map["SortedParticleDataFilename"] = ProjectRelativeFilename(this->_sorted_particle_data_filename);
QVariantMap channel_address_count_data_filename_list; QVariantMap channel_address_count_data_filename_list;
for (auto it = this->_channel_address_count_data_filename_list.constBegin(); it != this->_channel_address_count_data_filename_list.constEnd(); ++it) { for (auto it = this->_channel_address_count_data_filename_list.constBegin(); it != this->_channel_address_count_data_filename_list.constEnd(); ++it) {
channel_address_count_data_filename_list[QString::number(it.key())] = ProjectRelativeFilename(it.value()); channel_address_count_data_filename_list[QString::number(it.key())] = ProjectRelativeFilename(it.value());
@ -619,7 +607,7 @@ void MeasureAnalysisProjectModelList::ApplyEnergyScale(const QString &project_na
auto pro_model = this->_project_models[project_name]; auto pro_model = this->_project_models[project_name];
const QString& energy_scale_filename = pro_model->GetEnergyScaleFilename(); const QString& energy_scale_filename = pro_model->GetEnergyScaleFilename();
QString status = QStringLiteral(u"未配置"); QString status = QStringLiteral(u"未配置");
if (energy_scale_filename.isEmpty()) { if (!energy_scale_filename.isEmpty()) {
status = QStringLiteral(u"已配置"); status = QStringLiteral(u"已配置");
auto& node_map = this->_project_node_items[project_name]; auto& node_map = this->_project_node_items[project_name];
const QString& energy_scale_item_name = QStringLiteral(u"能量刻度"); const QString& energy_scale_item_name = QStringLiteral(u"能量刻度");
@ -844,7 +832,7 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProje
node_item->setData(project_name, ProjectName); node_item->setData(project_name, ProjectName);
node_map[item_name] = node_item; node_map[item_name] = node_item;
status = pro_model->GetSortAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); status = pro_model->GetAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效");
analys_type = QVariant::fromValue(AnalysisType::CountingRateView); analys_type = QVariant::fromValue(AnalysisType::CountingRateView);
item_name = QStringLiteral(u"计数率分析"); item_name = QStringLiteral(u"计数率分析");
node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true);
@ -865,14 +853,14 @@ void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProje
node_item->setData(project_name, ProjectName); node_item->setData(project_name, ProjectName);
node_map[item_name] = node_item; node_map[item_name] = node_item;
status = pro_model->GetSortAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); status = pro_model->GetAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效");
analys_type = QVariant::fromValue(AnalysisType::ParticleInTimeView); analys_type = QVariant::fromValue(AnalysisType::ParticleInTimeView);
item_name = QStringLiteral(u"粒子入射时间分析"); item_name = QStringLiteral(u"粒子入射时间分析");
node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true);
node_item->setData(project_name, ProjectName); node_item->setData(project_name, ProjectName);
node_map[item_name] = node_item; node_map[item_name] = node_item;
status = pro_model->GetSortAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效"); status = pro_model->GetAllChannelParticleDataFilename().isEmpty() ? QStringLiteral(u"无效") : QStringLiteral(u"有效");
analys_type = QVariant::fromValue(AnalysisType::ParticleTimeDiffView); analys_type = QVariant::fromValue(AnalysisType::ParticleTimeDiffView);
item_name = QStringLiteral(u"粒子时间差分析"); item_name = QStringLiteral(u"粒子时间差分析");
node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true); node_item = AddChildNode(interactive_analysis_item, item_name, status, analys_type, true);

View File

@ -28,23 +28,16 @@ public:
void SetMeasurePresetTime(ulong measure_preset_time); void SetMeasurePresetTime(ulong measure_preset_time);
void SetConformTimeWin(uint conform_time_win); void SetConformTimeWin(uint conform_time_win);
void SetIsMeasureComplete(bool is_measure_complete); void SetIsMeasureComplete(bool is_measure_complete);
void SetMeasureDeviceParamsCfgFilename(const QString& filename); void SetMeasureDeviceParamsCfgFilename(const QString& filename);
void SetEnergyScaleFilename(const QString& filename); void SetEnergyScaleFilename(const QString& filename);
void SetEfficiencyScaleFilename(const QString& filename); void SetEfficiencyScaleFilename(const QString& filename);
void SetAllChannelParticleDataFilename(const QString& filename); void SetAllChannelParticleDataFilename(const QString& filename);
void SetSortedParticleDataFilename(const QString& filename);
// void SetChannelParticleDataFilename(uint channel, const QString& filename); // void SetChannelParticleDataFilename(uint channel, const QString& filename);
void SetChannelAddressCountDataFilename(uint channel, const QString& filename); void SetChannelAddressCountDataFilename(uint channel, const QString& filename);
// void SetAllChannelParticleTotalCountDataFilename(const QString& filename); // void SetAllChannelParticleTotalCountDataFilename(const QString& filename);
void SetChannelEnergyCountDataFilename(uint channel, const QString& filename); void SetChannelEnergyCountDataFilename(uint channel, const QString& filename);
void SetAllChannelEnergyTotalCountDataFilename(const QString& filename); void SetAllChannelEnergyTotalCountDataFilename(const QString& filename);
void SetTimeWinConformParticleData(uint time_win, uint conform_particle_count, const QString& filename); void SetTimeWinConformParticleData(uint time_win, uint conform_particle_count, const QString& filename);
void SetAnalysisCustomData(AnalysisType analysis_type, const QString& data_item_name, const QString& data_filename); void SetAnalysisCustomData(AnalysisType analysis_type, const QString& data_item_name, const QString& data_filename);
const QString& GetProjectDir() const; const QString& GetProjectDir() const;
@ -58,23 +51,16 @@ public:
const QString& GetMeasureDeviceParamsCfgFilename() const; const QString& GetMeasureDeviceParamsCfgFilename() const;
const QString& GetEnergyScaleFilename() const; const QString& GetEnergyScaleFilename() const;
const QString& GetEfficiencyScaleFilename() const; const QString& GetEfficiencyScaleFilename() const;
const QString& GetAllChannelParticleDataFilename() const; const QString& GetAllChannelParticleDataFilename() const;
const QString& GetSortAllChannelParticleDataFilename() const;
// const QMap<uint, QString>& GetChannelParticleDataFilenameList() const; // const QMap<uint, QString>& GetChannelParticleDataFilenameList() const;
// const QString& GetChannelParticleDataFilename(uint channel) const; // const QString& GetChannelParticleDataFilename(uint channel) const;
const QMap<uint, QString>& GetChannelAddressCountDataFilenameList() const; const QMap<uint, QString>& GetChannelAddressCountDataFilenameList() const;
const QString GetChannelAddressCountDataFilename(uint channel) const; const QString GetChannelAddressCountDataFilename(uint channel) const;
// const QString& GetAllChannelParticleTotalCountDataFilename() const; // const QString& GetAllChannelParticleTotalCountDataFilename() const;
const QMap<uint, QString>& GetChannelEnergyCountDataFilenameList() const; const QMap<uint, QString>& GetChannelEnergyCountDataFilenameList() const;
const QString GetChannelEnergyCountDataFilename(uint channel) const; const QString GetChannelEnergyCountDataFilename(uint channel) const;
const QString& GetAllChannelEnergyTotalCountDataFilename() const; const QString& GetAllChannelEnergyTotalCountDataFilename() const;
const QMap<uint, QString> GetTimeWinConformParticleDataFilenameList(uint time_win) const; const QMap<uint, QString> GetTimeWinConformParticleDataFilenameList(uint time_win) const;
const QString GetAnalysisCustomData(AnalysisType analysis_type, const QString& data_item_name); const QString GetAnalysisCustomData(AnalysisType analysis_type, const QString& data_item_name);
private: private:
@ -85,25 +71,18 @@ private:
QString _description_info; QString _description_info;
ulong _measure_preset_time = 0; ulong _measure_preset_time = 0;
uint _conform_time_win = 50; uint _conform_time_win = 50;
bool _is_measure_complete = false; bool _is_measure_complete = false;
QString _measure_device_params_cfg_filename; QString _measure_device_params_cfg_filename;
QString _energy_scale_filename; QString _energy_scale_filename;
QString _efficiency_scale_filename; QString _efficiency_scale_filename;
QString _all_channel_particle_data_filename; QString _all_channel_particle_data_filename;
QString _sorted_particle_data_filename;
// QMap<uint, QString> _channel_particle_data_filename_list; // QMap<uint, QString> _channel_particle_data_filename_list;
QMap<uint, QString> _channel_address_count_data_filename_list; QMap<uint, QString> _channel_address_count_data_filename_list;
// QString _all_channel_particle_total_count_data_filename; // QString _all_channel_particle_total_count_data_filename;
QMap<uint, QString> _channel_energy_count_data_filename_list; QMap<uint, QString> _channel_energy_count_data_filename_list;
QString _all_channel_energy_total_count_data_filename; QString _all_channel_energy_total_count_data_filename;
QMap<uint, QMap<uint, QString> > _time_win_conform_particle_data; QMap<uint, QMap<uint, QString> > _time_win_conform_particle_data;
QMap<AnalysisType, QMap<QString, QString> > _analysis_custom_data_set; QMap<AnalysisType, QMap<QString, QString> > _analysis_custom_data_set;
public: public: