EnergySpectrumAnalyer/src/EnergyCountPeakFitView/EnergyCountPeakFitView.h

173 lines
5.8 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 ENERGYCOUNTPEAKFITVIEW_H
#define ENERGYCOUNTPEAKFITVIEW_H
#include "PeakFitParamsDialog.h"
#include <MeasureAnalysisView.h>
#include <QDateTime>
#include <QJsonArray>
#include <QJsonObject>
#include <QObject>
#include <QRubberBand>
#include <QWidget>
#include <QwtPickerDragRectMachine>
#include <QwtPlotPicker>
#include <qwt_plot_shapeitem.h>
#include "DataCalcProcess/AdaptiveSimpsonIntegrate.h"
#include "DataCalcProcess/FindPeaksBySvd.h"
#include "DataCalcProcess/MathModelDefine.h"
#include "DataCalcProcess/NolinearLeastSquaresCurveFit.h"
struct PeakFitResult {
double center; // 峰中心能量 (keV)
double amplitude; // 高斯振幅
double sigma; // 高斯宽度
double fwhm; // 半高宽 = sigma * 2.355
double area; // 峰面积(积分)
double baseline; // 常数项 C
double sigmoidH; // Sigmoid 项高度 H
double sigmoidW; // Sigmoid 项宽度 W
};
struct FitCurveData {
double amplitude; // 峰幅度
double sigma; // 高斯sigma
double sigmoidH; // Sigmoid高度
double sigmoidW; // Sigmoid宽度
double baseline; // 本底
double center; // 峰中心
double xMin; // 曲线X范围最小值
double xMax; // 曲线X范围最大值
QRectF selectionRect; // 关联的框选区域
double fwhm; // 半高宽
double area; // 峰面积
int selectionIndex; // 框选区域在_selectionRectItems中的索引
int curveStartIndex; // 拟合曲线在_fitCurves中的起始索引每条对应2条曲线
};
struct PeakFitHistoryItem {
QDateTime timestamp;
QList<FitCurveData> curveList; // 存储多条曲线
QJsonObject toJson() const;
static PeakFitHistoryItem fromJson(const QJsonObject& obj);
};
struct CurrentFitRecord {
PeakFitResult result; // 拟合结果
arma::vec params; // 完整拟合参数
double xMin; // X范围最小值
double xMax; // X范围最大值
int historyIndex; // 对应_fitHistoryList中的索引-1表示未保存
CurrentFitRecord()
: historyIndex(-1)
{
} // 构造函数初始化
};
struct DisplayedCurveRef {
int historyIndex; // 对应 _fitHistoryList 的索引
int curveIndex; // 对应 curveList 的索引
int curveStartIndex; // 对应 _fitCurves 中的起始索引一条历史曲线对应2条Qwt曲线拟合+本底)
int rectIndex; // 对应 _selectionRectItems 中的索引
};
class PlotRectItem; // 前向声明
class QMenu;
class CustomQwtPlot;
class CustomQwtPlotXaxisSelector;
class QwtPlotPicker;
class QwtPlotCurve;
class BusyIndicator;
class EnergyCountPeakFitView : public MeasureAnalysisView {
Q_OBJECT
public:
EnergyCountPeakFitView(QWidget* parent = nullptr);
virtual ~EnergyCountPeakFitView();
virtual void InitViewWorkspace(const QString& project_name) override final;
virtual void SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set);
private:
void setupPlot();
void setupMenu();
void loadDataFromFile(const QString& data_name, const QString& filename);
void loadHistoryFromFile();
void saveHistoryToFile();
int saveCurrentFitToHistory(const QRectF& selectionRect);
// 处理鼠标悬停检测
void updateHoverState(const QPoint& mousePos);
// 显示选中的曲线
void displaySelectedCurves(const QList<FitCurveData>& curves, const QList<DisplayedCurveRef>& refs);
//检查指定历史曲线是否当前正在显示
bool isHistoryCurveDisplayed(int historyIndex, int curveIndex) const;
private slots:
void onActionCurveShowSetting();
void onActionPlotConfigure();
void clearAllSelectionRects();
void clearFitCurves(); // 清除所有拟合曲线
void onActionShowFitHistory();
void onActionDeleteHoveredRect();
// 重新拟合当前悬停的框选区域
void onActionRefitCurrentRect();
void onNewFitResultAdded(); // 新拟合结果同步刷新槽
void onHistoryDlgClosed(); // 历史对话框关闭清理槽
protected:
bool eventFilter(QObject* watched, QEvent* event) override; // 事件过滤器
private:
void startSelection(const QPoint& pos);
void updateSelection(const QPoint& pos);
void finishSelection();
void addSelectionRect(const QRectF& plotRect,int index);
void fadeSelectionRectBorders();
QList<PeakFitResult> performPeakFitting(const QVector<double>& x, const QVector<double>& y /*, const arma::vec* userP0 = nullptr*/);
// 根据拟合参数生成曲线
QList<QwtPlotCurve*> createFitCurve(const PeakFitResult& result, arma::vec xVec);
// 更新历史对话框并保持指定的选中状态
void updateHistoryDialogWithSelection(const QList<DisplayedCurveRef>& selectedRefs);
signals:
void newFitResultAdded();
private:
CustomQwtPlot* _plot = nullptr;
QMenu* _menu = nullptr;
QDialog* _curve_show_setting_dlg = nullptr;
CustomQwtPlotXaxisSelector* _data_selector = nullptr;
// 手动框选状态
bool _isSelecting = false;
QPoint _selectionStart;
QRubberBand* _rubberBand = nullptr; // 原生橡皮筋
QList<PlotRectItem*> _selectionRectItems;
QwtPlotCurve* _fittedCurve = nullptr; // 显示拟合结果的曲线
// 存储当前显示的拟合曲线,用于清除
QList<QwtPlotCurve*> _fitCurves;
QString _historyFilePath;
PeakFitResult _lastFitResult;
arma::vec _lastFitParams; // 6个拟合参数 (A, delt, H, W, C, P)
double _lastXMin = 0.0, _lastXMax = 0.0;
bool _hasLastFit = false;
QString _workspace;
// 存储当前所有拟合结果(用于多曲线管理)
QList<CurrentFitRecord> _currentFitRecords;
// 历史记录列表
QList<PeakFitHistoryItem> _fitHistoryList;
// 当前悬停的框选区域
PlotRectItem* _hoveredRectItem = nullptr;
QList<DisplayedCurveRef> _displayedHistoryCurves;
QDialog* _historyDlg = nullptr; // 跟踪当前打开的峰拟合结果对话框
};
#endif // ENERGYCOUNTPEAKFITVIEW_H