Compare commits

..

No commits in common. "1c80d3fcfe4983b7f312b0154b3afac77ce5c1b5" and "e04e2bf28b87ec6a6f02a523098ce12daa132e86" have entirely different histories.

4 changed files with 1 additions and 369 deletions

View File

@ -1,260 +0,0 @@
#include "ParticleTimePoorView.h"
#include "ui_ParticleTimePoorView.h"
#include <QVBoxLayout>
#include <QPushButton>
#include <QMessageBox>
#include <QwtPlotCurve>
#include <QwtPlotMarker>
#include <QwtPlotZoneItem>
#include <QwtPlotCanvas>
#include <QwtPlotHistogram>
#include <QwtLegend>
#include <QwtText>
#include <cmath>
#include <QtMath>
#include "CustomQwtPlot.h"
#include <QDebug>
#include <GlobalDefine.h>
#include <QPen>
ParticleTimePoorView::ParticleTimePoorView(QWidget *parent) :
MeasureAnalysisView(parent),
ui(new Ui::ParticleTimePoorView)
{
ui->setupUi(this);
this->setViewType(PlotFrame);
InitUi();
}
ParticleTimePoorView::~ParticleTimePoorView()
{
delete ui;
}
void ParticleTimePoorView::InitViewWorkspace(const QString &project_name)
{
}
#include <QwtScaleWidget>
void ParticleTimePoorView::SetAnalyzeDataFilename(const QMap<QString, QVariant> &data_files_set)
{
if (data_files_set.isEmpty()) {
LOG_WARN("文件集合为空");
return;
}
QString filePath = data_files_set.first().toString();
LOG_INFO("读取文件: " + filePath);
io::CSVReader<4> in(QStrToSysPath(filePath));
in.read_header(io::ignore_extra_column, "板卡号", "通道号", "道址", "时间计数");
int board, channel;
double energy, time_count;
QVector<uint64_t> timestamps;
while (in.read_row(board, channel, energy, time_count)) {
timestamps.append(static_cast<uint64_t>(time_count));
}
if (timestamps.size() < 2) {
qDebug() << "数据不足,无法计算时间差";
return;
}
// 1. 统计时间差分布
const int nNs = 50; // 分组宽度
QMap<uint64_t, int> mapVal;
for (int i = 0; i < timestamps.size() - 1; ++i) {
uint64_t diff = timestamps[i+1] - timestamps[i];
uint64_t binIndex = diff / nNs;
mapVal[binIndex]++;
}
// 2. 准备直方图数据
QVector<QwtIntervalSample> histogramData;
double xMin = 0.0, xMax = 0.0; // 用于记录实际数据的最小/最大 x 值
int nmaxy = 0;
QMap<uint64_t, int>::iterator it = mapVal.begin();
for (; it != mapVal.end(); ++it) {
uint64_t binIndex = it.key();
int count = it.value();
double center = binIndex * nNs + nNs / 2.0;
double halfWidth = (nNs - 1) / 2.0;
double left = center - halfWidth;
double right = center + halfWidth;
if (left < xMin) xMin = left;
if (right > xMax) xMax = right;
QwtInterval interval(left, right);
histogramData.append(QwtIntervalSample(count, interval));
if (count > nmaxy) nmaxy = count;
}
// 3. 创建直方图
QwtPlotHistogram* histogram = new QwtPlotHistogram();
histogram->setSamples(histogramData); // 注意QwtPlotHistogram 使用 setData()
histogram->setBrush(QBrush(QColor(23, 229, 238)));
histogram->setStyle(QwtPlotHistogram::Columns);
histogram->attach(plot);
m_histogram = histogram; // 保存指针以便后续动态调整 y 轴
// ========== 修改后的 x 轴范围设置 ==========
const double MAX_DISPLAY_TIME = 5000.0; // 最大显示时间差 (ns),可根据需求调整
// 确保 xMin 不为负
if (xMin < 0.0) xMin = 0.0;
// x 轴显示上限:取实际数据最大值和 MAX_DISPLAY_TIME 的最小值
double xDisplayMax = qMin(xMax, MAX_DISPLAY_TIME);
// 如果实际数据最大值小于最大显示上限,则使用实际最大值;否则使用限制值
if (xDisplayMax <= xMin) xDisplayMax = xMin + 1.0; // 防止空范围
plot->setAxisScale(QwtPlot::xBottom, xMin, xDisplayMax);
plot->setAxisScale(QwtPlot::yLeft, 0, nmaxy * 1.05);
// ==========================================
// 4. 启用水平拖拽
QwtPlotPanner* panner = new QwtPlotPanner(plot->canvas());
panner->setAxisEnabled(QwtPlot::yLeft, false);
panner->setAxisEnabled(QwtPlot::xBottom, true);
// 获取 x 轴的 QwtScaleWidget
QwtScaleWidget* xAxisWidget = plot->axisWidget(QwtPlot::xBottom);
if (xAxisWidget) {
// 连接 x 轴的 scaleDivChanged 信号(无参版本)
connect(xAxisWidget, &QwtScaleWidget::scaleDivChanged, this,
[this]() {
if (m_histogram) {
// 获取当前 x 轴范围
const QwtScaleDiv& scaleDiv = plot->axisScaleDiv(QwtPlot::xBottom);
double min = scaleDiv.lowerBound();
double max = scaleDiv.upperBound();
// 计算当前 x 可见范围内的最大计数值
double maxY = 0.0;
const QwtSeriesData<QwtIntervalSample>* data = m_histogram->data();
if (data) {
for (int i = 0; i < data->size(); ++i) {
QwtIntervalSample sample = data->sample(i);
if (sample.interval.intersects(QwtInterval(min, max))) {
if (sample.value > maxY)
maxY = sample.value;
}
}
}
if (maxY == 0.0) maxY = 1.0;
plot->setAxisScale(QwtPlot::yLeft, 0, maxY * 1.05);
plot->replot();
}
});
}
// 6. 设置轴标题
plot->setAxisTitle(QwtPlot::xBottom, QStringLiteral(u"时间差 (ns)"));
plot->setAxisTitle(QwtPlot::yLeft, QStringLiteral(u"粒子计数"));
plot->replot();
LOG_INFO("直方图已添加并刷新");
}
void ParticleTimePoorView::setData(QVector<ParticleInjectTime> data)
{
// int energyStart = ui->label_energyStart->text().toInt();
// int energyEnd = ui->label_energyEnd->text().toInt();
// QVector<double> x;
// QVector<double> y;
// double minValue = 0;
// double maxValue = 0;
// for(auto info : data)
// {
// if(info.dEnergy <= energyStart || info.dEnergy >= energyEnd)
// {
// continue;
// }
// x.append(info.index);
// y.append(info.dTime);
// minValue = qMin(minValue, info.dTime);
// maxValue = qMax(maxValue, info.dTime);
// }
// // 创建曲线并设置数据
// QwtPlotCurve *curve = new QwtPlotCurve();
// curve->setSamples(x, y);
// // 将曲线添加到 CustomQwtPlot 中(会自动分配颜色)
// plot->AddCurve(curve);
// // 设置坐标轴范围和标题
//// plot->setAxisScale(QwtPlot::xBottom, 0, x.last());
//// plot->setAxisScale(QwtPlot::yLeft,minValue , maxValue);
// LOG_INFO(QStringLiteral(u"%1数据读取完毕.").arg(this->GetViewName()));
// // 刷新绘图
// plot->replot();
}
QVector<ParticleInjectTime> ParticleTimePoorView::getParticleInjectTimeData(QString path)
{
QVector<ParticleInjectTime> records;
io::CSVReader<4> in(QStrToSysPath(path));
in.read_header(io::ignore_extra_column, "板卡号", "通道号", "能量(KeV)", "时间计数");
int board, channel;
double energy, time_count;
int lineNumber = 0;
// 逐行读取
while (in.read_row(board, channel, energy, time_count))
{
int detector = board + channel * 8;
lineNumber++;
if(detector >= 32)
{
continue;
}
ParticleInjectTime rec;
rec.index = lineNumber;
rec.dEnergy = energy;
rec.dTime = time_count;
records.append(rec);
}
return records;
}
void ParticleTimePoorView::InitUi()
{
plot = new CustomQwtPlot();
plot->SetXaxisDragScale(true);
setupPlot();
ui->verticalLayout_2->addWidget(plot);
}
void ParticleTimePoorView::setupPlot()
{
plot->setCanvasBackground(Qt::white);
QwtPlotCanvas* canvas = qobject_cast<QwtPlotCanvas*>(plot->canvas());
canvas->setFrameStyle(QFrame::NoFrame);
plot->setAxisTitle(QwtPlot::xBottom, QStringLiteral(u"粒子计数"));
plot->setAxisTitle(QwtPlot::yLeft, QStringLiteral(u"时间差"));
// set axis auto scale
plot->setAxisAutoScale(QwtPlot::xBottom, true);
plot->setAxisAutoScale(QwtPlot::yLeft, true);
// 启用网格线
plot->enableAxis(QwtPlot::xBottom);
plot->enableAxis(QwtPlot::yLeft);
// // 设置QWT图例
// QwtLegend* legend = new QwtLegend();
// legend->setDefaultItemMode(QwtLegendData::ReadOnly);
// plot->insertLegend(legend, QwtPlot::RightLegend);
plot->SetXaxisDragScale(true);
}

