EnergySpectrumAnalyer/src/AntiConformEnergySpectrumView/AntiConformEnergySpectrumView.cpp
徐海 d1d5b1d3d0 1、修改添加图表的还原
2、修改bug
3、更新测量数据接收代码
2026-05-12 20:57:54 +08:00

180 lines
5.4 KiB
C++

#include "AntiConformEnergySpectrumView.h"
#include "BusyIndicator.h"
#include "CustomQwtPlot.h"
#include "csv.h"
#include <GlobalDefine.h>
#include <QFileInfo>
#include <QMenu>
#include <QPen>
#include <QThread>
#include <QVBoxLayout>
#include <QwtPlotCanvas>
#include <QwtPlotCurve>
#include <QwtText>
#include <algorithm>
#include <cstdint>
#include <map>
#include <vector>
struct SpectrumData {
int board_id;
int channel_id;
double energy;
uint64_t timestamp;
};
AntiConformEnergySpectrumView::AntiConformEnergySpectrumView(QWidget* parent)
: MeasureAnalysisView(parent)
{
this->setViewType(PlotFrame);
this->_menu = new QMenu(this);
setupMenu();
_plot = new CustomQwtPlot();
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(_plot);
_plot->setCanvasBackground(Qt::white);
QwtPlotCanvas* canvas = qobject_cast<QwtPlotCanvas*>(_plot->canvas());
canvas->setFrameStyle(QFrame::NoFrame);
QFont font = this->font();
font.setBold(false);
QwtText x_label = QStringLiteral(u"能量(KeV)");
QwtText y_label = QStringLiteral(u"反符合事件次数");
x_label.setFont(font);
y_label.setFont(font);
_plot->setAxisTitle(QwtPlot::xBottom, x_label);
_plot->setAxisTitle(QwtPlot::yLeft, y_label);
_plot->setAxisAutoScale(QwtPlot::xBottom, true);
_plot->setAxisAutoScale(QwtPlot::yLeft, true);
_plot->enableAxis(QwtPlot::xBottom);
_plot->enableAxis(QwtPlot::yLeft);
_plot->SetAxisDragScale(QwtPlot::xBottom, true);
_plot->SetAxisDragScale(QwtPlot::yLeft, true);
_curve = new QwtPlotCurve();
_curve->setStyle(QwtPlotCurve::Lines);
_curve->setPen(QPen(QColor(23, 229, 238), 2));
_plot->AddCurve(_curve);
_busy_indicator = new BusyIndicator(this);
}
AntiConformEnergySpectrumView::~AntiConformEnergySpectrumView()
{
}
void AntiConformEnergySpectrumView::InitViewWorkspace(const QString& project_name)
{
Q_UNUSED(project_name);
}
void AntiConformEnergySpectrumView::SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set)
{
const QString& data_filename = data_files_set.first().toString();
if (!data_filename.isEmpty() && QFileInfo(data_filename).exists()) {
this->_data_filename = data_filename;
this->loadAndProcess();
}
}
void AntiConformEnergySpectrumView::loadAndProcess()
{
auto functionToRun = [this]() {
if (_data_filename.isEmpty())
return;
_busy_indicator->Start();
std::vector<SpectrumData> rawData;
io::CSVReader<4> in(QStrToSysPath(_data_filename));
in.read_header(io::ignore_extra_column,
QString(QStringLiteral(u"板卡号")).toStdString(),
QString(QStringLiteral(u"通道号")).toStdString(),
QString(QStringLiteral(u"能量(KeV)")).toStdString(),
QString(QStringLiteral(u"时间计数")).toStdString());
int board, channel;
double energy;
unsigned long long time_count;
while (in.read_row(board, channel, energy, time_count)) {
SpectrumData sd;
sd.board_id = board;
sd.channel_id = channel;
sd.energy = energy;
sd.timestamp = time_count;
rawData.push_back(sd);
}
if (rawData.empty()) {
_busy_indicator->Stop();
return;
}
const int STEP = 1;
std::map<int, double> hist;
for (const auto& spdt : rawData) {
int idx = static_cast<int>(spdt.energy) / STEP;
hist[idx] += 1.0;
}
QVector<double> vx, vy;
for (const auto& pair : hist) {
vx.push_back(pair.first * STEP);
vy.push_back(pair.second);
}
if (vx.isEmpty()) {
_busy_indicator->Stop();
return;
}
double dmaxx = *std::max_element(vx.begin(), vx.end());
double dmaxy = *std::max_element(vy.begin(), vy.end());
QMetaObject::invokeMethod(this, [this, vx, vy, dmaxx, dmaxy]() {
_curve->setSamples(vx, vy);
_plot->SetAxisInitRange(QwtPlot::xBottom, 0.0f, dmaxx);
_plot->SetAxisInitRange(QwtPlot::yLeft, 0.0f, dmaxy);
_plot->replot();
_busy_indicator->Stop(); }, Qt::QueuedConnection);
};
QThread* load_thread = QThread::create(functionToRun);
load_thread->start();
}
void AntiConformEnergySpectrumView::onActionPlotConfigure()
{
}
void AntiConformEnergySpectrumView::showEvent(QShowEvent* e)
{
Q_UNUSED(e);
if (_busy_indicator) {
_busy_indicator->setGeometry(this->rect());
this->update();
}
}
void AntiConformEnergySpectrumView::setupMenu()
{
this->setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &AntiConformEnergySpectrumView::customContextMenuRequested, [this](const QPoint& pos) {
this->_menu->exec(this->mapToGlobal(pos));
});
QAction* action_plot_reset = this->_menu->addAction(QStringLiteral(u"还原"));
action_plot_reset->setObjectName("plot_reset");
connect(action_plot_reset, &QAction::triggered, [this]() {
this->_plot->ResetPlot();
});
this->_menu->addSeparator();
QAction* action_plot_config = this->_menu->addAction(QStringLiteral(u"图表配置"));
action_plot_config->setObjectName("plot_config");
connect(action_plot_config, &QAction::triggered, this, &AntiConformEnergySpectrumView::onActionPlotConfigure);
}