EnergySpectrumAnalyer/src/EnergyCountPeakFitView/EnergyCountPeakFitView.h
2026-05-13 11:29:36 +08:00

166 lines
5.5 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; // 峰面积
};
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();
void saveCurrentFitToHistory(); // 保存当前拟合结果
void displayFitFromHistory(const PeakFitHistoryItem& item); // 显示历史拟合曲线
// 处理鼠标悬停检测
void updateHoverState(const QPoint& mousePos);
// 显示选中的曲线
void displaySelectedCurves(const QList<FitCurveData>& curves, const QList<DisplayedCurveRef>& 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<PeakFitResult> performPeakFitting(const QVector<double>& x, const QVector<double>& y /*, const arma::vec* userP0 = nullptr*/);
// 根据拟合参数生成曲线
QwtPlotCurve* createFitCurve(const PeakFitResult& result, double xMin, double xMax, const QString& name);
QList<QwtPlotCurve*> 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<PlotRectItem*> _selectionRectItems;
QwtPlotCurve* _fittedCurve = nullptr; // 显示拟合结果的曲线
// 存储当前显示的拟合曲线,用于清除
QList<QwtPlotCurve*> _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<CurrentFitRecord> _currentFitRecords;
// 历史记录列表
QList<PeakFitHistoryItem> _fitHistoryList;
// 当前悬停的框选区域
PlotRectItem* _hoveredRectItem = nullptr;
QList<DisplayedCurveRef> _displayedHistoryCurves;
};
#endif // ENERGYCOUNTPEAKFITVIEW_H