View File

@ -1,44 +0,0 @@
#ifndef PARTICLETIMEPOORVIEW_H
#define PARTICLETIMEPOORVIEW_H
#include <QWidget>
#include "qwt.h"
#include "CustomQwtPlot.h"
#include <QFile>
#include <QTextStream>
#include "MeasureAnalysisView.h"
#include "csv.h"
#include <QwtPlotHistogram>
namespace Ui {
class ParticleTimePoorView;
}
class ParticleTimePoorView : public MeasureAnalysisView
{
Q_OBJECT
public:
explicit ParticleTimePoorView(QWidget *parent = nullptr);
virtual ~ParticleTimePoorView();
virtual void InitViewWorkspace(const QString& project_name) override final;
virtual void SetAnalyzeDataFilename(const QMap<QString, QVariant>& data_files_set);
void setData(QVector<ParticleInjectTime> data);
//获取数据
QVector<ParticleInjectTime> getParticleInjectTimeData(QString path);
private:
void InitUi();
void setupPlot();
private:
Ui::ParticleTimePoorView *ui;
CustomQwtPlot *plot;
QVector<ParticleInjectTime> m_AllData;//存储的所有的粒子入射时间数据
QwtPlotHistogram* m_histogram;
};
#endif // PARTICLEINJECTTIMEANALYSIS_H

View File

@ -1,64 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ParticleTimePoorView</class>
<widget class="QWidget" name="ParticleTimePoorView">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>997</width>
<height>307</height>
</rect>
</property>
<property name="windowTitle">
<string>ParticleInjectTimeAnalysis</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

View File

@ -71,7 +71,7 @@ SOURCES += \
VirtualTable/SampleDataSource.cpp \
VirtualTable/VirtualTableModel.cpp \
VirtualTable/VirtualTableView.cpp \
ParticleTimePoorView/ParticleTimePoorView.cpp \
ParticleTimePoorView/ParticleTimePoorView.cpp\
main.cpp
HEADERS += \