166 lines
5.5 KiB
C++
166 lines
5.5 KiB
C++
#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
|