EnergySpectrumAnalyer/src/ThreeDimensionalConformityAnalysisView/ConformityAnalysis.h
2026-05-20 17:53:49 +08:00

197 lines
8.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef CONFORMITYANALYSIS_H
#define CONFORMITYANALYSIS_H
#include <QWidget>
#include <iostream>
#include "ParticleDataStatistics.h"
#include "ThreeDDisplay.h"
#include "csv.h"
#include "MeasureAnalysisView.h"
#include <QVector>
#include <QDateTime>
#include <QJsonObject>
#include <QJsonArray>
#include <QtConcurrent>
#include <QFutureWatcher>
#include <QMutex>
#include <QMetaType>
#include <QTextStream>
#include <QDataStream>
// Ui类前向声明
namespace Ui {
class ConformityAnalysis;
}
typedef struct particleCoincidenceEvent
{
int eventId;//事件ID
int board;//板卡号
int channel;//通道号
double energy;//能量
qulonglong timeCounter;//时间计数
}PARTICLECOINCIDENCEEVENT;
// 预计算结果结构体(仅保存计算后的数据)
struct ConformityCalculatedResult {
int conformCount; // 符合粒子数
QString dataFileName; // 原始CSV文件名
int totalEvents; // 符合事件总计数
double primaryEnergyStart; // 初级粒子能量范围-起始
double primaryEnergyEnd; // 初级粒子能量范围-结束
double secondaryEnergyStart; // 次级粒子能量范围-起始
double secondaryEnergyEnd; // 次级粒子能量范围-结束
// 板卡通道计数数据8板×4通道
int boardChannelData[MAX_BOARD][MAX_CHANNEL];
// 初级粒子计数数据
QMap<QString, int> firstParticleData;
// 三维曲面数据
QVector<SurfacePoint> surfaceData;
// 构造函数
ConformityCalculatedResult() {
memset(boardChannelData, 0, sizeof(boardChannelData));
totalEvents = 0;
primaryEnergyStart = primaryEnergyEnd = 0.0;
secondaryEnergyStart = secondaryEnergyEnd = 0.0;
}
};
Q_DECLARE_METATYPE(ConformityCalculatedResult)
// 一致性分析历史数据结构体
struct ConformityHistoryItem {
QDateTime timestamp; // 保存时间戳
QString dataFileName; // 原始CSV文件名
int conformCount; // 符合粒子数2/3/4...9
int totalEvents; // 符合事件总计数
double primaryEnergyStart; // 初级粒子能量范围-起始
double primaryEnergyEnd; // 初级粒子能量范围-结束
double secondaryEnergyStart; // 次级粒子能量范围-起始
double secondaryEnergyEnd; // 次级粒子能量范围-结束
// 板卡通道计数数据8板×4通道
int boardChannelData[MAX_BOARD][MAX_CHANNEL];
// 初级粒子计数数据
QMap<QString, int> firstParticleData;
// 三维曲面数据
QVector<SurfacePoint> surfaceData;
// JSON序列化/反序列化方法
QJsonObject toJson() const;
static ConformityHistoryItem fromJson(const QJsonObject& obj);
// 转换为预计算结果
ConformityCalculatedResult toCalculatedResult() const;
// 从预计算结果创建历史记录
static ConformityHistoryItem fromCalculatedResult(const ConformityCalculatedResult& result);
};
Q_DECLARE_METATYPE(ConformityHistoryItem)
class ConformityAnalysis : public MeasureAnalysisView
{
Q_OBJECT
private:
QMap<QString, int> m_FirstParticle;
QMap<QString, int> m_subordinate;
QVector<particleCoincidenceEvent*> m_beginVector;
QVector<particleCoincidenceEvent*> m_secondVector;
QVector<SurfacePoint> m_surfaceData;
public:
explicit ConformityAnalysis(QWidget *parent = nullptr);
~ConformityAnalysis();
virtual void InitViewWorkspace(const QString& project_name) override final;
virtual void SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set);
//设置csv文件路径及文件名称
void setCsvFile(QString fileName);
//读取csv文件兼容旧代码
void readCsv();
private slots:
void slot_InitialState();
void slot_ClickedBoard(int board,int channel);
// 符合数切换槽函数
void slot_ConformCountChanged(int index);
// 单个符合数解析完成槽函数
void onSingleParseFinished(int conformCount);
// 所有符合数解析完成槽函数
void onAllParseFinished();
// 保存单个预计算结果到历史记录(主线程执行)
void saveResultToHistory(const ConformityCalculatedResult& result);
private:
//处理板卡信息
void handleBoard(const QVector<particleCoincidenceEvent*>& data, int boardChannelData[MAX_BOARD][MAX_CHANNEL]);
//统计每个板卡的初级粒子计数
QMap<QString, int> statisticsFirstParticleQuantity(const QVector<particleCoincidenceEvent*>& data);
//处理当前板卡初级粒子信息
QVector<particleCoincidenceEvent*> handleBasicSubordinate(int Board, int Channel, const QVector<particleCoincidenceEvent*>& data);
//处理次级粒子信息
QMap<QString,int> handleSubordinate(QVector<particleCoincidenceEvent*> &eventData,int Board, int Channel);
// 获取最大值
int getMaxValue();
//计算全部的初级粒子范围 和 次级粒子范围
void calculateFirstSecondRange(const QVector<particleCoincidenceEvent*>& data,
double& firstStart, double& firstEnd,
double& secondStart, double& secondEnd);
//设置板卡数据信息
void setAllBoardData();
//设置符合事件相关信息
void setThreeUiData();
//全部谱图数据处理
QVector<SurfacePoint> generateSurfaceData(const QVector<particleCoincidenceEvent*> events);
// 数据保存/加载核心方法(按符合数分文件)
void loadHistoryFromFile();
void saveHistoryToFile();
// 流式写入JSON零大小限制
void saveJsonStream(int conformCount, const ConformityHistoryItem& item);
// 二进制保存超大曲面数据
void saveSurfaceDataToBinary(int conformCount, const QVector<SurfacePoint>& data);
// 仅保存指定符合数的历史记录到对应文件
void saveSingleHistoryToFile(int conformCount, const ConformityHistoryItem& item);
int saveCurrentAnalysisToHistory(int conformCount);
// 根据符合数和文件名查找历史记录
int findHistoryIndex(const QString& fileName, int conformCount) const;
// 后台解析所有符合数数据(单线程串行,内存稳定)
void parseAllConformDataInBackground();
// 流式解析并计算单个符合数,内存占用<10MB
ConformityCalculatedResult streamParseAndCalculate(int conformCount, const QString& fileName);
// 显示指定符合数的数据(优先从历史/预计算缓存加载)
void displayConformData(int conformCount);
// 释放所有缓存数据
void clearAllCachedData();
// 读取csv文件仅用于点击板卡时按需加载
QVector<particleCoincidenceEvent*> readCsv(const QString& fileName);
// 释放事件数组内存
void freeEventVector(QVector<particleCoincidenceEvent*>& vec);
private:
Ui::ConformityAnalysis *ui;
QString m_fileName;
int m_boardChannel[MAX_BOARD][MAX_CHANNEL];
// 当前显示的符合数数据(仅保留当前显示的原始数据)
QVector<particleCoincidenceEvent*> _currentSpectrumData;
double m_dFirstStart = 0.0;//初级粒子起始能量
double m_dFirstEnd = 0.0;//初级粒子终止能量
double m_dSecondStart = 0.0;//次级粒子起始能量
double m_dSecondEnd = 0.0;//次级粒子终止能量
int m_iComply = 0;//符合事件总计数
int m_currentConformCount = 2; // 当前选中的符合粒子数默认2重
// 数据持久化相关成员变量
QString _workspace; // 项目工作空间路径
QList<ConformityHistoryItem> _conformityHistoryList; // 所有历史记录列表
// 预计算结果缓存(仅保存计算后的数据,内存占用极小)
QMap<int, ConformityCalculatedResult> m_calculatedCache;
QMutex m_cacheMutex; // 缓存访问互斥锁
QMutex m_historyMutex; // 历史记录访问互斥锁
QFutureWatcher<void>* m_parseWatcher = nullptr; // 后台解析监视器
QMap<int, QString> m_conformFileMap; // 符合数->文件路径映射
bool m_isParsing = false; // 是否正在解析
};
#endif // CONFORMITYANALYSIS_H