1、添加反符合能谱;2、修改部分BUG
This commit is contained in:
parent
664b115aaa
commit
1c0e8569e5
|
|
@ -0,0 +1,158 @@
|
|||
#include "AntiConformEnergySpectrumView.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QwtPlotCurve>
|
||||
#include <QwtPlotCanvas>
|
||||
#include <QwtText>
|
||||
#include "CustomQwtPlot.h"
|
||||
#include <GlobalDefine.h>
|
||||
#include "csv.h"
|
||||
#include <QFileInfo>
|
||||
#include <QThread>
|
||||
#include "BusyIndicator.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <QPen>
|
||||
struct SpectrumData
|
||||
{
|
||||
int board_id;
|
||||
int channel_id;
|
||||
double energy;
|
||||
uint64_t timestamp;
|
||||
};
|
||||
|
||||
|
||||
AntiConformEnergySpectrumView::AntiConformEnergySpectrumView(QWidget *parent) :
|
||||
MeasureAnalysisView(parent)
|
||||
{
|
||||
this->setViewType(PlotFrame);
|
||||
|
||||
_plot = new CustomQwtPlot();
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->addWidget(_plot);
|
||||
|
||||
_plot->setCanvasBackground(Qt::white);
|
||||
QwtPlotCanvas* canvas = qobject_cast<QwtPlotCanvas*>(_plot->canvas());
|
||||
canvas->setFrameStyle(QFrame::NoFrame);
|
||||
|
||||
QFont font = this->font();
|
||||
font.setBold(false);
|
||||
QwtText x_label = QStringLiteral(u"能量(KeV)");
|
||||
QwtText y_label = QStringLiteral(u"反符合事件次数");
|
||||
x_label.setFont(font);
|
||||
y_label.setFont(font);
|
||||
_plot->setAxisTitle(QwtPlot::xBottom, x_label);
|
||||
_plot->setAxisTitle(QwtPlot::yLeft, y_label);
|
||||
|
||||
_plot->setAxisAutoScale(QwtPlot::xBottom, true);
|
||||
_plot->setAxisAutoScale(QwtPlot::yLeft, true);
|
||||
_plot->enableAxis(QwtPlot::xBottom);
|
||||
_plot->enableAxis(QwtPlot::yLeft);
|
||||
_plot->SetAxisDragScale(QwtPlot::xBottom, true);
|
||||
|
||||
_curve = new QwtPlotCurve();
|
||||
_curve->setStyle(QwtPlotCurve::Lines);
|
||||
_curve->setPen(QPen(QColor(23, 229, 238), 2));
|
||||
_plot->AddCurve(_curve);
|
||||
|
||||
_busy_indicator = new BusyIndicator(this);
|
||||
}
|
||||
|
||||
AntiConformEnergySpectrumView::~AntiConformEnergySpectrumView()
|
||||
{
|
||||
}
|
||||
|
||||
void AntiConformEnergySpectrumView::InitViewWorkspace(const QString &project_name)
|
||||
{
|
||||
Q_UNUSED(project_name);
|
||||
}
|
||||
|
||||
void AntiConformEnergySpectrumView::SetAnalyzeDataFilename(const QMap<QString, QVariant> &data_files_set)
|
||||
{
|
||||
const QString& data_filename = data_files_set.first().toString();
|
||||
if (!data_filename.isEmpty() && QFileInfo(data_filename).exists()) {
|
||||
this->_data_filename = data_filename;
|
||||
this->loadAndProcess();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AntiConformEnergySpectrumView::loadAndProcess()
|
||||
{
|
||||
auto functionToRun = [this]() {
|
||||
if (_data_filename.isEmpty()) return;
|
||||
|
||||
_busy_indicator->Start();
|
||||
|
||||
std::vector<SpectrumData> rawData;
|
||||
io::CSVReader<4> in(QStrToSysPath(_data_filename));
|
||||
in.read_header(io::ignore_extra_column,
|
||||
QString(QStringLiteral(u"板卡号")).toStdString(),
|
||||
QString(QStringLiteral(u"通道号")).toStdString(),
|
||||
QString(QStringLiteral(u"能量(KeV)")).toStdString(),
|
||||
QString(QStringLiteral(u"时间计数")).toStdString());
|
||||
|
||||
int board, channel;
|
||||
double energy;
|
||||
unsigned long long time_count;
|
||||
while (in.read_row(board, channel, energy, time_count)) {
|
||||
SpectrumData sd;
|
||||
sd.board_id = board;
|
||||
sd.channel_id = channel;
|
||||
sd.energy = energy;
|
||||
sd.timestamp = time_count;
|
||||
rawData.push_back(sd);
|
||||
}
|
||||
|
||||
if (rawData.empty()) {
|
||||
_busy_indicator->Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
const int STEP = 1;
|
||||
std::map<int, double> hist;
|
||||
|
||||
for (const auto& spdt : rawData) {
|
||||
int idx = static_cast<int>(spdt.energy) / STEP;
|
||||
hist[idx] += 1.0;
|
||||
}
|
||||
|
||||
QVector<double> vx, vy;
|
||||
for (const auto& pair : hist) {
|
||||
vx.push_back(pair.first * STEP);
|
||||
vy.push_back(pair.second);
|
||||
}
|
||||
|
||||
if (vx.isEmpty()) {
|
||||
_busy_indicator->Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
double dmaxx = *std::max_element(vx.begin(), vx.end());
|
||||
double dmaxy = *std::max_element(vy.begin(), vy.end());
|
||||
|
||||
QMetaObject::invokeMethod(this, [this, vx, vy, dmaxx, dmaxy]() {
|
||||
_curve->setSamples(vx, vy);
|
||||
|
||||
_plot->setAxisScale(QwtPlot::xBottom, 0, dmaxx);
|
||||
_plot->setAxisScale(QwtPlot::yLeft, 0, dmaxy * 1.1);
|
||||
_plot->replot();
|
||||
_busy_indicator->Stop();
|
||||
}, Qt::QueuedConnection);
|
||||
};
|
||||
|
||||
QThread* load_thread = QThread::create(functionToRun);
|
||||
load_thread->start();
|
||||
}
|
||||
|
||||
void AntiConformEnergySpectrumView::showEvent(QShowEvent *e)
|
||||
{
|
||||
Q_UNUSED(e);
|
||||
if (_busy_indicator) {
|
||||
_busy_indicator->setGeometry(this->rect());
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef ANTICONFORMENERGYSPECTRUMVIEW_H
|
||||
#define ANTICONFORMENERGYSPECTRUMVIEW_H
|
||||
|
||||
#include "MeasureAnalysisView.h"
|
||||
|
||||
class CustomQwtPlot;
|
||||
class QwtPlotCurve;
|
||||
class BusyIndicator;
|
||||
|
||||
class AntiConformEnergySpectrumView : public MeasureAnalysisView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AntiConformEnergySpectrumView(QWidget *parent = nullptr);
|
||||
virtual ~AntiConformEnergySpectrumView();
|
||||
virtual void InitViewWorkspace(const QString& project_name) override final;
|
||||
virtual void SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set) override;
|
||||
|
||||
protected:
|
||||
virtual void showEvent(QShowEvent* e) override final;
|
||||
|
||||
private:
|
||||
void loadAndProcess(); // 读取CSV,执行符合处理,绘制能谱折线图
|
||||
|
||||
private:
|
||||
BusyIndicator* _busy_indicator = nullptr;
|
||||
CustomQwtPlot* _plot = nullptr;
|
||||
QwtPlotCurve* _curve = nullptr;
|
||||
QString _data_filename;
|
||||
};
|
||||
|
||||
#endif // ANTICONFORMENERGYSPECTRUMVIEW_H
|
||||
|
||||
|
||||
|
|
@ -106,9 +106,6 @@ private:
|
|||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QColor getDistinctColorForManyCurves(int curve_index);
|
||||
|
||||
#endif // CUSTOMQWTPLOT_H
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ void SortDataByTimestamp(std::vector<SpectrumData>& data)
|
|||
bool ProcessCoincidence(
|
||||
std::vector<SpectrumData>& data,
|
||||
std::vector<CoincidenceEvent>& events,
|
||||
std::vector<AntiCoincidenceEvent>& anti_coincidence_events,
|
||||
unsigned int time_window,
|
||||
int min_order,
|
||||
int max_order
|
||||
|
|
@ -187,8 +188,13 @@ bool ProcessCoincidence(
|
|||
if (n < min_order) {
|
||||
return false;
|
||||
}
|
||||
if (min_order < 2 || max_order < min_order)
|
||||
return false;
|
||||
std::vector<bool> is_used(n, false);
|
||||
// 使用滑动窗口寻找符合事件
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (is_used[i])
|
||||
continue;
|
||||
std::vector<SpectrumData> current_coincidence;
|
||||
current_coincidence.push_back(data[i]);
|
||||
// 寻找时间窗口内的其他事件
|
||||
|
|
@ -206,6 +212,10 @@ bool ProcessCoincidence(
|
|||
// 保存符合条件的事件
|
||||
int coincidence_order = current_coincidence.size();
|
||||
if (coincidence_order >= min_order && coincidence_order <= max_order) {
|
||||
// 标记这些事件已被使用
|
||||
for (int k = 0; k < coincidence_order; ++k) {
|
||||
is_used[i + k] = true;
|
||||
}
|
||||
CoincidenceEvent result;
|
||||
result.coincidence_order = coincidence_order;
|
||||
result.events = current_coincidence;
|
||||
|
|
@ -213,6 +223,31 @@ bool ProcessCoincidence(
|
|||
events.push_back(result);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (is_used[i])
|
||||
continue;
|
||||
bool is_anti = true;
|
||||
// 检查前向时间窗口内是否有其他事件
|
||||
if (i > 0) {
|
||||
unsigned long long diff_prev = data[i].timestamp - data[i-1].timestamp;
|
||||
if (diff_prev <= time_window)
|
||||
is_anti = false;
|
||||
}
|
||||
// 检查后向时间窗口内是否有其他事件
|
||||
if (i < n-1 && is_anti) {
|
||||
unsigned long long diff_next = data[i+1].timestamp - data[i].timestamp;
|
||||
if (diff_next <= time_window)
|
||||
is_anti = false;
|
||||
}
|
||||
// 满足反符合条件
|
||||
if (is_anti) {
|
||||
AntiCoincidenceEvent res;
|
||||
res.event = data[i];
|
||||
res.time_window = time_window;
|
||||
anti_coincidence_events.push_back(res);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,11 @@ namespace F2t9Order {
|
|||
std::vector<SpectrumData> events; // 符合的事件集合
|
||||
unsigned int time_window; // 使用的时间窗口(秒)
|
||||
};
|
||||
// 反符合事件结构体(只包含未参与任何符合的独立事件)
|
||||
struct AntiCoincidenceEvent {
|
||||
SpectrumData event; // 反符合单事件
|
||||
unsigned int time_window; // 时间窗口
|
||||
};
|
||||
|
||||
// 读取CSV数据文件
|
||||
std::vector<SpectrumData> ReadCsv(const std::string& filename);
|
||||
|
|
@ -39,6 +44,7 @@ namespace F2t9Order {
|
|||
bool ProcessCoincidence(
|
||||
std::vector<SpectrumData> &data,
|
||||
std::vector<CoincidenceEvent> &events,
|
||||
std::vector<AntiCoincidenceEvent>& anti_coincidence_events,
|
||||
unsigned int time_window, // 时间窗口(纳秒)
|
||||
int min_order = 2, // 最小符合次数
|
||||
int max_order = 9 // 最大符合次数
|
||||
|
|
|
|||
|
|
@ -466,6 +466,7 @@ bool CoincidenceEventAnalysisTask::processTask()
|
|||
if (particle_data_filename.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
std::string time_win_str = QString(QStringLiteral(u"时间窗口")).toStdString();
|
||||
std::string event_id_str = QString(QStringLiteral(u"事件ID")).toStdString();
|
||||
std::string board_id_str = QString(QStringLiteral(u"板卡号")).toStdString();
|
||||
std::string channel_id_str = QString(QStringLiteral(u"通道号")).toStdString();
|
||||
|
|
@ -490,8 +491,9 @@ bool CoincidenceEventAnalysisTask::processTask()
|
|||
spec_data_item.timestamp)) {
|
||||
spec_data.push_back(spec_data_item);
|
||||
}
|
||||
std::vector<CoincidenceEvent> events;
|
||||
if (!ProcessCoincidence(spec_data, events, project_model->GetConformTimeWin())) {
|
||||
std::vector<CoincidenceEvent> coincidence_events;
|
||||
std::vector<AntiCoincidenceEvent> anti_coincidence_events;
|
||||
if (!ProcessCoincidence(spec_data, coincidence_events, anti_coincidence_events, project_model->GetConformTimeWin())) {
|
||||
LOG_WARN(QStringLiteral(u"粒子符合数据处理异常!"));
|
||||
}
|
||||
const QString& coincidence_data_dir_name = QStringLiteral(u"粒子符合数据");
|
||||
|
|
@ -500,7 +502,7 @@ bool CoincidenceEventAnalysisTask::processTask()
|
|||
const QString& coincidence_data_dir_path = project_dir.filePath(coincidence_data_dir_name);
|
||||
QMap<int, std::shared_ptr<std::ofstream> > coincidence_data_out_stream_map;
|
||||
unsigned long long event_id = 0;
|
||||
for (const CoincidenceEvent& event : events) {
|
||||
for (const CoincidenceEvent& event : coincidence_events) {
|
||||
++ event_id;
|
||||
const QString& event_data_filename = QDir(coincidence_data_dir_path).filePath(QStringLiteral(u"[%1ns]%2个粒子符合事件[未刻度].csv").arg(project_model->GetConformTimeWin()).arg(event.coincidence_order));
|
||||
if ( !coincidence_data_out_stream_map.contains(event.coincidence_order) ) {
|
||||
|
|
@ -514,6 +516,13 @@ bool CoincidenceEventAnalysisTask::processTask()
|
|||
}
|
||||
project_model->SetTimeWinConformParticleData(project_model->GetConformTimeWin(), event.coincidence_order, event_data_filename);
|
||||
}
|
||||
const QString& anti_event_data_filename = QDir(coincidence_data_dir_path).filePath(QStringLiteral(u"反符合事件[未刻度].csv"));
|
||||
std::ofstream anti_event_data_out_stream(QStrToSysPath(anti_event_data_filename));
|
||||
anti_event_data_out_stream << time_win_str << "," << board_id_str << "," << channel_id_str << "," << addr_str << "," << time_str << std::endl;
|
||||
for (const AntiCoincidenceEvent& anti_event : anti_coincidence_events) {
|
||||
anti_event_data_out_stream << anti_event.time_window << "," << anti_event.event.board_id << "," << anti_event.event.channel_id << "," << anti_event.event.energy << "," << anti_event.event.timestamp << std::endl;
|
||||
}
|
||||
project_model->SetAntiConformParticleData(project_model->GetConformTimeWin(), anti_event_data_filename);
|
||||
} catch (const std::exception& e) {
|
||||
const QString& e_what = QString::fromUtf8(e.what());
|
||||
LOG_WARN(QStringLiteral(u"粒子符合数据处理异常:%1").arg(e_what));
|
||||
|
|
@ -931,7 +940,83 @@ bool EnergyScaleCoincidenceDataTask::processTask()
|
|||
conformParticleDataEnergyScale(time_win, coincidence_order, conform_particle_data_filename);
|
||||
}
|
||||
}
|
||||
|
||||
const QString& info = QStringLiteral(u"符合能谱数据处理完成.");
|
||||
LOG_INFO(info);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EnergyScaleaAntiCoincidenceDataTask::processTask()
|
||||
{
|
||||
const QString& project_name = GetProjectName();
|
||||
MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(project_name);
|
||||
if (project_model == nullptr) {
|
||||
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& coincidence_data_dir_name = QStringLiteral(u"符合能谱数据");
|
||||
QDir project_dir(project_model->GetProjectDir());
|
||||
project_dir.mkpath(coincidence_data_dir_name);
|
||||
const QString& coincidence_data_dir_path = project_dir.filePath(coincidence_data_dir_name);
|
||||
|
||||
std::string time_win_str = QString(QStringLiteral(u"时间窗口")).toStdString();
|
||||
std::string board_id_str = QString(QStringLiteral(u"板卡号")).toStdString();
|
||||
std::string channel_id_str = QString(QStringLiteral(u"通道号")).toStdString();
|
||||
std::string addr_str = QString(QStringLiteral(u"道址")).toStdString();
|
||||
std::string energy_str = QString(QStringLiteral(u"能量(KeV)")).toStdString();
|
||||
std::string time_str = QString(QStringLiteral(u"时间计数")).toStdString();
|
||||
|
||||
const auto& anti_conform_particle_data = project_model->GetAntiConformParticleData();
|
||||
for (const auto& time_win : anti_conform_particle_data.keys()) {
|
||||
const auto&anti_conform_particle_data_filename = anti_conform_particle_data.value(time_win);
|
||||
try {
|
||||
io::CSVReader<
|
||||
5,
|
||||
io::trim_chars<' ', '\t'>,
|
||||
io::double_quote_escape<',', '"'>,
|
||||
io::throw_on_overflow,
|
||||
io::empty_line_comment>
|
||||
reader(QStrToSysPath(anti_conform_particle_data_filename));
|
||||
reader.read_header(io::ignore_extra_column, time_win_str, board_id_str, channel_id_str, addr_str, time_str);
|
||||
|
||||
const QString& anti_coincidence_energy_data_filename = QDir(coincidence_data_dir_path).filePath(QStringLiteral(u"反符合粒子事件.csv"));
|
||||
std::ofstream out_stream(QStrToSysPath(anti_coincidence_energy_data_filename));
|
||||
out_stream << time_win_str << "," << board_id_str << "," << channel_id_str << "," << energy_str << "," << time_str << "\n" ;
|
||||
using namespace CoincidenceSpectrum::F2t9Order;
|
||||
unsigned int time_window;
|
||||
SpectrumData data_item;
|
||||
while (reader.read_row(
|
||||
time_window,
|
||||
data_item.board_id,
|
||||
data_item.channel_id,
|
||||
data_item.energy,
|
||||
data_item.timestamp)) {
|
||||
int channel_num = (data_item.board_id) * 4 + (data_item.channel_id + 1);
|
||||
const QString& channel_name = QStringLiteral(u"通道%1").arg(channel_num);
|
||||
auto coeffs = energy_scale_data_model.GetEnergyFitResultCoeffs(channel_name);
|
||||
if (!coeffs.empty()) {
|
||||
data_item.energy = GaussPolyCoe::Predict(coeffs, data_item.energy);
|
||||
out_stream << time_window << "," << data_item.board_id << "," << data_item.channel_id << "," << data_item.energy << "," << data_item.timestamp << "\n" ;
|
||||
} else {
|
||||
LOG_WARN(QStringLiteral(u"符合能谱数据处理异常:%1能量刻度拟合参数为空!").arg(channel_name));
|
||||
}
|
||||
}
|
||||
out_stream.close();
|
||||
project_model->SetAntiConformEnergyData(time_win, anti_coincidence_energy_data_filename);
|
||||
} catch (const std::exception& e) {
|
||||
const QString& e_what = QString::fromStdString(e.what());
|
||||
LOG_WARN(QStringLiteral(u"反符合能谱数据处理异常:%1").arg(e_what));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const QString& info = QStringLiteral(u"反符合能谱数据处理完成.");
|
||||
LOG_INFO(info);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,6 +143,12 @@ namespace DataProcessWorkPool
|
|||
private:
|
||||
virtual bool processTask() override;
|
||||
};
|
||||
|
||||
class EnergyScaleaAntiCoincidenceDataTask : public DataProcessTask
|
||||
{
|
||||
private:
|
||||
virtual bool processTask() override;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DATAPROCESSWORKPOOL_H
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
// 转换Qt字符串路径为系统编码的C字符串(解决中文路径问题)
|
||||
static const char* QStrToSysPath(const QString& qstr_path)
|
||||
{
|
||||
static std::string sys_path; // 静态变量避免内存释放
|
||||
std::string sys_path; // 静态变量避免内存释放
|
||||
#ifdef Q_OS_WIN
|
||||
// Windows:转为GBK编码
|
||||
QTextCodec* gbkCodec = QTextCodec::codecForName("GBK");
|
||||
|
|
|
|||
|
|
@ -113,6 +113,16 @@ void MeasureAnalysisProjectModel::SetTimeWinConformEnergyData(uint time_win, uin
|
|||
this->_time_win_conform_energy_data[time_win][conform_particle_count] = filename;
|
||||
}
|
||||
|
||||
void MeasureAnalysisProjectModel::SetAntiConformParticleData(uint time_win, const QString &filename)
|
||||
{
|
||||
this->_anti_conform_particle_data[time_win] = filename;
|
||||
}
|
||||
|
||||
void MeasureAnalysisProjectModel::SetAntiConformEnergyData(uint time_win, const QString &filename)
|
||||
{
|
||||
this->_anti_conform_energy_data[time_win] = filename;
|
||||
}
|
||||
|
||||
void MeasureAnalysisProjectModel::SetAnalysisCustomData(AnalysisType analysis_type, const QString &data_item_name, const QString &data_filename)
|
||||
{
|
||||
this->_analysis_custom_data_set[analysis_type][data_item_name] = data_filename;
|
||||
|
|
@ -259,6 +269,26 @@ const QMap<uint, QString> MeasureAnalysisProjectModel::GetTimeWinConformEnergyDa
|
|||
return conform_energy_data;
|
||||
}
|
||||
|
||||
const QMap<uint, QString> &MeasureAnalysisProjectModel::GetAntiConformParticleData()
|
||||
{
|
||||
return _anti_conform_particle_data;
|
||||
}
|
||||
|
||||
const QString &MeasureAnalysisProjectModel::GetAntiConformParticleData(uint time_win)
|
||||
{
|
||||
return _anti_conform_particle_data.value(time_win);
|
||||
}
|
||||
|
||||
const QMap<uint, QString> &MeasureAnalysisProjectModel::GetAntiConformEnergyData()
|
||||
{
|
||||
return _anti_conform_energy_data;
|
||||
}
|
||||
|
||||
const QString &MeasureAnalysisProjectModel::GetAntiConformEnergyData(uint time_win)
|
||||
{
|
||||
return _anti_conform_energy_data.value(time_win);
|
||||
}
|
||||
|
||||
const QString MeasureAnalysisProjectModel::GetAnalysisCustomData(AnalysisType analysis_type, const QString &data_item_name)
|
||||
{
|
||||
return this->_analysis_custom_data_set.value(analysis_type).value(data_item_name);
|
||||
|
|
@ -403,6 +433,16 @@ bool MeasureAnalysisProjectModel::LoadProjectModel(const QString& project_filena
|
|||
this->_time_win_conform_energy_data[time_win] = conform_energy_data;
|
||||
}
|
||||
|
||||
const auto& anti_conform_particle_data = model_data["AntiConformParticleData"].toMap();
|
||||
for (auto it = anti_conform_particle_data.constBegin(); it!=anti_conform_particle_data.constEnd(); ++it) {
|
||||
this->_anti_conform_particle_data[it.key().toUInt()] = ProjectAbsFilename(it.value().toString());
|
||||
}
|
||||
|
||||
const auto& anti_conform_energy_data = model_data["AntiConformEnergyData"].toMap();
|
||||
for (auto it = anti_conform_energy_data.constBegin(); it!=anti_conform_energy_data.constEnd(); ++it) {
|
||||
this->_anti_conform_energy_data[it.key().toUInt()] = ProjectAbsFilename(it.value().toString());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -473,6 +513,18 @@ bool MeasureAnalysisProjectModel::SaveProjectModel()
|
|||
}
|
||||
project_json_obj_map["TimeWinConformEnergyData"] = time_win_conform_energy_data;
|
||||
|
||||
QVariantMap anti_conform_particle_data;
|
||||
for (auto it = this->_anti_conform_particle_data.constBegin(); it != this->_anti_conform_particle_data.constEnd(); ++it) {
|
||||
anti_conform_particle_data[QString::number(it.key())] = ProjectRelativeFilename(it.value());
|
||||
}
|
||||
project_json_obj_map["AntiConformParticleData"] = anti_conform_particle_data;
|
||||
|
||||
QVariantMap anti_conform_energy_data;
|
||||
for (auto it = this->_anti_conform_energy_data.constBegin(); it != this->_anti_conform_energy_data.constEnd(); ++it) {
|
||||
anti_conform_energy_data[QString::number(it.key())] = ProjectRelativeFilename(it.value());
|
||||
}
|
||||
project_json_obj_map["AntiConformEnergyData"] = anti_conform_energy_data;
|
||||
|
||||
// 将项目模型保存到json文件
|
||||
QJsonDocument json_doc = QJsonDocument::fromVariant(project_json_obj_map);
|
||||
QFile json_file(this->_project_filename);
|
||||
|
|
@ -743,6 +795,10 @@ void MeasureAnalysisProjectModelList::ApplyEnergyScale(const QString &project_na
|
|||
auto coincidence_process_task = new DataProcessWorkPool::EnergyScaleCoincidenceDataTask;
|
||||
coincidence_process_task->SetFinishedNotifier(this, "onEnergyScaleCoincidenceDataFinished", project_name);
|
||||
coincidence_process_task->StartTask();
|
||||
|
||||
auto anti_coincidence_process_task = new DataProcessWorkPool::EnergyScaleaAntiCoincidenceDataTask;
|
||||
anti_coincidence_process_task->SetFinishedNotifier(this, "onEnergyScaleAntiCoincidenceDataFinished", project_name);
|
||||
anti_coincidence_process_task->StartTask();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -954,11 +1010,6 @@ void MeasureAnalysisProjectModelList::onEnergyScaleCoincidenceDataFinished(bool
|
|||
auto energy_total_count_spec_item = node_map[item_name];
|
||||
this->SetNodeStatus(energy_total_count_spec_item, status, status_ok);
|
||||
}
|
||||
item_name = QStringLiteral(u"反符合能谱[%1ns]").arg(conform_time_win);
|
||||
if (node_map.contains(item_name)) {
|
||||
auto energy_total_count_spec_item = node_map[item_name];
|
||||
this->SetNodeStatus(energy_total_count_spec_item, status, status_ok);
|
||||
}
|
||||
item_name = QStringLiteral(u"二维符合能谱[%1ns]").arg(conform_time_win);
|
||||
if (node_map.contains(item_name)) {
|
||||
auto energy_total_count_spec_item = node_map[item_name];
|
||||
|
|
@ -977,6 +1028,33 @@ void MeasureAnalysisProjectModelList::onEnergyScaleCoincidenceDataFinished(bool
|
|||
}
|
||||
}
|
||||
|
||||
void MeasureAnalysisProjectModelList::onEnergyScaleAntiCoincidenceDataFinished(bool ok, const QString &project_name, const QVariant &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
if ( !ok )
|
||||
return;
|
||||
if (this->_project_models.contains(project_name)) {
|
||||
auto pro_model = this->_project_models[project_name];
|
||||
auto& node_map = this->_project_node_items[project_name];
|
||||
const auto& anti_conform_energy_data = pro_model->GetAntiConformEnergyData();
|
||||
for (const auto& time_win : anti_conform_energy_data.keys()) {
|
||||
bool status_ok = false;
|
||||
QString status = QStringLiteral(u"无效");
|
||||
const QString& data_filename = anti_conform_energy_data.value(time_win);
|
||||
if ( (!data_filename.isEmpty()) && QFile::exists(data_filename) ) {
|
||||
status_ok = true;
|
||||
status = QStringLiteral(u"有效");
|
||||
}
|
||||
QString item_name = QStringLiteral(u"反符合能谱[%1ns]").arg(time_win);
|
||||
if (node_map.contains(item_name)) {
|
||||
auto anti_conform_erergy_spec_item = node_map[item_name];
|
||||
this->SetNodeStatus(anti_conform_erergy_spec_item, status, status_ok);
|
||||
}
|
||||
}
|
||||
pro_model->SaveProjectModel();
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureAnalysisProjectModelList::intiProjectNodeStruce(MeasureAnalysisProjectModel* pro_model)
|
||||
{
|
||||
if (!pro_model) {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ public:
|
|||
void SetParticleEnergyDataFilename(const QString& filename);
|
||||
void SetTimeWinConformParticleData(uint time_win, uint conform_particle_count, const QString& filename);
|
||||
void SetTimeWinConformEnergyData(uint time_win, uint conform_particle_count, const QString& filename);
|
||||
void SetAntiConformParticleData(uint time_win, const QString& filename);
|
||||
void SetAntiConformEnergyData(uint time_win, const QString& filename);
|
||||
void SetAnalysisCustomData(AnalysisType analysis_type, const QString& data_item_name, const QString& data_filename);
|
||||
|
||||
const QString& GetProjectDir() const;
|
||||
|
|
@ -63,6 +65,10 @@ public:
|
|||
const QMap<uint, QString> GetTimeWinConformParticleDataFilenameList(uint time_win) const;
|
||||
const QMap<uint, QMap<uint, QString> > GetConformParticleEnergyDataFilenameList() const;
|
||||
const QMap<uint, QString> GetTimeWinConformEnergyDataFilenameList(uint time_win) const;
|
||||
const QMap<uint, QString>& GetAntiConformParticleData();
|
||||
const QString& GetAntiConformParticleData(uint time_win);
|
||||
const QMap<uint, QString>& GetAntiConformEnergyData();
|
||||
const QString& GetAntiConformEnergyData(uint time_win);
|
||||
const QString GetAnalysisCustomData(AnalysisType analysis_type, const QString& data_item_name);
|
||||
|
||||
void SetDeviceGuid(const QString& device_guid);
|
||||
|
|
@ -96,6 +102,9 @@ private:
|
|||
QString _particle_energy_data_filename;
|
||||
QMap<uint, QMap<uint, QString> > _time_win_conform_particle_data;
|
||||
QMap<uint, QMap<uint, QString> > _time_win_conform_energy_data;
|
||||
QMap<uint, QString> _anti_conform_particle_data;
|
||||
QMap<uint, QString> _anti_conform_energy_data;
|
||||
|
||||
QMap<AnalysisType, QMap<QString, QString> > _analysis_custom_data_set;
|
||||
|
||||
QString _device_guid;
|
||||
|
|
@ -160,6 +169,7 @@ private slots:
|
|||
void onEnergyCountProcessFinished(bool ok, const QString& project_name, const QVariant& data);
|
||||
void onCoincidenceProcessFinished(bool ok, const QString& project_name, const QVariant& data);
|
||||
void onEnergyScaleCoincidenceDataFinished(bool ok, const QString& project_name, const QVariant& data);
|
||||
void onEnergyScaleAntiCoincidenceDataFinished(bool ok, const QString& project_name, const QVariant& data);
|
||||
|
||||
signals:
|
||||
void removedProjectModel(const QString& project_name);
|
||||
|
|
|
|||
|
|
@ -269,6 +269,13 @@ void MeasureAnalysisTreeView::onNodeDoubleClicked(const QModelIndex& index)
|
|||
}
|
||||
}
|
||||
} break;
|
||||
case AnalysisType::AntiCoincidenceSpectrumView: {
|
||||
MeasureAnalysisProjectModel* project_model = _model->GetProjectModel(project_name);
|
||||
if (project_model) {
|
||||
auto file_name = project_model->GetAntiConformEnergyData(project_model->GetConformTimeWin());
|
||||
data_files_set[QStringLiteral(u"反符合粒子数据")] = file_name;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "ParticleTimeDifferenceView.h"
|
||||
#include "TwoDSpectralCompliance.h"
|
||||
#include "ConformToTheEnergySpectrum.h"
|
||||
#include "AntiConformEnergySpectrumView.h"
|
||||
#include <QMap>
|
||||
|
||||
MeasureAnalysisView* MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type)
|
||||
|
|
@ -101,8 +102,8 @@ MeasureAnalysisView* MeasureAnalysisView::NewAnalyzeView(AnalysisType view_type)
|
|||
new_view->setDeleteOnClose(false);
|
||||
} break;
|
||||
case AnalysisType::AntiCoincidenceSpectrumView: {
|
||||
// new_view = new MeasureAnalysisDataTableView;
|
||||
// new_view->setDeleteOnClose(false);
|
||||
new_view = new AntiConformEnergySpectrumView;
|
||||
new_view->setDeleteOnClose(false);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
20
src/src.pro
20
src/src.pro
|
|
@ -8,7 +8,6 @@ msvc {
|
|||
QMAKE_CXXFLAGS += /utf-8
|
||||
}
|
||||
|
||||
|
||||
include($${PWD}/../Common.pri)
|
||||
include($${PROJECT_DIR}/3rdlib/QsLog/QsLog.pri)
|
||||
include($${PROJECT_DIR}/3rdlib/QtAdvancedDockingSystem/ads.pri)
|
||||
|
|
@ -38,8 +37,8 @@ INCLUDEPATH += \
|
|||
$${PWD}/DeviceParameterConfig \
|
||||
$${PWD}/2DSpectralCompliance \
|
||||
$${PWD}/ConformToTheEnergySpectrum \
|
||||
$${PWD}/NuclideLib
|
||||
|
||||
$${PWD}/NuclideLib \
|
||||
$${PWD}/AntiConformEnergySpectrumView
|
||||
|
||||
DEPENDPATH += \
|
||||
$${PWD}/BusyIndicator \
|
||||
|
|
@ -57,11 +56,8 @@ DEPENDPATH += \
|
|||
$${PWD}/DeviceParameterConfig \
|
||||
$${PWD}/2DSpectralCompliance \
|
||||
$${PWD}/ConformToTheEnergySpectrum \
|
||||
$${PWD}/NuclideLib
|
||||
|
||||
|
||||
|
||||
|
||||
$${PWD}/NuclideLib \
|
||||
$${PWD}/AntiConformEnergySpectrumView
|
||||
|
||||
SOURCES += \
|
||||
2DSpectralCompliance/TwoDSpectralCompliance.cpp \
|
||||
|
|
@ -104,6 +100,7 @@ SOURCES += \
|
|||
EnergyCountPeakFitView/EnergyCountPeakFitView.cpp \
|
||||
ConformToTheEnergySpectrum/ConformToTheEnergySpectrum.cpp \
|
||||
NuclideLib/NuclideLib.cpp \
|
||||
AntiConformEnergySpectrumView/AntiConformEnergySpectrumView.cpp \
|
||||
main.cpp
|
||||
|
||||
HEADERS += \
|
||||
|
|
@ -149,10 +146,8 @@ HEADERS += \
|
|||
ThreeDimensionalConformityAnalysisView/ThreeDDisplay.h \
|
||||
EnergyCountPeakFitView/EnergyCountPeakFitView.h \
|
||||
ConformToTheEnergySpectrum/ConformToTheEnergySpectrum.h \
|
||||
NuclideLib/NuclideLib.h
|
||||
|
||||
|
||||
|
||||
NuclideLib/NuclideLib.h \
|
||||
AntiConformEnergySpectrumView/AntiConformEnergySpectrumView.h
|
||||
|
||||
FORMS += \
|
||||
2DSpectralCompliance/TwoDSpectralCompliance.ui \
|
||||
|
|
@ -172,7 +167,6 @@ FORMS += \
|
|||
ThreeDimensionalConformityAnalysisView/ConformityAnalysis.ui \
|
||||
NuclideLib/NuclideLib.ui
|
||||
|
||||
|
||||
DEFINES += ENABLE_DEBUG
|
||||
contains(DEFINES, ENABLE_DEBUG) {
|
||||
CONFIG += console
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user