#ifndef CONFORMITYANALYSIS_H #define CONFORMITYANALYSIS_H #include #include #include "ParticleDataStatistics.h" #include "ThreeDDisplay.h" #include "csv.h" #include "MeasureAnalysisView.h" #include #include #include #include #include #include #include #include #include #include // 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 firstParticleData; // 三维曲面数据 QVector 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 firstParticleData; // 三维曲面数据 QVector 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 m_FirstParticle; QMap m_subordinate; QVector m_beginVector; QVector m_secondVector; QVector m_surfaceData; public: explicit ConformityAnalysis(QWidget *parent = nullptr); ~ConformityAnalysis(); virtual void InitViewWorkspace(const QString& project_name) override final; virtual void SetAnalyzeDataFilename(const QMap& 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& data, int boardChannelData[MAX_BOARD][MAX_CHANNEL]); //统计每个板卡的初级粒子计数 QMap statisticsFirstParticleQuantity(const QVector& data); //处理当前板卡初级粒子信息 QVector handleBasicSubordinate(int Board, int Channel, const QVector& data); //处理次级粒子信息 QMap handleSubordinate(QVector &eventData,int Board, int Channel); // 获取最大值 int getMaxValue(); //计算全部的初级粒子范围 和 次级粒子范围 void calculateFirstSecondRange(const QVector& data, double& firstStart, double& firstEnd, double& secondStart, double& secondEnd); //设置板卡数据信息 void setAllBoardData(); //设置符合事件相关信息 void setThreeUiData(); //全部谱图数据处理 QVector generateSurfaceData(const QVector events); // 数据保存/加载核心方法(按符合数分文件) void loadHistoryFromFile(); void saveHistoryToFile(); // 流式写入JSON(零大小限制) void saveJsonStream(int conformCount, const ConformityHistoryItem& item); // 二进制保存超大曲面数据 void saveSurfaceDataToBinary(int conformCount, const QVector& 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 readCsv(const QString& fileName); // 释放事件数组内存 void freeEventVector(QVector& vec); private: Ui::ConformityAnalysis *ui; QString m_fileName; int m_boardChannel[MAX_BOARD][MAX_CHANNEL]; // 当前显示的符合数数据(仅保留当前显示的原始数据) QVector _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 _conformityHistoryList; // 所有历史记录列表 // 预计算结果缓存(仅保存计算后的数据,内存占用极小) QMap m_calculatedCache; QMutex m_cacheMutex; // 缓存访问互斥锁 QMutex m_historyMutex; // 历史记录访问互斥锁 QFutureWatcher* m_parseWatcher = nullptr; // 后台解析监视器 QMap m_conformFileMap; // 符合数->文件路径映射 bool m_isParsing = false; // 是否正在解析 }; #endif // CONFORMITYANALYSIS_H