#ifndef ENERGYCOUNTPEAKFITVIEW_H #define ENERGYCOUNTPEAKFITVIEW_H #include "PeakFitParamsDialog.h" #include #include #include #include #include #include // 新增 #include #include #include #include // 新增 #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; // 峰面积 }; struct PeakFitHistoryItem { QDateTime timestamp; QList 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& data_files_set); private: void setupPlot(); void setupMenu(); void loadDataFromFile(const QString& data_name, const QString& filename); void loadHistoryFromFile(); void saveHistoryToFile(); void saveCurrentFitToHistory(); // 保存当前拟合结果 void displayFitFromHistory(const PeakFitHistoryItem& item); // 显示历史拟合曲线 // 处理鼠标悬停检测 void updateHoverState(const QPoint& mousePos); // 显示选中的曲线 void displaySelectedCurves(const QList& curves, const QList& refs); private slots: void onActionCurveShowSetting(); void onActionPlotConfigure(); void clearAllSelectionRects(); void clearFitCurves(); // 清除所有拟合曲线 void onActionSaveCurrentFit(); void onActionShowFitHistory(); void onActionDeleteHoveredRect(); // 重新拟合当前悬停的框选区域 void onActionRefitCurrentRect(); 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); void fadeSelectionRectBorders(); QList performPeakFitting(const QVector& x, const QVector& y /*, const arma::vec* userP0 = nullptr*/); // 根据拟合参数生成曲线 QwtPlotCurve* createFitCurve(const PeakFitResult& result, double xMin, double xMax, const QString& name); QList createFitCurve(const PeakFitResult& result, arma::vec xVec); 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 _selectionRectItems; QwtPlotCurve* _fittedCurve = nullptr; // 显示拟合结果的曲线 // 存储当前显示的拟合曲线,用于清除 QList _fitCurves; QString _historyFilePath; // [NEW] 最近一次拟合结果(用于手动保存) 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 _currentFitRecords; // 历史记录列表 QList _fitHistoryList; // 当前悬停的框选区域 PlotRectItem* _hoveredRectItem = nullptr; QList _displayedHistoryCurves; }; #endif // ENERGYCOUNTPEAKFITVIEW_H